1/* 2 * Blackfin On-Chip Real Time Clock Driver 3 * Supports BF531/BF532/BF533/BF534/BF536/BF537 4 * 5 * Copyright 2004-2007 Analog Devices Inc. 6 * 7 * Enter bugs at http://blackfin.uclinux.org/ 8 * 9 * Licensed under the GPL-2 or later. 10 */ 11 12/* The biggest issue we deal with in this driver is that register writes are 13 * synced to the RTC frequency of 1Hz. So if you write to a register and 14 * attempt to write again before the first write has completed, the new write 15 * is simply discarded. This can easily be troublesome if userspace disables 16 * one event (say periodic) and then right after enables an event (say alarm). 17 * Since all events are maintained in the same interrupt mask register, if 18 * we wrote to it to disable the first event and then wrote to it again to 19 * enable the second event, that second event would not be enabled as the 20 * write would be discarded and things quickly fall apart. 21 * 22 * To keep this delay from significantly degrading performance (we, in theory, 23 * would have to sleep for up to 1 second everytime we wanted to write a 24 * register), we only check the write pending status before we start to issue 25 * a new write. We bank on the idea that it doesnt matter when the sync 26 * happens so long as we don't attempt another write before it does. The only 27 * time userspace would take this penalty is when they try and do multiple 28 * operations right after another ... but in this case, they need to take the 29 * sync penalty, so we should be OK. 30 * 31 * Also note that the RTC_ISTAT register does not suffer this penalty; its 32 * writes to clear status registers complete immediately. 33 */ 34 35#include <linux/module.h> 36#include <linux/kernel.h> 37#include <linux/bcd.h> 38#include <linux/rtc.h> 39#include <linux/init.h> 40#include <linux/platform_device.h> 41#include <linux/seq_file.h> 42#include <linux/interrupt.h> 43#include <linux/spinlock.h> 44#include <linux/delay.h> 45 46#include <asm/blackfin.h> 47 48#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __FUNCTION__, __LINE__, ## args) 49#define stampit() stamp("here i am") 50 51struct bfin_rtc { 52 struct rtc_device *rtc_dev; 53 struct rtc_time rtc_alarm; 54 spinlock_t lock; 55}; 56 57/* Bit values for the ISTAT / ICTL registers */ 58#define RTC_ISTAT_WRITE_COMPLETE 0x8000 59#define RTC_ISTAT_WRITE_PENDING 0x4000 60#define RTC_ISTAT_ALARM_DAY 0x0040 61#define RTC_ISTAT_24HR 0x0020 62#define RTC_ISTAT_HOUR 0x0010 63#define RTC_ISTAT_MIN 0x0008 64#define RTC_ISTAT_SEC 0x0004 65#define RTC_ISTAT_ALARM 0x0002 66#define RTC_ISTAT_STOPWATCH 0x0001 67 68/* Shift values for RTC_STAT register */ 69#define DAY_BITS_OFF 17 70#define HOUR_BITS_OFF 12 71#define MIN_BITS_OFF 6 72#define SEC_BITS_OFF 0 73 74/* Some helper functions to convert between the common RTC notion of time 75 * and the internal Blackfin notion that is stored in 32bits. 76 */ 77static inline u32 rtc_time_to_bfin(unsigned long now) 78{ 79 u32 sec = (now % 60); 80 u32 min = (now % (60 * 60)) / 60; 81 u32 hour = (now % (60 * 60 * 24)) / (60 * 60); 82 u32 days = (now / (60 * 60 * 24)); 83 return (sec << SEC_BITS_OFF) + 84 (min << MIN_BITS_OFF) + 85 (hour << HOUR_BITS_OFF) + 86 (days << DAY_BITS_OFF); 87} 88static inline unsigned long rtc_bfin_to_time(u32 rtc_bfin) 89{ 90 return (((rtc_bfin >> SEC_BITS_OFF) & 0x003F)) + 91 (((rtc_bfin >> MIN_BITS_OFF) & 0x003F) * 60) + 92 (((rtc_bfin >> HOUR_BITS_OFF) & 0x001F) * 60 * 60) + 93 (((rtc_bfin >> DAY_BITS_OFF) & 0x7FFF) * 60 * 60 * 24); 94} 95static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm) 96{ 97 rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm); 98} 99 100/* Wait for the previous write to a RTC register to complete. 101 * Unfortunately, we can't sleep here as that introduces a race condition when 102 * turning on interrupt events. Consider this: 103 * - process sets alarm 104 * - process enables alarm 105 * - process sleeps while waiting for rtc write to sync 106 * - interrupt fires while process is sleeping 107 * - interrupt acks the event by writing to ISTAT 108 * - interrupt sets the WRITE PENDING bit 109 * - interrupt handler finishes 110 * - process wakes up, sees WRITE PENDING bit set, goes to sleep 111 * - interrupt fires while process is sleeping 112 * If anyone can point out the obvious solution here, i'm listening :). This 113 * shouldn't be an issue on an SMP or preempt system as this function should 114 * only be called with the rtc lock held. 115 */ 116static void rtc_bfin_sync_pending(void) 117{ 118 stampit(); 119 while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_COMPLETE)) { 120 if (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)) 121 break; 122 } 123 bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); 124} 125 126static void rtc_bfin_reset(struct bfin_rtc *rtc) 127{ 128 /* Initialize the RTC. Enable pre-scaler to scale RTC clock 129 * to 1Hz and clear interrupt/status registers. */ 130 spin_lock_irq(&rtc->lock); 131 rtc_bfin_sync_pending(); 132 bfin_write_RTC_PREN(0x1); 133 bfin_write_RTC_ICTL(0); 134 bfin_write_RTC_SWCNT(0); 135 bfin_write_RTC_ALARM(0); 136 bfin_write_RTC_ISTAT(0xFFFF); 137 spin_unlock_irq(&rtc->lock); 138} 139 140static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) 141{ 142 struct platform_device *pdev = to_platform_device(dev_id); 143 struct bfin_rtc *rtc = platform_get_drvdata(pdev); 144 unsigned long events = 0; 145 u16 rtc_istat; 146 147 stampit(); 148 149 spin_lock_irq(&rtc->lock); 150 151 rtc_istat = bfin_read_RTC_ISTAT(); 152 153 if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { 154 bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); 155 events |= RTC_AF | RTC_IRQF; 156 } 157 158 if (rtc_istat & RTC_ISTAT_STOPWATCH) { 159 bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); 160 events |= RTC_PF | RTC_IRQF; 161 bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); 162 } 163 164 if (rtc_istat & RTC_ISTAT_SEC) { 165 bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); 166 events |= RTC_UF | RTC_IRQF; 167 } 168 169 rtc_update_irq(rtc->rtc_dev, 1, events); 170 171 spin_unlock_irq(&rtc->lock); 172 173 return IRQ_HANDLED; 174} 175 176static int bfin_rtc_open(struct device *dev) 177{ 178 struct bfin_rtc *rtc = dev_get_drvdata(dev); 179 int ret; 180 181 stampit(); 182 183 ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_DISABLED, "rtc-bfin", dev); 184 if (unlikely(ret)) { 185 dev_err(dev, "request RTC IRQ failed with %d\n", ret); 186 return ret; 187 } 188 189 rtc_bfin_reset(rtc); 190 191 return ret; 192} 193 194static void bfin_rtc_release(struct device *dev) 195{ 196 struct bfin_rtc *rtc = dev_get_drvdata(dev); 197 stampit(); 198 rtc_bfin_reset(rtc); 199 free_irq(IRQ_RTC, dev); 200} 201 202static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 203{ 204 struct bfin_rtc *rtc = dev_get_drvdata(dev); 205 206 stampit(); 207 208 switch (cmd) { 209 case RTC_PIE_ON: 210 stampit(); 211 spin_lock_irq(&rtc->lock); 212 rtc_bfin_sync_pending(); 213 bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); 214 bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); 215 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_STOPWATCH); 216 spin_unlock_irq(&rtc->lock); 217 return 0; 218 case RTC_PIE_OFF: 219 stampit(); 220 spin_lock_irq(&rtc->lock); 221 rtc_bfin_sync_pending(); 222 bfin_write_RTC_SWCNT(0); 223 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_STOPWATCH); 224 spin_unlock_irq(&rtc->lock); 225 return 0; 226 227 case RTC_UIE_ON: 228 stampit(); 229 spin_lock_irq(&rtc->lock); 230 rtc_bfin_sync_pending(); 231 bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); 232 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_SEC); 233 spin_unlock_irq(&rtc->lock); 234 return 0; 235 case RTC_UIE_OFF: 236 stampit(); 237 spin_lock_irq(&rtc->lock); 238 rtc_bfin_sync_pending(); 239 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_SEC); 240 spin_unlock_irq(&rtc->lock); 241 return 0; 242 243 case RTC_AIE_ON: { 244 unsigned long rtc_alarm; 245 u16 which_alarm; 246 int ret = 0; 247 248 stampit(); 249 250 spin_lock_irq(&rtc->lock); 251 252 rtc_bfin_sync_pending(); 253 if (rtc->rtc_alarm.tm_yday == -1) { 254 struct rtc_time now; 255 rtc_bfin_to_tm(bfin_read_RTC_STAT(), &now); 256 now.tm_sec = rtc->rtc_alarm.tm_sec; 257 now.tm_min = rtc->rtc_alarm.tm_min; 258 now.tm_hour = rtc->rtc_alarm.tm_hour; 259 ret = rtc_tm_to_time(&now, &rtc_alarm); 260 which_alarm = RTC_ISTAT_ALARM; 261 } else { 262 ret = rtc_tm_to_time(&rtc->rtc_alarm, &rtc_alarm); 263 which_alarm = RTC_ISTAT_ALARM_DAY; 264 } 265 if (ret == 0) { 266 bfin_write_RTC_ISTAT(which_alarm); 267 bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm)); 268 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | which_alarm); 269 } 270 271 spin_unlock_irq(&rtc->lock); 272 273 return ret; 274 } 275 case RTC_AIE_OFF: 276 stampit(); 277 spin_lock_irq(&rtc->lock); 278 rtc_bfin_sync_pending(); 279 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); 280 spin_unlock_irq(&rtc->lock); 281 return 0; 282 } 283 284 return -ENOIOCTLCMD; 285} 286 287static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) 288{ 289 struct bfin_rtc *rtc = dev_get_drvdata(dev); 290 291 stampit(); 292 293 spin_lock_irq(&rtc->lock); 294 rtc_bfin_sync_pending(); 295 rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm); 296 spin_unlock_irq(&rtc->lock); 297 298 return 0; 299} 300 301static int bfin_rtc_set_time(struct device *dev, struct rtc_time *tm) 302{ 303 struct bfin_rtc *rtc = dev_get_drvdata(dev); 304 int ret; 305 unsigned long now; 306 307 stampit(); 308 309 spin_lock_irq(&rtc->lock); 310 311 ret = rtc_tm_to_time(tm, &now); 312 if (ret == 0) { 313 rtc_bfin_sync_pending(); 314 bfin_write_RTC_STAT(rtc_time_to_bfin(now)); 315 } 316 317 spin_unlock_irq(&rtc->lock); 318 319 return ret; 320} 321 322static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 323{ 324 struct bfin_rtc *rtc = dev_get_drvdata(dev); 325 stampit(); 326 memcpy(&alrm->time, &rtc->rtc_alarm, sizeof(struct rtc_time)); 327 alrm->pending = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); 328 return 0; 329} 330 331static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 332{ 333 struct bfin_rtc *rtc = dev_get_drvdata(dev); 334 stampit(); 335 memcpy(&rtc->rtc_alarm, &alrm->time, sizeof(struct rtc_time)); 336 return 0; 337} 338 339static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) 340{ 341#define yesno(x) (x ? "yes" : "no") 342 u16 ictl = bfin_read_RTC_ICTL(); 343 stampit(); 344 seq_printf(seq, "alarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM)); 345 seq_printf(seq, "wkalarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM_DAY)); 346 seq_printf(seq, "seconds_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_SEC)); 347 seq_printf(seq, "periodic_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_STOPWATCH)); 348#ifdef DEBUG 349 seq_printf(seq, "RTC_STAT\t: 0x%08X\n", bfin_read_RTC_STAT()); 350 seq_printf(seq, "RTC_ICTL\t: 0x%04X\n", bfin_read_RTC_ICTL()); 351 seq_printf(seq, "RTC_ISTAT\t: 0x%04X\n", bfin_read_RTC_ISTAT()); 352 seq_printf(seq, "RTC_SWCNT\t: 0x%04X\n", bfin_read_RTC_SWCNT()); 353 seq_printf(seq, "RTC_ALARM\t: 0x%08X\n", bfin_read_RTC_ALARM()); 354 seq_printf(seq, "RTC_PREN\t: 0x%04X\n", bfin_read_RTC_PREN()); 355#endif 356 return 0; 357} 358 359static int bfin_irq_set_freq(struct device *dev, int freq) 360{ 361 struct bfin_rtc *rtc = dev_get_drvdata(dev); 362 stampit(); 363 rtc->rtc_dev->irq_freq = freq; 364 return 0; 365} 366 367static struct rtc_class_ops bfin_rtc_ops = { 368 .open = bfin_rtc_open, 369 .release = bfin_rtc_release, 370 .ioctl = bfin_rtc_ioctl, 371 .read_time = bfin_rtc_read_time, 372 .set_time = bfin_rtc_set_time, 373 .read_alarm = bfin_rtc_read_alarm, 374 .set_alarm = bfin_rtc_set_alarm, 375 .proc = bfin_rtc_proc, 376 .irq_set_freq = bfin_irq_set_freq, 377}; 378 379static int __devinit bfin_rtc_probe(struct platform_device *pdev) 380{ 381 struct bfin_rtc *rtc; 382 int ret = 0; 383 384 stampit(); 385 386 rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); 387 if (unlikely(!rtc)) 388 return -ENOMEM; 389 390 spin_lock_init(&rtc->lock); 391 392 rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE); 393 if (unlikely(IS_ERR(rtc))) { 394 ret = PTR_ERR(rtc->rtc_dev); 395 goto err; 396 } 397 rtc->rtc_dev->irq_freq = 0; 398 rtc->rtc_dev->max_user_freq = (2 << 16); /* stopwatch is an unsigned 16 bit reg */ 399 400 platform_set_drvdata(pdev, rtc); 401 402 return 0; 403 404err: 405 kfree(rtc); 406 return ret; 407} 408 409static int __devexit bfin_rtc_remove(struct platform_device *pdev) 410{ 411 struct bfin_rtc *rtc = platform_get_drvdata(pdev); 412 413 rtc_device_unregister(rtc->rtc_dev); 414 platform_set_drvdata(pdev, NULL); 415 kfree(rtc); 416 417 return 0; 418} 419 420static struct platform_driver bfin_rtc_driver = { 421 .driver = { 422 .name = "rtc-bfin", 423 .owner = THIS_MODULE, 424 }, 425 .probe = bfin_rtc_probe, 426 .remove = __devexit_p(bfin_rtc_remove), 427}; 428 429static int __init bfin_rtc_init(void) 430{ 431 stampit(); 432 return platform_driver_register(&bfin_rtc_driver); 433} 434 435static void __exit bfin_rtc_exit(void) 436{ 437 platform_driver_unregister(&bfin_rtc_driver); 438} 439 440module_init(bfin_rtc_init); 441module_exit(bfin_rtc_exit); 442 443MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver"); 444MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); 445MODULE_LICENSE("GPL"); 446