All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] soc/fsl: add freescale dir for SOC specific drivers
@ 2014-09-26  6:48 Dongsheng Wang
  2014-09-26  6:48 ` [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform Dongsheng Wang
  0 siblings, 1 reply; 14+ messages in thread
From: Dongsheng Wang @ 2014-09-26  6:48 UTC (permalink / raw)
  To: santosh.shilimkar, sandeep_n, olof, galak, shawn.guo
  Cc: gregkh, paul, arnd, dongsheng.wang, linux-kernel, shawn.guo

From: Wang Dongsheng <dongsheng.wang@freescale.com>

Some Freescale device drivers need to move to soc/, because these drivers
are specific drivers. Before the soc/ to be created, the drivers had been
there arch/ or drivers/misc/, but now soc/ dir is a better choice.

Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index c854385..063af9e 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,4 +2,17 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/qcom/Kconfig"
 
+config	FSL_SOC_DRIVERS
+	bool "Freescale Soc Drivers"
+	depends on FSL_SOC || ARCH_MXC
+	default n
+	help
+	Say y here to enable Freescale Soc Device Drivers support.
+	The Soc Drivers provides the device driver that is a specific block
+	or feature on Freescale platform.
+
+if FSL_SOC_DRIVERS
+	source "drivers/soc/fsl/Kconfig"
+endif
+
 endmenu
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 3b1b95d..b8f32c3 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
+obj-$(CONFIG_FSL_SOC_DRIVERS)	+= fsl/
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 0000000..72df9b3
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,3 @@
+if ARM
+source "drivers/soc/fsl/Kconfig.arm"
+endif
diff --git a/drivers/soc/fsl/Kconfig.arm b/drivers/soc/fsl/Kconfig.arm
new file mode 100644
index 0000000..8c90b82
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig.arm
@@ -0,0 +1,16 @@
+#
+# Freescale ARM SOC Drivers
+#
+
+config	LS1_SOC_DRIVERS
+	bool "LS1021A Soc Drivers"
+	depends on SOC_LS1021A
+	default n
+	help
+	Say y here to enable Freescale LS1021A Soc Device Drivers support.
+	The Soc Drivers provides the device driver that is a specific block
+	or feature on LS1021A platform.
+
+if LS1_SOC_DRIVERS
+	source "drivers/soc/fsl/ls1/Kconfig"
+endif
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
new file mode 100644
index 0000000..5ca0e1c
--- /dev/null
+++ b/drivers/soc/fsl/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for ls1 Soc specific device drivers.
+#
+
+obj-$(CONFIG_LS1_SOC_DRIVERS) += ls1/
diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig
new file mode 100644
index 0000000..7556f44
--- /dev/null
+++ b/drivers/soc/fsl/ls1/Kconfig
@@ -0,0 +1,3 @@
+#
+# LS-1 Soc drivers
+#
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
  2014-09-26  6:48 [PATCH 1/2] soc/fsl: add freescale dir for SOC specific drivers Dongsheng Wang
@ 2014-09-26  6:48 ` Dongsheng Wang
  2014-09-26 14:04   ` Kumar Gala
  0 siblings, 1 reply; 14+ messages in thread
From: Dongsheng Wang @ 2014-09-26  6:48 UTC (permalink / raw)
  To: santosh.shilimkar, sandeep_n, olof, galak, shawn.guo
  Cc: gregkh, paul, arnd, dongsheng.wang, linux-kernel, shawn.guo

From: Wang Dongsheng <dongsheng.wang@freescale.com>

Only Ftm0 can be used when system going to deep sleep. So this driver
to support ftm0 as a wakeup source.

Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>

diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig
index 7556f44..c9b04c4 100644
--- a/drivers/soc/fsl/ls1/Kconfig
+++ b/drivers/soc/fsl/ls1/Kconfig
@@ -1,3 +1,11 @@
 #
 # LS-1 Soc drivers
 #
+config  FTM_ALARM
+	bool "FTM alarm driver"
+	depends on SOC_LS1021A
+	default n
+	help
+	Say y here to enable FTM alarm support.  The FTM alarm provides
+	alarm functions for wakeup system from deep sleep.  There is only
+	one FTM can be used in ALARM(FTM 0).
diff --git a/drivers/soc/fsl/ls1/Makefile b/drivers/soc/fsl/ls1/Makefile
new file mode 100644
index 0000000..6299aa1
--- /dev/null
+++ b/drivers/soc/fsl/ls1/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FTM_ALARM) += ftm_alarm.o
diff --git a/drivers/soc/fsl/ls1/ftm_alarm.c b/drivers/soc/fsl/ls1/ftm_alarm.c
new file mode 100644
index 0000000..f7629cd
--- /dev/null
+++ b/drivers/soc/fsl/ls1/ftm_alarm.c
@@ -0,0 +1,272 @@
+/*
+ * Freescale FlexTimer Module (FTM) Alarm driver.
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#define FTM_SC			0x00
+#define FTM_SC_CLK_SHIFT	3
+#define FTM_SC_CLK_MASK		(0x3 << FTM_SC_CLK_SHIFT)
+#define FTM_SC_CLK(c)		((c) << FTM_SC_CLK_SHIFT)
+#define FTM_SC_PS_MASK		0x7
+#define FTM_SC_TOIE		BIT(6)
+#define FTM_SC_TOF		BIT(7)
+
+#define FTM_SC_CLKS_FIXED_FREQ	0x02
+
+#define FTM_CNT			0x04
+#define FTM_MOD			0x08
+#define FTM_CNTIN		0x4C
+
+#define FIXED_FREQ_CLK		32000
+#define MAX_FREQ_DIV		(1 << FTM_SC_PS_MASK)
+#define MAX_COUNT_VAL		0xffff
+
+static void __iomem *ftm1_base;
+static u32 alarm_freq;
+static bool big_endian;
+
+static inline u32 ftm_readl(void __iomem *addr)
+{
+	if (big_endian)
+		return ioread32be(addr);
+
+	return ioread32(addr);
+}
+
+static inline void ftm_writel(u32 val, void __iomem *addr)
+{
+	if (big_endian)
+		iowrite32be(val, addr);
+	else
+		iowrite32(val, addr);
+}
+
+static inline void ftm_counter_enable(void __iomem *base)
+{
+	u32 val;
+
+	/* select and enable counter clock source */
+	val = ftm_readl(base + FTM_SC);
+	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_counter_disable(void __iomem *base)
+{
+	u32 val;
+
+	/* disable counter clock source */
+	val = ftm_readl(base + FTM_SC);
+	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_acknowledge(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val &= ~FTM_SC_TOF;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_enable(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val |= FTM_SC_TOIE;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_disable(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val &= ~FTM_SC_TOIE;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_reset_counter(void __iomem *base)
+{
+	/*
+	 * The CNT register contains the FTM counter value.
+	 * Reset clears the CNT register. Writing any value to COUNT
+	 * updates the counter with its initial value, CNTIN.
+	 */
+	ftm_writel(0x00, base + FTM_CNT);
+}
+
+static u32 time_to_cycle(unsigned long time)
+{
+	u32 cycle;
+
+	cycle = time * alarm_freq;
+	if (cycle > MAX_COUNT_VAL) {
+		pr_err("Out of alarm range.\n");
+		cycle = 0;
+	}
+
+	return cycle;
+}
+
+static u32 cycle_to_time(u32 cycle)
+{
+	return cycle / alarm_freq + 1;
+}
+
+static void ftm_clean_alarm(void)
+{
+	ftm_counter_disable(ftm1_base);
+
+	ftm_writel(0x00, ftm1_base + FTM_CNTIN);
+	ftm_writel(~0UL, ftm1_base + FTM_MOD);
+
+	ftm_reset_counter(ftm1_base);
+}
+
+static int ftm_set_alarm(u64 cycle)
+{
+	ftm_irq_disable(ftm1_base);
+
+	/*
+	 * The counter increments until the value of MOD is reached,
+	 * at which point the counter is reloaded with the value of CNTIN.
+	 * The TOF (the overflow flag) bit is set when the FTM counter
+	 * changes from MOD to CNTIN. So we should using the cycle - 1.
+	 */
+	ftm_writel(cycle - 1, ftm1_base + FTM_MOD);
+
+	ftm_counter_enable(ftm1_base);
+
+	ftm_irq_enable(ftm1_base);
+
+	return 0;
+}
+
+static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
+{
+	ftm_irq_acknowledge(ftm1_base);
+	ftm_irq_disable(ftm1_base);
+	ftm_clean_alarm();
+
+	return IRQ_HANDLED;
+}
+
+static ssize_t ftm_alarm_show(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	u32 count, val;
+
+	count = ftm_readl(ftm1_base + FTM_MOD);
+	val = ftm_readl(ftm1_base + FTM_CNT);
+	val = (count & MAX_COUNT_VAL) - val;
+	val = cycle_to_time(val);
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ftm_alarm_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	u32 cycle;
+	unsigned long time;
+
+	if (kstrtoul(buf, 0, &time))
+		return -EINVAL;
+
+	ftm_clean_alarm();
+
+	cycle = time_to_cycle(time);
+	if (!cycle)
+		return -EINVAL;
+
+	ftm_set_alarm(cycle);
+
+	return count;
+}
+
+static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
+			ftm_alarm_show, ftm_alarm_store);
+
+static int ftm_alarm_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *r;
+	int irq;
+	int ret;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -ENODEV;
+
+	ftm1_base = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(ftm1_base))
+		return PTR_ERR(ftm1_base);
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq <= 0) {
+		pr_err("ftm: unable to get IRQ from DT, %d\n", irq);
+		return -EINVAL;
+	}
+
+	big_endian = of_property_read_bool(np, "big-endian");
+
+	ret = devm_request_irq(&pdev->dev, irq, ftm_alarm_interrupt,
+			       IRQF_NO_SUSPEND, dev_name(&pdev->dev), NULL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to request irq\n");
+		return ret;
+	}
+
+	ret = device_create_file(&pdev->dev, &ftm_alarm_attributes);
+	if (ret) {
+		dev_err(&pdev->dev, "create sysfs fail.\n");
+		return ret;
+	}
+
+	alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
+
+	ftm_clean_alarm();
+
+	return ret;
+}
+
+static const struct of_device_id ftm_alarm_match[] = {
+	{ .compatible = "fsl,ftm-alarm", },
+	{ .compatible = "fsl,ftm-timer", },
+	{ },
+};
+
+static struct platform_driver ftm_alarm_driver = {
+	.probe		= ftm_alarm_probe,
+	.driver		= {
+		.name	= "ftm-alarm",
+		.owner	= THIS_MODULE,
+		.of_match_table = ftm_alarm_match,
+	},
+};
+
+static int __init ftm_alarm_init(void)
+{
+	return platform_driver_register(&ftm_alarm_driver);
+}
+device_initcall(ftm_alarm_init);
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
  2014-09-26  6:48 ` [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform Dongsheng Wang
@ 2014-09-26 14:04   ` Kumar Gala
  2014-09-28  2:55     ` Dongsheng.Wang
  0 siblings, 1 reply; 14+ messages in thread
From: Kumar Gala @ 2014-09-26 14:04 UTC (permalink / raw)
  To: Dongsheng Wang
  Cc: Santosh Shilimkar, Sandeep Nair, Olof Johansson, shawn.guo,
	Greg KH, Paul Walmsley, Arnd Bergmann, linux-kernel, shawn.guo


On Sep 26, 2014, at 1:48 AM, Dongsheng Wang <dongsheng.wang@freescale.com> wrote:

> From: Wang Dongsheng <dongsheng.wang@freescale.com>
> 
> Only Ftm0 can be used when system going to deep sleep. So this driver
> to support ftm0 as a wakeup source.
> 
> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>

How does this differ from drivers/clocksource/fsl_ftm_timer.c

Why not extend that with the alarm functionality you need?

Also, where is the DT binding spec for this (if you plan on having a separate driver)?

- k

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
  2014-09-26 14:04   ` Kumar Gala
@ 2014-09-28  2:55     ` Dongsheng.Wang
  0 siblings, 0 replies; 14+ messages in thread
From: Dongsheng.Wang @ 2014-09-28  2:55 UTC (permalink / raw)
  To: Kumar Gala
  Cc: Santosh Shilimkar, Sandeep Nair, Olof Johansson, shawn.guo,
	Greg KH, Paul Walmsley, Arnd Bergmann, linux-kernel,
	Shengchao Guo

Thanks for your review. :)


> -----Original Message-----
> From: Kumar Gala [mailto:galak@codeaurora.org]
> Sent: Friday, September 26, 2014 10:04 PM
> To: Wang Dongsheng-B40534
> Cc: Santosh Shilimkar; Sandeep Nair; Olof Johansson; shawn.guo@linaro.org; Greg
> KH; Paul Walmsley; Arnd Bergmann; linux-kernel@vger.kernel.org; Guo Shawn-R65073
> Subject: Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
> 
> 
> On Sep 26, 2014, at 1:48 AM, Dongsheng Wang <dongsheng.wang@freescale.com> wrote:
> 
> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> >
> > Only Ftm0 can be used when system going to deep sleep. So this driver
> > to support ftm0 as a wakeup source.
> >
> > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> 
> How does this differ from drivers/clocksource/fsl_ftm_timer.c

Fsl_ftm_timer.c is only for system to provide a clock driver. FTM ip-block can be used
by other functions such as PWM. I think we should not put all of functions into a .c file.
So ftm0 alarm function as a specific block driver in SOC dir.

> 
> Why not extend that with the alarm functionality you need?
The framework of clocksource not provide sys interface to set alarm. And codes of ftm0-alarm
not touch on clocksource framework.

> 
> Also, where is the DT binding spec for this (if you plan on having a separate
> driver)?
Yes, now only a driver. My DT depend on LS1 device tree patches, now LS1 DT is upstreaming but not apply.
After LS1 DT apply, I will add ftm alarm device node.

Regards,
-Dongsheng

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
  2015-08-14 10:06         ` Linus Walleij
@ 2015-08-21  3:07           ` Wang Dongsheng
  -1 siblings, 0 replies; 14+ messages in thread
From: Wang Dongsheng @ 2015-08-21  3:07 UTC (permalink / raw)
  To: Linus Walleij, John Stultz, Russell King - ARM Linux
  Cc: Alessandro Zummo, Alexandre Belloni, Shawn Guo, Nair, Sandeep,
	Hans de Goede, Huan Wang, linux-arm-kernel, linux-kernel,
	rtc-linux

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 5988 bytes --]

Hi Walleij and Russell,

I will drop this patch. Thanks for your review.

[PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers

But the 1/2 of the patches also need, because there has another patch(Freescale FPGA driver) need 1/2 patch.
Need I push the 1/2 patch with another patches(Freescale FPGA driver) or push 1/2 standalone without another
patch? 

Regards,
-Dongsheng

> -----Original Message-----
> From: Linus Walleij [mailto:linus.walleij@linaro.org]
> Sent: Friday, August 14, 2015 6:07 PM
> To: Wang Dongsheng-B40534; John Stultz
> Cc: Alessandro Zummo; Alexandre Belloni; Shawn Guo; Nair, Sandeep; Hans de Goede;
> Wang Huan-B18965; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; rtc-linux@googlegroups.com
> Subject: Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
> 
> On Fri, Aug 14, 2015 at 5:12 AM, Wang Dongsheng
> <Dongsheng.Wang@freescale.com> wrote:
> >> On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
> >> <dongsheng.wang@freescale.com> wrote:
> >>
> >> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> >> >
> >> > Only Ftm0 can be used when system going to deep sleep. So this driver
> >> > to support ftm0 as a wakeup source.
> >> >
> >> > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> >> > ---
> >> > *V2*
> >> > Change Copyright 2014 to 2015.
> >> (...)
> >> > +config FTM_ALARM
> >> > +       bool "FTM alarm driver"
> >> > +       depends on SOC_LS1021A
> >> > +       default n
> >> > +       help
> >> > +         Say y here to enable FTM alarm support.  The FTM alarm provides
> >> > +         alarm functions for wakeup system from deep sleep.  There is only
> >> > +         one FTM can be used in ALARM(FTM 0).
> >> (...)
> >> > +static u32 time_to_cycle(unsigned long time)
> >> > +static u32 cycle_to_time(u32 cycle)
> >> > +static int ftm_set_alarm(u64 cycle)
> >> > +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
> >> > +static ssize_t ftm_alarm_show(struct device *dev,
> >> > +                             struct device_attribute *attr,
> >> > +                             char *buf)
> >> > +static ssize_t ftm_alarm_store(struct device *dev,
> >> > +                              struct device_attribute *attr,
> >> > +                              const char *buf, size_t count)
> >> (...)
> >> > +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm,
> 0644,
> >> > +                       ftm_alarm_show, ftm_alarm_store);
> >>
> >> If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.
> >>
> >> But I don't get it. Why is this driver not in drivers/rtc?
> >>
> >> It does a subset of what an RTC does. The ioctl()'s of an RTC
> >> can do what you want to do. And much much more.
> >>
> >> If it can't do all an RTC can do, surely the RTC subsystem
> >> can be augmented to host it anyway. It's way to close to
> >> an RTC to have it's own random sysfs driver like this.
> >>
> >> Unless I'm totally off, rewrite this to an RTC driver and post
> >> it to the RTC maintainers.
> >
> > FlexTimer is not a RTC device and not have any rtc deivce function. They
> belong to
> > different devices, why we need to register this to RTC framework? I am
> confused about this.
> >
> > Now in freescale layerscape platform this driver is only for FlexTimer0, and
> not
> > fit for each flextimer. Because only FlexTimer0 still turn-on when system in
> the Deep Sleep.
> >
> > If the "alarm" make you feel confused or mislead you think this is a RTC
> devices. I think
> > I need to change the "alarm" to "timer".
> 
> I think it is an RTC, it is just that the hardware engineer
> designed it with a wakeup usecase in mind and did not call
> it an RTC. Wakeup is one of the things RTCs do.
> 
> If you inspect a few drivers in drivers/rtc such as drivers/rtc/rtc-pl030.c
> you will find that they are just as crude as this "alarm" thing.
> 
> It has a counter that counts cycles, it has a comparator
> and an alarm function. It is an on-chip RTC, just like PL030
> no matter what the datasheet or hardware engineer thinks it
> should be called, the Linux kernel calls this an RTC, and it
> has a subsystem for handling it, so we should use it and
> not invent random new stuff.
> 
> If the hardware is really so strange that the counter can only
> be started if you also put an alarm at the same time (I doubt
> it, but OK if you say so) it is a subset of an RTC that can
> only be used for alarms but not timekeeping, but it should
> *still* live in drivers/rtc.
> 
> Think for a moment on the huge effort that John Stultz put into
> integrating Android alarm timers with POSIX and the RTC
> subsystem and fixing it all from the smallest handset to
> the largest S360 supercomputer. The approach of a custom
> device just throws all of that out the window and reinvents the
> mechanism in userspace, forcing all standardized userspace to
> have special code to handle this special alarm with its
> special sysfs ABI.
> 
> Check
> commit ff3ead96d17f47ee70c294a5cc2cce9b61e82f0f
> "timers: Introduce in-kernel alarm-timer interface"
> for example.
> 
> Even if you persist on keeping it in its own magic driver
> like this, it should implement the alarm timer interface
> from <linux/alarmtimer.h> and I bet after that you don't
> need the sysfs files anymore, as the system will sleep
> and wake up from the regular syscalls instead of using
> magic poking in sysfs from userspace. AFAICT this hardware
> is designed for exactly this usecase.
> 
> tools/testing/selftests/timers/alarmtimer-suspend.c
> is there for you to test your driver with alarmtimer
> support.
> 
> Needless to say: if you implement it as an RTC you get the
> alarmtimer interaction for free. That is why we have the
> subsystem after all: to be helpful.
> 
> Yours,
> Linus Walleij
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
@ 2015-08-21  3:07           ` Wang Dongsheng
  0 siblings, 0 replies; 14+ messages in thread
From: Wang Dongsheng @ 2015-08-21  3:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Walleij and Russell,

I will drop this patch. Thanks for your review.

[PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers

But the 1/2 of the patches also need, because there has another patch(Freescale FPGA driver) need 1/2 patch.
Need I push the 1/2 patch with another patches(Freescale FPGA driver) or push 1/2 standalone without another
patch? 

Regards,
-Dongsheng

> -----Original Message-----
> From: Linus Walleij [mailto:linus.walleij at linaro.org]
> Sent: Friday, August 14, 2015 6:07 PM
> To: Wang Dongsheng-B40534; John Stultz
> Cc: Alessandro Zummo; Alexandre Belloni; Shawn Guo; Nair, Sandeep; Hans de Goede;
> Wang Huan-B18965; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; rtc-linux at googlegroups.com
> Subject: Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
> 
> On Fri, Aug 14, 2015 at 5:12 AM, Wang Dongsheng
> <Dongsheng.Wang@freescale.com> wrote:
> >> On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
> >> <dongsheng.wang@freescale.com> wrote:
> >>
> >> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> >> >
> >> > Only Ftm0 can be used when system going to deep sleep. So this driver
> >> > to support ftm0 as a wakeup source.
> >> >
> >> > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> >> > ---
> >> > *V2*
> >> > Change Copyright 2014 to 2015.
> >> (...)
> >> > +config FTM_ALARM
> >> > +       bool "FTM alarm driver"
> >> > +       depends on SOC_LS1021A
> >> > +       default n
> >> > +       help
> >> > +         Say y here to enable FTM alarm support.  The FTM alarm provides
> >> > +         alarm functions for wakeup system from deep sleep.  There is only
> >> > +         one FTM can be used in ALARM(FTM 0).
> >> (...)
> >> > +static u32 time_to_cycle(unsigned long time)
> >> > +static u32 cycle_to_time(u32 cycle)
> >> > +static int ftm_set_alarm(u64 cycle)
> >> > +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
> >> > +static ssize_t ftm_alarm_show(struct device *dev,
> >> > +                             struct device_attribute *attr,
> >> > +                             char *buf)
> >> > +static ssize_t ftm_alarm_store(struct device *dev,
> >> > +                              struct device_attribute *attr,
> >> > +                              const char *buf, size_t count)
> >> (...)
> >> > +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm,
> 0644,
> >> > +                       ftm_alarm_show, ftm_alarm_store);
> >>
> >> If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.
> >>
> >> But I don't get it. Why is this driver not in drivers/rtc?
> >>
> >> It does a subset of what an RTC does. The ioctl()'s of an RTC
> >> can do what you want to do. And much much more.
> >>
> >> If it can't do all an RTC can do, surely the RTC subsystem
> >> can be augmented to host it anyway. It's way to close to
> >> an RTC to have it's own random sysfs driver like this.
> >>
> >> Unless I'm totally off, rewrite this to an RTC driver and post
> >> it to the RTC maintainers.
> >
> > FlexTimer is not a RTC device and not have any rtc deivce function. They
> belong to
> > different devices, why we need to register this to RTC framework? I am
> confused about this.
> >
> > Now in freescale layerscape platform this driver is only for FlexTimer0, and
> not
> > fit for each flextimer. Because only FlexTimer0 still turn-on when system in
> the Deep Sleep.
> >
> > If the "alarm" make you feel confused or mislead you think this is a RTC
> devices. I think
> > I need to change the "alarm" to "timer".
> 
> I think it is an RTC, it is just that the hardware engineer
> designed it with a wakeup usecase in mind and did not call
> it an RTC. Wakeup is one of the things RTCs do.
> 
> If you inspect a few drivers in drivers/rtc such as drivers/rtc/rtc-pl030.c
> you will find that they are just as crude as this "alarm" thing.
> 
> It has a counter that counts cycles, it has a comparator
> and an alarm function. It is an on-chip RTC, just like PL030
> no matter what the datasheet or hardware engineer thinks it
> should be called, the Linux kernel calls this an RTC, and it
> has a subsystem for handling it, so we should use it and
> not invent random new stuff.
> 
> If the hardware is really so strange that the counter can only
> be started if you also put an alarm at the same time (I doubt
> it, but OK if you say so) it is a subset of an RTC that can
> only be used for alarms but not timekeeping, but it should
> *still* live in drivers/rtc.
> 
> Think for a moment on the huge effort that John Stultz put into
> integrating Android alarm timers with POSIX and the RTC
> subsystem and fixing it all from the smallest handset to
> the largest S360 supercomputer. The approach of a custom
> device just throws all of that out the window and reinvents the
> mechanism in userspace, forcing all standardized userspace to
> have special code to handle this special alarm with its
> special sysfs ABI.
> 
> Check
> commit ff3ead96d17f47ee70c294a5cc2cce9b61e82f0f
> "timers: Introduce in-kernel alarm-timer interface"
> for example.
> 
> Even if you persist on keeping it in its own magic driver
> like this, it should implement the alarm timer interface
> from <linux/alarmtimer.h> and I bet after that you don't
> need the sysfs files anymore, as the system will sleep
> and wake up from the regular syscalls instead of using
> magic poking in sysfs from userspace. AFAICT this hardware
> is designed for exactly this usecase.
> 
> tools/testing/selftests/timers/alarmtimer-suspend.c
> is there for you to test your driver with alarmtimer
> support.
> 
> Needless to say: if you implement it as an RTC you get the
> alarmtimer interaction for free. That is why we have the
> subsystem after all: to be helpful.
> 
> Yours,
> Linus Walleij

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
  2015-08-14  3:12       ` Wang Dongsheng
@ 2015-08-14 10:06         ` Linus Walleij
  -1 siblings, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2015-08-14 10:06 UTC (permalink / raw)
  To: Wang Dongsheng, John Stultz
  Cc: Alessandro Zummo, Alexandre Belloni, Shawn Guo, Nair, Sandeep,
	Hans de Goede, Huan Wang, linux-arm-kernel, linux-kernel,
	rtc-linux

On Fri, Aug 14, 2015 at 5:12 AM, Wang Dongsheng
<Dongsheng.Wang@freescale.com> wrote:
>> On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
>> <dongsheng.wang@freescale.com> wrote:
>>
>> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
>> >
>> > Only Ftm0 can be used when system going to deep sleep. So this driver
>> > to support ftm0 as a wakeup source.
>> >
>> > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
>> > ---
>> > *V2*
>> > Change Copyright 2014 to 2015.
>> (...)
>> > +config FTM_ALARM
>> > +       bool "FTM alarm driver"
>> > +       depends on SOC_LS1021A
>> > +       default n
>> > +       help
>> > +         Say y here to enable FTM alarm support.  The FTM alarm provides
>> > +         alarm functions for wakeup system from deep sleep.  There is only
>> > +         one FTM can be used in ALARM(FTM 0).
>> (...)
>> > +static u32 time_to_cycle(unsigned long time)
>> > +static u32 cycle_to_time(u32 cycle)
>> > +static int ftm_set_alarm(u64 cycle)
>> > +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
>> > +static ssize_t ftm_alarm_show(struct device *dev,
>> > +                             struct device_attribute *attr,
>> > +                             char *buf)
>> > +static ssize_t ftm_alarm_store(struct device *dev,
>> > +                              struct device_attribute *attr,
>> > +                              const char *buf, size_t count)
>> (...)
>> > +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
>> > +                       ftm_alarm_show, ftm_alarm_store);
>>
>> If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.
>>
>> But I don't get it. Why is this driver not in drivers/rtc?
>>
>> It does a subset of what an RTC does. The ioctl()'s of an RTC
>> can do what you want to do. And much much more.
>>
>> If it can't do all an RTC can do, surely the RTC subsystem
>> can be augmented to host it anyway. It's way to close to
>> an RTC to have it's own random sysfs driver like this.
>>
>> Unless I'm totally off, rewrite this to an RTC driver and post
>> it to the RTC maintainers.
>
> FlexTimer is not a RTC device and not have any rtc deivce function. They belong to
> different devices, why we need to register this to RTC framework? I am confused about this.
>
> Now in freescale layerscape platform this driver is only for FlexTimer0, and not
> fit for each flextimer. Because only FlexTimer0 still turn-on when system in the Deep Sleep.
>
> If the "alarm" make you feel confused or mislead you think this is a RTC devices. I think
> I need to change the "alarm" to "timer".

I think it is an RTC, it is just that the hardware engineer
designed it with a wakeup usecase in mind and did not call
it an RTC. Wakeup is one of the things RTCs do.

If you inspect a few drivers in drivers/rtc such as drivers/rtc/rtc-pl030.c
you will find that they are just as crude as this "alarm" thing.

It has a counter that counts cycles, it has a comparator
and an alarm function. It is an on-chip RTC, just like PL030
no matter what the datasheet or hardware engineer thinks it
should be called, the Linux kernel calls this an RTC, and it
has a subsystem for handling it, so we should use it and
not invent random new stuff.

If the hardware is really so strange that the counter can only
be started if you also put an alarm at the same time (I doubt
it, but OK if you say so) it is a subset of an RTC that can
only be used for alarms but not timekeeping, but it should
*still* live in drivers/rtc.

Think for a moment on the huge effort that John Stultz put into
integrating Android alarm timers with POSIX and the RTC
subsystem and fixing it all from the smallest handset to
the largest S360 supercomputer. The approach of a custom
device just throws all of that out the window and reinvents the
mechanism in userspace, forcing all standardized userspace to
have special code to handle this special alarm with its
special sysfs ABI.

Check
commit ff3ead96d17f47ee70c294a5cc2cce9b61e82f0f
"timers: Introduce in-kernel alarm-timer interface"
for example.

Even if you persist on keeping it in its own magic driver
like this, it should implement the alarm timer interface
from <linux/alarmtimer.h> and I bet after that you don't
need the sysfs files anymore, as the system will sleep
and wake up from the regular syscalls instead of using
magic poking in sysfs from userspace. AFAICT this hardware
is designed for exactly this usecase.

tools/testing/selftests/timers/alarmtimer-suspend.c
is there for you to test your driver with alarmtimer
support.

Needless to say: if you implement it as an RTC you get the
alarmtimer interaction for free. That is why we have the
subsystem after all: to be helpful.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
@ 2015-08-14 10:06         ` Linus Walleij
  0 siblings, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2015-08-14 10:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Aug 14, 2015 at 5:12 AM, Wang Dongsheng
<Dongsheng.Wang@freescale.com> wrote:
>> On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
>> <dongsheng.wang@freescale.com> wrote:
>>
>> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
>> >
>> > Only Ftm0 can be used when system going to deep sleep. So this driver
>> > to support ftm0 as a wakeup source.
>> >
>> > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
>> > ---
>> > *V2*
>> > Change Copyright 2014 to 2015.
>> (...)
>> > +config FTM_ALARM
>> > +       bool "FTM alarm driver"
>> > +       depends on SOC_LS1021A
>> > +       default n
>> > +       help
>> > +         Say y here to enable FTM alarm support.  The FTM alarm provides
>> > +         alarm functions for wakeup system from deep sleep.  There is only
>> > +         one FTM can be used in ALARM(FTM 0).
>> (...)
>> > +static u32 time_to_cycle(unsigned long time)
>> > +static u32 cycle_to_time(u32 cycle)
>> > +static int ftm_set_alarm(u64 cycle)
>> > +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
>> > +static ssize_t ftm_alarm_show(struct device *dev,
>> > +                             struct device_attribute *attr,
>> > +                             char *buf)
>> > +static ssize_t ftm_alarm_store(struct device *dev,
>> > +                              struct device_attribute *attr,
>> > +                              const char *buf, size_t count)
>> (...)
>> > +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
>> > +                       ftm_alarm_show, ftm_alarm_store);
>>
>> If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.
>>
>> But I don't get it. Why is this driver not in drivers/rtc?
>>
>> It does a subset of what an RTC does. The ioctl()'s of an RTC
>> can do what you want to do. And much much more.
>>
>> If it can't do all an RTC can do, surely the RTC subsystem
>> can be augmented to host it anyway. It's way to close to
>> an RTC to have it's own random sysfs driver like this.
>>
>> Unless I'm totally off, rewrite this to an RTC driver and post
>> it to the RTC maintainers.
>
> FlexTimer is not a RTC device and not have any rtc deivce function. They belong to
> different devices, why we need to register this to RTC framework? I am confused about this.
>
> Now in freescale layerscape platform this driver is only for FlexTimer0, and not
> fit for each flextimer. Because only FlexTimer0 still turn-on when system in the Deep Sleep.
>
> If the "alarm" make you feel confused or mislead you think this is a RTC devices. I think
> I need to change the "alarm" to "timer".

I think it is an RTC, it is just that the hardware engineer
designed it with a wakeup usecase in mind and did not call
it an RTC. Wakeup is one of the things RTCs do.

If you inspect a few drivers in drivers/rtc such as drivers/rtc/rtc-pl030.c
you will find that they are just as crude as this "alarm" thing.

It has a counter that counts cycles, it has a comparator
and an alarm function. It is an on-chip RTC, just like PL030
no matter what the datasheet or hardware engineer thinks it
should be called, the Linux kernel calls this an RTC, and it
has a subsystem for handling it, so we should use it and
not invent random new stuff.

If the hardware is really so strange that the counter can only
be started if you also put an alarm at the same time (I doubt
it, but OK if you say so) it is a subset of an RTC that can
only be used for alarms but not timekeeping, but it should
*still* live in drivers/rtc.

Think for a moment on the huge effort that John Stultz put into
integrating Android alarm timers with POSIX and the RTC
subsystem and fixing it all from the smallest handset to
the largest S360 supercomputer. The approach of a custom
device just throws all of that out the window and reinvents the
mechanism in userspace, forcing all standardized userspace to
have special code to handle this special alarm with its
special sysfs ABI.

Check
commit ff3ead96d17f47ee70c294a5cc2cce9b61e82f0f
"timers: Introduce in-kernel alarm-timer interface"
for example.

Even if you persist on keeping it in its own magic driver
like this, it should implement the alarm timer interface
from <linux/alarmtimer.h> and I bet after that you don't
need the sysfs files anymore, as the system will sleep
and wake up from the regular syscalls instead of using
magic poking in sysfs from userspace. AFAICT this hardware
is designed for exactly this usecase.

tools/testing/selftests/timers/alarmtimer-suspend.c
is there for you to test your driver with alarmtimer
support.

Needless to say: if you implement it as an RTC you get the
alarmtimer interaction for free. That is why we have the
subsystem after all: to be helpful.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
  2015-08-13 13:54     ` Linus Walleij
@ 2015-08-14  3:12       ` Wang Dongsheng
  -1 siblings, 0 replies; 14+ messages in thread
From: Wang Dongsheng @ 2015-08-14  3:12 UTC (permalink / raw)
  To: Linus Walleij, John Stultz, Alessandro Zummo, Alexandre Belloni
  Cc: Shawn Guo, Nair, Sandeep, Hans de Goede, Huan Wang,
	linux-arm-kernel, linux-kernel, rtc-linux

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 3109 bytes --]



> -----Original Message-----
> From: Linus Walleij [mailto:linus.walleij@linaro.org]
> Sent: Thursday, August 13, 2015 9:54 PM
> To: Wang Dongsheng-B40534; John Stultz; Alessandro Zummo; Alexandre Belloni
> Cc: Shawn Guo; Nair, Sandeep; Hans de Goede; Wang Huan-B18965; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org; rtc-
> linux@googlegroups.com
> Subject: Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
> 
> On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
> <dongsheng.wang@freescale.com> wrote:
> 
> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> >
> > Only Ftm0 can be used when system going to deep sleep. So this driver
> > to support ftm0 as a wakeup source.
> >
> > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> > ---
> > *V2*
> > Change Copyright 2014 to 2015.
> (...)
> > +config FTM_ALARM
> > +       bool "FTM alarm driver"
> > +       depends on SOC_LS1021A
> > +       default n
> > +       help
> > +         Say y here to enable FTM alarm support.  The FTM alarm provides
> > +         alarm functions for wakeup system from deep sleep.  There is only
> > +         one FTM can be used in ALARM(FTM 0).
> (...)
> > +static u32 time_to_cycle(unsigned long time)
> > +static u32 cycle_to_time(u32 cycle)
> > +static int ftm_set_alarm(u64 cycle)
> > +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
> > +static ssize_t ftm_alarm_show(struct device *dev,
> > +                             struct device_attribute *attr,
> > +                             char *buf)
> > +static ssize_t ftm_alarm_store(struct device *dev,
> > +                              struct device_attribute *attr,
> > +                              const char *buf, size_t count)
> (...)
> > +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
> > +                       ftm_alarm_show, ftm_alarm_store);
> 
> If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.
> 
> But I don't get it. Why is this driver not in drivers/rtc?
> 
> It does a subset of what an RTC does. The ioctl()'s of an RTC
> can do what you want to do. And much much more.
> 
> If it can't do all an RTC can do, surely the RTC subsystem
> can be augmented to host it anyway. It's way to close to
> an RTC to have it's own random sysfs driver like this.
> 
> Unless I'm totally off, rewrite this to an RTC driver and post
> it to the RTC maintainers.
> 

FlexTimer is not a RTC device and not have any rtc deivce function. They belong to
different devices, why we need to register this to RTC framework? I am confused about this.

Now in freescale layerscape platform this driver is only for FlexTimer0, and not
fit for each flextimer. Because only FlexTimer0 still turn-on when system in the Deep Sleep.

If the "alarm" make you feel confused or mislead you think this is a RTC devices. I think
I need to change the "alarm" to "timer".

Regards,
-Dongsheng
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
@ 2015-08-14  3:12       ` Wang Dongsheng
  0 siblings, 0 replies; 14+ messages in thread
From: Wang Dongsheng @ 2015-08-14  3:12 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Linus Walleij [mailto:linus.walleij at linaro.org]
> Sent: Thursday, August 13, 2015 9:54 PM
> To: Wang Dongsheng-B40534; John Stultz; Alessandro Zummo; Alexandre Belloni
> Cc: Shawn Guo; Nair, Sandeep; Hans de Goede; Wang Huan-B18965; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org; rtc-
> linux at googlegroups.com
> Subject: Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
> 
> On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
> <dongsheng.wang@freescale.com> wrote:
> 
> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> >
> > Only Ftm0 can be used when system going to deep sleep. So this driver
> > to support ftm0 as a wakeup source.
> >
> > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> > ---
> > *V2*
> > Change Copyright 2014 to 2015.
> (...)
> > +config FTM_ALARM
> > +       bool "FTM alarm driver"
> > +       depends on SOC_LS1021A
> > +       default n
> > +       help
> > +         Say y here to enable FTM alarm support.  The FTM alarm provides
> > +         alarm functions for wakeup system from deep sleep.  There is only
> > +         one FTM can be used in ALARM(FTM 0).
> (...)
> > +static u32 time_to_cycle(unsigned long time)
> > +static u32 cycle_to_time(u32 cycle)
> > +static int ftm_set_alarm(u64 cycle)
> > +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
> > +static ssize_t ftm_alarm_show(struct device *dev,
> > +                             struct device_attribute *attr,
> > +                             char *buf)
> > +static ssize_t ftm_alarm_store(struct device *dev,
> > +                              struct device_attribute *attr,
> > +                              const char *buf, size_t count)
> (...)
> > +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
> > +                       ftm_alarm_show, ftm_alarm_store);
> 
> If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.
> 
> But I don't get it. Why is this driver not in drivers/rtc?
> 
> It does a subset of what an RTC does. The ioctl()'s of an RTC
> can do what you want to do. And much much more.
> 
> If it can't do all an RTC can do, surely the RTC subsystem
> can be augmented to host it anyway. It's way to close to
> an RTC to have it's own random sysfs driver like this.
> 
> Unless I'm totally off, rewrite this to an RTC driver and post
> it to the RTC maintainers.
> 

FlexTimer is not a RTC device and not have any rtc deivce function. They belong to
different devices, why we need to register this to RTC framework? I am confused about this.

Now in freescale layerscape platform this driver is only for FlexTimer0, and not
fit for each flextimer. Because only FlexTimer0 still turn-on when system in the Deep Sleep.

If the "alarm" make you feel confused or mislead you think this is a RTC devices. I think
I need to change the "alarm" to "timer".

Regards,
-Dongsheng

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
  2015-08-12  5:53   ` Dongsheng Wang
@ 2015-08-13 13:54     ` Linus Walleij
  -1 siblings, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2015-08-13 13:54 UTC (permalink / raw)
  To: Dongsheng Wang, John Stultz, Alessandro Zummo, Alexandre Belloni
  Cc: Shawn Guo, Nair, Sandeep, Hans de Goede, alison.wang,
	linux-arm-kernel, linux-kernel, rtc-linux

On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
<dongsheng.wang@freescale.com> wrote:

> From: Wang Dongsheng <dongsheng.wang@freescale.com>
>
> Only Ftm0 can be used when system going to deep sleep. So this driver
> to support ftm0 as a wakeup source.
>
> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> ---
> *V2*
> Change Copyright 2014 to 2015.
(...)
> +config FTM_ALARM
> +       bool "FTM alarm driver"
> +       depends on SOC_LS1021A
> +       default n
> +       help
> +         Say y here to enable FTM alarm support.  The FTM alarm provides
> +         alarm functions for wakeup system from deep sleep.  There is only
> +         one FTM can be used in ALARM(FTM 0).
(...)
> +static u32 time_to_cycle(unsigned long time)
> +static u32 cycle_to_time(u32 cycle)
> +static int ftm_set_alarm(u64 cycle)
> +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
> +static ssize_t ftm_alarm_show(struct device *dev,
> +                             struct device_attribute *attr,
> +                             char *buf)
> +static ssize_t ftm_alarm_store(struct device *dev,
> +                              struct device_attribute *attr,
> +                              const char *buf, size_t count)
(...)
> +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
> +                       ftm_alarm_show, ftm_alarm_store);

If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.

But I don't get it. Why is this driver not in drivers/rtc?

It does a subset of what an RTC does. The ioctl()'s of an RTC
can do what you want to do. And much much more.

If it can't do all an RTC can do, surely the RTC subsystem
can be augmented to host it anyway. It's way to close to
an RTC to have it's own random sysfs driver like this.

Unless I'm totally off, rewrite this to an RTC driver and post
it to the RTC maintainers.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
@ 2015-08-13 13:54     ` Linus Walleij
  0 siblings, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2015-08-13 13:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
<dongsheng.wang@freescale.com> wrote:

> From: Wang Dongsheng <dongsheng.wang@freescale.com>
>
> Only Ftm0 can be used when system going to deep sleep. So this driver
> to support ftm0 as a wakeup source.
>
> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> ---
> *V2*
> Change Copyright 2014 to 2015.
(...)
> +config FTM_ALARM
> +       bool "FTM alarm driver"
> +       depends on SOC_LS1021A
> +       default n
> +       help
> +         Say y here to enable FTM alarm support.  The FTM alarm provides
> +         alarm functions for wakeup system from deep sleep.  There is only
> +         one FTM can be used in ALARM(FTM 0).
(...)
> +static u32 time_to_cycle(unsigned long time)
> +static u32 cycle_to_time(u32 cycle)
> +static int ftm_set_alarm(u64 cycle)
> +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
> +static ssize_t ftm_alarm_show(struct device *dev,
> +                             struct device_attribute *attr,
> +                             char *buf)
> +static ssize_t ftm_alarm_store(struct device *dev,
> +                              struct device_attribute *attr,
> +                              const char *buf, size_t count)
(...)
> +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
> +                       ftm_alarm_show, ftm_alarm_store);

If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.

But I don't get it. Why is this driver not in drivers/rtc?

It does a subset of what an RTC does. The ioctl()'s of an RTC
can do what you want to do. And much much more.

If it can't do all an RTC can do, surely the RTC subsystem
can be augmented to host it anyway. It's way to close to
an RTC to have it's own random sysfs driver like this.

Unless I'm totally off, rewrite this to an RTC driver and post
it to the RTC maintainers.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
  2015-08-12  5:53 [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers Dongsheng Wang
@ 2015-08-12  5:53   ` Dongsheng Wang
  0 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Wang @ 2015-08-12  5:53 UTC (permalink / raw)
  To: shawn.guo
  Cc: linus.walleij, sandeep_n, hdegoede, alison.wang,
	linux-arm-kernel, linux-kernel, Wang Dongsheng

From: Wang Dongsheng <dongsheng.wang@freescale.com>

Only Ftm0 can be used when system going to deep sleep. So this driver
to support ftm0 as a wakeup source.

Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
---
*V2*
Change Copyright 2014 to 2015.

diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig
index 7556f44..e6282dc 100644
--- a/drivers/soc/fsl/ls1/Kconfig
+++ b/drivers/soc/fsl/ls1/Kconfig
@@ -1,3 +1,11 @@
 #
 # LS-1 Soc drivers
 #
+config	FTM_ALARM
+	bool "FTM alarm driver"
+	depends on SOC_LS1021A
+	default n
+	help
+	  Say y here to enable FTM alarm support.  The FTM alarm provides
+	  alarm functions for wakeup system from deep sleep.  There is only
+	  one FTM can be used in ALARM(FTM 0).
diff --git a/drivers/soc/fsl/ls1/Makefile b/drivers/soc/fsl/ls1/Makefile
new file mode 100644
index 0000000..6299aa1
--- /dev/null
+++ b/drivers/soc/fsl/ls1/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FTM_ALARM) += ftm_alarm.o
diff --git a/drivers/soc/fsl/ls1/ftm_alarm.c b/drivers/soc/fsl/ls1/ftm_alarm.c
new file mode 100644
index 0000000..f7629cd
--- /dev/null
+++ b/drivers/soc/fsl/ls1/ftm_alarm.c
@@ -0,0 +1,272 @@
+/*
+ * Freescale FlexTimer Module (FTM) Alarm driver.
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#define FTM_SC			0x00
+#define FTM_SC_CLK_SHIFT	3
+#define FTM_SC_CLK_MASK		(0x3 << FTM_SC_CLK_SHIFT)
+#define FTM_SC_CLK(c)		((c) << FTM_SC_CLK_SHIFT)
+#define FTM_SC_PS_MASK		0x7
+#define FTM_SC_TOIE		BIT(6)
+#define FTM_SC_TOF		BIT(7)
+
+#define FTM_SC_CLKS_FIXED_FREQ	0x02
+
+#define FTM_CNT			0x04
+#define FTM_MOD			0x08
+#define FTM_CNTIN		0x4C
+
+#define FIXED_FREQ_CLK		32000
+#define MAX_FREQ_DIV		(1 << FTM_SC_PS_MASK)
+#define MAX_COUNT_VAL		0xffff
+
+static void __iomem *ftm1_base;
+static u32 alarm_freq;
+static bool big_endian;
+
+static inline u32 ftm_readl(void __iomem *addr)
+{
+	if (big_endian)
+		return ioread32be(addr);
+
+	return ioread32(addr);
+}
+
+static inline void ftm_writel(u32 val, void __iomem *addr)
+{
+	if (big_endian)
+		iowrite32be(val, addr);
+	else
+		iowrite32(val, addr);
+}
+
+static inline void ftm_counter_enable(void __iomem *base)
+{
+	u32 val;
+
+	/* select and enable counter clock source */
+	val = ftm_readl(base + FTM_SC);
+	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_counter_disable(void __iomem *base)
+{
+	u32 val;
+
+	/* disable counter clock source */
+	val = ftm_readl(base + FTM_SC);
+	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_acknowledge(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val &= ~FTM_SC_TOF;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_enable(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val |= FTM_SC_TOIE;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_disable(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val &= ~FTM_SC_TOIE;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_reset_counter(void __iomem *base)
+{
+	/*
+	 * The CNT register contains the FTM counter value.
+	 * Reset clears the CNT register. Writing any value to COUNT
+	 * updates the counter with its initial value, CNTIN.
+	 */
+	ftm_writel(0x00, base + FTM_CNT);
+}
+
+static u32 time_to_cycle(unsigned long time)
+{
+	u32 cycle;
+
+	cycle = time * alarm_freq;
+	if (cycle > MAX_COUNT_VAL) {
+		pr_err("Out of alarm range.\n");
+		cycle = 0;
+	}
+
+	return cycle;
+}
+
+static u32 cycle_to_time(u32 cycle)
+{
+	return cycle / alarm_freq + 1;
+}
+
+static void ftm_clean_alarm(void)
+{
+	ftm_counter_disable(ftm1_base);
+
+	ftm_writel(0x00, ftm1_base + FTM_CNTIN);
+	ftm_writel(~0UL, ftm1_base + FTM_MOD);
+
+	ftm_reset_counter(ftm1_base);
+}
+
+static int ftm_set_alarm(u64 cycle)
+{
+	ftm_irq_disable(ftm1_base);
+
+	/*
+	 * The counter increments until the value of MOD is reached,
+	 * at which point the counter is reloaded with the value of CNTIN.
+	 * The TOF (the overflow flag) bit is set when the FTM counter
+	 * changes from MOD to CNTIN. So we should using the cycle - 1.
+	 */
+	ftm_writel(cycle - 1, ftm1_base + FTM_MOD);
+
+	ftm_counter_enable(ftm1_base);
+
+	ftm_irq_enable(ftm1_base);
+
+	return 0;
+}
+
+static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
+{
+	ftm_irq_acknowledge(ftm1_base);
+	ftm_irq_disable(ftm1_base);
+	ftm_clean_alarm();
+
+	return IRQ_HANDLED;
+}
+
+static ssize_t ftm_alarm_show(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	u32 count, val;
+
+	count = ftm_readl(ftm1_base + FTM_MOD);
+	val = ftm_readl(ftm1_base + FTM_CNT);
+	val = (count & MAX_COUNT_VAL) - val;
+	val = cycle_to_time(val);
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ftm_alarm_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	u32 cycle;
+	unsigned long time;
+
+	if (kstrtoul(buf, 0, &time))
+		return -EINVAL;
+
+	ftm_clean_alarm();
+
+	cycle = time_to_cycle(time);
+	if (!cycle)
+		return -EINVAL;
+
+	ftm_set_alarm(cycle);
+
+	return count;
+}
+
+static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
+			ftm_alarm_show, ftm_alarm_store);
+
+static int ftm_alarm_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *r;
+	int irq;
+	int ret;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -ENODEV;
+
+	ftm1_base = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(ftm1_base))
+		return PTR_ERR(ftm1_base);
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq <= 0) {
+		pr_err("ftm: unable to get IRQ from DT, %d\n", irq);
+		return -EINVAL;
+	}
+
+	big_endian = of_property_read_bool(np, "big-endian");
+
+	ret = devm_request_irq(&pdev->dev, irq, ftm_alarm_interrupt,
+			       IRQF_NO_SUSPEND, dev_name(&pdev->dev), NULL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to request irq\n");
+		return ret;
+	}
+
+	ret = device_create_file(&pdev->dev, &ftm_alarm_attributes);
+	if (ret) {
+		dev_err(&pdev->dev, "create sysfs fail.\n");
+		return ret;
+	}
+
+	alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
+
+	ftm_clean_alarm();
+
+	return ret;
+}
+
+static const struct of_device_id ftm_alarm_match[] = {
+	{ .compatible = "fsl,ftm-alarm", },
+	{ .compatible = "fsl,ftm-timer", },
+	{ },
+};
+
+static struct platform_driver ftm_alarm_driver = {
+	.probe		= ftm_alarm_probe,
+	.driver		= {
+		.name	= "ftm-alarm",
+		.owner	= THIS_MODULE,
+		.of_match_table = ftm_alarm_match,
+	},
+};
+
+static int __init ftm_alarm_init(void)
+{
+	return platform_driver_register(&ftm_alarm_driver);
+}
+device_initcall(ftm_alarm_init);
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
@ 2015-08-12  5:53   ` Dongsheng Wang
  0 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Wang @ 2015-08-12  5:53 UTC (permalink / raw)
  To: linux-arm-kernel

From: Wang Dongsheng <dongsheng.wang@freescale.com>

Only Ftm0 can be used when system going to deep sleep. So this driver
to support ftm0 as a wakeup source.

Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
---
*V2*
Change Copyright 2014 to 2015.

diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig
index 7556f44..e6282dc 100644
--- a/drivers/soc/fsl/ls1/Kconfig
+++ b/drivers/soc/fsl/ls1/Kconfig
@@ -1,3 +1,11 @@
 #
 # LS-1 Soc drivers
 #
+config	FTM_ALARM
+	bool "FTM alarm driver"
+	depends on SOC_LS1021A
+	default n
+	help
+	  Say y here to enable FTM alarm support.  The FTM alarm provides
+	  alarm functions for wakeup system from deep sleep.  There is only
+	  one FTM can be used in ALARM(FTM 0).
diff --git a/drivers/soc/fsl/ls1/Makefile b/drivers/soc/fsl/ls1/Makefile
new file mode 100644
index 0000000..6299aa1
--- /dev/null
+++ b/drivers/soc/fsl/ls1/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FTM_ALARM) += ftm_alarm.o
diff --git a/drivers/soc/fsl/ls1/ftm_alarm.c b/drivers/soc/fsl/ls1/ftm_alarm.c
new file mode 100644
index 0000000..f7629cd
--- /dev/null
+++ b/drivers/soc/fsl/ls1/ftm_alarm.c
@@ -0,0 +1,272 @@
+/*
+ * Freescale FlexTimer Module (FTM) Alarm driver.
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#define FTM_SC			0x00
+#define FTM_SC_CLK_SHIFT	3
+#define FTM_SC_CLK_MASK		(0x3 << FTM_SC_CLK_SHIFT)
+#define FTM_SC_CLK(c)		((c) << FTM_SC_CLK_SHIFT)
+#define FTM_SC_PS_MASK		0x7
+#define FTM_SC_TOIE		BIT(6)
+#define FTM_SC_TOF		BIT(7)
+
+#define FTM_SC_CLKS_FIXED_FREQ	0x02
+
+#define FTM_CNT			0x04
+#define FTM_MOD			0x08
+#define FTM_CNTIN		0x4C
+
+#define FIXED_FREQ_CLK		32000
+#define MAX_FREQ_DIV		(1 << FTM_SC_PS_MASK)
+#define MAX_COUNT_VAL		0xffff
+
+static void __iomem *ftm1_base;
+static u32 alarm_freq;
+static bool big_endian;
+
+static inline u32 ftm_readl(void __iomem *addr)
+{
+	if (big_endian)
+		return ioread32be(addr);
+
+	return ioread32(addr);
+}
+
+static inline void ftm_writel(u32 val, void __iomem *addr)
+{
+	if (big_endian)
+		iowrite32be(val, addr);
+	else
+		iowrite32(val, addr);
+}
+
+static inline void ftm_counter_enable(void __iomem *base)
+{
+	u32 val;
+
+	/* select and enable counter clock source */
+	val = ftm_readl(base + FTM_SC);
+	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_counter_disable(void __iomem *base)
+{
+	u32 val;
+
+	/* disable counter clock source */
+	val = ftm_readl(base + FTM_SC);
+	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_acknowledge(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val &= ~FTM_SC_TOF;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_enable(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val |= FTM_SC_TOIE;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_disable(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val &= ~FTM_SC_TOIE;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_reset_counter(void __iomem *base)
+{
+	/*
+	 * The CNT register contains the FTM counter value.
+	 * Reset clears the CNT register. Writing any value to COUNT
+	 * updates the counter with its initial value, CNTIN.
+	 */
+	ftm_writel(0x00, base + FTM_CNT);
+}
+
+static u32 time_to_cycle(unsigned long time)
+{
+	u32 cycle;
+
+	cycle = time * alarm_freq;
+	if (cycle > MAX_COUNT_VAL) {
+		pr_err("Out of alarm range.\n");
+		cycle = 0;
+	}
+
+	return cycle;
+}
+
+static u32 cycle_to_time(u32 cycle)
+{
+	return cycle / alarm_freq + 1;
+}
+
+static void ftm_clean_alarm(void)
+{
+	ftm_counter_disable(ftm1_base);
+
+	ftm_writel(0x00, ftm1_base + FTM_CNTIN);
+	ftm_writel(~0UL, ftm1_base + FTM_MOD);
+
+	ftm_reset_counter(ftm1_base);
+}
+
+static int ftm_set_alarm(u64 cycle)
+{
+	ftm_irq_disable(ftm1_base);
+
+	/*
+	 * The counter increments until the value of MOD is reached,
+	 * at which point the counter is reloaded with the value of CNTIN.
+	 * The TOF (the overflow flag) bit is set when the FTM counter
+	 * changes from MOD to CNTIN. So we should using the cycle - 1.
+	 */
+	ftm_writel(cycle - 1, ftm1_base + FTM_MOD);
+
+	ftm_counter_enable(ftm1_base);
+
+	ftm_irq_enable(ftm1_base);
+
+	return 0;
+}
+
+static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
+{
+	ftm_irq_acknowledge(ftm1_base);
+	ftm_irq_disable(ftm1_base);
+	ftm_clean_alarm();
+
+	return IRQ_HANDLED;
+}
+
+static ssize_t ftm_alarm_show(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	u32 count, val;
+
+	count = ftm_readl(ftm1_base + FTM_MOD);
+	val = ftm_readl(ftm1_base + FTM_CNT);
+	val = (count & MAX_COUNT_VAL) - val;
+	val = cycle_to_time(val);
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ftm_alarm_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	u32 cycle;
+	unsigned long time;
+
+	if (kstrtoul(buf, 0, &time))
+		return -EINVAL;
+
+	ftm_clean_alarm();
+
+	cycle = time_to_cycle(time);
+	if (!cycle)
+		return -EINVAL;
+
+	ftm_set_alarm(cycle);
+
+	return count;
+}
+
+static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
+			ftm_alarm_show, ftm_alarm_store);
+
+static int ftm_alarm_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *r;
+	int irq;
+	int ret;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -ENODEV;
+
+	ftm1_base = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(ftm1_base))
+		return PTR_ERR(ftm1_base);
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq <= 0) {
+		pr_err("ftm: unable to get IRQ from DT, %d\n", irq);
+		return -EINVAL;
+	}
+
+	big_endian = of_property_read_bool(np, "big-endian");
+
+	ret = devm_request_irq(&pdev->dev, irq, ftm_alarm_interrupt,
+			       IRQF_NO_SUSPEND, dev_name(&pdev->dev), NULL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to request irq\n");
+		return ret;
+	}
+
+	ret = device_create_file(&pdev->dev, &ftm_alarm_attributes);
+	if (ret) {
+		dev_err(&pdev->dev, "create sysfs fail.\n");
+		return ret;
+	}
+
+	alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
+
+	ftm_clean_alarm();
+
+	return ret;
+}
+
+static const struct of_device_id ftm_alarm_match[] = {
+	{ .compatible = "fsl,ftm-alarm", },
+	{ .compatible = "fsl,ftm-timer", },
+	{ },
+};
+
+static struct platform_driver ftm_alarm_driver = {
+	.probe		= ftm_alarm_probe,
+	.driver		= {
+		.name	= "ftm-alarm",
+		.owner	= THIS_MODULE,
+		.of_match_table = ftm_alarm_match,
+	},
+};
+
+static int __init ftm_alarm_init(void)
+{
+	return platform_driver_register(&ftm_alarm_driver);
+}
+device_initcall(ftm_alarm_init);
-- 
2.1.0.27.g96db324

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2015-08-21  3:22 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-26  6:48 [PATCH 1/2] soc/fsl: add freescale dir for SOC specific drivers Dongsheng Wang
2014-09-26  6:48 ` [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform Dongsheng Wang
2014-09-26 14:04   ` Kumar Gala
2014-09-28  2:55     ` Dongsheng.Wang
2015-08-12  5:53 [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers Dongsheng Wang
2015-08-12  5:53 ` [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform Dongsheng Wang
2015-08-12  5:53   ` Dongsheng Wang
2015-08-13 13:54   ` Linus Walleij
2015-08-13 13:54     ` Linus Walleij
2015-08-14  3:12     ` Wang Dongsheng
2015-08-14  3:12       ` Wang Dongsheng
2015-08-14 10:06       ` Linus Walleij
2015-08-14 10:06         ` Linus Walleij
2015-08-21  3:07         ` Wang Dongsheng
2015-08-21  3:07           ` Wang Dongsheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.