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> 30*1a71fb84SWolfram Sang #include <linux/stmp_device.h> 31*1a71fb84SWolfram Sang #include <linux/stmp3xxx_rtc_wdt.h> 32df17f631Sdmitry pervushin 3346b21218SWolfram Sang #include <mach/common.h> 3447eac337SWolfram Sang 3547eac337SWolfram Sang #define STMP3XXX_RTC_CTRL 0x0 36b5167159SWolfram Sang #define STMP3XXX_RTC_CTRL_SET 0x4 37b5167159SWolfram Sang #define STMP3XXX_RTC_CTRL_CLR 0x8 3847eac337SWolfram Sang #define STMP3XXX_RTC_CTRL_ALARM_IRQ_EN 0x00000001 3947eac337SWolfram Sang #define STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN 0x00000002 4047eac337SWolfram Sang #define STMP3XXX_RTC_CTRL_ALARM_IRQ 0x00000004 41*1a71fb84SWolfram Sang #define STMP3XXX_RTC_CTRL_WATCHDOGEN 0x00000010 4247eac337SWolfram Sang 4347eac337SWolfram Sang #define STMP3XXX_RTC_STAT 0x10 4447eac337SWolfram Sang #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 4547eac337SWolfram Sang #define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000 4647eac337SWolfram Sang 4747eac337SWolfram Sang #define STMP3XXX_RTC_SECONDS 0x30 4847eac337SWolfram Sang 4947eac337SWolfram Sang #define STMP3XXX_RTC_ALARM 0x40 5047eac337SWolfram Sang 51*1a71fb84SWolfram Sang #define STMP3XXX_RTC_WATCHDOG 0x50 52*1a71fb84SWolfram Sang 5347eac337SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0 0x60 54b5167159SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 55b5167159SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 5647eac337SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002 5747eac337SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 5847eac337SWolfram Sang #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 59df17f631Sdmitry pervushin 60*1a71fb84SWolfram Sang #define STMP3XXX_RTC_PERSISTENT1 0x70 61*1a71fb84SWolfram Sang /* missing bitmask in headers */ 62*1a71fb84SWolfram Sang #define STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER 0x80000000 63*1a71fb84SWolfram Sang 64df17f631Sdmitry pervushin struct stmp3xxx_rtc_data { 65df17f631Sdmitry pervushin struct rtc_device *rtc; 66df17f631Sdmitry pervushin void __iomem *io; 677e794cb7SWolfram Sang int irq_alarm; 68df17f631Sdmitry pervushin }; 69df17f631Sdmitry pervushin 70*1a71fb84SWolfram Sang #if IS_ENABLED(CONFIG_STMP3XXX_RTC_WATCHDOG) 71*1a71fb84SWolfram Sang /** 72*1a71fb84SWolfram Sang * stmp3xxx_wdt_set_timeout - configure the watchdog inside the STMP3xxx RTC 73*1a71fb84SWolfram Sang * @dev: the parent device of the watchdog (= the RTC) 74*1a71fb84SWolfram Sang * @timeout: the desired value for the timeout register of the watchdog. 75*1a71fb84SWolfram Sang * 0 disables the watchdog 76*1a71fb84SWolfram Sang * 77*1a71fb84SWolfram Sang * The watchdog needs one register and two bits which are in the RTC domain. 78*1a71fb84SWolfram Sang * To handle the resource conflict, the RTC driver will create another 79*1a71fb84SWolfram Sang * platform_device for the watchdog driver as a child of the RTC device. 80*1a71fb84SWolfram Sang * The watchdog driver is passed the below accessor function via platform_data 81*1a71fb84SWolfram Sang * to configure the watchdog. Locking is not needed because accessing SET/CLR 82*1a71fb84SWolfram Sang * registers is atomic. 83*1a71fb84SWolfram Sang */ 84*1a71fb84SWolfram Sang 85*1a71fb84SWolfram Sang static void stmp3xxx_wdt_set_timeout(struct device *dev, u32 timeout) 86*1a71fb84SWolfram Sang { 87*1a71fb84SWolfram Sang struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 88*1a71fb84SWolfram Sang 89*1a71fb84SWolfram Sang if (timeout) { 90*1a71fb84SWolfram Sang writel(timeout, rtc_data->io + STMP3XXX_RTC_WATCHDOG); 91*1a71fb84SWolfram Sang writel(STMP3XXX_RTC_CTRL_WATCHDOGEN, 92*1a71fb84SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_SET); 93*1a71fb84SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER, 94*1a71fb84SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_SET); 95*1a71fb84SWolfram Sang } else { 96*1a71fb84SWolfram Sang writel(STMP3XXX_RTC_CTRL_WATCHDOGEN, 97*1a71fb84SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_CLR); 98*1a71fb84SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER, 99*1a71fb84SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_CLR); 100*1a71fb84SWolfram Sang } 101*1a71fb84SWolfram Sang } 102*1a71fb84SWolfram Sang 103*1a71fb84SWolfram Sang static struct stmp3xxx_wdt_pdata wdt_pdata = { 104*1a71fb84SWolfram Sang .wdt_set_timeout = stmp3xxx_wdt_set_timeout, 105*1a71fb84SWolfram Sang }; 106*1a71fb84SWolfram Sang 107*1a71fb84SWolfram Sang static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) 108*1a71fb84SWolfram Sang { 109*1a71fb84SWolfram Sang struct platform_device *wdt_pdev = 110*1a71fb84SWolfram Sang platform_device_alloc("stmp3xxx_rtc_wdt", rtc_pdev->id); 111*1a71fb84SWolfram Sang 112*1a71fb84SWolfram Sang if (wdt_pdev) { 113*1a71fb84SWolfram Sang wdt_pdev->dev.parent = &rtc_pdev->dev; 114*1a71fb84SWolfram Sang wdt_pdev->dev.platform_data = &wdt_pdata; 115*1a71fb84SWolfram Sang platform_device_add(wdt_pdev); 116*1a71fb84SWolfram Sang } 117*1a71fb84SWolfram Sang } 118*1a71fb84SWolfram Sang #else 119*1a71fb84SWolfram Sang static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) 120*1a71fb84SWolfram Sang { 121*1a71fb84SWolfram Sang } 122*1a71fb84SWolfram Sang #endif /* CONFIG_STMP3XXX_RTC_WATCHDOG */ 123*1a71fb84SWolfram Sang 124df17f631Sdmitry pervushin static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) 125df17f631Sdmitry pervushin { 126df17f631Sdmitry pervushin /* 127df17f631Sdmitry pervushin * The datasheet doesn't say which way round the 128df17f631Sdmitry pervushin * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0, 129df17f631Sdmitry pervushin * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS 130df17f631Sdmitry pervushin */ 131b5167159SWolfram Sang while (readl(rtc_data->io + STMP3XXX_RTC_STAT) & 13247eac337SWolfram Sang (0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) 133df17f631Sdmitry pervushin cpu_relax(); 134df17f631Sdmitry pervushin } 135df17f631Sdmitry pervushin 136df17f631Sdmitry pervushin /* Time read/write */ 137df17f631Sdmitry pervushin static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) 138df17f631Sdmitry pervushin { 139df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 140df17f631Sdmitry pervushin 141df17f631Sdmitry pervushin stmp3xxx_wait_time(rtc_data); 142b5167159SWolfram Sang rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); 143df17f631Sdmitry pervushin return 0; 144df17f631Sdmitry pervushin } 145df17f631Sdmitry pervushin 146df17f631Sdmitry pervushin static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) 147df17f631Sdmitry pervushin { 148df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 149df17f631Sdmitry pervushin 150b5167159SWolfram Sang writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); 151df17f631Sdmitry pervushin stmp3xxx_wait_time(rtc_data); 152df17f631Sdmitry pervushin return 0; 153df17f631Sdmitry pervushin } 154df17f631Sdmitry pervushin 155df17f631Sdmitry pervushin /* interrupt(s) handler */ 156df17f631Sdmitry pervushin static irqreturn_t stmp3xxx_rtc_interrupt(int irq, void *dev_id) 157df17f631Sdmitry pervushin { 158df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev_id); 1597e794cb7SWolfram Sang u32 status = readl(rtc_data->io + STMP3XXX_RTC_CTRL); 160df17f631Sdmitry pervushin 16147eac337SWolfram Sang if (status & STMP3XXX_RTC_CTRL_ALARM_IRQ) { 162b5167159SWolfram Sang writel(STMP3XXX_RTC_CTRL_ALARM_IRQ, 163b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 1647e794cb7SWolfram Sang rtc_update_irq(rtc_data->rtc, 1, RTC_AF | RTC_IRQF); 165df17f631Sdmitry pervushin return IRQ_HANDLED; 166df17f631Sdmitry pervushin } 167df17f631Sdmitry pervushin 1687e794cb7SWolfram Sang return IRQ_NONE; 1697e794cb7SWolfram Sang } 1707e794cb7SWolfram Sang 171df17f631Sdmitry pervushin static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled) 172df17f631Sdmitry pervushin { 173df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 174df17f631Sdmitry pervushin 175df17f631Sdmitry pervushin if (enabled) { 176b5167159SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 177b5167159SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, 178b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET); 179b5167159SWolfram Sang writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 180b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_SET); 181df17f631Sdmitry pervushin } else { 182b5167159SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 183b5167159SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, 184b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 185b5167159SWolfram Sang writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 186b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 187df17f631Sdmitry pervushin } 188df17f631Sdmitry pervushin return 0; 189df17f631Sdmitry pervushin } 190df17f631Sdmitry pervushin 191df17f631Sdmitry pervushin static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 192df17f631Sdmitry pervushin { 193df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 194df17f631Sdmitry pervushin 195b5167159SWolfram Sang rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_ALARM), &alm->time); 196df17f631Sdmitry pervushin return 0; 197df17f631Sdmitry pervushin } 198df17f631Sdmitry pervushin 199df17f631Sdmitry pervushin static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 200df17f631Sdmitry pervushin { 201df17f631Sdmitry pervushin unsigned long t; 202df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 203df17f631Sdmitry pervushin 204df17f631Sdmitry pervushin rtc_tm_to_time(&alm->time, &t); 205b5167159SWolfram Sang writel(t, rtc_data->io + STMP3XXX_RTC_ALARM); 2067e794cb7SWolfram Sang 2077e794cb7SWolfram Sang stmp3xxx_alarm_irq_enable(dev, alm->enabled); 2087e794cb7SWolfram Sang 209df17f631Sdmitry pervushin return 0; 210df17f631Sdmitry pervushin } 211df17f631Sdmitry pervushin 212df17f631Sdmitry pervushin static struct rtc_class_ops stmp3xxx_rtc_ops = { 213df17f631Sdmitry pervushin .alarm_irq_enable = 214df17f631Sdmitry pervushin stmp3xxx_alarm_irq_enable, 215df17f631Sdmitry pervushin .read_time = stmp3xxx_rtc_gettime, 216df17f631Sdmitry pervushin .set_mmss = stmp3xxx_rtc_set_mmss, 217df17f631Sdmitry pervushin .read_alarm = stmp3xxx_rtc_read_alarm, 218df17f631Sdmitry pervushin .set_alarm = stmp3xxx_rtc_set_alarm, 219df17f631Sdmitry pervushin }; 220df17f631Sdmitry pervushin 221df17f631Sdmitry pervushin static int stmp3xxx_rtc_remove(struct platform_device *pdev) 222df17f631Sdmitry pervushin { 223df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(pdev); 224df17f631Sdmitry pervushin 225df17f631Sdmitry pervushin if (!rtc_data) 226df17f631Sdmitry pervushin return 0; 227df17f631Sdmitry pervushin 2287e794cb7SWolfram Sang writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 229b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 230df17f631Sdmitry pervushin free_irq(rtc_data->irq_alarm, &pdev->dev); 231df17f631Sdmitry pervushin rtc_device_unregister(rtc_data->rtc); 232a91d2babSWolfram Sang platform_set_drvdata(pdev, NULL); 233df17f631Sdmitry pervushin iounmap(rtc_data->io); 234df17f631Sdmitry pervushin kfree(rtc_data); 235df17f631Sdmitry pervushin 236df17f631Sdmitry pervushin return 0; 237df17f631Sdmitry pervushin } 238df17f631Sdmitry pervushin 239df17f631Sdmitry pervushin static int stmp3xxx_rtc_probe(struct platform_device *pdev) 240df17f631Sdmitry pervushin { 241df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data; 242df17f631Sdmitry pervushin struct resource *r; 243df17f631Sdmitry pervushin int err; 244df17f631Sdmitry pervushin 245df17f631Sdmitry pervushin rtc_data = kzalloc(sizeof *rtc_data, GFP_KERNEL); 246df17f631Sdmitry pervushin if (!rtc_data) 247df17f631Sdmitry pervushin return -ENOMEM; 248df17f631Sdmitry pervushin 249df17f631Sdmitry pervushin r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 250df17f631Sdmitry pervushin if (!r) { 251df17f631Sdmitry pervushin dev_err(&pdev->dev, "failed to get resource\n"); 252df17f631Sdmitry pervushin err = -ENXIO; 253df17f631Sdmitry pervushin goto out_free; 254df17f631Sdmitry pervushin } 255df17f631Sdmitry pervushin 256df17f631Sdmitry pervushin rtc_data->io = ioremap(r->start, resource_size(r)); 257df17f631Sdmitry pervushin if (!rtc_data->io) { 258df17f631Sdmitry pervushin dev_err(&pdev->dev, "ioremap failed\n"); 259df17f631Sdmitry pervushin err = -EIO; 260df17f631Sdmitry pervushin goto out_free; 261df17f631Sdmitry pervushin } 262df17f631Sdmitry pervushin 263df17f631Sdmitry pervushin rtc_data->irq_alarm = platform_get_irq(pdev, 0); 264df17f631Sdmitry pervushin 265b5167159SWolfram Sang if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & 26647eac337SWolfram Sang STMP3XXX_RTC_STAT_RTC_PRESENT)) { 267df17f631Sdmitry pervushin dev_err(&pdev->dev, "no device onboard\n"); 268df17f631Sdmitry pervushin err = -ENODEV; 269df17f631Sdmitry pervushin goto out_remap; 270df17f631Sdmitry pervushin } 271df17f631Sdmitry pervushin 272a91d2babSWolfram Sang platform_set_drvdata(pdev, rtc_data); 273a91d2babSWolfram Sang 27446b21218SWolfram Sang mxs_reset_block(rtc_data->io); 275b5167159SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 27647eac337SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | 27747eac337SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, 278b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 279a91d2babSWolfram Sang 2807e794cb7SWolfram Sang writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN | 2817e794cb7SWolfram Sang STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 2827e794cb7SWolfram Sang rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 2837e794cb7SWolfram Sang 284df17f631Sdmitry pervushin rtc_data->rtc = rtc_device_register(pdev->name, &pdev->dev, 285df17f631Sdmitry pervushin &stmp3xxx_rtc_ops, THIS_MODULE); 286df17f631Sdmitry pervushin if (IS_ERR(rtc_data->rtc)) { 287df17f631Sdmitry pervushin err = PTR_ERR(rtc_data->rtc); 288df17f631Sdmitry pervushin goto out_remap; 289df17f631Sdmitry pervushin } 290df17f631Sdmitry pervushin 2917e794cb7SWolfram Sang err = request_irq(rtc_data->irq_alarm, stmp3xxx_rtc_interrupt, 0, 2927e794cb7SWolfram Sang "RTC alarm", &pdev->dev); 293df17f631Sdmitry pervushin if (err) { 294df17f631Sdmitry pervushin dev_err(&pdev->dev, "Cannot claim IRQ%d\n", 295df17f631Sdmitry pervushin rtc_data->irq_alarm); 296df17f631Sdmitry pervushin goto out_irq_alarm; 297df17f631Sdmitry pervushin } 298df17f631Sdmitry pervushin 299*1a71fb84SWolfram Sang stmp3xxx_wdt_register(pdev); 300df17f631Sdmitry pervushin return 0; 301df17f631Sdmitry pervushin 302df17f631Sdmitry pervushin out_irq_alarm: 303df17f631Sdmitry pervushin rtc_device_unregister(rtc_data->rtc); 304df17f631Sdmitry pervushin out_remap: 305a91d2babSWolfram Sang platform_set_drvdata(pdev, NULL); 306df17f631Sdmitry pervushin iounmap(rtc_data->io); 307df17f631Sdmitry pervushin out_free: 308df17f631Sdmitry pervushin kfree(rtc_data); 309df17f631Sdmitry pervushin return err; 310df17f631Sdmitry pervushin } 311df17f631Sdmitry pervushin 312df17f631Sdmitry pervushin #ifdef CONFIG_PM 313df17f631Sdmitry pervushin static int stmp3xxx_rtc_suspend(struct platform_device *dev, pm_message_t state) 314df17f631Sdmitry pervushin { 315df17f631Sdmitry pervushin return 0; 316df17f631Sdmitry pervushin } 317df17f631Sdmitry pervushin 318df17f631Sdmitry pervushin static int stmp3xxx_rtc_resume(struct platform_device *dev) 319df17f631Sdmitry pervushin { 320df17f631Sdmitry pervushin struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(dev); 321df17f631Sdmitry pervushin 32246b21218SWolfram Sang mxs_reset_block(rtc_data->io); 323b5167159SWolfram Sang writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 32447eac337SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | 32547eac337SWolfram Sang STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, 326b5167159SWolfram Sang rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 327df17f631Sdmitry pervushin return 0; 328df17f631Sdmitry pervushin } 329df17f631Sdmitry pervushin #else 330df17f631Sdmitry pervushin #define stmp3xxx_rtc_suspend NULL 331df17f631Sdmitry pervushin #define stmp3xxx_rtc_resume NULL 332df17f631Sdmitry pervushin #endif 333df17f631Sdmitry pervushin 334dd8d20a3SMarek Vasut static const struct of_device_id rtc_dt_ids[] = { 335dd8d20a3SMarek Vasut { .compatible = "fsl,stmp3xxx-rtc", }, 336dd8d20a3SMarek Vasut { /* sentinel */ } 337dd8d20a3SMarek Vasut }; 338dd8d20a3SMarek Vasut MODULE_DEVICE_TABLE(of, rtc_dt_ids); 339dd8d20a3SMarek Vasut 340df17f631Sdmitry pervushin static struct platform_driver stmp3xxx_rtcdrv = { 341df17f631Sdmitry pervushin .probe = stmp3xxx_rtc_probe, 342df17f631Sdmitry pervushin .remove = stmp3xxx_rtc_remove, 343df17f631Sdmitry pervushin .suspend = stmp3xxx_rtc_suspend, 344df17f631Sdmitry pervushin .resume = stmp3xxx_rtc_resume, 345df17f631Sdmitry pervushin .driver = { 346df17f631Sdmitry pervushin .name = "stmp3xxx-rtc", 347df17f631Sdmitry pervushin .owner = THIS_MODULE, 348c8a6046eSSachin Kamat .of_match_table = of_match_ptr(rtc_dt_ids), 349df17f631Sdmitry pervushin }, 350df17f631Sdmitry pervushin }; 351df17f631Sdmitry pervushin 3520c4eae66SAxel Lin module_platform_driver(stmp3xxx_rtcdrv); 353df17f631Sdmitry pervushin 354df17f631Sdmitry pervushin MODULE_DESCRIPTION("STMP3xxx RTC Driver"); 3557e794cb7SWolfram Sang MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and " 3567e794cb7SWolfram Sang "Wolfram Sang <w.sang@pengutronix.de>"); 357df17f631Sdmitry pervushin MODULE_LICENSE("GPL"); 358