diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 5 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1302.c | 85 | ||||
-rw-r--r-- | drivers/rtc/rtc-isl1208.c | 45 | ||||
-rw-r--r-- | drivers/rtc/rtc-mxc.c | 25 | ||||
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 107 | ||||
-rw-r--r-- | drivers/rtc/rtc-wm831x.c | 16 |
7 files changed, 185 insertions, 100 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 50ac047cd136..f1598324344c 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -640,7 +640,7 @@ config RTC_DRV_OMAP | |||
640 | 640 | ||
641 | config RTC_DRV_S3C | 641 | config RTC_DRV_S3C |
642 | tristate "Samsung S3C series SoC RTC" | 642 | tristate "Samsung S3C series SoC RTC" |
643 | depends on ARCH_S3C2410 | 643 | depends on ARCH_S3C2410 || ARCH_S3C64XX |
644 | help | 644 | help |
645 | RTC (Realtime Clock) driver for the clock inbuilt into the | 645 | RTC (Realtime Clock) driver for the clock inbuilt into the |
646 | Samsung S3C24XX series of SoCs. This can provide periodic | 646 | Samsung S3C24XX series of SoCs. This can provide periodic |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 96e8e70fbf1e..11b8ea29d2b7 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -719,6 +719,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
719 | } | 719 | } |
720 | } | 720 | } |
721 | 721 | ||
722 | cmos_rtc.dev = dev; | ||
723 | dev_set_drvdata(dev, &cmos_rtc); | ||
724 | |||
722 | cmos_rtc.rtc = rtc_device_register(driver_name, dev, | 725 | cmos_rtc.rtc = rtc_device_register(driver_name, dev, |
723 | &cmos_rtc_ops, THIS_MODULE); | 726 | &cmos_rtc_ops, THIS_MODULE); |
724 | if (IS_ERR(cmos_rtc.rtc)) { | 727 | if (IS_ERR(cmos_rtc.rtc)) { |
@@ -726,8 +729,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
726 | goto cleanup0; | 729 | goto cleanup0; |
727 | } | 730 | } |
728 | 731 | ||
729 | cmos_rtc.dev = dev; | ||
730 | dev_set_drvdata(dev, &cmos_rtc); | ||
731 | rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); | 732 | rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); |
732 | 733 | ||
733 | spin_lock_irq(&rtc_lock); | 734 | spin_lock_irq(&rtc_lock); |
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 532acf9b05d8..359d1e04626c 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/bcd.h> | 18 | #include <linux/bcd.h> |
19 | #include <asm/rtc.h> | ||
20 | 19 | ||
21 | #define DRV_NAME "rtc-ds1302" | 20 | #define DRV_NAME "rtc-ds1302" |
22 | #define DRV_VERSION "0.1.1" | 21 | #define DRV_VERSION "0.1.1" |
@@ -34,14 +33,55 @@ | |||
34 | #define RTC_ADDR_MIN 0x01 /* Address of minute register */ | 33 | #define RTC_ADDR_MIN 0x01 /* Address of minute register */ |
35 | #define RTC_ADDR_SEC 0x00 /* Address of second register */ | 34 | #define RTC_ADDR_SEC 0x00 /* Address of second register */ |
36 | 35 | ||
36 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
37 | #include <asm/rtc.h> | ||
38 | #include <mach/snapgear.h> | ||
39 | |||
37 | #define RTC_RESET 0x1000 | 40 | #define RTC_RESET 0x1000 |
38 | #define RTC_IODATA 0x0800 | 41 | #define RTC_IODATA 0x0800 |
39 | #define RTC_SCLK 0x0400 | 42 | #define RTC_SCLK 0x0400 |
40 | 43 | ||
41 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
42 | #include <mach/snapgear.h> | ||
43 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) | 44 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) |
44 | #define get_dp() SECUREEDGE_READ_IOPORT() | 45 | #define get_dp() SECUREEDGE_READ_IOPORT() |
46 | #define ds1302_set_tx() | ||
47 | #define ds1302_set_rx() | ||
48 | |||
49 | static inline int ds1302_hw_init(void) | ||
50 | { | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static inline void ds1302_reset(void) | ||
55 | { | ||
56 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | ||
57 | } | ||
58 | |||
59 | static inline void ds1302_clock(void) | ||
60 | { | ||
61 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
62 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
63 | } | ||
64 | |||
65 | static inline void ds1302_start(void) | ||
66 | { | ||
67 | set_dp(get_dp() | RTC_RESET); | ||
68 | } | ||
69 | |||
70 | static inline void ds1302_stop(void) | ||
71 | { | ||
72 | set_dp(get_dp() & ~RTC_RESET); | ||
73 | } | ||
74 | |||
75 | static inline void ds1302_txbit(int bit) | ||
76 | { | ||
77 | set_dp((get_dp() & ~RTC_IODATA) | (bit ? RTC_IODATA : 0)); | ||
78 | } | ||
79 | |||
80 | static inline int ds1302_rxbit(void) | ||
81 | { | ||
82 | return !!(get_dp() & RTC_IODATA); | ||
83 | } | ||
84 | |||
45 | #else | 85 | #else |
46 | #error "Add support for your platform" | 86 | #error "Add support for your platform" |
47 | #endif | 87 | #endif |
@@ -50,11 +90,11 @@ static void ds1302_sendbits(unsigned int val) | |||
50 | { | 90 | { |
51 | int i; | 91 | int i; |
52 | 92 | ||
93 | ds1302_set_tx(); | ||
94 | |||
53 | for (i = 8; (i); i--, val >>= 1) { | 95 | for (i = 8; (i); i--, val >>= 1) { |
54 | set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? | 96 | ds1302_txbit(val & 0x1); |
55 | RTC_IODATA : 0)); | 97 | ds1302_clock(); |
56 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
57 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
58 | } | 98 | } |
59 | } | 99 | } |
60 | 100 | ||
@@ -63,10 +103,11 @@ static unsigned int ds1302_recvbits(void) | |||
63 | unsigned int val; | 103 | unsigned int val; |
64 | int i; | 104 | int i; |
65 | 105 | ||
106 | ds1302_set_rx(); | ||
107 | |||
66 | for (i = 0, val = 0; (i < 8); i++) { | 108 | for (i = 0, val = 0; (i < 8); i++) { |
67 | val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i); | 109 | val |= (ds1302_rxbit() << i); |
68 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | 110 | ds1302_clock(); |
69 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
70 | } | 111 | } |
71 | 112 | ||
72 | return val; | 113 | return val; |
@@ -76,23 +117,24 @@ static unsigned int ds1302_readbyte(unsigned int addr) | |||
76 | { | 117 | { |
77 | unsigned int val; | 118 | unsigned int val; |
78 | 119 | ||
79 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 120 | ds1302_reset(); |
80 | 121 | ||
81 | set_dp(get_dp() | RTC_RESET); | 122 | ds1302_start(); |
82 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); | 123 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); |
83 | val = ds1302_recvbits(); | 124 | val = ds1302_recvbits(); |
84 | set_dp(get_dp() & ~RTC_RESET); | 125 | ds1302_stop(); |
85 | 126 | ||
86 | return val; | 127 | return val; |
87 | } | 128 | } |
88 | 129 | ||
89 | static void ds1302_writebyte(unsigned int addr, unsigned int val) | 130 | static void ds1302_writebyte(unsigned int addr, unsigned int val) |
90 | { | 131 | { |
91 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 132 | ds1302_reset(); |
92 | set_dp(get_dp() | RTC_RESET); | 133 | |
134 | ds1302_start(); | ||
93 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); | 135 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); |
94 | ds1302_sendbits(val); | 136 | ds1302_sendbits(val); |
95 | set_dp(get_dp() & ~RTC_RESET); | 137 | ds1302_stop(); |
96 | } | 138 | } |
97 | 139 | ||
98 | static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) | 140 | static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) |
@@ -167,13 +209,20 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev) | |||
167 | { | 209 | { |
168 | struct rtc_device *rtc; | 210 | struct rtc_device *rtc; |
169 | 211 | ||
212 | if (ds1302_hw_init()) { | ||
213 | dev_err(&pdev->dev, "Failed to init communication channel"); | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
170 | /* Reset */ | 217 | /* Reset */ |
171 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 218 | ds1302_reset(); |
172 | 219 | ||
173 | /* Write a magic value to the DS1302 RAM, and see if it sticks. */ | 220 | /* Write a magic value to the DS1302 RAM, and see if it sticks. */ |
174 | ds1302_writebyte(RTC_ADDR_RAM0, 0x42); | 221 | ds1302_writebyte(RTC_ADDR_RAM0, 0x42); |
175 | if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) | 222 | if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) { |
223 | dev_err(&pdev->dev, "Failed to probe"); | ||
176 | return -ENODEV; | 224 | return -ENODEV; |
225 | } | ||
177 | 226 | ||
178 | rtc = rtc_device_register("ds1302", &pdev->dev, | 227 | rtc = rtc_device_register("ds1302", &pdev->dev, |
179 | &ds1302_rtc_ops, THIS_MODULE); | 228 | &ds1302_rtc_ops, THIS_MODULE); |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 054e05294af8..468200c38ecb 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -462,39 +462,16 @@ isl1208_sysfs_store_usr(struct device *dev, | |||
462 | static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, | 462 | static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, |
463 | isl1208_sysfs_store_usr); | 463 | isl1208_sysfs_store_usr); |
464 | 464 | ||
465 | static int | 465 | static struct attribute *isl1208_rtc_attrs[] = { |
466 | isl1208_sysfs_register(struct device *dev) | 466 | &dev_attr_atrim.attr, |
467 | { | 467 | &dev_attr_dtrim.attr, |
468 | int err; | 468 | &dev_attr_usr.attr, |
469 | 469 | NULL | |
470 | err = device_create_file(dev, &dev_attr_atrim); | 470 | }; |
471 | if (err) | ||
472 | return err; | ||
473 | |||
474 | err = device_create_file(dev, &dev_attr_dtrim); | ||
475 | if (err) { | ||
476 | device_remove_file(dev, &dev_attr_atrim); | ||
477 | return err; | ||
478 | } | ||
479 | |||
480 | err = device_create_file(dev, &dev_attr_usr); | ||
481 | if (err) { | ||
482 | device_remove_file(dev, &dev_attr_atrim); | ||
483 | device_remove_file(dev, &dev_attr_dtrim); | ||
484 | } | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | static int | ||
490 | isl1208_sysfs_unregister(struct device *dev) | ||
491 | { | ||
492 | device_remove_file(dev, &dev_attr_dtrim); | ||
493 | device_remove_file(dev, &dev_attr_atrim); | ||
494 | device_remove_file(dev, &dev_attr_usr); | ||
495 | 471 | ||
496 | return 0; | 472 | static const struct attribute_group isl1208_rtc_sysfs_files = { |
497 | } | 473 | .attrs = isl1208_rtc_attrs, |
474 | }; | ||
498 | 475 | ||
499 | static int | 476 | static int |
500 | isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | 477 | isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) |
@@ -529,7 +506,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
529 | dev_warn(&client->dev, "rtc power failure detected, " | 506 | dev_warn(&client->dev, "rtc power failure detected, " |
530 | "please set clock.\n"); | 507 | "please set clock.\n"); |
531 | 508 | ||
532 | rc = isl1208_sysfs_register(&client->dev); | 509 | rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); |
533 | if (rc) | 510 | if (rc) |
534 | goto exit_unregister; | 511 | goto exit_unregister; |
535 | 512 | ||
@@ -546,7 +523,7 @@ isl1208_remove(struct i2c_client *client) | |||
546 | { | 523 | { |
547 | struct rtc_device *rtc = i2c_get_clientdata(client); | 524 | struct rtc_device *rtc = i2c_get_clientdata(client); |
548 | 525 | ||
549 | isl1208_sysfs_unregister(&client->dev); | 526 | sysfs_remove_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); |
550 | rtc_device_unregister(rtc); | 527 | rtc_device_unregister(rtc); |
551 | 528 | ||
552 | return 0; | 529 | return 0; |
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index d71fe61db1d6..25ec921db07c 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c | |||
@@ -379,7 +379,6 @@ static struct rtc_class_ops mxc_rtc_ops = { | |||
379 | 379 | ||
380 | static int __init mxc_rtc_probe(struct platform_device *pdev) | 380 | static int __init mxc_rtc_probe(struct platform_device *pdev) |
381 | { | 381 | { |
382 | struct clk *clk; | ||
383 | struct resource *res; | 382 | struct resource *res; |
384 | struct rtc_device *rtc; | 383 | struct rtc_device *rtc; |
385 | struct rtc_plat_data *pdata = NULL; | 384 | struct rtc_plat_data *pdata = NULL; |
@@ -402,14 +401,15 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
402 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, | 401 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, |
403 | resource_size(res)); | 402 | resource_size(res)); |
404 | 403 | ||
405 | clk = clk_get(&pdev->dev, "ckil"); | 404 | pdata->clk = clk_get(&pdev->dev, "rtc"); |
406 | if (IS_ERR(clk)) { | 405 | if (IS_ERR(pdata->clk)) { |
407 | ret = PTR_ERR(clk); | 406 | dev_err(&pdev->dev, "unable to get clock!\n"); |
407 | ret = PTR_ERR(pdata->clk); | ||
408 | goto exit_free_pdata; | 408 | goto exit_free_pdata; |
409 | } | 409 | } |
410 | 410 | ||
411 | rate = clk_get_rate(clk); | 411 | clk_enable(pdata->clk); |
412 | clk_put(clk); | 412 | rate = clk_get_rate(pdata->clk); |
413 | 413 | ||
414 | if (rate == 32768) | 414 | if (rate == 32768) |
415 | reg = RTC_INPUT_CLK_32768HZ; | 415 | reg = RTC_INPUT_CLK_32768HZ; |
@@ -420,7 +420,7 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
420 | else { | 420 | else { |
421 | dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); | 421 | dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); |
422 | ret = -EINVAL; | 422 | ret = -EINVAL; |
423 | goto exit_free_pdata; | 423 | goto exit_put_clk; |
424 | } | 424 | } |
425 | 425 | ||
426 | reg |= RTC_ENABLE_BIT; | 426 | reg |= RTC_ENABLE_BIT; |
@@ -428,18 +428,9 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
428 | if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { | 428 | if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { |
429 | dev_err(&pdev->dev, "hardware module can't be enabled!\n"); | 429 | dev_err(&pdev->dev, "hardware module can't be enabled!\n"); |
430 | ret = -EIO; | 430 | ret = -EIO; |
431 | goto exit_free_pdata; | 431 | goto exit_put_clk; |
432 | } | ||
433 | |||
434 | pdata->clk = clk_get(&pdev->dev, "rtc"); | ||
435 | if (IS_ERR(pdata->clk)) { | ||
436 | dev_err(&pdev->dev, "unable to get clock!\n"); | ||
437 | ret = PTR_ERR(pdata->clk); | ||
438 | goto exit_free_pdata; | ||
439 | } | 432 | } |
440 | 433 | ||
441 | clk_enable(pdata->clk); | ||
442 | |||
443 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, | 434 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, |
444 | THIS_MODULE); | 435 | THIS_MODULE); |
445 | if (IS_ERR(rtc)) { | 436 | if (IS_ERR(rtc)) { |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 4969b6059c89..e5972b2c17b7 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -29,6 +29,11 @@ | |||
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | #include <plat/regs-rtc.h> | 30 | #include <plat/regs-rtc.h> |
31 | 31 | ||
32 | enum s3c_cpu_type { | ||
33 | TYPE_S3C2410, | ||
34 | TYPE_S3C64XX, | ||
35 | }; | ||
36 | |||
32 | /* I have yet to find an S3C implementation with more than one | 37 | /* I have yet to find an S3C implementation with more than one |
33 | * of these rtc blocks in */ | 38 | * of these rtc blocks in */ |
34 | 39 | ||
@@ -37,6 +42,7 @@ static struct resource *s3c_rtc_mem; | |||
37 | static void __iomem *s3c_rtc_base; | 42 | static void __iomem *s3c_rtc_base; |
38 | static int s3c_rtc_alarmno = NO_IRQ; | 43 | static int s3c_rtc_alarmno = NO_IRQ; |
39 | static int s3c_rtc_tickno = NO_IRQ; | 44 | static int s3c_rtc_tickno = NO_IRQ; |
45 | static enum s3c_cpu_type s3c_rtc_cpu_type; | ||
40 | 46 | ||
41 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); | 47 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); |
42 | 48 | ||
@@ -80,12 +86,25 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) | |||
80 | pr_debug("%s: pie=%d\n", __func__, enabled); | 86 | pr_debug("%s: pie=%d\n", __func__, enabled); |
81 | 87 | ||
82 | spin_lock_irq(&s3c_rtc_pie_lock); | 88 | spin_lock_irq(&s3c_rtc_pie_lock); |
83 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; | ||
84 | 89 | ||
85 | if (enabled) | 90 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
86 | tmp |= S3C2410_TICNT_ENABLE; | 91 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); |
92 | tmp &= ~S3C64XX_RTCCON_TICEN; | ||
93 | |||
94 | if (enabled) | ||
95 | tmp |= S3C64XX_RTCCON_TICEN; | ||
96 | |||
97 | writeb(tmp, s3c_rtc_base + S3C2410_RTCCON); | ||
98 | } else { | ||
99 | tmp = readb(s3c_rtc_base + S3C2410_TICNT); | ||
100 | tmp &= ~S3C2410_TICNT_ENABLE; | ||
101 | |||
102 | if (enabled) | ||
103 | tmp |= S3C2410_TICNT_ENABLE; | ||
104 | |||
105 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | ||
106 | } | ||
87 | 107 | ||
88 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | ||
89 | spin_unlock_irq(&s3c_rtc_pie_lock); | 108 | spin_unlock_irq(&s3c_rtc_pie_lock); |
90 | 109 | ||
91 | return 0; | 110 | return 0; |
@@ -93,15 +112,21 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) | |||
93 | 112 | ||
94 | static int s3c_rtc_setfreq(struct device *dev, int freq) | 113 | static int s3c_rtc_setfreq(struct device *dev, int freq) |
95 | { | 114 | { |
96 | unsigned int tmp; | 115 | struct platform_device *pdev = to_platform_device(dev); |
116 | struct rtc_device *rtc_dev = platform_get_drvdata(pdev); | ||
117 | unsigned int tmp = 0; | ||
97 | 118 | ||
98 | if (!is_power_of_2(freq)) | 119 | if (!is_power_of_2(freq)) |
99 | return -EINVAL; | 120 | return -EINVAL; |
100 | 121 | ||
101 | spin_lock_irq(&s3c_rtc_pie_lock); | 122 | spin_lock_irq(&s3c_rtc_pie_lock); |
102 | 123 | ||
103 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | 124 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { |
104 | tmp |= (128 / freq)-1; | 125 | tmp = readb(s3c_rtc_base + S3C2410_TICNT); |
126 | tmp &= S3C2410_TICNT_ENABLE; | ||
127 | } | ||
128 | |||
129 | tmp |= (rtc_dev->max_user_freq / freq)-1; | ||
105 | 130 | ||
106 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | 131 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
107 | spin_unlock_irq(&s3c_rtc_pie_lock); | 132 | spin_unlock_irq(&s3c_rtc_pie_lock); |
@@ -283,10 +308,17 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
283 | 308 | ||
284 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | 309 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) |
285 | { | 310 | { |
286 | unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | 311 | unsigned int ticnt; |
287 | 312 | ||
288 | seq_printf(seq, "periodic_IRQ\t: %s\n", | 313 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
289 | (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); | 314 | ticnt = readb(s3c_rtc_base + S3C2410_RTCCON); |
315 | ticnt &= S3C64XX_RTCCON_TICEN; | ||
316 | } else { | ||
317 | ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | ||
318 | ticnt &= S3C2410_TICNT_ENABLE; | ||
319 | } | ||
320 | |||
321 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); | ||
290 | return 0; | 322 | return 0; |
291 | } | 323 | } |
292 | 324 | ||
@@ -353,10 +385,16 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
353 | 385 | ||
354 | if (!en) { | 386 | if (!en) { |
355 | tmp = readb(base + S3C2410_RTCCON); | 387 | tmp = readb(base + S3C2410_RTCCON); |
356 | writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON); | 388 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
357 | 389 | tmp &= ~S3C64XX_RTCCON_TICEN; | |
358 | tmp = readb(base + S3C2410_TICNT); | 390 | tmp &= ~S3C2410_RTCCON_RTCEN; |
359 | writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT); | 391 | writeb(tmp, base + S3C2410_RTCCON); |
392 | |||
393 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { | ||
394 | tmp = readb(base + S3C2410_TICNT); | ||
395 | tmp &= ~S3C2410_TICNT_ENABLE; | ||
396 | writeb(tmp, base + S3C2410_TICNT); | ||
397 | } | ||
360 | } else { | 398 | } else { |
361 | /* re-enable the device, and check it is ok */ | 399 | /* re-enable the device, and check it is ok */ |
362 | 400 | ||
@@ -472,7 +510,12 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
472 | goto err_nortc; | 510 | goto err_nortc; |
473 | } | 511 | } |
474 | 512 | ||
475 | rtc->max_user_freq = 128; | 513 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
514 | rtc->max_user_freq = 32768; | ||
515 | else | ||
516 | rtc->max_user_freq = 128; | ||
517 | |||
518 | s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; | ||
476 | 519 | ||
477 | platform_set_drvdata(pdev, rtc); | 520 | platform_set_drvdata(pdev, rtc); |
478 | return 0; | 521 | return 0; |
@@ -492,20 +535,30 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
492 | 535 | ||
493 | /* RTC Power management control */ | 536 | /* RTC Power management control */ |
494 | 537 | ||
495 | static int ticnt_save; | 538 | static int ticnt_save, ticnt_en_save; |
496 | 539 | ||
497 | static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 540 | static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
498 | { | 541 | { |
499 | /* save TICNT for anyone using periodic interrupts */ | 542 | /* save TICNT for anyone using periodic interrupts */ |
500 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | 543 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); |
544 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | ||
545 | ticnt_en_save = readb(s3c_rtc_base + S3C2410_RTCCON); | ||
546 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; | ||
547 | } | ||
501 | s3c_rtc_enable(pdev, 0); | 548 | s3c_rtc_enable(pdev, 0); |
502 | return 0; | 549 | return 0; |
503 | } | 550 | } |
504 | 551 | ||
505 | static int s3c_rtc_resume(struct platform_device *pdev) | 552 | static int s3c_rtc_resume(struct platform_device *pdev) |
506 | { | 553 | { |
554 | unsigned int tmp; | ||
555 | |||
507 | s3c_rtc_enable(pdev, 1); | 556 | s3c_rtc_enable(pdev, 1); |
508 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | 557 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); |
558 | if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { | ||
559 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); | ||
560 | writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); | ||
561 | } | ||
509 | return 0; | 562 | return 0; |
510 | } | 563 | } |
511 | #else | 564 | #else |
@@ -513,13 +566,27 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
513 | #define s3c_rtc_resume NULL | 566 | #define s3c_rtc_resume NULL |
514 | #endif | 567 | #endif |
515 | 568 | ||
516 | static struct platform_driver s3c2410_rtc_driver = { | 569 | static struct platform_device_id s3c_rtc_driver_ids[] = { |
570 | { | ||
571 | .name = "s3c2410-rtc", | ||
572 | .driver_data = TYPE_S3C2410, | ||
573 | }, { | ||
574 | .name = "s3c64xx-rtc", | ||
575 | .driver_data = TYPE_S3C64XX, | ||
576 | }, | ||
577 | { } | ||
578 | }; | ||
579 | |||
580 | MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); | ||
581 | |||
582 | static struct platform_driver s3c_rtc_driver = { | ||
517 | .probe = s3c_rtc_probe, | 583 | .probe = s3c_rtc_probe, |
518 | .remove = __devexit_p(s3c_rtc_remove), | 584 | .remove = __devexit_p(s3c_rtc_remove), |
519 | .suspend = s3c_rtc_suspend, | 585 | .suspend = s3c_rtc_suspend, |
520 | .resume = s3c_rtc_resume, | 586 | .resume = s3c_rtc_resume, |
587 | .id_table = s3c_rtc_driver_ids, | ||
521 | .driver = { | 588 | .driver = { |
522 | .name = "s3c2410-rtc", | 589 | .name = "s3c-rtc", |
523 | .owner = THIS_MODULE, | 590 | .owner = THIS_MODULE, |
524 | }, | 591 | }, |
525 | }; | 592 | }; |
@@ -529,12 +596,12 @@ static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics | |||
529 | static int __init s3c_rtc_init(void) | 596 | static int __init s3c_rtc_init(void) |
530 | { | 597 | { |
531 | printk(banner); | 598 | printk(banner); |
532 | return platform_driver_register(&s3c2410_rtc_driver); | 599 | return platform_driver_register(&s3c_rtc_driver); |
533 | } | 600 | } |
534 | 601 | ||
535 | static void __exit s3c_rtc_exit(void) | 602 | static void __exit s3c_rtc_exit(void) |
536 | { | 603 | { |
537 | platform_driver_unregister(&s3c2410_rtc_driver); | 604 | platform_driver_unregister(&s3c_rtc_driver); |
538 | } | 605 | } |
539 | 606 | ||
540 | module_init(s3c_rtc_init); | 607 | module_init(s3c_rtc_init); |
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index b16cfe57a484..82931dc65c0b 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c | |||
@@ -449,17 +449,17 @@ static int wm831x_rtc_probe(struct platform_device *pdev) | |||
449 | goto err; | 449 | goto err; |
450 | } | 450 | } |
451 | 451 | ||
452 | ret = wm831x_request_irq(wm831x, per_irq, wm831x_per_irq, | 452 | ret = request_threaded_irq(per_irq, NULL, wm831x_per_irq, |
453 | IRQF_TRIGGER_RISING, "wm831x_rtc_per", | 453 | IRQF_TRIGGER_RISING, "RTC period", |
454 | wm831x_rtc); | 454 | wm831x_rtc); |
455 | if (ret != 0) { | 455 | if (ret != 0) { |
456 | dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n", | 456 | dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n", |
457 | per_irq, ret); | 457 | per_irq, ret); |
458 | } | 458 | } |
459 | 459 | ||
460 | ret = wm831x_request_irq(wm831x, alm_irq, wm831x_alm_irq, | 460 | ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq, |
461 | IRQF_TRIGGER_RISING, "wm831x_rtc_alm", | 461 | IRQF_TRIGGER_RISING, "RTC alarm", |
462 | wm831x_rtc); | 462 | wm831x_rtc); |
463 | if (ret != 0) { | 463 | if (ret != 0) { |
464 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", | 464 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", |
465 | alm_irq, ret); | 465 | alm_irq, ret); |
@@ -478,8 +478,8 @@ static int __devexit wm831x_rtc_remove(struct platform_device *pdev) | |||
478 | int per_irq = platform_get_irq_byname(pdev, "PER"); | 478 | int per_irq = platform_get_irq_byname(pdev, "PER"); |
479 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); | 479 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); |
480 | 480 | ||
481 | wm831x_free_irq(wm831x_rtc->wm831x, alm_irq, wm831x_rtc); | 481 | free_irq(alm_irq, wm831x_rtc); |
482 | wm831x_free_irq(wm831x_rtc->wm831x, per_irq, wm831x_rtc); | 482 | free_irq(per_irq, wm831x_rtc); |
483 | rtc_device_unregister(wm831x_rtc->rtc); | 483 | rtc_device_unregister(wm831x_rtc->rtc); |
484 | kfree(wm831x_rtc); | 484 | kfree(wm831x_rtc); |
485 | 485 | ||