devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V4 RESEND 0/3] rtc: atcrtc100: Add Andes ATCRTC100 RTC driver
@ 2024-11-27 14:19 CL Wang
  2024-11-27 14:19 ` [PATCH V4 RESEND 1/3] rtc: atcrtc100: Add " CL Wang
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: CL Wang @ 2024-11-27 14:19 UTC (permalink / raw)
  To: cl634, alexandre.belloni, robh, krzk+dt, conor+dt, devicetree
  Cc: linux-rtc, linux-kernel, tim609, ycliang

This patch series adds support for the Andes ATCRTC100 Real-Time Clock. 

The series is now based on the rtc-next branch from:
git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git.

This V4 submission addresses the feedback received from Krzysztof:
1. Ensured that the patch series is based on rtc-next.
2. Verified recipients and mailing lists using scripts/get_maintainer.pl.
3. Included all necessary To/Cc entries for proper review.

For details of the change log, please refer to the commit log of each patch.

Please kindly review.

CL Wang (3):
  rtc: atcrtc100: Add ATCRTC100 RTC driver
  dt-bindings: rtc: Add support for ATCRTC100 RTC
  MAINTAINERS: Add entry for ATCRTC100 RTC driver

 .../bindings/rtc/andestech,atcrtc100.yaml     |  43 ++
 MAINTAINERS                                   |   6 +
 drivers/rtc/Kconfig                           |  15 +
 drivers/rtc/Makefile                          |   1 +
 drivers/rtc/rtc-atcrtc100.c                   | 524 ++++++++++++++++++
 5 files changed, 589 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml
 create mode 100644 drivers/rtc/rtc-atcrtc100.c

-- 
2.34.1


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

* [PATCH V4 RESEND 1/3] rtc: atcrtc100: Add ATCRTC100 RTC driver
  2024-11-27 14:19 [PATCH V4 RESEND 0/3] rtc: atcrtc100: Add Andes ATCRTC100 RTC driver CL Wang
@ 2024-11-27 14:19 ` CL Wang
  2024-11-27 14:19 ` [PATCH V4 RESEND 2/3] dt-bindings: rtc: Add support for ATCRTC100 RTC CL Wang
  2024-11-27 14:19 ` [PATCH V4 RESEND 3/3] MAINTAINERS: Add entry for ATCRTC100 RTC driver CL Wang
  2 siblings, 0 replies; 6+ messages in thread
From: CL Wang @ 2024-11-27 14:19 UTC (permalink / raw)
  To: cl634, alexandre.belloni, robh, krzk+dt, conor+dt, devicetree
  Cc: linux-rtc, linux-kernel, tim609, ycliang

RTC driver for Andes ATCRTC100 Real-Time Clock.

Signed-off-by: CL Wang <cl634@andestech.com>

---
Changes for v1:
 - Initial version of the ATCRTC100 driver.

Changes for v2:
 - Replaced legacy APIs with devm APIs for system resource allocation.
 - Used regmap APIs to access I/O registers.

Changes for v3:
 - Removed 'of_match_ptr()'.
 - Added check for WriteDone status before accessing Counter, Alarm, and Control registers.

Changes for v4:
 - Refined the procedure for setting the wake-up source.
 - Fixed coding style to comply with Linux coding style guidelines.
---
 drivers/rtc/Kconfig         |  15 ++
 drivers/rtc/Makefile        |   1 +
 drivers/rtc/rtc-atcrtc100.c | 524 ++++++++++++++++++++++++++++++++++++
 3 files changed, 540 insertions(+)
 create mode 100644 drivers/rtc/rtc-atcrtc100.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index a60bcc791a48..eac651f65578 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1040,6 +1040,21 @@ config RTC_DRV_ALPHA
 	  Direct support for the real-time clock found on every Alpha
 	  system, specifically MC146818 compatibles.  If in doubt, say Y.
 
+config RTC_DRV_ATCRTC100
+	tristate "Andes ATCRTC100"
+	depends on RISCV
+	select REGMAP_MMIO
+	help
+	  If you say yes here you will get support for the Andes ATCRTC100
+	  RTC driver.
+
+	  This driver provides support for the Andes ATCRTC100 real-time clock
+	  device. It allows setting and retrieving the time and date, as well
+	  as setting alarms.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called rtc-atcrtc100.
+
 config RTC_DRV_DS1216
 	tristate "Dallas DS1216"
 	depends on SNI_RM
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 489b4ab07068..1a738d011e20 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_RTC_DRV_ASM9260)	+= rtc-asm9260.o
 obj-$(CONFIG_RTC_DRV_ASPEED)	+= rtc-aspeed.o
 obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
 obj-$(CONFIG_RTC_DRV_AT91SAM9)	+= rtc-at91sam9.o
+obj-$(CONFIG_RTC_DRV_ATCRTC100) += rtc-atcrtc100.o
 obj-$(CONFIG_RTC_DRV_AU1XXX)	+= rtc-au1xxx.o
 obj-$(CONFIG_RTC_DRV_BBNSM)	+= rtc-nxp-bbnsm.o
 obj-$(CONFIG_RTC_DRV_BD70528)	+= rtc-bd70528.o
diff --git a/drivers/rtc/rtc-atcrtc100.c b/drivers/rtc/rtc-atcrtc100.c
new file mode 100644
index 000000000000..40629f796f3b
--- /dev/null
+++ b/drivers/rtc/rtc-atcrtc100.c
@@ -0,0 +1,524 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Driver for Andes ATCRTC100 real time clock.
+ *
+ * Copyright (C) 2024 Andes Technology Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/pm_wakeirq.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+
+#define RTC_ID		0x00	/* ID and Revision */
+#define ID_OFF		12
+#define ID_MSK		(0xFFFFF << ID_OFF)
+#define ATCRTC100ID	(0x03011 << ID_OFF)
+#define RTC_RSV		0x4	/* Reserve */
+#define RTC_CNT		0x10	/* Counter */
+#define RTC_ALM		0x14	/* Alarm */
+#define DAY_OFF		17
+#define DAY_MSK		0x7FFF
+#define HOUR_OFF	12
+#define HOUR_MSK	0x1F
+#define MIN_OFF		6
+#define MIN_MSK		0x3F
+#define SEC_OFF		0
+#define SEC_MSK		0x3F
+#define RTC_SECOND(x)	((x >> SEC_OFF) & SEC_MSK)	/* RTC sec */
+#define RTC_MINUTE(x)	((x >> MIN_OFF) & MIN_MSK)	/* RTC min */
+#define RTC_HOUR(x)	((x >> HOUR_OFF) & HOUR_MSK)	/* RTC hour */
+#define RTC_DAYS(x)	((x >> DAY_OFF) & DAY_MSK)	/* RTC day */
+
+#define RTC_CR		0x18	/* Control */
+#define RTC_EN		(0x1UL << 0)
+#define ALARM_WAKEUP	(0x1UL << 1)
+#define ALARM_INT	(0x1UL << 2)
+#define DAY_INT		(0x1UL << 3)
+#define HOUR_INT	(0x1UL << 4)
+#define MIN_INT		(0x1UL << 5)
+#define SEC_INT		(0x1UL << 6)
+#define HSEC_INT	(0x1UL << 7)
+#define RTC_STA		0x1C	/* Status */
+#define WRITE_DONE	(0x1UL << 16)
+#define RTC_TRIM	0x20	/* Digital Trimming */
+
+#define ATCRTC_TIME_TO_SEC(D, H, M, S)	(D * 86400LL + H * 3600 + M * 60 + S)
+
+#define ATCRTC_TIMEOUT_US		1000000
+#define ATCRTC_TIMEOUT_USLEEP_MIN	20
+#define ATCRTC_TIMEOUT_USLEEP_MAX	30
+
+struct atcrtc_dev {
+	struct rtc_device	*rtc_dev;
+	struct regmap		*regmap;
+	struct delayed_work	rtc_work;
+	struct mutex		lock;
+	unsigned int		alarm_irq;
+	unsigned int		time_irq;
+	unsigned char		alarm_en;
+};
+
+static const struct regmap_config atcrtc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = RTC_TRIM,
+	.cache_type = REGCACHE_NONE,
+};
+
+/**
+ * atcrtc_check_write_done - Check whether the ATCRTC100 is ready or not.
+ * @rtc: Pointer of atcrtc_dev.
+ *
+ * The WriteDone bit in the status register indicates the synchronization
+ * progress of RTC register updates. This bit is cleared to zero whenever
+ * any RTC control register such as the Counter, Alarm, Control, or Digital
+ * Trimming registers is updated. It returns to one only after all previous
+ * updates to these registers have been fully synchronized to the RTC clock
+ * domain. If a register update is in the process of being synchronized, a
+ * second update to the same register may be ignored.
+ */
+static int atcrtc_check_write_done(struct atcrtc_dev *rtc)
+{
+	int loop;
+	int timeout;
+
+	might_sleep();
+	timeout = ATCRTC_TIMEOUT_US / ATCRTC_TIMEOUT_USLEEP_MIN;
+
+	for (loop = 0; loop < timeout; loop++) {
+		if (regmap_test_bits(rtc->regmap, RTC_STA, WRITE_DONE))
+			return 0;
+
+		usleep_range(ATCRTC_TIMEOUT_USLEEP_MIN,
+			     ATCRTC_TIMEOUT_USLEEP_MAX);
+	}
+	dev_err(&rtc->rtc_dev->dev, "Device is busy too long\n");
+	return -EBUSY;
+}
+
+static irqreturn_t atcrtc_periodic_isr(int irq, void *dev)
+{
+	struct atcrtc_dev *rtc = dev;
+
+	if (regmap_test_bits(rtc->regmap, RTC_STA, SEC_INT)) {
+		regmap_write_bits(rtc->regmap, RTC_STA, SEC_INT, SEC_INT);
+		rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+
+static irqreturn_t atcrtc_alarm_isr(int irq, void *dev)
+{
+	struct atcrtc_dev *rtc = dev;
+
+	if (regmap_test_bits(rtc->regmap, RTC_STA, ALARM_INT)) {
+		regmap_write_bits(rtc->regmap, RTC_STA, ALARM_INT, ALARM_INT);
+		rtc->alarm_en = 0;
+		schedule_delayed_work(&rtc->rtc_work, 0);
+		rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+
+static int atcrtc_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
+	int ret;
+
+	mutex_lock(&rtc->lock);
+
+	ret = atcrtc_check_write_done(rtc);
+	if (ret) {
+		mutex_unlock(&rtc->lock);
+		return ret;
+	}
+
+	if (enable)
+		regmap_update_bits(rtc->regmap, RTC_CR, ALARM_INT, ALARM_INT);
+	else
+		regmap_update_bits(rtc->regmap, RTC_CR, ALARM_INT, 0);
+
+	mutex_unlock(&rtc->lock);
+
+	return 0;
+}
+
+static int atcrtc_alarm_enable(struct device *dev, unsigned int enable)
+{
+	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
+	int ret;
+
+	mutex_lock(&rtc->lock);
+
+	ret = atcrtc_check_write_done(rtc);
+	if (ret) {
+		mutex_unlock(&rtc->lock);
+		return ret;
+	}
+
+	if (enable) {
+		regmap_update_bits(rtc->regmap,
+				   RTC_CR,
+				   ALARM_WAKEUP,
+				   ALARM_WAKEUP);
+	} else {
+		regmap_update_bits(rtc->regmap, RTC_CR, ALARM_WAKEUP, 0);
+	}
+
+	mutex_unlock(&rtc->lock);
+
+	return 0;
+}
+
+static void atcrtc_alarm_clear(struct work_struct *work)
+{
+	struct atcrtc_dev *rtc =
+		container_of(work, struct atcrtc_dev, rtc_work.work);
+	int ret;
+
+	mutex_lock(&rtc->lock);
+	if (rtc->alarm_en == 0) {
+		ret = atcrtc_check_write_done(rtc);
+		if (ret) {
+			mutex_unlock(&rtc->lock);
+			return;
+		}
+		regmap_update_bits(rtc->regmap, RTC_CR, ALARM_INT, 0);
+	}
+	mutex_unlock(&rtc->lock);
+}
+
+static time64_t atcrtc_read_rtc_time(struct atcrtc_dev *rtc)
+{
+	time64_t time;
+	unsigned int rtc_cnt;
+
+	regmap_read(rtc->regmap, RTC_CNT, &rtc_cnt);
+	time = ATCRTC_TIME_TO_SEC(RTC_DAYS(rtc_cnt),
+				  RTC_HOUR(rtc_cnt),
+				  RTC_MINUTE(rtc_cnt),
+				  RTC_SECOND(rtc_cnt));
+	return time;
+}
+
+static int atcrtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
+	time64_t time;
+
+	mutex_lock(&rtc->lock);
+	time = atcrtc_read_rtc_time(rtc);
+	mutex_unlock(&rtc->lock);
+
+	rtc_time64_to_tm(time, tm);
+	if (rtc_valid_tm(tm) < 0) {
+		dev_err(dev, "Invalid date: %lld\n", time);
+		rtc_time64_to_tm(0, tm);
+	}
+	return 0;
+}
+
+static void atcrtc_set_rtc_time(struct atcrtc_dev *rtc, time64_t time)
+{
+	int rem;
+	unsigned int counter;
+	unsigned int day;
+	unsigned int hour;
+	unsigned int min;
+	unsigned int sec;
+
+	day = div_s64_rem(time, 86400, &rem);
+	hour = rem / 3600;
+	rem -= hour * 3600;
+	min = rem / 60;
+	sec = rem - min * 60;
+	counter = ((day & DAY_MSK) << DAY_OFF)
+		  | ((hour & HOUR_MSK) << HOUR_OFF)
+		  | ((min & MIN_MSK) << MIN_OFF)
+		  | ((sec & SEC_MSK) << SEC_OFF);
+
+	regmap_write(rtc->regmap, RTC_CNT, counter);
+}
+
+static int atcrtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
+	time64_t sys_time;
+	int ret;
+
+	sys_time = rtc_tm_to_time64(tm);
+
+	mutex_lock(&rtc->lock);
+
+	ret = atcrtc_check_write_done(rtc);
+	if (ret) {
+		mutex_unlock(&rtc->lock);
+		return ret;
+	}
+	atcrtc_set_rtc_time(rtc, sys_time);
+
+	mutex_unlock(&rtc->lock);
+
+	return 0;
+}
+
+static int atcrtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
+	struct rtc_time *tm = &wkalrm->time;
+	unsigned int rtc_alarm;
+
+	mutex_lock(&rtc->lock);
+
+	regmap_read(rtc->regmap, RTC_ALM, &rtc_alarm);
+	wkalrm->enabled = regmap_test_bits(rtc->regmap, RTC_CR, ALARM_INT);
+
+	mutex_unlock(&rtc->lock);
+
+	tm->tm_hour = (rtc_alarm >> HOUR_OFF) & HOUR_MSK;
+	tm->tm_min  = (rtc_alarm >> MIN_OFF) & MIN_MSK;
+	tm->tm_sec  = (rtc_alarm >> SEC_OFF) & SEC_MSK;
+
+	return 0;
+}
+
+static int atcrtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
+	struct rtc_time *tm = &wkalrm->time;
+	unsigned int alm = 0;
+	int ret = rtc_valid_tm(tm);
+
+	if (ret < 0) {
+		dev_err(dev, "Invalid alarm value: %d\n", ret);
+		return ret;
+	}
+
+	mutex_lock(&rtc->lock);
+
+	ret = atcrtc_check_write_done(rtc);
+	if (ret) {
+		mutex_unlock(&rtc->lock);
+		return ret;
+	}
+
+	/* Disable alarm interrupt and clear the alarm flag */
+	regmap_update_bits(rtc->regmap, RTC_CR, ALARM_INT, 0);
+	rtc->alarm_en = 0;
+
+	/* Set alarm time */
+	alm |= ((tm->tm_sec & SEC_MSK) << SEC_OFF);
+	alm |= ((tm->tm_min & MIN_MSK) << MIN_OFF);
+	alm |= ((tm->tm_hour & HOUR_MSK) << HOUR_OFF);
+	regmap_write(rtc->regmap, RTC_ALM, alm);
+
+	if (wkalrm->enabled) {
+		rtc->alarm_en = 1;
+		ret = atcrtc_check_write_done(rtc);
+		if (ret) {
+			mutex_unlock(&rtc->lock);
+			return ret;
+		}
+
+		regmap_update_bits(rtc->regmap, RTC_CR, ALARM_INT, ALARM_INT);
+	}
+
+	mutex_unlock(&rtc->lock);
+	return 0;
+}
+
+static int atcrtc_hw_init(struct atcrtc_dev *rtc)
+{
+	unsigned int rtc_id;
+	int ret;
+
+	regmap_read(rtc->regmap, RTC_ID, &rtc_id);
+	if ((rtc_id & ID_MSK) != ATCRTC100ID)
+		return -ENOENT;
+
+	ret = atcrtc_check_write_done(rtc);
+	if (ret)
+		return ret;
+	regmap_update_bits(rtc->regmap, RTC_CR, RTC_EN, RTC_EN);
+
+	return 0;
+}
+
+static const struct rtc_class_ops rtc_ops = {
+	.read_time = atcrtc_read_time,
+	.set_time = atcrtc_set_time,
+	.read_alarm = atcrtc_read_alarm,
+	.set_alarm = atcrtc_set_alarm,
+	.alarm_irq_enable = atcrtc_alarm_irq_enable,
+};
+
+static int atcrtc_probe(struct platform_device *pdev)
+{
+	struct atcrtc_dev *atcrtc_dev;
+	void __iomem *reg_base;
+	int ret = 0;
+
+	atcrtc_dev = devm_kzalloc(&pdev->dev, sizeof(*atcrtc_dev), GFP_KERNEL);
+	if (!atcrtc_dev)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, atcrtc_dev);
+	mutex_init(&atcrtc_dev->lock);
+
+	reg_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg_base)) {
+		dev_err(&pdev->dev,
+			"Failed to map I/O space: %ld\n",
+			PTR_ERR(reg_base));
+		return PTR_ERR(atcrtc_dev->regmap);
+	}
+
+	atcrtc_dev->regmap = devm_regmap_init_mmio(&pdev->dev,
+						   reg_base,
+						   &atcrtc_regmap_config);
+	if (IS_ERR(atcrtc_dev->regmap)) {
+		dev_err(&pdev->dev,
+			"Failed to initialize regmap: %ld\n",
+			PTR_ERR(atcrtc_dev->regmap));
+		return PTR_ERR(atcrtc_dev->regmap);
+	}
+
+	ret = atcrtc_hw_init(atcrtc_dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to initialize driver: %d\n", ret);
+		return ret;
+	}
+
+	atcrtc_dev->alarm_irq = platform_get_irq(pdev, 1);
+	if (atcrtc_dev->alarm_irq < 0) {
+		dev_err(&pdev->dev,
+			"Failed to get IRQ for alarm: %d\n",
+			atcrtc_dev->alarm_irq);
+		return atcrtc_dev->alarm_irq;
+	}
+	atcrtc_dev->time_irq = platform_get_irq(pdev, 0);
+	if (atcrtc_dev->time_irq < 0) {
+		dev_err(&pdev->dev,
+			"Failed to get IRQ for periodic interrupt: %d\n",
+			atcrtc_dev->time_irq);
+		return atcrtc_dev->time_irq;
+	}
+
+	ret = devm_request_irq(&pdev->dev,
+			       atcrtc_dev->alarm_irq,
+			       atcrtc_alarm_isr,
+			       0,
+			       "atcrtc alarm",
+			       atcrtc_dev);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to request IRQ %d for alarm: %d\n",
+			atcrtc_dev->alarm_irq,
+			ret);
+		return ret;
+	}
+
+	ret = devm_request_irq(&pdev->dev,
+			       atcrtc_dev->time_irq,
+			       atcrtc_periodic_isr,
+			       0,
+			       "atcrtc time",
+			       atcrtc_dev);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to request IRQ %d for periodic interrupt: %d\n",
+			atcrtc_dev->time_irq,
+			ret);
+		return ret;
+	}
+
+	atcrtc_dev->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
+	if (IS_ERR(atcrtc_dev->rtc_dev)) {
+		dev_err(&pdev->dev,
+			"Failed to allocate RTC device: %ld\n",
+			PTR_ERR(atcrtc_dev->rtc_dev));
+		return PTR_ERR(atcrtc_dev->rtc_dev);
+	}
+
+	ret = atcrtc_alarm_enable(&pdev->dev, true);
+	if (ret)
+		return ret;
+	set_bit(RTC_FEATURE_ALARM, atcrtc_dev->rtc_dev->features);
+
+	ret = device_init_wakeup(&pdev->dev, true);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to initialize wake device: %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = dev_pm_set_wake_irq(&pdev->dev, atcrtc_dev->alarm_irq);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to set wake IRQ: %d\n", ret);
+		device_init_wakeup(&pdev->dev, false);
+		return ret;
+	}
+
+	atcrtc_dev->rtc_dev->ops = &rtc_ops;
+	/*
+	 * There are 15 bits in the Day field of the Counter register.
+	 * It can count up to 32,767 days, about 89.8 years.
+	 */
+	atcrtc_dev->rtc_dev->range_max = mktime64(2089, 12, 31, 23, 59, 59);
+	atcrtc_dev->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000;
+
+	INIT_DELAYED_WORK(&atcrtc_dev->rtc_work, atcrtc_alarm_clear);
+	return devm_rtc_register_device(atcrtc_dev->rtc_dev);
+}
+
+static int atcrtc_resume(struct device *dev)
+{
+	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(rtc->alarm_irq);
+
+	return 0;
+}
+
+static int atcrtc_suspend(struct device *dev)
+{
+	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(rtc->alarm_irq);
+
+	return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(atcrtc_pm_ops, atcrtc_suspend, atcrtc_resume);
+
+static const struct of_device_id atcrtc_dt_match[] = {
+	{ .compatible = "andestech,atcrtc100" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, atcrtc_dt_match);
+
+static struct platform_driver atcrtc_platform_driver = {
+	.driver = {
+		.name = "atcrtc100",
+		.of_match_table = atcrtc_dt_match,
+		.pm = pm_sleep_ptr(&atcrtc_pm_ops),
+	},
+	.probe = atcrtc_probe,
+};
+
+module_platform_driver(atcrtc_platform_driver);
+
+MODULE_AUTHOR("CL Wang <cl634@andestech.com>");
+MODULE_DESCRIPTION("Andes ATCRTC100 driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1


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

* [PATCH V4 RESEND 2/3] dt-bindings: rtc: Add support for ATCRTC100 RTC
  2024-11-27 14:19 [PATCH V4 RESEND 0/3] rtc: atcrtc100: Add Andes ATCRTC100 RTC driver CL Wang
  2024-11-27 14:19 ` [PATCH V4 RESEND 1/3] rtc: atcrtc100: Add " CL Wang
@ 2024-11-27 14:19 ` CL Wang
  2024-12-03 17:06   ` Rob Herring
  2024-11-27 14:19 ` [PATCH V4 RESEND 3/3] MAINTAINERS: Add entry for ATCRTC100 RTC driver CL Wang
  2 siblings, 1 reply; 6+ messages in thread
From: CL Wang @ 2024-11-27 14:19 UTC (permalink / raw)
  To: cl634, alexandre.belloni, robh, krzk+dt, conor+dt, devicetree
  Cc: linux-rtc, linux-kernel, tim609, ycliang

Document Device Tree bindings for the Andes ATCRTC100 Real-Time Clock.

Signed-off-by: CL Wang <cl634@andestech.com>

---
Changes for v2:
 - First version of devicetree bindings for the Andes ATCRTC100 Real-Time Clock.

Changes for v3:
 - Used compatible as the filename.
 - Placed allOf after maintainers.
 - Replaced additionalProperties: false with unevaluatedProperties: false.
 - Added descriptions for interrupts.

Changes for v4:
 - Removed wakeup-source attribute.
---
 .../bindings/rtc/andestech,atcrtc100.yaml     | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml

diff --git a/Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml b/Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml
new file mode 100644
index 000000000000..ec0a736793c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/andestech,atcrtc100.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Andes ATCRTC100 Real-Time Clock
+
+maintainers:
+  - CL Wang <cl634@andestech.com>
+
+allOf:
+  - $ref: rtc.yaml#
+
+properties:
+  compatible:
+    enum:
+      - andestech,atcrtc100
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Periodic timekeeping interrupt
+      - description: RTC alarm interrupt
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    rtc@f0300000 {
+        compatible = "andestech,atcrtc100";
+        reg = <0xf0300000 0x100>;
+        interrupts = <1 IRQ_TYPE_LEVEL_HIGH>, <2 IRQ_TYPE_LEVEL_HIGH>;
+    };
-- 
2.34.1


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

* [PATCH V4 RESEND 3/3] MAINTAINERS: Add entry for ATCRTC100 RTC driver
  2024-11-27 14:19 [PATCH V4 RESEND 0/3] rtc: atcrtc100: Add Andes ATCRTC100 RTC driver CL Wang
  2024-11-27 14:19 ` [PATCH V4 RESEND 1/3] rtc: atcrtc100: Add " CL Wang
  2024-11-27 14:19 ` [PATCH V4 RESEND 2/3] dt-bindings: rtc: Add support for ATCRTC100 RTC CL Wang
@ 2024-11-27 14:19 ` CL Wang
  2 siblings, 0 replies; 6+ messages in thread
From: CL Wang @ 2024-11-27 14:19 UTC (permalink / raw)
  To: cl634, alexandre.belloni, robh, krzk+dt, conor+dt, devicetree
  Cc: linux-rtc, linux-kernel, tim609, ycliang

Add support entry for the Andes ATCRTC100 RTC driver in the MAINTAINERS file.

Signed-off-by: CL Wang <cl634@andestech.com>

---
Changes for v3:
 - Initial entry for the ATCRTC100 RTC driver.

Changes for v4:
 - No changes
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 99c5b41df823..6cc21af6eb23 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3559,6 +3559,12 @@ F:	drivers/power/reset/atc260x-poweroff.c
 F:	drivers/regulator/atc260x-regulator.c
 F:	include/linux/mfd/atc260x/*
 
+ATCRTC100 RTC DRIVER
+M:	CL Wang <cl634@andestech.com>
+S:	Supported
+F:	Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml
+F:	drivers/rtc/rtc-atcrtc100.c
+
 ATHEROS 71XX/9XXX GPIO DRIVER
 M:	Alban Bedel <albeu@free.fr>
 S:	Maintained
-- 
2.34.1


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

* Re: [PATCH V4 RESEND 2/3] dt-bindings: rtc: Add support for ATCRTC100 RTC
  2024-11-27 14:19 ` [PATCH V4 RESEND 2/3] dt-bindings: rtc: Add support for ATCRTC100 RTC CL Wang
@ 2024-12-03 17:06   ` Rob Herring
  2024-12-05  9:15     ` CL Wang
  0 siblings, 1 reply; 6+ messages in thread
From: Rob Herring @ 2024-12-03 17:06 UTC (permalink / raw)
  To: CL Wang
  Cc: alexandre.belloni, krzk+dt, conor+dt, devicetree, linux-rtc,
	linux-kernel, tim609, ycliang

On Wed, Nov 27, 2024 at 10:19:38PM +0800, CL Wang wrote:
> Document Device Tree bindings for the Andes ATCRTC100 Real-Time Clock.
> 
> Signed-off-by: CL Wang <cl634@andestech.com>
> 
> ---
> Changes for v2:
>  - First version of devicetree bindings for the Andes ATCRTC100 Real-Time Clock.
> 
> Changes for v3:
>  - Used compatible as the filename.
>  - Placed allOf after maintainers.
>  - Replaced additionalProperties: false with unevaluatedProperties: false.
>  - Added descriptions for interrupts.
> 
> Changes for v4:
>  - Removed wakeup-source attribute.
> ---
>  .../bindings/rtc/andestech,atcrtc100.yaml     | 43 +++++++++++++++++++
>  1 file changed, 43 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml

Missing Conor's tag from the 1st resend. If you got tags and need to 
resend, that's not a resend. You need to add the tags and it is v5.

But don't just go send v5 now for that. Alexandre can add the tag. 

Rob

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

* Re: [PATCH V4 RESEND 2/3] dt-bindings: rtc: Add support for ATCRTC100 RTC
  2024-12-03 17:06   ` Rob Herring
@ 2024-12-05  9:15     ` CL Wang
  0 siblings, 0 replies; 6+ messages in thread
From: CL Wang @ 2024-12-05  9:15 UTC (permalink / raw)
  To: Rob Herring
  Cc: alexandre.belloni, krzk+dt, conor+dt, devicetree, linux-rtc,
	linux-kernel, tim609, ycliang, cl634

Hi Rob,

Thank you for your review and comments.

I will include the reviewer's tag in the next version of the patch.
As you mentioned, if a tag is received and a resend is necessary,
I will include the tags and update the revision to v5.

Thank you again for your reminder.

Best regards,
CL

On Tue, Dec 03, 2024 at 11:06:51AM -0600, Rob Herring wrote:
> [EXTERNAL MAIL]
> 
> On Wed, Nov 27, 2024 at 10:19:38PM +0800, CL Wang wrote:
> > Document Device Tree bindings for the Andes ATCRTC100 Real-Time Clock.
> >
> > Signed-off-by: CL Wang <cl634@andestech.com>
> >
> > ---
> > Changes for v2:
> >  - First version of devicetree bindings for the Andes ATCRTC100 Real-Time Clock.
> >
> > Changes for v3:
> >  - Used compatible as the filename.
> >  - Placed allOf after maintainers.
> >  - Replaced additionalProperties: false with unevaluatedProperties: false.
> >  - Added descriptions for interrupts.
> >
> > Changes for v4:
> >  - Removed wakeup-source attribute.
> > ---
> >  .../bindings/rtc/andestech,atcrtc100.yaml     | 43 +++++++++++++++++++
> >  1 file changed, 43 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml
> 
> Missing Conor's tag from the 1st resend. If you got tags and need to
> resend, that's not a resend. You need to add the tags and it is v5.
> 
> But don't just go send v5 now for that. Alexandre can add the tag.
> 
> Rob

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

end of thread, other threads:[~2024-12-05  9:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-27 14:19 [PATCH V4 RESEND 0/3] rtc: atcrtc100: Add Andes ATCRTC100 RTC driver CL Wang
2024-11-27 14:19 ` [PATCH V4 RESEND 1/3] rtc: atcrtc100: Add " CL Wang
2024-11-27 14:19 ` [PATCH V4 RESEND 2/3] dt-bindings: rtc: Add support for ATCRTC100 RTC CL Wang
2024-12-03 17:06   ` Rob Herring
2024-12-05  9:15     ` CL Wang
2024-11-27 14:19 ` [PATCH V4 RESEND 3/3] MAINTAINERS: Add entry for ATCRTC100 RTC driver CL Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).