1/* 2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> 3 * JZ4740 SoC RTC driver 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2 of the License, or (at your 8 * option) any later version. 9 * 10 * You should have received a copy of the GNU General Public License along 11 * with this program; if not, write to the Free Software Foundation, Inc., 12 * 675 Mass Ave, Cambridge, MA 02139, USA. 13 * 14 */ 15 16#include <linux/kernel.h> 17#include <linux/module.h> 18#include <linux/platform_device.h> 19#include <linux/rtc.h> 20#include <linux/slab.h> 21#include <linux/spinlock.h> 22 23#define JZ_REG_RTC_CTRL 0x00 24#define JZ_REG_RTC_SEC 0x04 25#define JZ_REG_RTC_SEC_ALARM 0x08 26#define JZ_REG_RTC_REGULATOR 0x0C 27#define JZ_REG_RTC_HIBERNATE 0x20 28#define JZ_REG_RTC_SCRATCHPAD 0x34 29 30#define JZ_RTC_CTRL_WRDY BIT(7) 31#define JZ_RTC_CTRL_1HZ BIT(6) 32#define JZ_RTC_CTRL_1HZ_IRQ BIT(5) 33#define JZ_RTC_CTRL_AF BIT(4) 34#define JZ_RTC_CTRL_AF_IRQ BIT(3) 35#define JZ_RTC_CTRL_AE BIT(2) 36#define JZ_RTC_CTRL_ENABLE BIT(0) 37 38struct jz4740_rtc { 39 struct resource *mem; 40 void __iomem *base; 41 42 struct rtc_device *rtc; 43 44 unsigned int irq; 45 46 spinlock_t lock; 47}; 48 49static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg) 50{ 51 return readl(rtc->base + reg); 52} 53 54static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc) 55{ 56 uint32_t ctrl; 57 int timeout = 1000; 58 59 do { 60 ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); 61 } while (!(ctrl & JZ_RTC_CTRL_WRDY) && --timeout); 62 63 return timeout ? 0 : -EIO; 64} 65 66static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg, 67 uint32_t val) 68{ 69 int ret; 70 ret = jz4740_rtc_wait_write_ready(rtc); 71 if (ret == 0) 72 writel(val, rtc->base + reg); 73 74 return ret; 75} 76 77static int jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask, 78 bool set) 79{ 80 int ret; 81 unsigned long flags; 82 uint32_t ctrl; 83 84 spin_lock_irqsave(&rtc->lock, flags); 85 86 ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); 87 88 /* Don't clear interrupt flags by accident */ 89 ctrl |= JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF; 90 91 if (set) 92 ctrl |= mask; 93 else 94 ctrl &= ~mask; 95 96 ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl); 97 98 spin_unlock_irqrestore(&rtc->lock, flags); 99 100 return ret; 101} 102 103static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time) 104{ 105 struct jz4740_rtc *rtc = dev_get_drvdata(dev); 106 uint32_t secs, secs2; 107 int timeout = 5; 108 109 /* If the seconds register is read while it is updated, it can contain a 110 * bogus value. This can be avoided by making sure that two consecutive 111 * reads have the same value. 112 */ 113 secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); 114 secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); 115 116 while (secs != secs2 && --timeout) { 117 secs = secs2; 118 secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); 119 } 120 121 if (timeout == 0) 122 return -EIO; 123 124 rtc_time_to_tm(secs, time); 125 126 return rtc_valid_tm(time); 127} 128 129static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs) 130{ 131 struct jz4740_rtc *rtc = dev_get_drvdata(dev); 132 133 return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs); 134} 135 136static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 137{ 138 struct jz4740_rtc *rtc = dev_get_drvdata(dev); 139 uint32_t secs; 140 uint32_t ctrl; 141 142 secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM); 143 144 ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); 145 146 alrm->enabled = !!(ctrl & JZ_RTC_CTRL_AE); 147 alrm->pending = !!(ctrl & JZ_RTC_CTRL_AF); 148 149 rtc_time_to_tm(secs, &alrm->time); 150 151 return rtc_valid_tm(&alrm->time); 152} 153 154static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 155{ 156 int ret; 157 struct jz4740_rtc *rtc = dev_get_drvdata(dev); 158 unsigned long secs; 159 160 rtc_tm_to_time(&alrm->time, &secs); 161 162 ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs); 163 if (!ret) 164 ret = jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AE, alrm->enabled); 165 166 return ret; 167} 168 169static int jz4740_rtc_update_irq_enable(struct device *dev, unsigned int enable) 170{ 171 struct jz4740_rtc *rtc = dev_get_drvdata(dev); 172 return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ_IRQ, enable); 173} 174 175static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) 176{ 177 struct jz4740_rtc *rtc = dev_get_drvdata(dev); 178 return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ, enable); 179} 180 181static struct rtc_class_ops jz4740_rtc_ops = { 182 .read_time = jz4740_rtc_read_time, 183 .set_mmss = jz4740_rtc_set_mmss, 184 .read_alarm = jz4740_rtc_read_alarm, 185 .set_alarm = jz4740_rtc_set_alarm, 186 .update_irq_enable = jz4740_rtc_update_irq_enable, 187 .alarm_irq_enable = jz4740_rtc_alarm_irq_enable, 188}; 189 190static irqreturn_t jz4740_rtc_irq(int irq, void *data) 191{ 192 struct jz4740_rtc *rtc = data; 193 uint32_t ctrl; 194 unsigned long events = 0; 195 196 ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); 197 198 if (ctrl & JZ_RTC_CTRL_1HZ) 199 events |= (RTC_UF | RTC_IRQF); 200 201 if (ctrl & JZ_RTC_CTRL_AF) 202 events |= (RTC_AF | RTC_IRQF); 203 204 rtc_update_irq(rtc->rtc, 1, events); 205 206 jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, false); 207 208 return IRQ_HANDLED; 209} 210 211void jz4740_rtc_poweroff(struct device *dev) 212{ 213 struct jz4740_rtc *rtc = dev_get_drvdata(dev); 214 jz4740_rtc_reg_write(rtc, JZ_REG_RTC_HIBERNATE, 1); 215} 216EXPORT_SYMBOL_GPL(jz4740_rtc_poweroff); 217 218static int __devinit jz4740_rtc_probe(struct platform_device *pdev) 219{ 220 int ret; 221 struct jz4740_rtc *rtc; 222 uint32_t scratchpad; 223 224 rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); 225 if (!rtc) 226 return -ENOMEM; 227 228 rtc->irq = platform_get_irq(pdev, 0); 229 if (rtc->irq < 0) { 230 ret = -ENOENT; 231 dev_err(&pdev->dev, "Failed to get platform irq\n"); 232 goto err_free; 233 } 234 235 rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 236 if (!rtc->mem) { 237 ret = -ENOENT; 238 dev_err(&pdev->dev, "Failed to get platform mmio memory\n"); 239 goto err_free; 240 } 241 242 rtc->mem = request_mem_region(rtc->mem->start, resource_size(rtc->mem), 243 pdev->name); 244 if (!rtc->mem) { 245 ret = -EBUSY; 246 dev_err(&pdev->dev, "Failed to request mmio memory region\n"); 247 goto err_free; 248 } 249 250 rtc->base = ioremap_nocache(rtc->mem->start, resource_size(rtc->mem)); 251 if (!rtc->base) { 252 ret = -EBUSY; 253 dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); 254 goto err_release_mem_region; 255 } 256 257 spin_lock_init(&rtc->lock); 258 259 platform_set_drvdata(pdev, rtc); 260 261 rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops, 262 THIS_MODULE); 263 if (IS_ERR(rtc->rtc)) { 264 ret = PTR_ERR(rtc->rtc); 265 dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret); 266 goto err_iounmap; 267 } 268 269 ret = request_irq(rtc->irq, jz4740_rtc_irq, 0, 270 pdev->name, rtc); 271 if (ret) { 272 dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret); 273 goto err_unregister_rtc; 274 } 275 276 scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD); 277 if (scratchpad != 0x12345678) { 278 ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678); 279 ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0); 280 if (ret) { 281 dev_err(&pdev->dev, "Could not write write to RTC registers\n"); 282 goto err_free_irq; 283 } 284 } 285 286 return 0; 287 288err_free_irq: 289 free_irq(rtc->irq, rtc); 290err_unregister_rtc: 291 rtc_device_unregister(rtc->rtc); 292err_iounmap: 293 platform_set_drvdata(pdev, NULL); 294 iounmap(rtc->base); 295err_release_mem_region: 296 release_mem_region(rtc->mem->start, resource_size(rtc->mem)); 297err_free: 298 kfree(rtc); 299 300 return ret; 301} 302 303static int __devexit jz4740_rtc_remove(struct platform_device *pdev) 304{ 305 struct jz4740_rtc *rtc = platform_get_drvdata(pdev); 306 307 free_irq(rtc->irq, rtc); 308 309 rtc_device_unregister(rtc->rtc); 310 311 iounmap(rtc->base); 312 release_mem_region(rtc->mem->start, resource_size(rtc->mem)); 313 314 kfree(rtc); 315 316 platform_set_drvdata(pdev, NULL); 317 318 return 0; 319} 320 321struct platform_driver jz4740_rtc_driver = { 322 .probe = jz4740_rtc_probe, 323 .remove = __devexit_p(jz4740_rtc_remove), 324 .driver = { 325 .name = "jz4740-rtc", 326 .owner = THIS_MODULE, 327 }, 328}; 329 330static int __init jz4740_rtc_init(void) 331{ 332 return platform_driver_register(&jz4740_rtc_driver); 333} 334module_init(jz4740_rtc_init); 335 336static void __exit jz4740_rtc_exit(void) 337{ 338 platform_driver_unregister(&jz4740_rtc_driver); 339} 340module_exit(jz4740_rtc_exit); 341 342MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 343MODULE_LICENSE("GPL"); 344MODULE_DESCRIPTION("RTC driver for the JZ4740 SoC\n"); 345MODULE_ALIAS("platform:jz4740-rtc"); 346