Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.11-rc2 475 lines 12 kB view raw
1/* 2 * SiRFSoC Real Time Clock interface for Linux 3 * 4 * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company. 5 * 6 * Licensed under GPLv2 or later. 7 */ 8 9#include <linux/module.h> 10#include <linux/err.h> 11#include <linux/rtc.h> 12#include <linux/platform_device.h> 13#include <linux/slab.h> 14#include <linux/io.h> 15#include <linux/of.h> 16#include <linux/rtc/sirfsoc_rtciobrg.h> 17 18 19#define RTC_CN 0x00 20#define RTC_ALARM0 0x04 21#define RTC_ALARM1 0x18 22#define RTC_STATUS 0x08 23#define RTC_SW_VALUE 0x40 24#define SIRFSOC_RTC_AL1E (1<<6) 25#define SIRFSOC_RTC_AL1 (1<<4) 26#define SIRFSOC_RTC_HZE (1<<3) 27#define SIRFSOC_RTC_AL0E (1<<2) 28#define SIRFSOC_RTC_HZ (1<<1) 29#define SIRFSOC_RTC_AL0 (1<<0) 30#define RTC_DIV 0x0c 31#define RTC_DEEP_CTRL 0x14 32#define RTC_CLOCK_SWITCH 0x1c 33#define SIRFSOC_RTC_CLK 0x03 /* others are reserved */ 34 35/* Refer to RTC DIV switch */ 36#define RTC_HZ 16 37 38/* This macro is also defined in arch/arm/plat-sirfsoc/cpu.c */ 39#define RTC_SHIFT 4 40 41#define INTR_SYSRTC_CN 0x48 42 43struct sirfsoc_rtc_drv { 44 struct rtc_device *rtc; 45 u32 rtc_base; 46 u32 irq; 47 /* Overflow for every 8 years extra time */ 48 u32 overflow_rtc; 49#ifdef CONFIG_PM 50 u32 saved_counter; 51 u32 saved_overflow_rtc; 52#endif 53}; 54 55static int sirfsoc_rtc_read_alarm(struct device *dev, 56 struct rtc_wkalrm *alrm) 57{ 58 unsigned long rtc_alarm, rtc_count; 59 struct sirfsoc_rtc_drv *rtcdrv; 60 61 rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev); 62 63 local_irq_disable(); 64 65 rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); 66 67 rtc_alarm = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_ALARM0); 68 memset(alrm, 0, sizeof(struct rtc_wkalrm)); 69 70 /* 71 * assume alarm interval not beyond one round counter overflow_rtc: 72 * 0->0xffffffff 73 */ 74 /* if alarm is in next overflow cycle */ 75 if (rtc_count > rtc_alarm) 76 rtc_time_to_tm((rtcdrv->overflow_rtc + 1) 77 << (BITS_PER_LONG - RTC_SHIFT) 78 | rtc_alarm >> RTC_SHIFT, &(alrm->time)); 79 else 80 rtc_time_to_tm(rtcdrv->overflow_rtc 81 << (BITS_PER_LONG - RTC_SHIFT) 82 | rtc_alarm >> RTC_SHIFT, &(alrm->time)); 83 if (sirfsoc_rtc_iobrg_readl( 84 rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E) 85 alrm->enabled = 1; 86 local_irq_enable(); 87 88 return 0; 89} 90 91static int sirfsoc_rtc_set_alarm(struct device *dev, 92 struct rtc_wkalrm *alrm) 93{ 94 unsigned long rtc_status_reg, rtc_alarm; 95 struct sirfsoc_rtc_drv *rtcdrv; 96 rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev); 97 98 if (alrm->enabled) { 99 rtc_tm_to_time(&(alrm->time), &rtc_alarm); 100 101 local_irq_disable(); 102 103 rtc_status_reg = sirfsoc_rtc_iobrg_readl( 104 rtcdrv->rtc_base + RTC_STATUS); 105 if (rtc_status_reg & SIRFSOC_RTC_AL0E) { 106 /* 107 * An ongoing alarm in progress - ingore it and not 108 * to return EBUSY 109 */ 110 dev_info(dev, "An old alarm was set, will be replaced by a new one\n"); 111 } 112 113 sirfsoc_rtc_iobrg_writel( 114 rtc_alarm << RTC_SHIFT, rtcdrv->rtc_base + RTC_ALARM0); 115 rtc_status_reg &= ~0x07; /* mask out the lower status bits */ 116 /* 117 * This bit RTC_AL sets it as a wake-up source for Sleep Mode 118 * Writing 1 into this bit will clear it 119 */ 120 rtc_status_reg |= SIRFSOC_RTC_AL0; 121 /* enable the RTC alarm interrupt */ 122 rtc_status_reg |= SIRFSOC_RTC_AL0E; 123 sirfsoc_rtc_iobrg_writel( 124 rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); 125 local_irq_enable(); 126 } else { 127 /* 128 * if this function was called with enabled=0 129 * then it could mean that the application is 130 * trying to cancel an ongoing alarm 131 */ 132 local_irq_disable(); 133 134 rtc_status_reg = sirfsoc_rtc_iobrg_readl( 135 rtcdrv->rtc_base + RTC_STATUS); 136 if (rtc_status_reg & SIRFSOC_RTC_AL0E) { 137 /* clear the RTC status register's alarm bit */ 138 rtc_status_reg &= ~0x07; 139 /* write 1 into SIRFSOC_RTC_AL0 to force a clear */ 140 rtc_status_reg |= (SIRFSOC_RTC_AL0); 141 /* Clear the Alarm enable bit */ 142 rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); 143 144 sirfsoc_rtc_iobrg_writel(rtc_status_reg, 145 rtcdrv->rtc_base + RTC_STATUS); 146 } 147 148 local_irq_enable(); 149 } 150 151 return 0; 152} 153 154static int sirfsoc_rtc_read_time(struct device *dev, 155 struct rtc_time *tm) 156{ 157 unsigned long tmp_rtc = 0; 158 struct sirfsoc_rtc_drv *rtcdrv; 159 rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev); 160 /* 161 * This patch is taken from WinCE - Need to validate this for 162 * correctness. To work around sirfsoc RTC counter double sync logic 163 * fail, read several times to make sure get stable value. 164 */ 165 do { 166 tmp_rtc = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); 167 cpu_relax(); 168 } while (tmp_rtc != sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN)); 169 170 rtc_time_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT) | 171 tmp_rtc >> RTC_SHIFT, tm); 172 return 0; 173} 174 175static int sirfsoc_rtc_set_time(struct device *dev, 176 struct rtc_time *tm) 177{ 178 unsigned long rtc_time; 179 struct sirfsoc_rtc_drv *rtcdrv; 180 rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev); 181 182 rtc_tm_to_time(tm, &rtc_time); 183 184 rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT); 185 186 sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc, 187 rtcdrv->rtc_base + RTC_SW_VALUE); 188 sirfsoc_rtc_iobrg_writel( 189 rtc_time << RTC_SHIFT, rtcdrv->rtc_base + RTC_CN); 190 191 return 0; 192} 193 194static int sirfsoc_rtc_ioctl(struct device *dev, unsigned int cmd, 195 unsigned long arg) 196{ 197 switch (cmd) { 198 case RTC_PIE_ON: 199 case RTC_PIE_OFF: 200 case RTC_UIE_ON: 201 case RTC_UIE_OFF: 202 case RTC_AIE_ON: 203 case RTC_AIE_OFF: 204 return 0; 205 206 default: 207 return -ENOIOCTLCMD; 208 } 209} 210 211static const struct rtc_class_ops sirfsoc_rtc_ops = { 212 .read_time = sirfsoc_rtc_read_time, 213 .set_time = sirfsoc_rtc_set_time, 214 .read_alarm = sirfsoc_rtc_read_alarm, 215 .set_alarm = sirfsoc_rtc_set_alarm, 216 .ioctl = sirfsoc_rtc_ioctl 217}; 218 219static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata) 220{ 221 struct sirfsoc_rtc_drv *rtcdrv = pdata; 222 unsigned long rtc_status_reg = 0x0; 223 unsigned long events = 0x0; 224 225 rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS); 226 /* this bit will be set ONLY if an alarm was active 227 * and it expired NOW 228 * So this is being used as an ASSERT 229 */ 230 if (rtc_status_reg & SIRFSOC_RTC_AL0) { 231 /* 232 * clear the RTC status register's alarm bit 233 * mask out the lower status bits 234 */ 235 rtc_status_reg &= ~0x07; 236 /* write 1 into SIRFSOC_RTC_AL0 to ACK the alarm interrupt */ 237 rtc_status_reg |= (SIRFSOC_RTC_AL0); 238 /* Clear the Alarm enable bit */ 239 rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); 240 } 241 sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); 242 /* this should wake up any apps polling/waiting on the read 243 * after setting the alarm 244 */ 245 events |= RTC_IRQF | RTC_AF; 246 rtc_update_irq(rtcdrv->rtc, 1, events); 247 248 return IRQ_HANDLED; 249} 250 251static const struct of_device_id sirfsoc_rtc_of_match[] = { 252 { .compatible = "sirf,prima2-sysrtc"}, 253 {}, 254}; 255MODULE_DEVICE_TABLE(of, sirfsoc_rtc_of_match); 256 257static int sirfsoc_rtc_probe(struct platform_device *pdev) 258{ 259 int err; 260 unsigned long rtc_div; 261 struct sirfsoc_rtc_drv *rtcdrv; 262 struct device_node *np = pdev->dev.of_node; 263 264 rtcdrv = devm_kzalloc(&pdev->dev, 265 sizeof(struct sirfsoc_rtc_drv), GFP_KERNEL); 266 if (rtcdrv == NULL) { 267 dev_err(&pdev->dev, 268 "%s: can't alloc mem for drv struct\n", 269 pdev->name); 270 return -ENOMEM; 271 } 272 273 err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base); 274 if (err) { 275 dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n"); 276 goto error; 277 } 278 279 platform_set_drvdata(pdev, rtcdrv); 280 281 /* Register rtc alarm as a wakeup source */ 282 device_init_wakeup(&pdev->dev, 1); 283 284 /* 285 * Set SYS_RTC counter in RTC_HZ HZ Units 286 * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1 287 * If 16HZ, therefore RTC_DIV = 1023; 288 */ 289 rtc_div = ((32768 / RTC_HZ) / 2) - 1; 290 sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV); 291 292 rtcdrv->rtc = rtc_device_register(pdev->name, &(pdev->dev), 293 &sirfsoc_rtc_ops, THIS_MODULE); 294 if (IS_ERR(rtcdrv->rtc)) { 295 err = PTR_ERR(rtcdrv->rtc); 296 dev_err(&pdev->dev, "can't register RTC device\n"); 297 return err; 298 } 299 300 /* 0x3 -> RTC_CLK */ 301 sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK, 302 rtcdrv->rtc_base + RTC_CLOCK_SWITCH); 303 304 /* reset SYS RTC ALARM0 */ 305 sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0); 306 307 /* reset SYS RTC ALARM1 */ 308 sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1); 309 310 /* Restore RTC Overflow From Register After Command Reboot */ 311 rtcdrv->overflow_rtc = 312 sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE); 313 314 rtcdrv->irq = platform_get_irq(pdev, 0); 315 err = devm_request_irq( 316 &pdev->dev, 317 rtcdrv->irq, 318 sirfsoc_rtc_irq_handler, 319 IRQF_SHARED, 320 pdev->name, 321 rtcdrv); 322 if (err) { 323 dev_err(&pdev->dev, "Unable to register for the SiRF SOC RTC IRQ\n"); 324 goto error; 325 } 326 327 return 0; 328 329error: 330 if (rtcdrv->rtc) 331 rtc_device_unregister(rtcdrv->rtc); 332 333 return err; 334} 335 336static int sirfsoc_rtc_remove(struct platform_device *pdev) 337{ 338 struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev); 339 340 device_init_wakeup(&pdev->dev, 0); 341 rtc_device_unregister(rtcdrv->rtc); 342 343 return 0; 344} 345 346#ifdef CONFIG_PM 347 348static int sirfsoc_rtc_suspend(struct device *dev) 349{ 350 struct platform_device *pdev = to_platform_device(dev); 351 struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev); 352 rtcdrv->overflow_rtc = 353 sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE); 354 355 rtcdrv->saved_counter = 356 sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); 357 rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc; 358 if (device_may_wakeup(&pdev->dev)) 359 enable_irq_wake(rtcdrv->irq); 360 361 return 0; 362} 363 364static int sirfsoc_rtc_freeze(struct device *dev) 365{ 366 sirfsoc_rtc_suspend(dev); 367 368 return 0; 369} 370 371static int sirfsoc_rtc_thaw(struct device *dev) 372{ 373 u32 tmp; 374 struct sirfsoc_rtc_drv *rtcdrv; 375 rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev); 376 377 /* 378 * if resume from snapshot and the rtc power is losed, 379 * restroe the rtc settings 380 */ 381 if (SIRFSOC_RTC_CLK != sirfsoc_rtc_iobrg_readl( 382 rtcdrv->rtc_base + RTC_CLOCK_SWITCH)) { 383 u32 rtc_div; 384 /* 0x3 -> RTC_CLK */ 385 sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK, 386 rtcdrv->rtc_base + RTC_CLOCK_SWITCH); 387 /* 388 * Set SYS_RTC counter in RTC_HZ HZ Units 389 * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1 390 * If 16HZ, therefore RTC_DIV = 1023; 391 */ 392 rtc_div = ((32768 / RTC_HZ) / 2) - 1; 393 394 sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV); 395 396 /* reset SYS RTC ALARM0 */ 397 sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0); 398 399 /* reset SYS RTC ALARM1 */ 400 sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1); 401 } 402 rtcdrv->overflow_rtc = rtcdrv->saved_overflow_rtc; 403 404 /* 405 * if current counter is small than previous, 406 * it means overflow in sleep 407 */ 408 tmp = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); 409 if (tmp <= rtcdrv->saved_counter) 410 rtcdrv->overflow_rtc++; 411 /* 412 *PWRC Value Be Changed When Suspend, Restore Overflow 413 * In Memory To Register 414 */ 415 sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc, 416 rtcdrv->rtc_base + RTC_SW_VALUE); 417 418 return 0; 419} 420 421static int sirfsoc_rtc_resume(struct device *dev) 422{ 423 struct platform_device *pdev = to_platform_device(dev); 424 struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev); 425 sirfsoc_rtc_thaw(dev); 426 if (device_may_wakeup(&pdev->dev)) 427 disable_irq_wake(rtcdrv->irq); 428 429 return 0; 430} 431 432static int sirfsoc_rtc_restore(struct device *dev) 433{ 434 struct platform_device *pdev = to_platform_device(dev); 435 struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev); 436 437 if (device_may_wakeup(&pdev->dev)) 438 disable_irq_wake(rtcdrv->irq); 439 return 0; 440} 441 442#else 443#define sirfsoc_rtc_suspend NULL 444#define sirfsoc_rtc_resume NULL 445#define sirfsoc_rtc_freeze NULL 446#define sirfsoc_rtc_thaw NULL 447#define sirfsoc_rtc_restore NULL 448#endif 449 450static const struct dev_pm_ops sirfsoc_rtc_pm_ops = { 451 .suspend = sirfsoc_rtc_suspend, 452 .resume = sirfsoc_rtc_resume, 453 .freeze = sirfsoc_rtc_freeze, 454 .thaw = sirfsoc_rtc_thaw, 455 .restore = sirfsoc_rtc_restore, 456}; 457 458static struct platform_driver sirfsoc_rtc_driver = { 459 .driver = { 460 .name = "sirfsoc-rtc", 461 .owner = THIS_MODULE, 462#ifdef CONFIG_PM 463 .pm = &sirfsoc_rtc_pm_ops, 464#endif 465 .of_match_table = of_match_ptr(sirfsoc_rtc_of_match), 466 }, 467 .probe = sirfsoc_rtc_probe, 468 .remove = sirfsoc_rtc_remove, 469}; 470module_platform_driver(sirfsoc_rtc_driver); 471 472MODULE_DESCRIPTION("SiRF SoC rtc driver"); 473MODULE_AUTHOR("Xianglong Du <Xianglong.Du@csr.com>"); 474MODULE_LICENSE("GPL v2"); 475MODULE_ALIAS("platform:sirfsoc-rtc");