1 // SPDX-License-Identifier: GPL-2.0-only 2 /* drivers/rtc/rtc-s3c.c 3 * 4 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * 7 * Copyright (c) 2004,2006 Simtec Electronics 8 * Ben Dooks, <ben@simtec.co.uk> 9 * http://armlinux.simtec.co.uk/ 10 * 11 * S3C2410/S3C2440/S3C24XX Internal RTC Driver 12 */ 13 14 #include <linux/module.h> 15 #include <linux/fs.h> 16 #include <linux/string.h> 17 #include <linux/init.h> 18 #include <linux/platform_device.h> 19 #include <linux/interrupt.h> 20 #include <linux/rtc.h> 21 #include <linux/bcd.h> 22 #include <linux/clk.h> 23 #include <linux/log2.h> 24 #include <linux/slab.h> 25 #include <linux/of.h> 26 #include <linux/of_device.h> 27 #include <linux/uaccess.h> 28 #include <linux/io.h> 29 30 #include <asm/irq.h> 31 #include "rtc-s3c.h" 32 33 struct s3c_rtc { 34 struct device *dev; 35 struct rtc_device *rtc; 36 37 void __iomem *base; 38 struct clk *rtc_clk; 39 struct clk *rtc_src_clk; 40 bool alarm_enabled; 41 42 const struct s3c_rtc_data *data; 43 44 int irq_alarm; 45 spinlock_t alarm_lock; 46 47 bool wake_en; 48 }; 49 50 struct s3c_rtc_data { 51 bool needs_src_clk; 52 53 void (*irq_handler) (struct s3c_rtc *info, int mask); 54 void (*enable) (struct s3c_rtc *info); 55 void (*disable) (struct s3c_rtc *info); 56 }; 57 58 static int s3c_rtc_enable_clk(struct s3c_rtc *info) 59 { 60 int ret; 61 62 ret = clk_enable(info->rtc_clk); 63 if (ret) 64 return ret; 65 66 if (info->data->needs_src_clk) { 67 ret = clk_enable(info->rtc_src_clk); 68 if (ret) { 69 clk_disable(info->rtc_clk); 70 return ret; 71 } 72 } 73 return 0; 74 } 75 76 static void s3c_rtc_disable_clk(struct s3c_rtc *info) 77 { 78 if (info->data->needs_src_clk) 79 clk_disable(info->rtc_src_clk); 80 clk_disable(info->rtc_clk); 81 } 82 83 /* IRQ Handler */ 84 static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) 85 { 86 struct s3c_rtc *info = (struct s3c_rtc *)id; 87 88 if (info->data->irq_handler) 89 info->data->irq_handler(info, S3C2410_INTP_ALM); 90 91 return IRQ_HANDLED; 92 } 93 94 /* Update control registers */ 95 static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) 96 { 97 struct s3c_rtc *info = dev_get_drvdata(dev); 98 unsigned long flags; 99 unsigned int tmp; 100 int ret; 101 102 dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled); 103 104 ret = s3c_rtc_enable_clk(info); 105 if (ret) 106 return ret; 107 108 tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; 109 110 if (enabled) 111 tmp |= S3C2410_RTCALM_ALMEN; 112 113 writeb(tmp, info->base + S3C2410_RTCALM); 114 115 spin_lock_irqsave(&info->alarm_lock, flags); 116 117 if (info->alarm_enabled && !enabled) 118 s3c_rtc_disable_clk(info); 119 else if (!info->alarm_enabled && enabled) 120 ret = s3c_rtc_enable_clk(info); 121 122 info->alarm_enabled = enabled; 123 spin_unlock_irqrestore(&info->alarm_lock, flags); 124 125 s3c_rtc_disable_clk(info); 126 127 return ret; 128 } 129 130 /* Time read/write */ 131 static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) 132 { 133 struct s3c_rtc *info = dev_get_drvdata(dev); 134 unsigned int have_retried = 0; 135 int ret; 136 137 ret = s3c_rtc_enable_clk(info); 138 if (ret) 139 return ret; 140 141 retry_get_time: 142 rtc_tm->tm_min = readb(info->base + S3C2410_RTCMIN); 143 rtc_tm->tm_hour = readb(info->base + S3C2410_RTCHOUR); 144 rtc_tm->tm_mday = readb(info->base + S3C2410_RTCDATE); 145 rtc_tm->tm_mon = readb(info->base + S3C2410_RTCMON); 146 rtc_tm->tm_year = readb(info->base + S3C2410_RTCYEAR); 147 rtc_tm->tm_sec = readb(info->base + S3C2410_RTCSEC); 148 149 /* the only way to work out whether the system was mid-update 150 * when we read it is to check the second counter, and if it 151 * is zero, then we re-try the entire read 152 */ 153 154 if (rtc_tm->tm_sec == 0 && !have_retried) { 155 have_retried = 1; 156 goto retry_get_time; 157 } 158 159 rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); 160 rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); 161 rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); 162 rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); 163 rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); 164 rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); 165 166 s3c_rtc_disable_clk(info); 167 168 rtc_tm->tm_year += 100; 169 rtc_tm->tm_mon -= 1; 170 171 dev_dbg(dev, "read time %ptR\n", rtc_tm); 172 return 0; 173 } 174 175 static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) 176 { 177 struct s3c_rtc *info = dev_get_drvdata(dev); 178 int year = tm->tm_year - 100; 179 int ret; 180 181 dev_dbg(dev, "set time %ptR\n", tm); 182 183 /* we get around y2k by simply not supporting it */ 184 185 if (year < 0 || year >= 100) { 186 dev_err(dev, "rtc only supports 100 years\n"); 187 return -EINVAL; 188 } 189 190 ret = s3c_rtc_enable_clk(info); 191 if (ret) 192 return ret; 193 194 writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_RTCSEC); 195 writeb(bin2bcd(tm->tm_min), info->base + S3C2410_RTCMIN); 196 writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_RTCHOUR); 197 writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_RTCDATE); 198 writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON); 199 writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR); 200 201 s3c_rtc_disable_clk(info); 202 203 return 0; 204 } 205 206 static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) 207 { 208 struct s3c_rtc *info = dev_get_drvdata(dev); 209 struct rtc_time *alm_tm = &alrm->time; 210 unsigned int alm_en; 211 int ret; 212 213 ret = s3c_rtc_enable_clk(info); 214 if (ret) 215 return ret; 216 217 alm_tm->tm_sec = readb(info->base + S3C2410_ALMSEC); 218 alm_tm->tm_min = readb(info->base + S3C2410_ALMMIN); 219 alm_tm->tm_hour = readb(info->base + S3C2410_ALMHOUR); 220 alm_tm->tm_mon = readb(info->base + S3C2410_ALMMON); 221 alm_tm->tm_mday = readb(info->base + S3C2410_ALMDATE); 222 alm_tm->tm_year = readb(info->base + S3C2410_ALMYEAR); 223 224 alm_en = readb(info->base + S3C2410_RTCALM); 225 226 s3c_rtc_disable_clk(info); 227 228 alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; 229 230 dev_dbg(dev, "read alarm %d, %ptR\n", alm_en, alm_tm); 231 232 /* decode the alarm enable field */ 233 if (alm_en & S3C2410_RTCALM_SECEN) 234 alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); 235 236 if (alm_en & S3C2410_RTCALM_MINEN) 237 alm_tm->tm_min = bcd2bin(alm_tm->tm_min); 238 239 if (alm_en & S3C2410_RTCALM_HOUREN) 240 alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); 241 242 if (alm_en & S3C2410_RTCALM_DAYEN) 243 alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); 244 245 if (alm_en & S3C2410_RTCALM_MONEN) { 246 alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); 247 alm_tm->tm_mon -= 1; 248 } 249 250 if (alm_en & S3C2410_RTCALM_YEAREN) 251 alm_tm->tm_year = bcd2bin(alm_tm->tm_year); 252 253 return 0; 254 } 255 256 static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) 257 { 258 struct s3c_rtc *info = dev_get_drvdata(dev); 259 struct rtc_time *tm = &alrm->time; 260 unsigned int alrm_en; 261 int ret; 262 263 dev_dbg(dev, "s3c_rtc_setalarm: %d, %ptR\n", alrm->enabled, tm); 264 265 ret = s3c_rtc_enable_clk(info); 266 if (ret) 267 return ret; 268 269 alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; 270 writeb(0x00, info->base + S3C2410_RTCALM); 271 272 if (tm->tm_sec < 60 && tm->tm_sec >= 0) { 273 alrm_en |= S3C2410_RTCALM_SECEN; 274 writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_ALMSEC); 275 } 276 277 if (tm->tm_min < 60 && tm->tm_min >= 0) { 278 alrm_en |= S3C2410_RTCALM_MINEN; 279 writeb(bin2bcd(tm->tm_min), info->base + S3C2410_ALMMIN); 280 } 281 282 if (tm->tm_hour < 24 && tm->tm_hour >= 0) { 283 alrm_en |= S3C2410_RTCALM_HOUREN; 284 writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_ALMHOUR); 285 } 286 287 if (tm->tm_mon < 12 && tm->tm_mon >= 0) { 288 alrm_en |= S3C2410_RTCALM_MONEN; 289 writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_ALMMON); 290 } 291 292 if (tm->tm_mday <= 31 && tm->tm_mday >= 1) { 293 alrm_en |= S3C2410_RTCALM_DAYEN; 294 writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_ALMDATE); 295 } 296 297 dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en); 298 299 writeb(alrm_en, info->base + S3C2410_RTCALM); 300 301 s3c_rtc_setaie(dev, alrm->enabled); 302 303 s3c_rtc_disable_clk(info); 304 305 return 0; 306 } 307 308 static const struct rtc_class_ops s3c_rtcops = { 309 .read_time = s3c_rtc_gettime, 310 .set_time = s3c_rtc_settime, 311 .read_alarm = s3c_rtc_getalarm, 312 .set_alarm = s3c_rtc_setalarm, 313 .alarm_irq_enable = s3c_rtc_setaie, 314 }; 315 316 static void s3c24xx_rtc_enable(struct s3c_rtc *info) 317 { 318 unsigned int con, tmp; 319 320 con = readw(info->base + S3C2410_RTCCON); 321 /* re-enable the device, and check it is ok */ 322 if ((con & S3C2410_RTCCON_RTCEN) == 0) { 323 dev_info(info->dev, "rtc disabled, re-enabling\n"); 324 325 tmp = readw(info->base + S3C2410_RTCCON); 326 writew(tmp | S3C2410_RTCCON_RTCEN, info->base + S3C2410_RTCCON); 327 } 328 329 if (con & S3C2410_RTCCON_CNTSEL) { 330 dev_info(info->dev, "removing RTCCON_CNTSEL\n"); 331 332 tmp = readw(info->base + S3C2410_RTCCON); 333 writew(tmp & ~S3C2410_RTCCON_CNTSEL, 334 info->base + S3C2410_RTCCON); 335 } 336 337 if (con & S3C2410_RTCCON_CLKRST) { 338 dev_info(info->dev, "removing RTCCON_CLKRST\n"); 339 340 tmp = readw(info->base + S3C2410_RTCCON); 341 writew(tmp & ~S3C2410_RTCCON_CLKRST, 342 info->base + S3C2410_RTCCON); 343 } 344 } 345 346 static void s3c24xx_rtc_disable(struct s3c_rtc *info) 347 { 348 unsigned int con; 349 350 con = readw(info->base + S3C2410_RTCCON); 351 con &= ~S3C2410_RTCCON_RTCEN; 352 writew(con, info->base + S3C2410_RTCCON); 353 354 con = readb(info->base + S3C2410_TICNT); 355 con &= ~S3C2410_TICNT_ENABLE; 356 writeb(con, info->base + S3C2410_TICNT); 357 } 358 359 static void s3c6410_rtc_disable(struct s3c_rtc *info) 360 { 361 unsigned int con; 362 363 con = readw(info->base + S3C2410_RTCCON); 364 con &= ~S3C64XX_RTCCON_TICEN; 365 con &= ~S3C2410_RTCCON_RTCEN; 366 writew(con, info->base + S3C2410_RTCCON); 367 } 368 369 static int s3c_rtc_remove(struct platform_device *pdev) 370 { 371 struct s3c_rtc *info = platform_get_drvdata(pdev); 372 373 s3c_rtc_setaie(info->dev, 0); 374 375 if (info->data->needs_src_clk) 376 clk_unprepare(info->rtc_src_clk); 377 clk_unprepare(info->rtc_clk); 378 379 return 0; 380 } 381 382 static int s3c_rtc_probe(struct platform_device *pdev) 383 { 384 struct s3c_rtc *info = NULL; 385 struct rtc_time rtc_tm; 386 int ret; 387 388 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 389 if (!info) 390 return -ENOMEM; 391 392 info->dev = &pdev->dev; 393 info->data = of_device_get_match_data(&pdev->dev); 394 if (!info->data) { 395 dev_err(&pdev->dev, "failed getting s3c_rtc_data\n"); 396 return -EINVAL; 397 } 398 spin_lock_init(&info->alarm_lock); 399 400 platform_set_drvdata(pdev, info); 401 402 info->irq_alarm = platform_get_irq(pdev, 0); 403 if (info->irq_alarm < 0) 404 return info->irq_alarm; 405 406 dev_dbg(&pdev->dev, "s3c2410_rtc: alarm irq %d\n", info->irq_alarm); 407 408 /* get the memory region */ 409 info->base = devm_platform_ioremap_resource(pdev, 0); 410 if (IS_ERR(info->base)) 411 return PTR_ERR(info->base); 412 413 info->rtc_clk = devm_clk_get(&pdev->dev, "rtc"); 414 if (IS_ERR(info->rtc_clk)) { 415 ret = PTR_ERR(info->rtc_clk); 416 if (ret != -EPROBE_DEFER) 417 dev_err(&pdev->dev, "failed to find rtc clock\n"); 418 else 419 dev_dbg(&pdev->dev, "probe deferred due to missing rtc clk\n"); 420 return ret; 421 } 422 ret = clk_prepare_enable(info->rtc_clk); 423 if (ret) 424 return ret; 425 426 if (info->data->needs_src_clk) { 427 info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); 428 if (IS_ERR(info->rtc_src_clk)) { 429 ret = dev_err_probe(&pdev->dev, PTR_ERR(info->rtc_src_clk), 430 "failed to find rtc source clock\n"); 431 goto err_src_clk; 432 } 433 ret = clk_prepare_enable(info->rtc_src_clk); 434 if (ret) 435 goto err_src_clk; 436 } 437 438 /* disable RTC enable bits potentially set by the bootloader */ 439 if (info->data->disable) 440 info->data->disable(info); 441 442 /* check to see if everything is setup correctly */ 443 if (info->data->enable) 444 info->data->enable(info); 445 446 dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", 447 readw(info->base + S3C2410_RTCCON)); 448 449 device_init_wakeup(&pdev->dev, 1); 450 451 /* Check RTC Time */ 452 if (s3c_rtc_gettime(&pdev->dev, &rtc_tm)) { 453 rtc_tm.tm_year = 100; 454 rtc_tm.tm_mon = 0; 455 rtc_tm.tm_mday = 1; 456 rtc_tm.tm_hour = 0; 457 rtc_tm.tm_min = 0; 458 rtc_tm.tm_sec = 0; 459 460 s3c_rtc_settime(&pdev->dev, &rtc_tm); 461 462 dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); 463 } 464 465 /* register RTC and exit */ 466 info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, 467 THIS_MODULE); 468 if (IS_ERR(info->rtc)) { 469 dev_err(&pdev->dev, "cannot attach rtc\n"); 470 ret = PTR_ERR(info->rtc); 471 goto err_nortc; 472 } 473 474 ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq, 475 0, "s3c2410-rtc alarm", info); 476 if (ret) { 477 dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_alarm, ret); 478 goto err_nortc; 479 } 480 481 s3c_rtc_disable_clk(info); 482 483 return 0; 484 485 err_nortc: 486 if (info->data->disable) 487 info->data->disable(info); 488 489 if (info->data->needs_src_clk) 490 clk_disable_unprepare(info->rtc_src_clk); 491 err_src_clk: 492 clk_disable_unprepare(info->rtc_clk); 493 494 return ret; 495 } 496 497 #ifdef CONFIG_PM_SLEEP 498 499 static int s3c_rtc_suspend(struct device *dev) 500 { 501 struct s3c_rtc *info = dev_get_drvdata(dev); 502 int ret; 503 504 ret = s3c_rtc_enable_clk(info); 505 if (ret) 506 return ret; 507 508 if (info->data->disable) 509 info->data->disable(info); 510 511 if (device_may_wakeup(dev) && !info->wake_en) { 512 if (enable_irq_wake(info->irq_alarm) == 0) 513 info->wake_en = true; 514 else 515 dev_err(dev, "enable_irq_wake failed\n"); 516 } 517 518 return 0; 519 } 520 521 static int s3c_rtc_resume(struct device *dev) 522 { 523 struct s3c_rtc *info = dev_get_drvdata(dev); 524 525 if (info->data->enable) 526 info->data->enable(info); 527 528 s3c_rtc_disable_clk(info); 529 530 if (device_may_wakeup(dev) && info->wake_en) { 531 disable_irq_wake(info->irq_alarm); 532 info->wake_en = false; 533 } 534 535 return 0; 536 } 537 #endif 538 static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); 539 540 static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) 541 { 542 rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); 543 } 544 545 static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) 546 { 547 rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); 548 writeb(mask, info->base + S3C2410_INTP); 549 } 550 551 static struct s3c_rtc_data const s3c2410_rtc_data = { 552 .irq_handler = s3c24xx_rtc_irq, 553 .enable = s3c24xx_rtc_enable, 554 .disable = s3c24xx_rtc_disable, 555 }; 556 557 static struct s3c_rtc_data const s3c2416_rtc_data = { 558 .irq_handler = s3c24xx_rtc_irq, 559 .enable = s3c24xx_rtc_enable, 560 .disable = s3c24xx_rtc_disable, 561 }; 562 563 static struct s3c_rtc_data const s3c2443_rtc_data = { 564 .irq_handler = s3c24xx_rtc_irq, 565 .enable = s3c24xx_rtc_enable, 566 .disable = s3c24xx_rtc_disable, 567 }; 568 569 static struct s3c_rtc_data const s3c6410_rtc_data = { 570 .needs_src_clk = true, 571 .irq_handler = s3c6410_rtc_irq, 572 .enable = s3c24xx_rtc_enable, 573 .disable = s3c6410_rtc_disable, 574 }; 575 576 static const struct of_device_id s3c_rtc_dt_match[] = { 577 { 578 .compatible = "samsung,s3c2410-rtc", 579 .data = &s3c2410_rtc_data, 580 }, { 581 .compatible = "samsung,s3c2416-rtc", 582 .data = &s3c2416_rtc_data, 583 }, { 584 .compatible = "samsung,s3c2443-rtc", 585 .data = &s3c2443_rtc_data, 586 }, { 587 .compatible = "samsung,s3c6410-rtc", 588 .data = &s3c6410_rtc_data, 589 }, { 590 .compatible = "samsung,exynos3250-rtc", 591 .data = &s3c6410_rtc_data, 592 }, 593 { /* sentinel */ }, 594 }; 595 MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); 596 597 static struct platform_driver s3c_rtc_driver = { 598 .probe = s3c_rtc_probe, 599 .remove = s3c_rtc_remove, 600 .driver = { 601 .name = "s3c-rtc", 602 .pm = &s3c_rtc_pm_ops, 603 .of_match_table = of_match_ptr(s3c_rtc_dt_match), 604 }, 605 }; 606 module_platform_driver(s3c_rtc_driver); 607 608 MODULE_DESCRIPTION("Samsung S3C RTC Driver"); 609 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 610 MODULE_LICENSE("GPL"); 611 MODULE_ALIAS("platform:s3c2410-rtc"); 612