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

rtc: s3c: add s3c_rtc_data structure to use variant data instead of s3c_cpu_type

Add s3c_rtc_data structure to variant data according to SoC type. The
s3c_rtc_data structure includes some functions to control RTC operation
and specific data dependent on SoC type.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Chanwoo Choi and committed by
Linus Torvalds
ae05c950 d67288da

+297 -180
+297 -180
drivers/rtc/rtc-s3c.c
··· 32 32 #include <asm/irq.h> 33 33 #include "rtc-s3c.h" 34 34 35 - enum s3c_cpu_type { 36 - TYPE_S3C2410, 37 - TYPE_S3C2416, 38 - TYPE_S3C2443, 39 - TYPE_S3C64XX, 40 - }; 41 - 42 - struct s3c_rtc_drv_data { 43 - int cpu_type; 44 - }; 45 - 46 35 struct s3c_rtc { 47 36 struct device *dev; 48 37 struct rtc_device *rtc; ··· 40 51 struct clk *rtc_clk; 41 52 bool enabled; 42 53 43 - enum s3c_cpu_type cpu_type; 54 + struct s3c_rtc_data *data; 44 55 45 56 int irq_alarm; 46 57 int irq_tick; ··· 50 61 51 62 int ticnt_save, ticnt_en_save; 52 63 bool wake_en; 64 + }; 65 + 66 + struct s3c_rtc_data { 67 + int max_user_freq; 68 + 69 + void (*irq_handler) (struct s3c_rtc *info, int mask); 70 + void (*set_freq) (struct s3c_rtc *info, int freq); 71 + void (*enable_tick) (struct s3c_rtc *info, struct seq_file *seq); 72 + void (*select_tick_clk) (struct s3c_rtc *info); 73 + void (*save_tick_cnt) (struct s3c_rtc *info); 74 + void (*restore_tick_cnt) (struct s3c_rtc *info); 75 + void (*enable) (struct s3c_rtc *info); 76 + void (*disable) (struct s3c_rtc *info); 53 77 }; 54 78 55 79 static void s3c_rtc_alarm_clk_enable(struct s3c_rtc *info, bool enable) ··· 85 83 } 86 84 87 85 /* IRQ Handlers */ 88 - static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) 89 - { 90 - struct s3c_rtc *info = (struct s3c_rtc *)id; 91 - 92 - clk_enable(info->rtc_clk); 93 - rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); 94 - 95 - if (info->cpu_type == TYPE_S3C64XX) 96 - writeb(S3C2410_INTP_ALM, info->base + S3C2410_INTP); 97 - 98 - clk_disable(info->rtc_clk); 99 - 100 - s3c_rtc_alarm_clk_enable(info, false); 101 - 102 - return IRQ_HANDLED; 103 - } 104 - 105 86 static irqreturn_t s3c_rtc_tickirq(int irq, void *id) 106 87 { 107 88 struct s3c_rtc *info = (struct s3c_rtc *)id; 108 89 109 - clk_enable(info->rtc_clk); 110 - rtc_update_irq(info->rtc, 1, RTC_PF | RTC_IRQF); 90 + if (info->data->irq_handler) 91 + info->data->irq_handler(info, S3C2410_INTP_TIC); 111 92 112 - if (info->cpu_type == TYPE_S3C64XX) 113 - writeb(S3C2410_INTP_TIC, info->base + S3C2410_INTP); 93 + return IRQ_HANDLED; 94 + } 114 95 115 - clk_disable(info->rtc_clk); 96 + static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) 97 + { 98 + struct s3c_rtc *info = (struct s3c_rtc *)id; 99 + 100 + if (info->data->irq_handler) 101 + info->data->irq_handler(info, S3C2410_INTP_ALM); 116 102 117 103 return IRQ_HANDLED; 118 104 } ··· 127 137 return 0; 128 138 } 129 139 140 + /* Set RTC frequency */ 130 141 static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq) 131 142 { 132 - unsigned int tmp = 0; 133 - int val; 134 - 135 143 if (!is_power_of_2(freq)) 136 144 return -EINVAL; 137 145 138 146 clk_enable(info->rtc_clk); 139 147 spin_lock_irq(&info->pie_lock); 140 148 141 - if (info->cpu_type != TYPE_S3C64XX) { 142 - tmp = readb(info->base + S3C2410_TICNT); 143 - tmp &= S3C2410_TICNT_ENABLE; 144 - } 149 + if (info->data->set_freq) 150 + info->data->set_freq(info, freq); 145 151 146 - val = (info->rtc->max_user_freq / freq) - 1; 147 - 148 - if (info->cpu_type == TYPE_S3C2416 || info->cpu_type == TYPE_S3C2443) { 149 - tmp |= S3C2443_TICNT_PART(val); 150 - writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1); 151 - 152 - if (info->cpu_type == TYPE_S3C2416) 153 - writel(S3C2416_TICNT2_PART(val), 154 - info->base + S3C2416_TICNT2); 155 - } else { 156 - tmp |= val; 157 - } 158 - 159 - writel(tmp, info->base + S3C2410_TICNT); 160 152 spin_unlock_irq(&info->pie_lock); 161 153 clk_disable(info->rtc_clk); 162 154 ··· 146 174 } 147 175 148 176 /* Time read/write */ 149 - 150 177 static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) 151 178 { 152 179 struct s3c_rtc *info = dev_get_drvdata(dev); ··· 326 355 static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) 327 356 { 328 357 struct s3c_rtc *info = dev_get_drvdata(dev); 329 - unsigned int ticnt; 330 358 331 359 clk_enable(info->rtc_clk); 332 - if (info->cpu_type == TYPE_S3C64XX) { 333 - ticnt = readw(info->base + S3C2410_RTCCON); 334 - ticnt &= S3C64XX_RTCCON_TICEN; 335 - } else { 336 - ticnt = readb(info->base + S3C2410_TICNT); 337 - ticnt &= S3C2410_TICNT_ENABLE; 338 - } 339 360 340 - seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); 361 + if (info->data->enable_tick) 362 + info->data->enable_tick(info, seq); 363 + 341 364 clk_disable(info->rtc_clk); 365 + 342 366 return 0; 343 367 } 344 368 ··· 346 380 .alarm_irq_enable = s3c_rtc_setaie, 347 381 }; 348 382 349 - static void s3c_rtc_enable(struct s3c_rtc *info, int en) 383 + static void s3c24xx_rtc_enable(struct s3c_rtc *info) 350 384 { 351 385 unsigned int con, tmp; 352 386 353 387 clk_enable(info->rtc_clk); 354 388 355 389 con = readw(info->base + S3C2410_RTCCON); 356 - if (!en) { 357 - if (info->cpu_type == TYPE_S3C64XX) 358 - con &= ~S3C64XX_RTCCON_TICEN; 359 - con &= ~S3C2410_RTCCON_RTCEN; 360 - writew(con, info->base + S3C2410_RTCCON); 390 + /* re-enable the device, and check it is ok */ 391 + if ((con & S3C2410_RTCCON_RTCEN) == 0) { 392 + dev_info(info->dev, "rtc disabled, re-enabling\n"); 361 393 362 - if (info->cpu_type != TYPE_S3C64XX) { 363 - con = readb(info->base + S3C2410_TICNT); 364 - con &= ~S3C2410_TICNT_ENABLE; 365 - writeb(con, info->base + S3C2410_TICNT); 366 - } 367 - } else { 368 - /* re-enable the device, and check it is ok */ 369 - if ((con & S3C2410_RTCCON_RTCEN) == 0) { 370 - dev_info(info->dev, "rtc disabled, re-enabling\n"); 371 - 372 - tmp = readw(info->base + S3C2410_RTCCON); 373 - writew(tmp | S3C2410_RTCCON_RTCEN, 374 - info->base + S3C2410_RTCCON); 375 - } 376 - 377 - if (con & S3C2410_RTCCON_CNTSEL) { 378 - dev_info(info->dev, "removing RTCCON_CNTSEL\n"); 379 - 380 - tmp = readw(info->base + S3C2410_RTCCON); 381 - writew(tmp & ~S3C2410_RTCCON_CNTSEL, 382 - info->base + S3C2410_RTCCON); 383 - } 384 - 385 - if (con & S3C2410_RTCCON_CLKRST) { 386 - dev_info(info->dev, "removing RTCCON_CLKRST\n"); 387 - 388 - tmp = readw(info->base + S3C2410_RTCCON); 389 - writew(tmp & ~S3C2410_RTCCON_CLKRST, 390 - info->base + S3C2410_RTCCON); 391 - } 394 + tmp = readw(info->base + S3C2410_RTCCON); 395 + writew(tmp | S3C2410_RTCCON_RTCEN, 396 + info->base + S3C2410_RTCCON); 392 397 } 398 + 399 + if (con & S3C2410_RTCCON_CNTSEL) { 400 + dev_info(info->dev, "removing RTCCON_CNTSEL\n"); 401 + 402 + tmp = readw(info->base + S3C2410_RTCCON); 403 + writew(tmp & ~S3C2410_RTCCON_CNTSEL, 404 + info->base + S3C2410_RTCCON); 405 + } 406 + 407 + if (con & S3C2410_RTCCON_CLKRST) { 408 + dev_info(info->dev, "removing RTCCON_CLKRST\n"); 409 + 410 + tmp = readw(info->base + S3C2410_RTCCON); 411 + writew(tmp & ~S3C2410_RTCCON_CLKRST, 412 + info->base + S3C2410_RTCCON); 413 + } 414 + 415 + clk_disable(info->rtc_clk); 416 + } 417 + 418 + static void s3c24xx_rtc_disable(struct s3c_rtc *info) 419 + { 420 + unsigned int con; 421 + 422 + clk_enable(info->rtc_clk); 423 + 424 + con = readw(info->base + S3C2410_RTCCON); 425 + con &= ~S3C2410_RTCCON_RTCEN; 426 + writew(con, info->base + S3C2410_RTCCON); 427 + 428 + con = readb(info->base + S3C2410_TICNT); 429 + con &= ~S3C2410_TICNT_ENABLE; 430 + writeb(con, info->base + S3C2410_TICNT); 431 + 432 + clk_disable(info->rtc_clk); 433 + } 434 + 435 + static void s3c6410_rtc_disable(struct s3c_rtc *info) 436 + { 437 + unsigned int con; 438 + 439 + clk_enable(info->rtc_clk); 440 + 441 + con = readw(info->base + S3C2410_RTCCON); 442 + con &= ~S3C64XX_RTCCON_TICEN; 443 + con &= ~S3C2410_RTCCON_RTCEN; 444 + writew(con, info->base + S3C2410_RTCCON); 445 + 393 446 clk_disable(info->rtc_clk); 394 447 } 395 448 ··· 426 441 427 442 static const struct of_device_id s3c_rtc_dt_match[]; 428 443 429 - static inline int s3c_rtc_get_driver_data(struct platform_device *pdev) 444 + static struct s3c_rtc_data *s3c_rtc_get_data(struct platform_device *pdev) 430 445 { 431 - #ifdef CONFIG_OF 432 - struct s3c_rtc_drv_data *data; 446 + const struct of_device_id *match; 433 447 434 - if (pdev->dev.of_node) { 435 - const struct of_device_id *match; 436 - 437 - match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); 438 - data = (struct s3c_rtc_drv_data *) match->data; 439 - return data->cpu_type; 440 - } 441 - #endif 442 - return platform_get_device_id(pdev)->driver_data; 448 + match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); 449 + return (struct s3c_rtc_data *)match->data; 443 450 } 444 451 445 452 static int s3c_rtc_probe(struct platform_device *pdev) ··· 440 463 struct rtc_time rtc_tm; 441 464 struct resource *res; 442 465 int ret; 443 - int tmp; 444 466 445 467 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 446 468 if (!info) ··· 453 477 } 454 478 455 479 info->dev = &pdev->dev; 456 - info->cpu_type = s3c_rtc_get_driver_data(pdev); 480 + info->data = s3c_rtc_get_data(pdev); 481 + if (!info->data) { 482 + dev_err(&pdev->dev, "failed getting s3c_rtc_data\n"); 483 + return -EINVAL; 484 + } 457 485 spin_lock_init(&info->pie_lock); 458 486 spin_lock_init(&info->alarm_clk_lock); 459 487 ··· 486 506 clk_prepare_enable(info->rtc_clk); 487 507 488 508 /* check to see if everything is setup correctly */ 489 - s3c_rtc_enable(info, 1); 509 + if (info->data->enable) 510 + info->data->enable(info); 490 511 491 512 dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", 492 513 readw(info->base + S3C2410_RTCCON)); ··· 533 552 dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); 534 553 } 535 554 536 - if (info->cpu_type != TYPE_S3C2410) 537 - info->rtc->max_user_freq = 32768; 538 - else 539 - info->rtc->max_user_freq = 128; 540 - 541 - if (info->cpu_type == TYPE_S3C2416 || info->cpu_type == TYPE_S3C2443) { 542 - tmp = readw(info->base + S3C2410_RTCCON); 543 - tmp |= S3C2443_RTCCON_TICSEL; 544 - writew(tmp, info->base + S3C2410_RTCCON); 545 - } 555 + if (info->data->select_tick_clk) 556 + info->data->select_tick_clk(info); 546 557 547 558 s3c_rtc_setfreq(info, 1); 548 559 ··· 543 570 return 0; 544 571 545 572 err_nortc: 546 - s3c_rtc_enable(info, 0); 573 + if (info->data->disable) 574 + info->data->disable(info); 547 575 clk_disable_unprepare(info->rtc_clk); 548 576 549 577 return ret; ··· 557 583 struct s3c_rtc *info = dev_get_drvdata(dev); 558 584 559 585 clk_enable(info->rtc_clk); 586 + 560 587 /* save TICNT for anyone using periodic interrupts */ 561 - if (info->cpu_type == TYPE_S3C64XX) { 562 - info->ticnt_en_save = readw(info->base + S3C2410_RTCCON); 563 - info->ticnt_en_save &= S3C64XX_RTCCON_TICEN; 564 - info->ticnt_save = readl(info->base + S3C2410_TICNT); 565 - } else { 566 - info->ticnt_save = readb(info->base + S3C2410_TICNT); 567 - } 568 - s3c_rtc_enable(info, 0); 588 + if (info->data->save_tick_cnt) 589 + info->data->save_tick_cnt(info); 590 + 591 + if (info->data->disable) 592 + info->data->disable(info); 569 593 570 594 if (device_may_wakeup(dev) && !info->wake_en) { 571 595 if (enable_irq_wake(info->irq_alarm) == 0) ··· 571 599 else 572 600 dev_err(dev, "enable_irq_wake failed\n"); 573 601 } 602 + 574 603 clk_disable(info->rtc_clk); 575 604 576 605 return 0; ··· 580 607 static int s3c_rtc_resume(struct device *dev) 581 608 { 582 609 struct s3c_rtc *info = dev_get_drvdata(dev); 583 - unsigned int tmp; 584 610 585 611 clk_enable(info->rtc_clk); 586 - s3c_rtc_enable(info, 1); 587 - if (info->cpu_type == TYPE_S3C64XX) { 588 - writel(info->ticnt_save, info->base + S3C2410_TICNT); 589 - if (info->ticnt_en_save) { 590 - tmp = readw(info->base + S3C2410_RTCCON); 591 - writew(tmp | info->ticnt_en_save, 592 - info->base + S3C2410_RTCCON); 593 - } 594 - } else { 595 - writeb(info->ticnt_save, info->base + S3C2410_TICNT); 596 - } 612 + 613 + if (info->data->enable) 614 + info->data->enable(info); 615 + 616 + if (info->data->restore_tick_cnt) 617 + info->data->restore_tick_cnt(info); 597 618 598 619 if (device_may_wakeup(dev) && info->wake_en) { 599 620 disable_irq_wake(info->irq_alarm); 600 621 info->wake_en = false; 601 622 } 623 + 602 624 clk_disable(info->rtc_clk); 603 625 604 626 return 0; ··· 601 633 #endif 602 634 static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); 603 635 604 - #ifdef CONFIG_OF 605 - static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = { 606 - [TYPE_S3C2410] = { TYPE_S3C2410 }, 607 - [TYPE_S3C2416] = { TYPE_S3C2416 }, 608 - [TYPE_S3C2443] = { TYPE_S3C2443 }, 609 - [TYPE_S3C64XX] = { TYPE_S3C64XX }, 636 + static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) 637 + { 638 + clk_enable(info->rtc_clk); 639 + rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); 640 + clk_disable(info->rtc_clk); 641 + 642 + s3c_rtc_alarm_clk_enable(info, false); 643 + } 644 + 645 + static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) 646 + { 647 + clk_enable(info->rtc_clk); 648 + rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); 649 + writeb(mask, info->base + S3C2410_INTP); 650 + clk_disable(info->rtc_clk); 651 + 652 + s3c_rtc_alarm_clk_enable(info, false); 653 + } 654 + 655 + static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq) 656 + { 657 + unsigned int tmp = 0; 658 + int val; 659 + 660 + tmp = readb(info->base + S3C2410_TICNT); 661 + tmp &= S3C2410_TICNT_ENABLE; 662 + 663 + val = (info->rtc->max_user_freq / freq) - 1; 664 + tmp |= val; 665 + 666 + writel(tmp, info->base + S3C2410_TICNT); 667 + } 668 + 669 + static void s3c2416_rtc_setfreq(struct s3c_rtc *info, int freq) 670 + { 671 + unsigned int tmp = 0; 672 + int val; 673 + 674 + tmp = readb(info->base + S3C2410_TICNT); 675 + tmp &= S3C2410_TICNT_ENABLE; 676 + 677 + val = (info->rtc->max_user_freq / freq) - 1; 678 + 679 + tmp |= S3C2443_TICNT_PART(val); 680 + writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1); 681 + 682 + writel(S3C2416_TICNT2_PART(val), info->base + S3C2416_TICNT2); 683 + 684 + writel(tmp, info->base + S3C2410_TICNT); 685 + } 686 + 687 + static void s3c2443_rtc_setfreq(struct s3c_rtc *info, int freq) 688 + { 689 + unsigned int tmp = 0; 690 + int val; 691 + 692 + tmp = readb(info->base + S3C2410_TICNT); 693 + tmp &= S3C2410_TICNT_ENABLE; 694 + 695 + val = (info->rtc->max_user_freq / freq) - 1; 696 + 697 + tmp |= S3C2443_TICNT_PART(val); 698 + writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1); 699 + 700 + writel(tmp, info->base + S3C2410_TICNT); 701 + } 702 + 703 + static void s3c6410_rtc_setfreq(struct s3c_rtc *info, int freq) 704 + { 705 + int val; 706 + 707 + val = (info->rtc->max_user_freq / freq) - 1; 708 + writel(val, info->base + S3C2410_TICNT); 709 + } 710 + 711 + static void s3c24xx_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq) 712 + { 713 + unsigned int ticnt; 714 + 715 + ticnt = readb(info->base + S3C2410_TICNT); 716 + ticnt &= S3C2410_TICNT_ENABLE; 717 + 718 + seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); 719 + } 720 + 721 + static void s3c2416_rtc_select_tick_clk(struct s3c_rtc *info) 722 + { 723 + unsigned int con; 724 + 725 + con = readw(info->base + S3C2410_RTCCON); 726 + con |= S3C2443_RTCCON_TICSEL; 727 + writew(con, info->base + S3C2410_RTCCON); 728 + } 729 + 730 + static void s3c6410_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq) 731 + { 732 + unsigned int ticnt; 733 + 734 + ticnt = readw(info->base + S3C2410_RTCCON); 735 + ticnt &= S3C64XX_RTCCON_TICEN; 736 + 737 + seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); 738 + } 739 + 740 + static void s3c24xx_rtc_save_tick_cnt(struct s3c_rtc *info) 741 + { 742 + info->ticnt_save = readb(info->base + S3C2410_TICNT); 743 + } 744 + 745 + static void s3c24xx_rtc_restore_tick_cnt(struct s3c_rtc *info) 746 + { 747 + writeb(info->ticnt_save, info->base + S3C2410_TICNT); 748 + } 749 + 750 + static void s3c6410_rtc_save_tick_cnt(struct s3c_rtc *info) 751 + { 752 + info->ticnt_en_save = readw(info->base + S3C2410_RTCCON); 753 + info->ticnt_en_save &= S3C64XX_RTCCON_TICEN; 754 + info->ticnt_save = readl(info->base + S3C2410_TICNT); 755 + } 756 + 757 + static void s3c6410_rtc_restore_tick_cnt(struct s3c_rtc *info) 758 + { 759 + unsigned int con; 760 + 761 + writel(info->ticnt_save, info->base + S3C2410_TICNT); 762 + if (info->ticnt_en_save) { 763 + con = readw(info->base + S3C2410_RTCCON); 764 + writew(con | info->ticnt_en_save, 765 + info->base + S3C2410_RTCCON); 766 + } 767 + } 768 + 769 + static struct s3c_rtc_data const s3c2410_rtc_data = { 770 + .max_user_freq = 128, 771 + .irq_handler = s3c24xx_rtc_irq, 772 + .set_freq = s3c2410_rtc_setfreq, 773 + .enable_tick = s3c24xx_rtc_enable_tick, 774 + .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, 775 + .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, 776 + .enable = s3c24xx_rtc_enable, 777 + .disable = s3c24xx_rtc_disable, 778 + }; 779 + 780 + static struct s3c_rtc_data const s3c2416_rtc_data = { 781 + .max_user_freq = 32768, 782 + .irq_handler = s3c24xx_rtc_irq, 783 + .set_freq = s3c2416_rtc_setfreq, 784 + .enable_tick = s3c24xx_rtc_enable_tick, 785 + .select_tick_clk = s3c2416_rtc_select_tick_clk, 786 + .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, 787 + .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, 788 + .enable = s3c24xx_rtc_enable, 789 + .disable = s3c24xx_rtc_disable, 790 + }; 791 + 792 + static struct s3c_rtc_data const s3c2443_rtc_data = { 793 + .max_user_freq = 32768, 794 + .irq_handler = s3c24xx_rtc_irq, 795 + .set_freq = s3c2443_rtc_setfreq, 796 + .enable_tick = s3c24xx_rtc_enable_tick, 797 + .select_tick_clk = s3c2416_rtc_select_tick_clk, 798 + .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, 799 + .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, 800 + .enable = s3c24xx_rtc_enable, 801 + .disable = s3c24xx_rtc_disable, 802 + }; 803 + 804 + static struct s3c_rtc_data const s3c6410_rtc_data = { 805 + .max_user_freq = 32768, 806 + .irq_handler = s3c6410_rtc_irq, 807 + .set_freq = s3c6410_rtc_setfreq, 808 + .enable_tick = s3c6410_rtc_enable_tick, 809 + .save_tick_cnt = s3c6410_rtc_save_tick_cnt, 810 + .restore_tick_cnt = s3c6410_rtc_restore_tick_cnt, 811 + .enable = s3c24xx_rtc_enable, 812 + .disable = s3c6410_rtc_disable, 610 813 }; 611 814 612 815 static const struct of_device_id s3c_rtc_dt_match[] = { 613 816 { 614 817 .compatible = "samsung,s3c2410-rtc", 615 - .data = &s3c_rtc_drv_data_array[TYPE_S3C2410], 818 + .data = (void *)&s3c2410_rtc_data, 616 819 }, { 617 820 .compatible = "samsung,s3c2416-rtc", 618 - .data = &s3c_rtc_drv_data_array[TYPE_S3C2416], 821 + .data = (void *)&s3c2416_rtc_data, 619 822 }, { 620 823 .compatible = "samsung,s3c2443-rtc", 621 - .data = &s3c_rtc_drv_data_array[TYPE_S3C2443], 824 + .data = (void *)&s3c2443_rtc_data, 622 825 }, { 623 826 .compatible = "samsung,s3c6410-rtc", 624 - .data = &s3c_rtc_drv_data_array[TYPE_S3C64XX], 827 + .data = (void *)&s3c6410_rtc_data, 625 828 }, 626 - {}, 829 + { /* sentinel */ }, 627 830 }; 628 831 MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); 629 - #endif 630 - 631 - static struct platform_device_id s3c_rtc_driver_ids[] = { 632 - { 633 - .name = "s3c2410-rtc", 634 - .driver_data = TYPE_S3C2410, 635 - }, { 636 - .name = "s3c2416-rtc", 637 - .driver_data = TYPE_S3C2416, 638 - }, { 639 - .name = "s3c2443-rtc", 640 - .driver_data = TYPE_S3C2443, 641 - }, { 642 - .name = "s3c64xx-rtc", 643 - .driver_data = TYPE_S3C64XX, 644 - }, 645 - { } 646 - }; 647 - 648 - MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); 649 832 650 833 static struct platform_driver s3c_rtc_driver = { 651 834 .probe = s3c_rtc_probe, 652 835 .remove = s3c_rtc_remove, 653 - .id_table = s3c_rtc_driver_ids, 654 836 .driver = { 655 837 .name = "s3c-rtc", 656 838 .owner = THIS_MODULE, ··· 808 690 .of_match_table = of_match_ptr(s3c_rtc_dt_match), 809 691 }, 810 692 }; 811 - 812 693 module_platform_driver(s3c_rtc_driver); 813 694 814 695 MODULE_DESCRIPTION("Samsung S3C RTC Driver");