All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
@ 2016-10-24  1:42 ` Meng Yi
  0 siblings, 0 replies; 10+ messages in thread
From: Meng Yi @ 2016-10-24  1:42 UTC (permalink / raw)
  To: a.zummo, alexandre.belloni; +Cc: rtc-linux, linux-kernel, Meng Yi

For the platforms including LS1021A, LS1043A that has the
flextimer module, implementing alarm functions within RTC
subsystem to wakeup the system when system going to sleep.
Only Ftm0 can be used to wakeup the system.

Signed-off-by: Meng Yi <meng.yi@nxp.com>
---
 drivers/rtc/Kconfig       |   9 ++
 drivers/rtc/Makefile      |   1 +
 drivers/rtc/rtc-nxp-ftm.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 265 insertions(+)
 create mode 100644 drivers/rtc/rtc-nxp-ftm.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e859d14..0ba52b3 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1243,6 +1243,15 @@ config RTC_DRV_IMXDI
 	   This driver can also be built as a module, if so, the module
 	   will be called "rtc-imxdi".
 
+config RTC_DRV_NXP
+	tristate "NXP flextimer Real Time Alarm "
+	help
+	For the FlexTimer on LS1021A, LS1043A, we can use FTM0 as the wakeup
+	source.
+	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).
+
 config RTC_DRV_OMAP
 	tristate "TI OMAP Real Time Clock"
 	depends on ARCH_OMAP || ARCH_DAVINCI || COMPILE_TEST
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 1ac694a..abbf22c 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_RTC_DRV_GENERIC)	+= rtc-generic.o
 obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
 obj-$(CONFIG_RTC_DRV_HYM8563)	+= rtc-hym8563.o
 obj-$(CONFIG_RTC_DRV_IMXDI)	+= rtc-imxdi.o
+obj-$(CONFIG_RTC_DRV_NXP)	+= rtc-nxp-ftm.o
 obj-$(CONFIG_RTC_DRV_ISL12022)	+= rtc-isl12022.o
 obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o
 obj-$(CONFIG_RTC_DRV_JZ4740)	+= rtc-jz4740.o
diff --git a/drivers/rtc/rtc-nxp-ftm.c b/drivers/rtc/rtc-nxp-ftm.c
new file mode 100644
index 0000000..74c4358
--- /dev/null
+++ b/drivers/rtc/rtc-nxp-ftm.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * NXP FTM alarm device driver
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/of_irq.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
+
+struct ftm_rtc {
+	struct rtc_device *rtc_dev;
+	void __iomem *base;
+	bool endian;
+	u32 alarm_freq;
+};
+
+static struct ftm_rtc rtc;
+
+static inline u32 ftm_readl(void __iomem *addr)
+{
+	return rtc.endian ? ioread32be(addr) : ioread32(addr);
+}
+
+static inline void ftm_writel(u32 val, void __iomem *addr)
+{
+	return rtc.endian ? iowrite32be(val, addr) : iowrite32(val, addr);
+}
+
+static inline void ftm_counter_enable(bool enabled)
+{
+	u32 val;
+
+	/* select and enable counter clock source */
+	val = ftm_readl(rtc.base + FTM_SC);
+	if (enabled) {
+		val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+		val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
+	} else
+		val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	ftm_writel(val, rtc.base + FTM_SC);
+}
+
+static int ftm_irq_enable(bool enabled)
+{
+	u32 val;
+
+	val = ftm_readl(rtc.base + FTM_SC);
+	if (enabled)
+		val |= FTM_SC_TOIE;
+	else
+		val &= ~FTM_SC_TOIE;
+	ftm_writel(val, rtc.base + FTM_SC);
+
+	return 0;
+}
+
+static inline void ftm_irq_clear(void)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+	while ((FTM_SC_TOF & ftm_readl(rtc.base + FTM_SC)) &&
+		time_before(jiffies, timeout))
+		ftm_writel(ftm_readl(rtc.base + FTM_SC) & (~FTM_SC_TOF),
+			   rtc.base + FTM_SC);
+}
+
+static void ftm_clean_alarm(void)
+{
+	ftm_counter_enable(false);
+
+	ftm_writel(0x00, rtc.base + FTM_CNTIN);
+	ftm_writel(~0x00, rtc.base + FTM_MOD);
+
+	/*
+	 * 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, rtc.base + FTM_CNT);
+}
+
+static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
+{
+	rtc_alarm_irq_enable(rtc.rtc_dev, false);
+	ftm_irq_clear();
+	ftm_irq_enable(false);
+	ftm_clean_alarm();
+
+	return IRQ_HANDLED;
+}
+
+static int ftm_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	if (enabled)
+		ftm_irq_enable(true);
+	else
+		ftm_irq_enable(false);
+
+	return 0;
+}
+
+static int nxp_ftm_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct timeval time;
+	unsigned long local_time;
+
+	do_gettimeofday(&time);
+	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+	rtc_time_to_tm(local_time, tm);
+
+	return 0;
+}
+
+/*250Hz, 65536 / 250 = 262 second max*/
+static int nxp_ftm_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct rtc_time tm;
+	unsigned long now, alm_time, cycle;
+
+	nxp_ftm_rtc_read_time(dev, &tm);
+	rtc_tm_to_time(&tm, &now);
+	rtc_tm_to_time(&alm->time, &alm_time);
+
+	ftm_clean_alarm();
+	cycle = (alm_time - now) * rtc.alarm_freq;
+	if (cycle > MAX_COUNT_VAL) {
+		pr_err("Out of alarm range.\n");
+		return -EINVAL;
+	}
+
+	ftm_irq_enable(false);
+	/*
+	 * 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, rtc.base + FTM_MOD);
+
+	ftm_counter_enable(true);
+	ftm_irq_enable(true);
+
+	return 0;
+}
+
+static int nxp_ftm_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	return 0;
+}
+
+const struct rtc_class_ops nxp_ftm_rtc_ops = {
+	.read_time	= nxp_ftm_rtc_read_time,
+	.set_alarm	= nxp_ftm_rtc_set_alarm,
+	.read_alarm	= nxp_ftm_rtc_read_alarm,
+	.alarm_irq_enable	= ftm_alarm_irq_enable
+};
+
+static const struct of_device_id nxp_ftm_rtc_of_match[] = {
+	{
+		.compatible	= "fsl,ftm-clock",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, nxp_ftm_rtc_of_match);
+
+static int nxp_ftm_rtc_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *r;
+	int irq;
+	int ret;
+
+	rtc.alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -ENODEV;
+
+	rtc.base = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(rtc.base))
+		return PTR_ERR(rtc.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;
+	}
+
+	rtc.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;
+	}
+
+	device_init_wakeup(&pdev->dev, true);
+	rtc.rtc_dev = devm_rtc_device_register(&pdev->dev, "nxp-ftm",
+					       &nxp_ftm_rtc_ops,
+			THIS_MODULE);
+
+	ftm_clean_alarm();
+
+	return ret;
+}
+
+static struct platform_driver nxp_ftm_rtc_driver = {
+	.probe		= nxp_ftm_rtc_probe,
+	.driver		= {
+		.name	= "nxp_ftm_rtc",
+		.of_match_table = nxp_ftm_rtc_of_match,
+	},
+};
+
+module_platform_driver(nxp_ftm_rtc_driver);
+
+MODULE_DESCRIPTION("NXP/Freescale Flextimer RTC Driver");
+MODULE_LICENSE("GPL");
-- 
2.1.0.27.g96db324

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

* [rtc-linux] [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
@ 2016-10-24  1:42 ` Meng Yi
  0 siblings, 0 replies; 10+ messages in thread
From: Meng Yi @ 2016-10-24  1:42 UTC (permalink / raw)
  To: a.zummo, alexandre.belloni; +Cc: rtc-linux, linux-kernel, Meng Yi

For the platforms including LS1021A, LS1043A that has the
flextimer module, implementing alarm functions within RTC
subsystem to wakeup the system when system going to sleep.
Only Ftm0 can be used to wakeup the system.

Signed-off-by: Meng Yi <meng.yi@nxp.com>
---
 drivers/rtc/Kconfig       |   9 ++
 drivers/rtc/Makefile      |   1 +
 drivers/rtc/rtc-nxp-ftm.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 265 insertions(+)
 create mode 100644 drivers/rtc/rtc-nxp-ftm.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e859d14..0ba52b3 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1243,6 +1243,15 @@ config RTC_DRV_IMXDI
 	   This driver can also be built as a module, if so, the module
 	   will be called "rtc-imxdi".
 
+config RTC_DRV_NXP
+	tristate "NXP flextimer Real Time Alarm "
+	help
+	For the FlexTimer on LS1021A, LS1043A, we can use FTM0 as the wakeup
+	source.
+	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).
+
 config RTC_DRV_OMAP
 	tristate "TI OMAP Real Time Clock"
 	depends on ARCH_OMAP || ARCH_DAVINCI || COMPILE_TEST
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 1ac694a..abbf22c 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_RTC_DRV_GENERIC)	+= rtc-generic.o
 obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
 obj-$(CONFIG_RTC_DRV_HYM8563)	+= rtc-hym8563.o
 obj-$(CONFIG_RTC_DRV_IMXDI)	+= rtc-imxdi.o
+obj-$(CONFIG_RTC_DRV_NXP)	+= rtc-nxp-ftm.o
 obj-$(CONFIG_RTC_DRV_ISL12022)	+= rtc-isl12022.o
 obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o
 obj-$(CONFIG_RTC_DRV_JZ4740)	+= rtc-jz4740.o
diff --git a/drivers/rtc/rtc-nxp-ftm.c b/drivers/rtc/rtc-nxp-ftm.c
new file mode 100644
index 0000000..74c4358
--- /dev/null
+++ b/drivers/rtc/rtc-nxp-ftm.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * NXP FTM alarm device driver
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/of_irq.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
+
+struct ftm_rtc {
+	struct rtc_device *rtc_dev;
+	void __iomem *base;
+	bool endian;
+	u32 alarm_freq;
+};
+
+static struct ftm_rtc rtc;
+
+static inline u32 ftm_readl(void __iomem *addr)
+{
+	return rtc.endian ? ioread32be(addr) : ioread32(addr);
+}
+
+static inline void ftm_writel(u32 val, void __iomem *addr)
+{
+	return rtc.endian ? iowrite32be(val, addr) : iowrite32(val, addr);
+}
+
+static inline void ftm_counter_enable(bool enabled)
+{
+	u32 val;
+
+	/* select and enable counter clock source */
+	val = ftm_readl(rtc.base + FTM_SC);
+	if (enabled) {
+		val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+		val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
+	} else
+		val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	ftm_writel(val, rtc.base + FTM_SC);
+}
+
+static int ftm_irq_enable(bool enabled)
+{
+	u32 val;
+
+	val = ftm_readl(rtc.base + FTM_SC);
+	if (enabled)
+		val |= FTM_SC_TOIE;
+	else
+		val &= ~FTM_SC_TOIE;
+	ftm_writel(val, rtc.base + FTM_SC);
+
+	return 0;
+}
+
+static inline void ftm_irq_clear(void)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+	while ((FTM_SC_TOF & ftm_readl(rtc.base + FTM_SC)) &&
+		time_before(jiffies, timeout))
+		ftm_writel(ftm_readl(rtc.base + FTM_SC) & (~FTM_SC_TOF),
+			   rtc.base + FTM_SC);
+}
+
+static void ftm_clean_alarm(void)
+{
+	ftm_counter_enable(false);
+
+	ftm_writel(0x00, rtc.base + FTM_CNTIN);
+	ftm_writel(~0x00, rtc.base + FTM_MOD);
+
+	/*
+	 * 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, rtc.base + FTM_CNT);
+}
+
+static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
+{
+	rtc_alarm_irq_enable(rtc.rtc_dev, false);
+	ftm_irq_clear();
+	ftm_irq_enable(false);
+	ftm_clean_alarm();
+
+	return IRQ_HANDLED;
+}
+
+static int ftm_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	if (enabled)
+		ftm_irq_enable(true);
+	else
+		ftm_irq_enable(false);
+
+	return 0;
+}
+
+static int nxp_ftm_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct timeval time;
+	unsigned long local_time;
+
+	do_gettimeofday(&time);
+	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+	rtc_time_to_tm(local_time, tm);
+
+	return 0;
+}
+
+/*250Hz, 65536 / 250 = 262 second max*/
+static int nxp_ftm_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct rtc_time tm;
+	unsigned long now, alm_time, cycle;
+
+	nxp_ftm_rtc_read_time(dev, &tm);
+	rtc_tm_to_time(&tm, &now);
+	rtc_tm_to_time(&alm->time, &alm_time);
+
+	ftm_clean_alarm();
+	cycle = (alm_time - now) * rtc.alarm_freq;
+	if (cycle > MAX_COUNT_VAL) {
+		pr_err("Out of alarm range.\n");
+		return -EINVAL;
+	}
+
+	ftm_irq_enable(false);
+	/*
+	 * 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, rtc.base + FTM_MOD);
+
+	ftm_counter_enable(true);
+	ftm_irq_enable(true);
+
+	return 0;
+}
+
+static int nxp_ftm_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	return 0;
+}
+
+const struct rtc_class_ops nxp_ftm_rtc_ops = {
+	.read_time	= nxp_ftm_rtc_read_time,
+	.set_alarm	= nxp_ftm_rtc_set_alarm,
+	.read_alarm	= nxp_ftm_rtc_read_alarm,
+	.alarm_irq_enable	= ftm_alarm_irq_enable
+};
+
+static const struct of_device_id nxp_ftm_rtc_of_match[] = {
+	{
+		.compatible	= "fsl,ftm-clock",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, nxp_ftm_rtc_of_match);
+
+static int nxp_ftm_rtc_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *r;
+	int irq;
+	int ret;
+
+	rtc.alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -ENODEV;
+
+	rtc.base = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(rtc.base))
+		return PTR_ERR(rtc.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;
+	}
+
+	rtc.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;
+	}
+
+	device_init_wakeup(&pdev->dev, true);
+	rtc.rtc_dev = devm_rtc_device_register(&pdev->dev, "nxp-ftm",
+					       &nxp_ftm_rtc_ops,
+			THIS_MODULE);
+
+	ftm_clean_alarm();
+
+	return ret;
+}
+
+static struct platform_driver nxp_ftm_rtc_driver = {
+	.probe		= nxp_ftm_rtc_probe,
+	.driver		= {
+		.name	= "nxp_ftm_rtc",
+		.of_match_table = nxp_ftm_rtc_of_match,
+	},
+};
+
+module_platform_driver(nxp_ftm_rtc_driver);
+
+MODULE_DESCRIPTION("NXP/Freescale Flextimer RTC Driver");
+MODULE_LICENSE("GPL");
-- 
2.1.0.27.g96db324

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* RE: [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
  2016-10-24  1:42 ` [rtc-linux] " Meng Yi
@ 2016-11-02  8:23   ` Meng Yi
  -1 siblings, 0 replies; 10+ messages in thread
From: Meng Yi @ 2016-11-02  8:23 UTC (permalink / raw)
  To: Meng Yi, a.zummo, alexandre.belloni; +Cc: rtc-linux, linux-kernel

> +
> +static int ftm_alarm_irq_enable(struct device *dev, unsigned int
> +enabled) {
> +	if (enabled)
> +		ftm_irq_enable(true);
> +	else
> +		ftm_irq_enable(false);
> +
> +	return 0;
> +}
> +
> +static int nxp_ftm_rtc_read_time(struct device *dev, struct rtc_time
> +*tm) {
> +	struct timeval time;
> +	unsigned long local_time;
> +
> +	do_gettimeofday(&time);
> +	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
> +	rtc_time_to_tm(local_time, tm);
> +
> +	return 0;
> +}
> +

This is not really getting time from the RTC since FTM is not a RTC device,
But we need to get the time to setup alarm, so we are using system time for now.
Anybody have better idea?

Meng

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

* [rtc-linux] RE: [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
@ 2016-11-02  8:23   ` Meng Yi
  0 siblings, 0 replies; 10+ messages in thread
From: Meng Yi @ 2016-11-02  8:23 UTC (permalink / raw)
  To: Meng Yi, a.zummo, alexandre.belloni; +Cc: rtc-linux, linux-kernel

> +
> +static int ftm_alarm_irq_enable(struct device *dev, unsigned int
> +enabled) {
> +	if (enabled)
> +		ftm_irq_enable(true);
> +	else
> +		ftm_irq_enable(false);
> +
> +	return 0;
> +}
> +
> +static int nxp_ftm_rtc_read_time(struct device *dev, struct rtc_time
> +*tm) {
> +	struct timeval time;
> +	unsigned long local_time;
> +
> +	do_gettimeofday(&time);
> +	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
> +	rtc_time_to_tm(local_time, tm);
> +
> +	return 0;
> +}
> +

This is not really getting time from the RTC since FTM is not a RTC device,
But we need to get the time to setup alarm, so we are using system time for now.
Anybody have better idea?

Meng

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* Re: [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
  2016-11-02  8:23   ` [rtc-linux] " Meng Yi
@ 2016-12-01  0:32     ` Alexandre Belloni
  -1 siblings, 0 replies; 10+ messages in thread
From: Alexandre Belloni @ 2016-12-01  0:32 UTC (permalink / raw)
  To: Meng Yi; +Cc: a.zummo, rtc-linux, linux-kernel

On 02/11/2016 at 08:23:32 +0000, Meng Yi wrote :
> > +
> > +static int ftm_alarm_irq_enable(struct device *dev, unsigned int
> > +enabled) {
> > +	if (enabled)
> > +		ftm_irq_enable(true);
> > +	else
> > +		ftm_irq_enable(false);
> > +
> > +	return 0;
> > +}
> > +
> > +static int nxp_ftm_rtc_read_time(struct device *dev, struct rtc_time
> > +*tm) {
> > +	struct timeval time;
> > +	unsigned long local_time;
> > +
> > +	do_gettimeofday(&time);
> > +	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
> > +	rtc_time_to_tm(local_time, tm);
> > +
> > +	return 0;
> > +}
> > +
> 
> This is not really getting time from the RTC since FTM is not a RTC device,
> But we need to get the time to setup alarm, so we are using system time for now.
> Anybody have better idea?
> 

No, that seems fine to me. I'll review the rest of the driver.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [rtc-linux] Re: [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
@ 2016-12-01  0:32     ` Alexandre Belloni
  0 siblings, 0 replies; 10+ messages in thread
From: Alexandre Belloni @ 2016-12-01  0:32 UTC (permalink / raw)
  To: Meng Yi; +Cc: a.zummo, rtc-linux, linux-kernel

On 02/11/2016 at 08:23:32 +0000, Meng Yi wrote :
> > +
> > +static int ftm_alarm_irq_enable(struct device *dev, unsigned int
> > +enabled) {
> > +	if (enabled)
> > +		ftm_irq_enable(true);
> > +	else
> > +		ftm_irq_enable(false);
> > +
> > +	return 0;
> > +}
> > +
> > +static int nxp_ftm_rtc_read_time(struct device *dev, struct rtc_time
> > +*tm) {
> > +	struct timeval time;
> > +	unsigned long local_time;
> > +
> > +	do_gettimeofday(&time);
> > +	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
> > +	rtc_time_to_tm(local_time, tm);
> > +
> > +	return 0;
> > +}
> > +
> 
> This is not really getting time from the RTC since FTM is not a RTC device,
> But we need to get the time to setup alarm, so we are using system time for now.
> Anybody have better idea?
> 

No, that seems fine to me. I'll review the rest of the driver.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* RE: [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
  2016-12-01  0:32     ` [rtc-linux] " Alexandre Belloni
@ 2016-12-02  2:27       ` Meng Yi
  -1 siblings, 0 replies; 10+ messages in thread
From: Meng Yi @ 2016-12-02  2:27 UTC (permalink / raw)
  To: Alexandre Belloni; +Cc: a.zummo, rtc-linux, linux-kernel

> > > +
> > > +static int nxp_ftm_rtc_read_time(struct device *dev, struct
> > > +rtc_time
> > > +*tm) {
> > > +	struct timeval time;
> > > +	unsigned long local_time;
> > > +
> > > +	do_gettimeofday(&time);
> > > +	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
> > > +	rtc_time_to_tm(local_time, tm);
> > > +
> > > +	return 0;
> > > +}
> > > +
> >
> > This is not really getting time from the RTC since FTM is not a RTC
> > device, But we need to get the time to setup alarm, so we are using system
> time for now.
> > Anybody have better idea?
> >
> 
> No, that seems fine to me. I'll review the rest of the driver.

Thanks for your review, any feedback is welcomed!

> 
> 
> --
> Alexandre Belloni, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

Meng

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

* [rtc-linux] RE: [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
@ 2016-12-02  2:27       ` Meng Yi
  0 siblings, 0 replies; 10+ messages in thread
From: Meng Yi @ 2016-12-02  2:27 UTC (permalink / raw)
  To: Alexandre Belloni; +Cc: a.zummo, rtc-linux, linux-kernel

> > > +
> > > +static int nxp_ftm_rtc_read_time(struct device *dev, struct
> > > +rtc_time
> > > +*tm) {
> > > +	struct timeval time;
> > > +	unsigned long local_time;
> > > +
> > > +	do_gettimeofday(&time);
> > > +	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
> > > +	rtc_time_to_tm(local_time, tm);
> > > +
> > > +	return 0;
> > > +}
> > > +
> >
> > This is not really getting time from the RTC since FTM is not a RTC
> > device, But we need to get the time to setup alarm, so we are using system
> time for now.
> > Anybody have better idea?
> >
> 
> No, that seems fine to me. I'll review the rest of the driver.

Thanks for your review, any feedback is welcomed!

> 
> 
> --
> Alexandre Belloni, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

Meng

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

* Re: [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
  2016-10-24  1:42 ` [rtc-linux] " Meng Yi
@ 2017-01-27  0:03   ` Alexandre Belloni
  -1 siblings, 0 replies; 10+ messages in thread
From: Alexandre Belloni @ 2017-01-27  0:03 UTC (permalink / raw)
  To: Meng Yi; +Cc: a.zummo, rtc-linux, linux-kernel

Hi,

On 24/10/2016 at 09:42:16 +0800, Meng Yi wrote:
> For the platforms including LS1021A, LS1043A that has the
> flextimer module, implementing alarm functions within RTC
> subsystem to wakeup the system when system going to sleep.
> Only Ftm0 can be used to wakeup the system.
> 
> Signed-off-by: Meng Yi <meng.yi@nxp.com>
> ---
>  drivers/rtc/Kconfig       |   9 ++
>  drivers/rtc/Makefile      |   1 +
>  drivers/rtc/rtc-nxp-ftm.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 265 insertions(+)
>  create mode 100644 drivers/rtc/rtc-nxp-ftm.c
> 
> +static const struct of_device_id nxp_ftm_rtc_of_match[] = {
> +	{
> +		.compatible	= "fsl,ftm-clock",
> +	}, {
> +		/* sentinel */
> +	}
> +};
> +MODULE_DEVICE_TABLE(of, nxp_ftm_rtc_of_match);
> 

I think the patch is generally fine but I think you will get an issue
later if anybody is trying to use an FTM to actually do something else
(e.g. PWM, counter, quad decoder,...).

I'm asking because there is exactly this issue on atmel SoCs.

I think we may be missing a proper subsystem.

> +static int nxp_ftm_rtc_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct resource *r;
> +	int irq;
> +	int ret;
> +
> +	rtc.alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!r)
> +		return -ENODEV;
> +
> +	rtc.base = devm_ioremap_resource(&pdev->dev, r);
> +	if (IS_ERR(rtc.base))
> +		return PTR_ERR(rtc.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;
> +	}
> +
> +	rtc.endian = of_property_read_bool(np, "big-endian");
> +
Doesn't the platform know the endianness, is it really necessary to have
that in the device tree?


-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [rtc-linux] Re: [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source
@ 2017-01-27  0:03   ` Alexandre Belloni
  0 siblings, 0 replies; 10+ messages in thread
From: Alexandre Belloni @ 2017-01-27  0:03 UTC (permalink / raw)
  To: Meng Yi; +Cc: a.zummo, rtc-linux, linux-kernel

Hi,

On 24/10/2016 at 09:42:16 +0800, Meng Yi wrote:
> For the platforms including LS1021A, LS1043A that has the
> flextimer module, implementing alarm functions within RTC
> subsystem to wakeup the system when system going to sleep.
> Only Ftm0 can be used to wakeup the system.
> 
> Signed-off-by: Meng Yi <meng.yi@nxp.com>
> ---
>  drivers/rtc/Kconfig       |   9 ++
>  drivers/rtc/Makefile      |   1 +
>  drivers/rtc/rtc-nxp-ftm.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 265 insertions(+)
>  create mode 100644 drivers/rtc/rtc-nxp-ftm.c
> 
> +static const struct of_device_id nxp_ftm_rtc_of_match[] = {
> +	{
> +		.compatible	= "fsl,ftm-clock",
> +	}, {
> +		/* sentinel */
> +	}
> +};
> +MODULE_DEVICE_TABLE(of, nxp_ftm_rtc_of_match);
> 

I think the patch is generally fine but I think you will get an issue
later if anybody is trying to use an FTM to actually do something else
(e.g. PWM, counter, quad decoder,...).

I'm asking because there is exactly this issue on atmel SoCs.

I think we may be missing a proper subsystem.

> +static int nxp_ftm_rtc_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct resource *r;
> +	int irq;
> +	int ret;
> +
> +	rtc.alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
> +
> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!r)
> +		return -ENODEV;
> +
> +	rtc.base = devm_ioremap_resource(&pdev->dev, r);
> +	if (IS_ERR(rtc.base))
> +		return PTR_ERR(rtc.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;
> +	}
> +
> +	rtc.endian = of_property_read_bool(np, "big-endian");
> +
Doesn't the platform know the endianness, is it really necessary to have
that in the device tree?


-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

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

end of thread, other threads:[~2017-01-27  0:27 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-24  1:42 [RFC PATCH] rtc/nxp: add FTM alarm driver as the wakeup source Meng Yi
2016-10-24  1:42 ` [rtc-linux] " Meng Yi
2016-11-02  8:23 ` Meng Yi
2016-11-02  8:23   ` [rtc-linux] " Meng Yi
2016-12-01  0:32   ` Alexandre Belloni
2016-12-01  0:32     ` [rtc-linux] " Alexandre Belloni
2016-12-02  2:27     ` Meng Yi
2016-12-02  2:27       ` [rtc-linux] " Meng Yi
2017-01-27  0:03 ` Alexandre Belloni
2017-01-27  0:03   ` [rtc-linux] " Alexandre Belloni

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.