1 /* 2 * Freescale STMP37XX/STMP378X Real Time Clock driver 3 * 4 * Copyright (c) 2007 Sigmatel, Inc. 5 * Peter Hartley, <peter.hartley@sigmatel.com> 6 * 7 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. 8 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. 9 * Copyright 2011 Wolfram Sang, Pengutronix e.K. 10 */ 11 12 /* 13 * The code contained herein is licensed under the GNU General Public 14 * License. You may obtain a copy of the GNU General Public License 15 * Version 2 or later at the following locations: 16 * 17 * http://www.opensource.org/licenses/gpl-license.html 18 * http://www.gnu.org/copyleft/gpl.html 19 */ 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 #include <linux/io.h> 23 #include <linux/init.h> 24 #include <linux/platform_device.h> 25 #include <linux/interrupt.h> 26 #include <linux/rtc.h> 27 #include <linux/slab.h> 28 #include <linux/of_device.h> 29 #include <linux/of.h> 30 #include <linux/stmp_device.h> 31 #include <linux/stmp3xxx_rtc_wdt.h> 32 33 #define STMP3XXX_RTC_CTRL 0x0 34 #define STMP3XXX_RTC_CTRL_SET 0x4 35 #define STMP3XXX_RTC_CTRL_CLR 0x8 36 #define STMP3XXX_RTC_CTRL_ALARM_IRQ_EN 0x00000001 37 #define STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN 0x00000002 38 #define STMP3XXX_RTC_CTRL_ALARM_IRQ 0x00000004 39 #define STMP3XXX_RTC_CTRL_WATCHDOGEN 0x00000010 40 41 #define STMP3XXX_RTC_STAT 0x10 42 #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 43 #define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000 44 45 #define STMP3XXX_RTC_SECONDS 0x30 46 47 #define STMP3XXX_RTC_ALARM 0x40 48 49 #define STMP3XXX_RTC_WATCHDOG 0x50 50 51 #define STMP3XXX_RTC_PERSISTENT0 0x60 52 #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 53 #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 54 #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002 55 #define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 56 #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 57 58 #define STMP3XXX_RTC_PERSISTENT1 0x70 59 /* missing bitmask in headers */ 60 #define STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER 0x80000000 61 62 struct stmp3xxx_rtc_data { 63 struct rtc_device *rtc; 64 void __iomem *io; 65 int irq_alarm; 66 }; 67 68 #if IS_ENABLED(CONFIG_STMP3XXX_RTC_WATCHDOG) 69 /** 70 * stmp3xxx_wdt_set_timeout - configure the watchdog inside the STMP3xxx RTC 71 * @dev: the parent device of the watchdog (= the RTC) 72 * @timeout: the desired value for the timeout register of the watchdog. 73 * 0 disables the watchdog 74 * 75 * The watchdog needs one register and two bits which are in the RTC domain. 76 * To handle the resource conflict, the RTC driver will create another 77 * platform_device for the watchdog driver as a child of the RTC device. 78 * The watchdog driver is passed the below accessor function via platform_data 79 * to configure the watchdog. Locking is not needed because accessing SET/CLR 80 * registers is atomic. 81 */ 82 83 static void stmp3xxx_wdt_set_timeout(struct device *dev, u32 timeout) 84 { 85 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 86 87 if (timeout) { 88 writel(timeout, rtc_data->io + STMP3XXX_RTC_WATCHDOG); 89 writel(STMP3XXX_RTC_CTRL_WATCHDOGEN, 90 rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_SET); 91 writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER, 92 rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_SET); 93 } else { 94 writel(STMP3XXX_RTC_CTRL_WATCHDOGEN, 95 rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_CLR); 96 writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER, 97 rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_CLR); 98 } 99 } 100 101 static struct stmp3xxx_wdt_pdata wdt_pdata = { 102 .wdt_set_timeout = stmp3xxx_wdt_set_timeout, 103 }; 104 105 static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) 106 { 107 struct platform_device *wdt_pdev = 108 platform_device_alloc("stmp3xxx_rtc_wdt", rtc_pdev->id); 109 110 if (wdt_pdev) { 111 wdt_pdev->dev.parent = &rtc_pdev->dev; 112 wdt_pdev->dev.platform_data = &wdt_pdata; 113 platform_device_add(wdt_pdev); 114 } 115 } 116 #else 117 static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) 118 { 119 } 120 #endif /* CONFIG_STMP3XXX_RTC_WATCHDOG */ 121 122 static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) 123 { 124 /* 125 * The datasheet doesn't say which way round the 126 * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0, 127 * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS 128 */ 129 while (readl(rtc_data->io + STMP3XXX_RTC_STAT) & 130 (0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) 131 cpu_relax(); 132 } 133 134 /* Time read/write */ 135 static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) 136 { 137 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 138 139 stmp3xxx_wait_time(rtc_data); 140 rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); 141 return 0; 142 } 143 144 static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) 145 { 146 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 147 148 writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); 149 stmp3xxx_wait_time(rtc_data); 150 return 0; 151 } 152 153 /* interrupt(s) handler */ 154 static irqreturn_t stmp3xxx_rtc_interrupt(int irq, void *dev_id) 155 { 156 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev_id); 157 u32 status = readl(rtc_data->io + STMP3XXX_RTC_CTRL); 158 159 if (status & STMP3XXX_RTC_CTRL_ALARM_IRQ) { 160 writel(STMP3XXX_RTC_CTRL_ALARM_IRQ, 161 rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 162 rtc_update_irq(rtc_data->rtc, 1, RTC_AF | RTC_IRQF); 163 return IRQ_HANDLED; 164 } 165 166 return IRQ_NONE; 167 } 168 169 static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled) 170 { 171 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 172 173 if (enabled) { 174 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 175 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, 176 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET); 177 writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 178 rtc_data->io + STMP3XXX_RTC_CTRL_SET); 179 } else { 180 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 181 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN, 182 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 183 writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 184 rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 185 } 186 return 0; 187 } 188 189 static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 190 { 191 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 192 193 rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_ALARM), &alm->time); 194 return 0; 195 } 196 197 static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 198 { 199 unsigned long t; 200 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 201 202 rtc_tm_to_time(&alm->time, &t); 203 writel(t, rtc_data->io + STMP3XXX_RTC_ALARM); 204 205 stmp3xxx_alarm_irq_enable(dev, alm->enabled); 206 207 return 0; 208 } 209 210 static struct rtc_class_ops stmp3xxx_rtc_ops = { 211 .alarm_irq_enable = 212 stmp3xxx_alarm_irq_enable, 213 .read_time = stmp3xxx_rtc_gettime, 214 .set_mmss = stmp3xxx_rtc_set_mmss, 215 .read_alarm = stmp3xxx_rtc_read_alarm, 216 .set_alarm = stmp3xxx_rtc_set_alarm, 217 }; 218 219 static int stmp3xxx_rtc_remove(struct platform_device *pdev) 220 { 221 struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(pdev); 222 223 if (!rtc_data) 224 return 0; 225 226 writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 227 rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 228 platform_set_drvdata(pdev, NULL); 229 230 return 0; 231 } 232 233 static int stmp3xxx_rtc_probe(struct platform_device *pdev) 234 { 235 struct stmp3xxx_rtc_data *rtc_data; 236 struct resource *r; 237 int err; 238 239 rtc_data = devm_kzalloc(&pdev->dev, sizeof(*rtc_data), GFP_KERNEL); 240 if (!rtc_data) 241 return -ENOMEM; 242 243 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 244 if (!r) { 245 dev_err(&pdev->dev, "failed to get resource\n"); 246 return -ENXIO; 247 } 248 249 rtc_data->io = devm_ioremap(&pdev->dev, r->start, resource_size(r)); 250 if (!rtc_data->io) { 251 dev_err(&pdev->dev, "ioremap failed\n"); 252 return -EIO; 253 } 254 255 rtc_data->irq_alarm = platform_get_irq(pdev, 0); 256 257 if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & 258 STMP3XXX_RTC_STAT_RTC_PRESENT)) { 259 dev_err(&pdev->dev, "no device onboard\n"); 260 return -ENODEV; 261 } 262 263 platform_set_drvdata(pdev, rtc_data); 264 265 stmp_reset_block(rtc_data->io); 266 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 267 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | 268 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, 269 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 270 271 writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN | 272 STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, 273 rtc_data->io + STMP3XXX_RTC_CTRL_CLR); 274 275 rtc_data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 276 &stmp3xxx_rtc_ops, THIS_MODULE); 277 if (IS_ERR(rtc_data->rtc)) { 278 err = PTR_ERR(rtc_data->rtc); 279 goto out; 280 } 281 282 err = devm_request_irq(&pdev->dev, rtc_data->irq_alarm, 283 stmp3xxx_rtc_interrupt, 0, "RTC alarm", &pdev->dev); 284 if (err) { 285 dev_err(&pdev->dev, "Cannot claim IRQ%d\n", 286 rtc_data->irq_alarm); 287 goto out; 288 } 289 290 stmp3xxx_wdt_register(pdev); 291 return 0; 292 293 out: 294 platform_set_drvdata(pdev, NULL); 295 return err; 296 } 297 298 #ifdef CONFIG_PM_SLEEP 299 static int stmp3xxx_rtc_suspend(struct device *dev) 300 { 301 return 0; 302 } 303 304 static int stmp3xxx_rtc_resume(struct device *dev) 305 { 306 struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); 307 308 stmp_reset_block(rtc_data->io); 309 writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | 310 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | 311 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, 312 rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); 313 return 0; 314 } 315 #endif 316 317 static SIMPLE_DEV_PM_OPS(stmp3xxx_rtc_pm_ops, stmp3xxx_rtc_suspend, 318 stmp3xxx_rtc_resume); 319 320 static const struct of_device_id rtc_dt_ids[] = { 321 { .compatible = "fsl,stmp3xxx-rtc", }, 322 { /* sentinel */ } 323 }; 324 MODULE_DEVICE_TABLE(of, rtc_dt_ids); 325 326 static struct platform_driver stmp3xxx_rtcdrv = { 327 .probe = stmp3xxx_rtc_probe, 328 .remove = stmp3xxx_rtc_remove, 329 .driver = { 330 .name = "stmp3xxx-rtc", 331 .owner = THIS_MODULE, 332 .pm = &stmp3xxx_rtc_pm_ops, 333 .of_match_table = of_match_ptr(rtc_dt_ids), 334 }, 335 }; 336 337 module_platform_driver(stmp3xxx_rtcdrv); 338 339 MODULE_DESCRIPTION("STMP3xxx RTC Driver"); 340 MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and " 341 "Wolfram Sang <w.sang@pengutronix.de>"); 342 MODULE_LICENSE("GPL"); 343