xref: /linux/drivers/rtc/rtc-atcrtc100.c (revision d324e9a91502184e0ac201293a6ec0fbe10458ed)
17adca706SCL Wang // SPDX-License-Identifier: GPL-2.0-or-later
27adca706SCL Wang /*
37adca706SCL Wang  * Driver for Andes ATCRTC100 real time clock.
47adca706SCL Wang  *
57adca706SCL Wang  * Copyright (C) 2025 Andes Technology Corporation
67adca706SCL Wang  */
77adca706SCL Wang 
87adca706SCL Wang #include <linux/bitfield.h>
97adca706SCL Wang #include <linux/delay.h>
107adca706SCL Wang #include <linux/interrupt.h>
117adca706SCL Wang #include <linux/math64.h>
127adca706SCL Wang #include <linux/module.h>
137adca706SCL Wang #include <linux/of.h>
147adca706SCL Wang #include <linux/platform_device.h>
157adca706SCL Wang #include <linux/pm_wakeirq.h>
167adca706SCL Wang #include <linux/regmap.h>
177adca706SCL Wang #include <linux/rtc.h>
187adca706SCL Wang #include <linux/workqueue.h>
197adca706SCL Wang 
207adca706SCL Wang /* Register Offsets */
217adca706SCL Wang #define RTC_ID		0x00	/* ID and Revision Register */
227adca706SCL Wang #define RTC_RSV		0x04	/* Reserved Register */
237adca706SCL Wang #define RTC_CNT		0x10	/* Counter Register */
247adca706SCL Wang #define RTC_ALM		0x14	/* Alarm Register */
257adca706SCL Wang #define RTC_CR		0x18	/* Control Register */
267adca706SCL Wang #define RTC_STA		0x1C	/* Status Register */
277adca706SCL Wang #define RTC_TRIM	0x20	/* Digital Trimming Register */
287adca706SCL Wang 
297adca706SCL Wang /* RTC_ID Register */
307adca706SCL Wang #define ID_MSK		GENMASK(31, 8)
317adca706SCL Wang #define ID_ATCRTC100	0x030110
327adca706SCL Wang 
337adca706SCL Wang /* RTC_CNT and RTC_ALM Register Fields */
347adca706SCL Wang #define SEC_MSK		GENMASK(5, 0)
357adca706SCL Wang #define MIN_MSK		GENMASK(11, 6)
367adca706SCL Wang #define HOUR_MSK	GENMASK(16, 12)
377adca706SCL Wang #define DAY_MSK		GENMASK(31, 17)
387adca706SCL Wang #define RTC_SEC_GET(x)	FIELD_GET(SEC_MSK, x)
397adca706SCL Wang #define RTC_MIN_GET(x)	FIELD_GET(MIN_MSK, x)
407adca706SCL Wang #define RTC_HOUR_GET(x)	FIELD_GET(HOUR_MSK, x)
417adca706SCL Wang #define RTC_DAY_GET(x)	FIELD_GET(DAY_MSK, x)
427adca706SCL Wang #define RTC_SEC_SET(x)	FIELD_PREP(SEC_MSK, x)
437adca706SCL Wang #define RTC_MIN_SET(x)	FIELD_PREP(MIN_MSK, x)
447adca706SCL Wang #define RTC_HOUR_SET(x)	FIELD_PREP(HOUR_MSK, x)
457adca706SCL Wang #define RTC_DAY_SET(x)	FIELD_PREP(DAY_MSK, x)
467adca706SCL Wang 
477adca706SCL Wang /* RTC_CR Register Bits */
487adca706SCL Wang #define RTC_EN		BIT(0)	/* RTC Enable */
497adca706SCL Wang #define ALARM_WAKEUP	BIT(1)	/* Alarm Wakeup Enable */
507adca706SCL Wang #define ALARM_INT	BIT(2)	/* Alarm Interrupt Enable */
517adca706SCL Wang #define DAY_INT		BIT(3)	/* Day Interrupt Enable */
527adca706SCL Wang #define HOUR_INT	BIT(4)	/* Hour Interrupt Enable */
537adca706SCL Wang #define MIN_INT		BIT(5)	/* Minute Interrupt Enable */
547adca706SCL Wang #define SEC_INT		BIT(6)	/* Second Periodic Interrupt Enable */
557adca706SCL Wang #define HSEC_INT	BIT(7)	/* Half-Second Periodic Interrupt Enable */
567adca706SCL Wang 
577adca706SCL Wang /* RTC_STA Register Bits */
587adca706SCL Wang #define WRITE_DONE	BIT(16)	/* Register write completion status */
597adca706SCL Wang 
607adca706SCL Wang /* Time conversion macro */
617adca706SCL Wang #define ATCRTC_TIME_TO_SEC(D, H, M, S)	\
627adca706SCL Wang 	((time64_t)(D) * 86400 + (H) * 3600 + (M) * 60 + (S))
637adca706SCL Wang 
647adca706SCL Wang /* Timeout for waiting for the write_done bit */
657adca706SCL Wang #define ATCRTC_TIMEOUT_US		1000000
667adca706SCL Wang #define ATCRTC_TIMEOUT_USLEEP_MIN	20
677adca706SCL Wang #define ATCRTC_TIMEOUT_USLEEP_MAX	30
687adca706SCL Wang 
697adca706SCL Wang struct atcrtc_dev {
707adca706SCL Wang 	struct rtc_device	*rtc_dev;
717adca706SCL Wang 	struct regmap		*regmap;
727adca706SCL Wang 	struct work_struct	rtc_work;
737adca706SCL Wang 	unsigned int		alarm_irq;
747adca706SCL Wang 	bool			alarm_en;
757adca706SCL Wang };
767adca706SCL Wang 
777adca706SCL Wang static const struct regmap_config atcrtc_regmap_config = {
787adca706SCL Wang 	.reg_bits = 32,
797adca706SCL Wang 	.reg_stride = 4,
807adca706SCL Wang 	.val_bits = 32,
817adca706SCL Wang 	.max_register = RTC_TRIM,
827adca706SCL Wang 	.cache_type = REGCACHE_NONE,
837adca706SCL Wang };
847adca706SCL Wang 
857adca706SCL Wang /**
867adca706SCL Wang  * atcrtc_check_write_done - Wait for RTC registers to be synchronized.
877adca706SCL Wang  * @rtc: Pointer to the atcrtc_dev structure.
887adca706SCL Wang  *
897adca706SCL Wang  * The WriteDone bit in the status register indicates the synchronization
907adca706SCL Wang  * progress of RTC register updates. This bit is cleared to zero whenever
917adca706SCL Wang  * any RTC control register (Counter, Alarm, Control, etc.) is written.
927adca706SCL Wang  * It returns to one only after all previous updates have been fully
937adca706SCL Wang  * synchronized to the RTC clock domain. This function polls the WriteDone
947adca706SCL Wang  * bit with a timeout to ensure the device is ready for the next operation.
957adca706SCL Wang  *
967adca706SCL Wang  * Return: 0 on success, or -EBUSY on timeout.
977adca706SCL Wang  */
atcrtc_check_write_done(struct atcrtc_dev * rtc)987adca706SCL Wang static int atcrtc_check_write_done(struct atcrtc_dev *rtc)
997adca706SCL Wang {
1007adca706SCL Wang 	unsigned int val;
1017adca706SCL Wang 
1027adca706SCL Wang 	/*
1037adca706SCL Wang 	 * Using read_poll_timeout is more efficient than a manual loop
1047adca706SCL Wang 	 * with usleep_range.
1057adca706SCL Wang 	 */
1067adca706SCL Wang 	return regmap_read_poll_timeout(rtc->regmap, RTC_STA, val,
1077adca706SCL Wang 					val & WRITE_DONE,
1087adca706SCL Wang 					ATCRTC_TIMEOUT_USLEEP_MIN,
1097adca706SCL Wang 					ATCRTC_TIMEOUT_US);
1107adca706SCL Wang }
1117adca706SCL Wang 
atcrtc_alarm_isr(int irq,void * dev)1127adca706SCL Wang static irqreturn_t atcrtc_alarm_isr(int irq, void *dev)
1137adca706SCL Wang {
1147adca706SCL Wang 	struct atcrtc_dev *rtc = dev;
1157adca706SCL Wang 	unsigned int status;
1167adca706SCL Wang 
1177adca706SCL Wang 	regmap_read(rtc->regmap, RTC_STA, &status);
1187adca706SCL Wang 	if (status & ALARM_INT) {
1197adca706SCL Wang 		regmap_write(rtc->regmap, RTC_STA, ALARM_INT);
1207adca706SCL Wang 		rtc->alarm_en = false;
1217adca706SCL Wang 		schedule_work(&rtc->rtc_work);
1227adca706SCL Wang 		rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
1237adca706SCL Wang 		return IRQ_HANDLED;
1247adca706SCL Wang 	}
1257adca706SCL Wang 	return IRQ_NONE;
1267adca706SCL Wang }
1277adca706SCL Wang 
atcrtc_alarm_irq_enable(struct device * dev,unsigned int enable)1287adca706SCL Wang static int atcrtc_alarm_irq_enable(struct device *dev, unsigned int enable)
1297adca706SCL Wang {
1307adca706SCL Wang 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
1317adca706SCL Wang 	unsigned int mask;
1327adca706SCL Wang 	int ret;
1337adca706SCL Wang 
1347adca706SCL Wang 	ret = atcrtc_check_write_done(rtc);
1357adca706SCL Wang 	if (ret)
1367adca706SCL Wang 		return ret;
1377adca706SCL Wang 
1387adca706SCL Wang 	mask = ALARM_WAKEUP | ALARM_INT;
1397adca706SCL Wang 	regmap_update_bits(rtc->regmap, RTC_CR, mask, enable ? mask : 0);
1407adca706SCL Wang 
1417adca706SCL Wang 	return 0;
1427adca706SCL Wang }
1437adca706SCL Wang 
atcrtc_alarm_clear(struct work_struct * work)1447adca706SCL Wang static void atcrtc_alarm_clear(struct work_struct *work)
1457adca706SCL Wang {
1467adca706SCL Wang 	struct atcrtc_dev *rtc =
1477adca706SCL Wang 		container_of(work, struct atcrtc_dev, rtc_work);
1487adca706SCL Wang 	int ret;
1497adca706SCL Wang 
1507adca706SCL Wang 	rtc_lock(rtc->rtc_dev);
1517adca706SCL Wang 
1527adca706SCL Wang 	if (!rtc->alarm_en) {
1537adca706SCL Wang 		ret = atcrtc_check_write_done(rtc);
1547adca706SCL Wang 		if (ret)
1557adca706SCL Wang 			dev_info(&rtc->rtc_dev->dev,
1567adca706SCL Wang 				 "failed to sync before clearing alarm: %d\n",
1577adca706SCL Wang 				 ret);
1587adca706SCL Wang 		else
1597adca706SCL Wang 			regmap_update_bits(rtc->regmap, RTC_CR,
1607adca706SCL Wang 					   ALARM_WAKEUP | ALARM_INT, 0);
1617adca706SCL Wang 	}
1627adca706SCL Wang 	rtc_unlock(rtc->rtc_dev);
1637adca706SCL Wang }
1647adca706SCL Wang 
atcrtc_read_time(struct device * dev,struct rtc_time * tm)1657adca706SCL Wang static int atcrtc_read_time(struct device *dev, struct rtc_time *tm)
1667adca706SCL Wang {
1677adca706SCL Wang 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
1687adca706SCL Wang 	time64_t time;
1697adca706SCL Wang 	unsigned int rtc_cnt;
1707adca706SCL Wang 
1717adca706SCL Wang 	if (!regmap_test_bits(rtc->regmap, RTC_CR, RTC_EN))
1727adca706SCL Wang 		return -EIO;
1737adca706SCL Wang 
1747adca706SCL Wang 	regmap_read(rtc->regmap, RTC_CNT, &rtc_cnt);
1757adca706SCL Wang 	time = ATCRTC_TIME_TO_SEC(RTC_DAY_GET(rtc_cnt),
1767adca706SCL Wang 				  RTC_HOUR_GET(rtc_cnt),
1777adca706SCL Wang 				  RTC_MIN_GET(rtc_cnt),
1787adca706SCL Wang 				  RTC_SEC_GET(rtc_cnt));
1797adca706SCL Wang 	rtc_time64_to_tm(time, tm);
1807adca706SCL Wang 
1817adca706SCL Wang 	return 0;
1827adca706SCL Wang }
1837adca706SCL Wang 
atcrtc_set_time(struct device * dev,struct rtc_time * tm)1847adca706SCL Wang static int atcrtc_set_time(struct device *dev, struct rtc_time *tm)
1857adca706SCL Wang {
1867adca706SCL Wang 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
1877adca706SCL Wang 	time64_t time;
1887adca706SCL Wang 	unsigned int counter;
1897adca706SCL Wang 	unsigned int day;
1907adca706SCL Wang 	int ret;
1917adca706SCL Wang 
1927adca706SCL Wang 	time = rtc_tm_to_time64(tm);
1937adca706SCL Wang 	day = div_s64(time, 86400);
1947adca706SCL Wang 	counter = RTC_DAY_SET(day) |
1957adca706SCL Wang 		  RTC_HOUR_SET(tm->tm_hour) |
1967adca706SCL Wang 		  RTC_MIN_SET(tm->tm_min) |
1977adca706SCL Wang 		  RTC_SEC_SET(tm->tm_sec);
1987adca706SCL Wang 	ret = atcrtc_check_write_done(rtc);
1997adca706SCL Wang 	if (ret)
2007adca706SCL Wang 		return ret;
2017adca706SCL Wang 	regmap_write(rtc->regmap, RTC_CNT, counter);
2027adca706SCL Wang 
2037adca706SCL Wang 	ret = atcrtc_check_write_done(rtc);
2047adca706SCL Wang 	if (ret)
2057adca706SCL Wang 		return ret;
2067adca706SCL Wang 	regmap_update_bits(rtc->regmap, RTC_CR, RTC_EN, RTC_EN);
2077adca706SCL Wang 
2087adca706SCL Wang 	return 0;
2097adca706SCL Wang }
2107adca706SCL Wang 
atcrtc_read_alarm(struct device * dev,struct rtc_wkalrm * wkalrm)2117adca706SCL Wang static int atcrtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
2127adca706SCL Wang {
2137adca706SCL Wang 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
2147adca706SCL Wang 	struct rtc_time *tm = &wkalrm->time;
2157adca706SCL Wang 	unsigned int rtc_alarm;
2167adca706SCL Wang 
2177adca706SCL Wang 	wkalrm->enabled = regmap_test_bits(rtc->regmap, RTC_CR, ALARM_INT);
2187adca706SCL Wang 	regmap_read(rtc->regmap, RTC_ALM, &rtc_alarm);
2197adca706SCL Wang 	tm->tm_hour = RTC_HOUR_GET(rtc_alarm);
2207adca706SCL Wang 	tm->tm_min = RTC_MIN_GET(rtc_alarm);
2217adca706SCL Wang 	tm->tm_sec = RTC_SEC_GET(rtc_alarm);
2227adca706SCL Wang 
2237adca706SCL Wang 	/* The RTC alarm does not support day/month/year fields */
2247adca706SCL Wang 	tm->tm_mday = -1;
2257adca706SCL Wang 	tm->tm_mon = -1;
2267adca706SCL Wang 	tm->tm_year = -1;
2277adca706SCL Wang 
2287adca706SCL Wang 	return 0;
2297adca706SCL Wang }
2307adca706SCL Wang 
atcrtc_set_alarm(struct device * dev,struct rtc_wkalrm * wkalrm)2317adca706SCL Wang static int atcrtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
2327adca706SCL Wang {
2337adca706SCL Wang 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
2347adca706SCL Wang 	struct rtc_time *tm = &wkalrm->time;
2357adca706SCL Wang 	unsigned int rtc_alarm;
2367adca706SCL Wang 	int ret;
2377adca706SCL Wang 
2387adca706SCL Wang 	/* Disable alarm first before setting a new one */
2397adca706SCL Wang 	ret = atcrtc_alarm_irq_enable(dev, 0);
2407adca706SCL Wang 	if (ret)
2417adca706SCL Wang 		return ret;
2427adca706SCL Wang 
2437adca706SCL Wang 	rtc->alarm_en = false;
2447adca706SCL Wang 
2457adca706SCL Wang 	rtc_alarm = RTC_SEC_SET(tm->tm_sec) |
2467adca706SCL Wang 		    RTC_MIN_SET(tm->tm_min) |
2477adca706SCL Wang 		    RTC_HOUR_SET(tm->tm_hour);
2487adca706SCL Wang 
2497adca706SCL Wang 	ret = atcrtc_check_write_done(rtc);
2507adca706SCL Wang 	if (ret)
2517adca706SCL Wang 		return ret;
2527adca706SCL Wang 
2537adca706SCL Wang 	regmap_write(rtc->regmap, RTC_ALM, rtc_alarm);
2547adca706SCL Wang 
2557adca706SCL Wang 	rtc->alarm_en = wkalrm->enabled;
2567adca706SCL Wang 	ret = atcrtc_alarm_irq_enable(dev, wkalrm->enabled);
2577adca706SCL Wang 
2587adca706SCL Wang 	return ret;
2597adca706SCL Wang }
2607adca706SCL Wang 
2617adca706SCL Wang static const struct rtc_class_ops rtc_ops = {
2627adca706SCL Wang 	.read_time = atcrtc_read_time,
2637adca706SCL Wang 	.set_time = atcrtc_set_time,
2647adca706SCL Wang 	.read_alarm = atcrtc_read_alarm,
2657adca706SCL Wang 	.set_alarm = atcrtc_set_alarm,
2667adca706SCL Wang 	.alarm_irq_enable = atcrtc_alarm_irq_enable,
2677adca706SCL Wang };
2687adca706SCL Wang 
atcrtc_probe(struct platform_device * pdev)2697adca706SCL Wang static int atcrtc_probe(struct platform_device *pdev)
2707adca706SCL Wang {
2717adca706SCL Wang 	struct atcrtc_dev *atcrtc_dev;
2727adca706SCL Wang 	void __iomem *reg_base;
2737adca706SCL Wang 	unsigned int rtc_id;
2747adca706SCL Wang 	int ret;
2757adca706SCL Wang 
2767adca706SCL Wang 	atcrtc_dev = devm_kzalloc(&pdev->dev, sizeof(*atcrtc_dev), GFP_KERNEL);
2777adca706SCL Wang 	if (!atcrtc_dev)
2787adca706SCL Wang 		return -ENOMEM;
2797adca706SCL Wang 	platform_set_drvdata(pdev, atcrtc_dev);
2807adca706SCL Wang 
2817adca706SCL Wang 	reg_base = devm_platform_ioremap_resource(pdev, 0);
2827adca706SCL Wang 	if (IS_ERR(reg_base))
2837adca706SCL Wang 		return dev_err_probe(&pdev->dev, PTR_ERR(reg_base),
2847adca706SCL Wang 				     "Failed to map I/O space\n");
2857adca706SCL Wang 
2867adca706SCL Wang 	atcrtc_dev->regmap = devm_regmap_init_mmio(&pdev->dev,
2877adca706SCL Wang 						   reg_base,
2887adca706SCL Wang 						   &atcrtc_regmap_config);
2897adca706SCL Wang 	if (IS_ERR(atcrtc_dev->regmap))
2907adca706SCL Wang 		return dev_err_probe(&pdev->dev, PTR_ERR(atcrtc_dev->regmap),
2917adca706SCL Wang 				     "Failed to initialize regmap\n");
2927adca706SCL Wang 
2937adca706SCL Wang 	regmap_read(atcrtc_dev->regmap, RTC_ID, &rtc_id);
2947adca706SCL Wang 	if (FIELD_GET(ID_MSK, rtc_id) != ID_ATCRTC100)
2957adca706SCL Wang 		return dev_err_probe(&pdev->dev, -ENODEV,
2967adca706SCL Wang 				     "Failed to initialize RTC: unsupported hardware ID 0x%x\n",
2977adca706SCL Wang 				     rtc_id);
2987adca706SCL Wang 
299*159a740cSDan Carpenter 	ret = platform_get_irq(pdev, 1);
300*159a740cSDan Carpenter 	if (ret < 0)
301*159a740cSDan Carpenter 		return dev_err_probe(&pdev->dev, ret,
3027adca706SCL Wang 				     "Failed to get IRQ for alarm\n");
303*159a740cSDan Carpenter 	atcrtc_dev->alarm_irq = ret;
304*159a740cSDan Carpenter 
3057adca706SCL Wang 	ret = devm_request_irq(&pdev->dev,
3067adca706SCL Wang 			       atcrtc_dev->alarm_irq,
3077adca706SCL Wang 			       atcrtc_alarm_isr,
3087adca706SCL Wang 			       0,
3097adca706SCL Wang 			       "atcrtc_alarm",
3107adca706SCL Wang 			       atcrtc_dev);
3117adca706SCL Wang 	if (ret)
3127adca706SCL Wang 		return dev_err_probe(&pdev->dev, ret,
3137adca706SCL Wang 				     "Failed to request IRQ %d for alarm\n",
3147adca706SCL Wang 				     atcrtc_dev->alarm_irq);
3157adca706SCL Wang 
3167adca706SCL Wang 	atcrtc_dev->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
3177adca706SCL Wang 	if (IS_ERR(atcrtc_dev->rtc_dev))
3187adca706SCL Wang 		return dev_err_probe(&pdev->dev, PTR_ERR(atcrtc_dev->rtc_dev),
3197adca706SCL Wang 				     "Failed to allocate RTC device\n");
3207adca706SCL Wang 
3217adca706SCL Wang 	set_bit(RTC_FEATURE_ALARM, atcrtc_dev->rtc_dev->features);
3227adca706SCL Wang 	ret = device_init_wakeup(&pdev->dev, true);
3237adca706SCL Wang 	if (ret)
3247adca706SCL Wang 		return dev_err_probe(&pdev->dev, ret,
3257adca706SCL Wang 				     "Failed to initialize wake capability\n");
3267adca706SCL Wang 
3277adca706SCL Wang 	ret = dev_pm_set_wake_irq(&pdev->dev, atcrtc_dev->alarm_irq);
3287adca706SCL Wang 	if (ret) {
3297adca706SCL Wang 		device_init_wakeup(&pdev->dev, false);
3307adca706SCL Wang 		return dev_err_probe(&pdev->dev, ret,
3317adca706SCL Wang 				     "Failed to set wake IRQ\n");
3327adca706SCL Wang 	}
3337adca706SCL Wang 
3347adca706SCL Wang 	atcrtc_dev->rtc_dev->ops = &rtc_ops;
3357adca706SCL Wang 
3367adca706SCL Wang 	INIT_WORK(&atcrtc_dev->rtc_work, atcrtc_alarm_clear);
3377adca706SCL Wang 	return devm_rtc_register_device(atcrtc_dev->rtc_dev);
3387adca706SCL Wang }
3397adca706SCL Wang 
atcrtc_resume(struct device * dev)3407adca706SCL Wang static int atcrtc_resume(struct device *dev)
3417adca706SCL Wang {
3427adca706SCL Wang 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
3437adca706SCL Wang 
3447adca706SCL Wang 	if (device_may_wakeup(dev))
3457adca706SCL Wang 		disable_irq_wake(rtc->alarm_irq);
3467adca706SCL Wang 
3477adca706SCL Wang 	return 0;
3487adca706SCL Wang }
3497adca706SCL Wang 
atcrtc_suspend(struct device * dev)3507adca706SCL Wang static int atcrtc_suspend(struct device *dev)
3517adca706SCL Wang {
3527adca706SCL Wang 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
3537adca706SCL Wang 
3547adca706SCL Wang 	if (device_may_wakeup(dev))
3557adca706SCL Wang 		enable_irq_wake(rtc->alarm_irq);
3567adca706SCL Wang 
3577adca706SCL Wang 	return 0;
3587adca706SCL Wang }
3597adca706SCL Wang 
3607adca706SCL Wang static DEFINE_SIMPLE_DEV_PM_OPS(atcrtc_pm_ops, atcrtc_suspend, atcrtc_resume);
3617adca706SCL Wang 
3627adca706SCL Wang static const struct of_device_id atcrtc_dt_match[] = {
3637adca706SCL Wang 	{ .compatible = "andestech,atcrtc100" },
3647adca706SCL Wang 	{ },
3657adca706SCL Wang };
3667adca706SCL Wang MODULE_DEVICE_TABLE(of, atcrtc_dt_match);
3677adca706SCL Wang 
3687adca706SCL Wang static struct platform_driver atcrtc_platform_driver = {
3697adca706SCL Wang 	.driver = {
3707adca706SCL Wang 		.name = "atcrtc100",
3717adca706SCL Wang 		.of_match_table = atcrtc_dt_match,
3727adca706SCL Wang 		.pm = pm_sleep_ptr(&atcrtc_pm_ops),
3737adca706SCL Wang 	},
3747adca706SCL Wang 	.probe = atcrtc_probe,
3757adca706SCL Wang };
3767adca706SCL Wang 
3777adca706SCL Wang module_platform_driver(atcrtc_platform_driver);
3787adca706SCL Wang 
3797adca706SCL Wang MODULE_AUTHOR("CL Wang <cl634@andestech.com>");
3807adca706SCL Wang MODULE_DESCRIPTION("Andes ATCRTC100 driver");
3817adca706SCL Wang MODULE_LICENSE("GPL");
382