1df17f631Sdmitry pervushin /* 2df17f631Sdmitry pervushin * Freescale STMP37XX/STMP378X Real Time Clock driver 3df17f631Sdmitry pervushin * 4df17f631Sdmitry pervushin * Copyright (c) 2007 Sigmatel, Inc. 5df17f631Sdmitry pervushin * Peter Hartley, <peter.hartley@sigmatel.com> 6df17f631Sdmitry pervushin * 7df17f631Sdmitry pervushin * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. 8df17f631Sdmitry pervushin * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. 97e794cb7SWolfram Sang * Copyright 2011 Wolfram Sang, Pengutronix e.K. 10df17f631Sdmitry pervushin */ 11df17f631Sdmitry pervushin 12df17f631Sdmitry pervushin /* 13df17f631Sdmitry pervushin * The code contained herein is licensed under the GNU General Public 14df17f631Sdmitry pervushin * License. You may obtain a copy of the GNU General Public License 15df17f631Sdmitry pervushin * Version 2 or later at the following locations: 16df17f631Sdmitry pervushin * 17df17f631Sdmitry pervushin * http://www.opensource.org/licenses/gpl-license.html 18df17f631Sdmitry pervushin * http://www.gnu.org/copyleft/gpl.html 19df17f631Sdmitry pervushin */ 20df17f631Sdmitry pervushin #include <linux/kernel.h> 21df17f631Sdmitry pervushin #include <linux/module.h> 22b5167159SWolfram Sang #include <linux/io.h> 23df17f631Sdmitry pervushin #include <linux/init.h> 24df17f631Sdmitry pervushin #include <linux/platform_device.h> 25df17f631Sdmitry pervushin #include <linux/interrupt.h> 26df17f631Sdmitry pervushin #include <linux/rtc.h> 275a0e3ad6STejun Heo #include <linux/slab.h> 28dd8d20a3SMarek Vasut #include <linux/of_device.h> 29c8a6046eSSachin Kamat #include <linux/of.h> 301a71fb84SWolfram Sang #include <linux/stmp_device.h> 311a71fb84SWolfram Sang #include <linux/stmp3xxx_rtc_wdt.h> 32df17f631Sdmitry pervushin 3347eac337SWolfram Sang #define STMP3XXX_RTC_CTRL 0x0 34b5167159SWolfram Sang #define STMP3XXX_RTC_CTRL_SET 0x4 35b5167159SWolfram Sang #define STMP3XXX_RTC_CTRL_CLR 0x8 3647eac337SWolfram Sang #define STMP3XXX_RTC_CTRL_ALARM_IRQ_EN 0x00000001 3747eac337SWolfram Sang #define STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN 0x00000002 3847eac337SWolfram Sang #define STMP3XXX_RTC_CTRL_ALARM_IRQ 0x00000004 391a71fb84SWolfram Sang #define STMP3XXX_RTC_CTRL_WATCHDOGEN 0x00000010 4047eac337SWolfram Sang 4147eac337SWolfram Sang #define STMP3XXX_RTC_STAT 0x10 4247eac337SWolfram Sang #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 4347eac337SWolfram Sang #define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000 4447eac337SWolfram Sang 4547eac337SWolfram Sang #define STMP3XXX_RTC_SECONDS 0x30 4647eac337SWolfram Sang 4747eac337SWolfram Sang #define STMP3XXX_RTC_ALARM 0x40 4847eac337SWolfram Sang 491a71fb84SWolfram Sang #define STMP3XXX_RTC_WATCHDOG 0x50 501a71fb84SWolfram Sang 5147eac337SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0 0x60 52b5167159SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 53b5167159SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 5447eac337SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002 5547eac337SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 5647eac337SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 57df17f631Sdmitry pervushin 581a71fb84SWolfram Sang #define STMP3XXX_RTC_PERSISTENT1 0x70 591a71fb84SWolfram Sang /* missing bitmask in headers */ 601a71fb84SWolfram Sang #define STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER 0x80000000 611a71fb84SWolfram Sang 62df17f631Sdmitry pervushin struct stmp3xxx_rtc_data { 63df17f631Sdmitry pervushin struct rtc_device *rtc; 64df17f631Sdmitry pervushin void __iomem *io; 657e794cb7SWolfram Sang int irq_alarm; 66df17f631Sdmitry pervushin }; 67df17f631Sdmitry pervushin 681a71fb84SWolfram Sang #if IS_ENABLED(CONFIG_STMP3XXX_RTC_WATCHDOG) 691a71fb84SWolfram Sang /** 701a71fb84SWolfram Sang * stmp3xxx_wdt_set_timeout - configure the watchdog inside the STMP3xxx RTC 711a71fb84SWolfram Sang * @dev: the parent device of the watchdog (= the RTC) 721a71fb84SWolfram Sang * @timeout: the desired value for the timeout register of the watchdog. 731a71fb84SWolfram Sang * 0 disables the watchdog 741a71fb84SWolfram Sang * 751a71fb84SWolfram Sang * The watchdog needs one register and two bits which are in the RTC domain. 761a71fb84SWolfram Sang * To handle the resource conflict, the RTC driver will create another 771a71fb84SWolfram Sang * platform_device for the watchdog driver as a child of the RTC device. 781a71fb84SWolfram Sang * The watchdog driver is passed the below accessor function via platform_data 791a71fb84SWolfram Sang * to configure the watchdog. Locking is not needed because accessing SET/CLR 801a71fb84SWolfram Sang * registers is atomic. 811a71fb84SWolfram Sang */ 821a71fb84SWolfram Sang 831a71fb84SWolfram Sang static void stmp3xxx_wdt_set_timeout(struct device *dev, u32 timeout) 841a71fb84SWolfram Sang { 851a71fb84SWolfram Sang struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 861a71fb84SWolfram Sang 871a71fb84SWolfram Sang if (timeout) { 881a71fb84SWolfram Sang writel(timeout, rtc_data->io + STMP3XXX_RTC_WATCHDOG); 891a71fb84SWolfram Sang writel(STMP3XXX_RTC_CTRL_WATCHDOGEN, 901a71fb84SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_SET); 911a71fb84SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER, 921a71fb84SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_SET); 931a71fb84SWolfram Sang } else { 941a71fb84SWolfram Sang writel(STMP3XXX_RTC_CTRL_WATCHDOGEN, 951a71fb84SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_CLR); 961a71fb84SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER, 971a71fb84SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_CLR); 981a71fb84SWolfram Sang } 991a71fb84SWolfram Sang } 1001a71fb84SWolfram Sang 1011a71fb84SWolfram Sang static struct stmp3xxx_wdt_pdata wdt_pdata = { 1021a71fb84SWolfram Sang .wdt_set_timeout = stmp3xxx_wdt_set_timeout, 1031a71fb84SWolfram Sang }; 1041a71fb84SWolfram Sang 1051a71fb84SWolfram Sang static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) 1061a71fb84SWolfram Sang { 1071a71fb84SWolfram Sang struct platform_device *wdt_pdev = 1081a71fb84SWolfram Sang platform_device_alloc("stmp3xxx_rtc_wdt", rtc_pdev->id); 1091a71fb84SWolfram Sang 1101a71fb84SWolfram Sang if (wdt_pdev) { 1111a71fb84SWolfram Sang wdt_pdev->dev.parent = &rtc_pdev->dev; 1121a71fb84SWolfram Sang wdt_pdev->dev.platform_data = &wdt_pdata; 1131a71fb84SWolfram Sang platform_device_add(wdt_pdev); 1141a71fb84SWolfram Sang } 1151a71fb84SWolfram Sang } 1161a71fb84SWolfram Sang #else 1171a71fb84SWolfram Sang static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) 1181a71fb84SWolfram Sang { 1191a71fb84SWolfram Sang } 1201a71fb84SWolfram Sang #endif /* CONFIG_STMP3XXX_RTC_WATCHDOG */ 1211a71fb84SWolfram Sang 122df17f631Sdmitry pervushin static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) 123df17f631Sdmitry pervushin { 124df17f631Sdmitry pervushin /* 125df17f631Sdmitry pervushin * The datasheet doesn't say which way round the 126df17f631Sdmitry pervushin * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0, 127df17f631Sdmitry pervushin * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS 128df17f631Sdmitry pervushin */ 129b5167159SWolfram Sang while (readl(rtc_data->io + STMP3XXX_RTC_STAT) & 13047eac337SWolfram Sang (0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) 131df17f631Sdmitry pervushin cpu_relax(); 132df17f631Sdmitry pervushin } 133df17f631Sdmitry pervushin 134df17f631Sdmitry pervushin /* Time read/write */ 135df17f631Sdmitry pervushin static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) 136df17f631Sdmitry pervushin { 137df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 138df17f631Sdmitry pervushin 139df17f631Sdmitry pervushin stmp3xxx_wait_time(rtc_data); 140b5167159SWolfram Sang rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); 141df17f631Sdmitry pervushin return 0; 142df17f631Sdmitry pervushin } 143df17f631Sdmitry pervushin 144df17f631Sdmitry pervushin static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) 145df17f631Sdmitry pervushin { 146df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 147df17f631Sdmitry pervushin 148b5167159SWolfram Sang writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); 149df17f631Sdmitry pervushin stmp3xxx_wait_time(rtc_data); 150df17f631Sdmitry pervushin return 0; 151df17f631Sdmitry pervushin } 152df17f631Sdmitry pervushin 153df17f631Sdmitry pervushin /* interrupt(s) handler */ 154df17f631Sdmitry pervushin static irqreturn_t stmp3xxx_rtc_interrupt(int irq, void *dev_id) 155df17f631Sdmitry pervushin { 156df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev_id); 1577e794cb7SWolfram Sang u32 status = readl(rtc_data->io + STMP3XXX_RTC_CTRL); 158df17f631Sdmitry pervushin 15947eac337SWolfram Sang if (status & STMP3XXX_RTC_CTRL_ALARM_IRQ) { 160b5167159SWolfram Sang writel(STMP3XXX_RTC_CTRL_ALARM_IRQ, 161b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 1627e794cb7SWolfram Sang rtc_update_irq(rtc_data->rtc, 1, RTC_AF | RTC_IRQF); 163df17f631Sdmitry pervushin return IRQ_HANDLED; 164df17f631Sdmitry pervushin } 165df17f631Sdmitry pervushin 1667e794cb7SWolfram Sang return IRQ_NONE; 1677e794cb7SWolfram Sang } 1687e794cb7SWolfram Sang 169df17f631Sdmitry pervushin static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled) 170df17f631Sdmitry pervushin { 171df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 172df17f631Sdmitry pervushin 173df17f631Sdmitry pervushin if (enabled) { 174b5167159SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 175b5167159SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, 176b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET); 177b5167159SWolfram Sang writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 178b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_SET); 179df17f631Sdmitry pervushin } else { 180b5167159SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 181b5167159SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, 182b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 183b5167159SWolfram Sang writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 184b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 185df17f631Sdmitry pervushin } 186df17f631Sdmitry pervushin return 0; 187df17f631Sdmitry pervushin } 188df17f631Sdmitry pervushin 189df17f631Sdmitry pervushin static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 190df17f631Sdmitry pervushin { 191df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 192df17f631Sdmitry pervushin 193b5167159SWolfram Sang rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_ALARM), &alm->time); 194df17f631Sdmitry pervushin return 0; 195df17f631Sdmitry pervushin } 196df17f631Sdmitry pervushin 197df17f631Sdmitry pervushin static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 198df17f631Sdmitry pervushin { 199df17f631Sdmitry pervushin unsigned long t; 200df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 201df17f631Sdmitry pervushin 202df17f631Sdmitry pervushin rtc_tm_to_time(&alm->time, &t); 203b5167159SWolfram Sang writel(t, rtc_data->io + STMP3XXX_RTC_ALARM); 2047e794cb7SWolfram Sang 2057e794cb7SWolfram Sang stmp3xxx_alarm_irq_enable(dev, alm->enabled); 2067e794cb7SWolfram Sang 207df17f631Sdmitry pervushin return 0; 208df17f631Sdmitry pervushin } 209df17f631Sdmitry pervushin 210df17f631Sdmitry pervushin static struct rtc_class_ops stmp3xxx_rtc_ops = { 211df17f631Sdmitry pervushin .alarm_irq_enable = 212df17f631Sdmitry pervushin stmp3xxx_alarm_irq_enable, 213df17f631Sdmitry pervushin .read_time = stmp3xxx_rtc_gettime, 214df17f631Sdmitry pervushin .set_mmss = stmp3xxx_rtc_set_mmss, 215df17f631Sdmitry pervushin .read_alarm = stmp3xxx_rtc_read_alarm, 216df17f631Sdmitry pervushin .set_alarm = stmp3xxx_rtc_set_alarm, 217df17f631Sdmitry pervushin }; 218df17f631Sdmitry pervushin 219df17f631Sdmitry pervushin static int stmp3xxx_rtc_remove(struct platform_device *pdev) 220df17f631Sdmitry pervushin { 221df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(pdev); 222df17f631Sdmitry pervushin 223df17f631Sdmitry pervushin if (!rtc_data) 224df17f631Sdmitry pervushin return 0; 225df17f631Sdmitry pervushin 2267e794cb7SWolfram Sang writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 227b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 228df17f631Sdmitry pervushin free_irq(rtc_data->irq_alarm, &pdev->dev); 229df17f631Sdmitry pervushin rtc_device_unregister(rtc_data->rtc); 230a91d2babSWolfram Sang platform_set_drvdata(pdev, NULL); 231df17f631Sdmitry pervushin iounmap(rtc_data->io); 232df17f631Sdmitry pervushin kfree(rtc_data); 233df17f631Sdmitry pervushin 234df17f631Sdmitry pervushin return 0; 235df17f631Sdmitry pervushin } 236df17f631Sdmitry pervushin 237df17f631Sdmitry pervushin static int stmp3xxx_rtc_probe(struct platform_device *pdev) 238df17f631Sdmitry pervushin { 239df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data; 240df17f631Sdmitry pervushin struct resource *r; 241df17f631Sdmitry pervushin int err; 242df17f631Sdmitry pervushin 243df17f631Sdmitry pervushin rtc_data = kzalloc(sizeof *rtc_data, GFP_KERNEL); 244df17f631Sdmitry pervushin if (!rtc_data) 245df17f631Sdmitry pervushin return -ENOMEM; 246df17f631Sdmitry pervushin 247df17f631Sdmitry pervushin r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 248df17f631Sdmitry pervushin if (!r) { 249df17f631Sdmitry pervushin dev_err(&pdev->dev, "failed to get resource\n"); 250df17f631Sdmitry pervushin err = -ENXIO; 251df17f631Sdmitry pervushin goto out_free; 252df17f631Sdmitry pervushin } 253df17f631Sdmitry pervushin 254df17f631Sdmitry pervushin rtc_data->io = ioremap(r->start, resource_size(r)); 255df17f631Sdmitry pervushin if (!rtc_data->io) { 256df17f631Sdmitry pervushin dev_err(&pdev->dev, "ioremap failed\n"); 257df17f631Sdmitry pervushin err = -EIO; 258df17f631Sdmitry pervushin goto out_free; 259df17f631Sdmitry pervushin } 260df17f631Sdmitry pervushin 261df17f631Sdmitry pervushin rtc_data->irq_alarm = platform_get_irq(pdev, 0); 262df17f631Sdmitry pervushin 263b5167159SWolfram Sang if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & 26447eac337SWolfram Sang STMP3XXX_RTC_STAT_RTC_PRESENT)) { 265df17f631Sdmitry pervushin dev_err(&pdev->dev, "no device onboard\n"); 266df17f631Sdmitry pervushin err = -ENODEV; 267df17f631Sdmitry pervushin goto out_remap; 268df17f631Sdmitry pervushin } 269df17f631Sdmitry pervushin 270a91d2babSWolfram Sang platform_set_drvdata(pdev, rtc_data); 271a91d2babSWolfram Sang 272*36d1da1dSShawn Guo stmp_reset_block(rtc_data->io); 273b5167159SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 27447eac337SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | 27547eac337SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, 276b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 277a91d2babSWolfram Sang 2787e794cb7SWolfram Sang writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN | 2797e794cb7SWolfram Sang STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 2807e794cb7SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 2817e794cb7SWolfram Sang 282df17f631Sdmitry pervushin rtc_data->rtc = rtc_device_register(pdev->name, &pdev->dev, 283df17f631Sdmitry pervushin &stmp3xxx_rtc_ops, THIS_MODULE); 284df17f631Sdmitry pervushin if (IS_ERR(rtc_data->rtc)) { 285df17f631Sdmitry pervushin err = PTR_ERR(rtc_data->rtc); 286df17f631Sdmitry pervushin goto out_remap; 287df17f631Sdmitry pervushin } 288df17f631Sdmitry pervushin 2897e794cb7SWolfram Sang err = request_irq(rtc_data->irq_alarm, stmp3xxx_rtc_interrupt, 0, 2907e794cb7SWolfram Sang "RTC alarm", &pdev->dev); 291df17f631Sdmitry pervushin if (err) { 292df17f631Sdmitry pervushin dev_err(&pdev->dev, "Cannot claim IRQ%d\n", 293df17f631Sdmitry pervushin rtc_data->irq_alarm); 294df17f631Sdmitry pervushin goto out_irq_alarm; 295df17f631Sdmitry pervushin } 296df17f631Sdmitry pervushin 2971a71fb84SWolfram Sang stmp3xxx_wdt_register(pdev); 298df17f631Sdmitry pervushin return 0; 299df17f631Sdmitry pervushin 300df17f631Sdmitry pervushin out_irq_alarm: 301df17f631Sdmitry pervushin rtc_device_unregister(rtc_data->rtc); 302df17f631Sdmitry pervushin out_remap: 303a91d2babSWolfram Sang platform_set_drvdata(pdev, NULL); 304df17f631Sdmitry pervushin iounmap(rtc_data->io); 305df17f631Sdmitry pervushin out_free: 306df17f631Sdmitry pervushin kfree(rtc_data); 307df17f631Sdmitry pervushin return err; 308df17f631Sdmitry pervushin } 309df17f631Sdmitry pervushin 310df17f631Sdmitry pervushin #ifdef CONFIG_PM 311df17f631Sdmitry pervushin static int stmp3xxx_rtc_suspend(struct platform_device *dev, pm_message_t state) 312df17f631Sdmitry pervushin { 313df17f631Sdmitry pervushin return 0; 314df17f631Sdmitry pervushin } 315df17f631Sdmitry pervushin 316df17f631Sdmitry pervushin static int stmp3xxx_rtc_resume(struct platform_device *dev) 317df17f631Sdmitry pervushin { 318df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(dev); 319df17f631Sdmitry pervushin 320*36d1da1dSShawn Guo stmp_reset_block(rtc_data->io); 321b5167159SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 32247eac337SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | 32347eac337SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, 324b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 325df17f631Sdmitry pervushin return 0; 326df17f631Sdmitry pervushin } 327df17f631Sdmitry pervushin #else 328df17f631Sdmitry pervushin #define stmp3xxx_rtc_suspend NULL 329df17f631Sdmitry pervushin #define stmp3xxx_rtc_resume NULL 330df17f631Sdmitry pervushin #endif 331df17f631Sdmitry pervushin 332dd8d20a3SMarek Vasut static const struct of_device_id rtc_dt_ids[] = { 333dd8d20a3SMarek Vasut { .compatible = "fsl,stmp3xxx-rtc", }, 334dd8d20a3SMarek Vasut { /* sentinel */ } 335dd8d20a3SMarek Vasut }; 336dd8d20a3SMarek Vasut MODULE_DEVICE_TABLE(of, rtc_dt_ids); 337dd8d20a3SMarek Vasut 338df17f631Sdmitry pervushin static struct platform_driver stmp3xxx_rtcdrv = { 339df17f631Sdmitry pervushin .probe = stmp3xxx_rtc_probe, 340df17f631Sdmitry pervushin .remove = stmp3xxx_rtc_remove, 341df17f631Sdmitry pervushin .suspend = stmp3xxx_rtc_suspend, 342df17f631Sdmitry pervushin .resume = stmp3xxx_rtc_resume, 343df17f631Sdmitry pervushin .driver = { 344df17f631Sdmitry pervushin .name = "stmp3xxx-rtc", 345df17f631Sdmitry pervushin .owner = THIS_MODULE, 346c8a6046eSSachin Kamat .of_match_table = of_match_ptr(rtc_dt_ids), 347df17f631Sdmitry pervushin }, 348df17f631Sdmitry pervushin }; 349df17f631Sdmitry pervushin 3500c4eae66SAxel Lin module_platform_driver(stmp3xxx_rtcdrv); 351df17f631Sdmitry pervushin 352df17f631Sdmitry pervushin MODULE_DESCRIPTION("STMP3xxx RTC Driver"); 3537e794cb7SWolfram Sang MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and " 3547e794cb7SWolfram Sang "Wolfram Sang <w.sang@pengutronix.de>"); 355df17f631Sdmitry pervushin MODULE_LICENSE("GPL"); 356