From bd729d72b428261f2975360e0c117d7d7a2cd6e8 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 5 Jan 2012 15:21:19 -0800 Subject: rtc: Avoid setting alarm to a time in the past In some cases at boot up, the RTC alarm may be set in the past, but still have the enabled flag on. This was causing problems, because we would then enqueue the alarm into the timerqueue, but it would never fire. This would clog up the timerqueue and keep other alarms from working. The fix is to check the alarm against the current rtc time at boot and avoid enqueueing the alarm if it is in the past. Reported-by: NeilBrown Tested-by: NeilBrown Tested-by: Sander Eikelenboom Signed-off-by: John Stultz --- drivers/rtc/interface.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8a1c031391d6..c55a16041b6e 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -380,18 +380,27 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm); int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) { int err; + struct rtc_time now; err = rtc_valid_tm(&alarm->time); if (err != 0) return err; + err = rtc_read_time(rtc, &now); + if (err) + return err; + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); rtc->aie_timer.period = ktime_set(0, 0); - if (alarm->enabled) { + + /* Alarm has to be enabled & in the futrure for us to enqueue it */ + if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 < + rtc->aie_timer.node.expires.tv64)) { + rtc->aie_timer.enabled = 1; timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); } -- cgit v1.2.3 From 5f9679d29c7959445d4af1eb85ee55e4ebad4a93 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Dec 2011 09:39:15 +1100 Subject: rtc: Expire alarms after the time is set. (v2) If the alarm time programming in the rtc is ever in the past, it won't fire, and any other alarm will be queued after it so they won't fire either. So any time that the alarm might be in the past, we need to trigger the irq handler to ensure the old alarm is cleared and the timer queue is fully in the future. This is done whenever the RTC clock is set. This is the second revision of this patch, which was earlier reverted. This version avoids the initialization problem, which is handled by a different patch. Tested-by: Sander Eikelenboom Signed-off-by: NeilBrown [Remove problematic initialization change, update commit log, also catch set_mmss case -jstultz] Signed-off-by: John Stultz --- drivers/rtc/interface.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index c55a16041b6e..167e68a9ffda 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -73,6 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) err = -EINVAL; mutex_unlock(&rtc->ops_lock); + /* A timer might have just expired */ + schedule_work(&rtc->irqwork); return err; } EXPORT_SYMBOL_GPL(rtc_set_time); @@ -112,6 +114,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) err = -EINVAL; mutex_unlock(&rtc->ops_lock); + /* A timer might have just expired */ + schedule_work(&rtc->irqwork); return err; } -- cgit v1.2.3 From 41c7f7424259ff11009449f87c95656f69f9b186 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 22 Nov 2011 11:03:14 +0100 Subject: rtc: Disable the alarm in the hardware (v2) Currently, the RTC code does not disable the alarm in the hardware. This means that after a sequence such as the one below (the files are in the RTC sysfs), the box will boot up after 2 minutes even though we've asked for the alarm to be turned off. # echo $((`cat since_epoch`)+120) > wakealarm # echo 0 > wakealarm # poweroff Fix this by disabling the alarm when there are no timers to run. The original version of this patch was reverted. This version disables the irq directly instead of setting a disabled timer in the future. Cc: stable@kernel.org Cc: John Stultz Signed-off-by: Rabin Vincent [Merged in the second revision from Rabin] Signed-off-by: John Stultz --- drivers/rtc/interface.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 167e68a9ffda..dc87eda65814 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -776,6 +776,14 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) return 0; } +static void rtc_alarm_disable(struct rtc_device *rtc) +{ + if (!rtc->ops || !rtc->ops->alarm_irq_enable) + return; + + rtc->ops->alarm_irq_enable(rtc->dev.parent, false); +} + /** * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue * @rtc rtc device @@ -797,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) struct rtc_wkalrm alarm; int err; next = timerqueue_getnext(&rtc->timerqueue); - if (!next) + if (!next) { + rtc_alarm_disable(rtc); return; + } alarm.time = rtc_ktime_to_tm(next->expires); alarm.enabled = 1; err = __rtc_set_alarm(rtc, &alarm); @@ -860,7 +870,8 @@ again: err = __rtc_set_alarm(rtc, &alarm); if (err == -ETIME) goto again; - } + } else + rtc_alarm_disable(rtc); mutex_unlock(&rtc->ops_lock); } -- cgit v1.2.3 From 9e5ed094c89e55fbf11d2e81d60be98eb12346c0 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 15 Mar 2012 10:40:38 +0100 Subject: ARM: 7362/1: AMBA: Add module_amba_driver() helper macro for amba_driver For simple modules that contain a single amba_driver without any additional setup code then ends up being a block of duplicated boilerplate. This patch adds a new macro, module_amba_driver(), which replaces the module_init()/module_exit() registrations with template functions. Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- drivers/char/hw_random/nomadik-rng.c | 13 +------------ drivers/dma/pl330.c | 13 +------------ drivers/input/serio/ambakmi.c | 13 +------------ drivers/mmc/host/mmci.c | 12 +----------- drivers/rtc/rtc-pl030.c | 13 +------------ drivers/rtc/rtc-pl031.c | 13 +------------ drivers/watchdog/sp805_wdt.c | 12 +----------- include/linux/amba/bus.h | 9 +++++++++ sound/arm/aaci.c | 13 +------------ 9 files changed, 17 insertions(+), 94 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/char/hw_random/nomadik-rng.c b/drivers/char/hw_random/nomadik-rng.c index 3d3c1e6703b4..96de0249e595 100644 --- a/drivers/char/hw_random/nomadik-rng.c +++ b/drivers/char/hw_random/nomadik-rng.c @@ -107,17 +107,6 @@ static struct amba_driver nmk_rng_driver = { .id_table = nmk_rng_ids, }; -static int __init nmk_rng_init(void) -{ - return amba_driver_register(&nmk_rng_driver); -} - -static void __devexit nmk_rng_exit(void) -{ - amba_driver_unregister(&nmk_rng_driver); -} - -module_init(nmk_rng_init); -module_exit(nmk_rng_exit); +module_amba_driver(nmk_rng_driver); MODULE_LICENSE("GPL"); diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index b8ec03ee8e22..16b66c827f19 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1035,18 +1035,7 @@ static struct amba_driver pl330_driver = { .remove = pl330_remove, }; -static int __init pl330_init(void) -{ - return amba_driver_register(&pl330_driver); -} -module_init(pl330_init); - -static void __exit pl330_exit(void) -{ - amba_driver_unregister(&pl330_driver); - return; -} -module_exit(pl330_exit); +module_amba_driver(pl330_driver); MODULE_AUTHOR("Jaswinder Singh "); MODULE_DESCRIPTION("API Driver for PL330 DMAC"); diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 8407d5b0ced8..2ffd110bd5bc 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c @@ -208,18 +208,7 @@ static struct amba_driver ambakmi_driver = { .resume = amba_kmi_resume, }; -static int __init amba_kmi_init(void) -{ - return amba_driver_register(&ambakmi_driver); -} - -static void __exit amba_kmi_exit(void) -{ - amba_driver_unregister(&ambakmi_driver); -} - -module_init(amba_kmi_init); -module_exit(amba_kmi_exit); +module_amba_driver(ambakmi_driver); MODULE_AUTHOR("Russell King "); MODULE_DESCRIPTION("AMBA KMI controller driver"); diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 304f2f98b680..6692392c05dd 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1519,18 +1519,8 @@ static struct amba_driver mmci_driver = { .id_table = mmci_ids, }; -static int __init mmci_init(void) -{ - return amba_driver_register(&mmci_driver); -} - -static void __exit mmci_exit(void) -{ - amba_driver_unregister(&mmci_driver); -} +module_amba_driver(mmci_driver); -module_init(mmci_init); -module_exit(mmci_exit); module_param(fmax, uint, 0444); MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index 02111fee077e..b2d3d20baebc 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c @@ -185,18 +185,7 @@ static struct amba_driver pl030_driver = { .id_table = pl030_ids, }; -static int __init pl030_init(void) -{ - return amba_driver_register(&pl030_driver); -} - -static void __exit pl030_exit(void) -{ - amba_driver_unregister(&pl030_driver); -} - -module_init(pl030_init); -module_exit(pl030_exit); +module_amba_driver(pl030_driver); MODULE_AUTHOR("Russell King "); MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver"); diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index a952c8de1dd7..359e2c53c545 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -431,18 +431,7 @@ static struct amba_driver pl031_driver = { .remove = pl031_remove, }; -static int __init pl031_init(void) -{ - return amba_driver_register(&pl031_driver); -} - -static void __exit pl031_exit(void) -{ - amba_driver_unregister(&pl031_driver); -} - -module_init(pl031_init); -module_exit(pl031_exit); +module_amba_driver(pl031_driver); MODULE_AUTHOR("Deepak Saxena Date: Fri, 23 Mar 2012 15:02:29 -0700 Subject: rtc-spear: fix for balancing the enable_irq_wake in Power Mgmt Handle the fix for unbalanced irq for the cases when enable_irq_wake fails, and a warning related to same is displayed on the console. The workaround is handled at the driver level. Signed-off-by: Deepak Sikri Signed-off-by: Viresh Kumar Acked-by: Rajeev Kumar Cc: Shiraz Hashim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-spear.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index 19a28a671a8e..4f068e9ec0f8 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c @@ -80,6 +80,7 @@ struct spear_rtc_config { struct clk *clk; spinlock_t lock; void __iomem *ioaddr; + unsigned int irq_wake; }; static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config) @@ -463,9 +464,10 @@ static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) int irq; irq = platform_get_irq(pdev, 0); - if (device_may_wakeup(&pdev->dev)) - enable_irq_wake(irq); - else { + if (device_may_wakeup(&pdev->dev)) { + if (!enable_irq_wake(irq)) + config->irq_wake = 1; + } else { spear_rtc_disable_interrupt(config); clk_disable(config->clk); } @@ -481,9 +483,12 @@ static int spear_rtc_resume(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); - if (device_may_wakeup(&pdev->dev)) - disable_irq_wake(irq); - else { + if (device_may_wakeup(&pdev->dev)) { + if (config->irq_wake) { + disable_irq_wake(irq); + config->irq_wake = 0; + } + } else { clk_enable(config->clk); spear_rtc_enable_interrupt(config); } -- cgit v1.2.3 From 131f8b75f1c00a5a822ff2103db588466e942490 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Fri, 23 Mar 2012 15:02:29 -0700 Subject: rtc/spear: fix for RTC_AIE_ON and RTC_AIE_OFF ioctl errors Define API for '.alarm_irq_enable' to enable and disable alarm irq. This is required by the framework else RTC_AIE_ON and RTC_AIE_OFF ioctls return errors. Signed-off-by: Shiraz Hashim Signed-off-by: Viresh Kumar Cc: Deepak Sikri Acked-by: Rajeev Kumar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-spear.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index 4f068e9ec0f8..646937473515 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c @@ -327,11 +327,39 @@ static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) return 0; } + +static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rtc_device *rtc = platform_get_drvdata(pdev); + struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + int ret = 0; + + spear_rtc_clear_interrupt(config); + + switch (enabled) { + case 0: + /* alarm off */ + spear_rtc_disable_interrupt(config); + break; + case 1: + /* alarm on */ + spear_rtc_enable_interrupt(config); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + static struct rtc_class_ops spear_rtc_ops = { .read_time = spear_rtc_read_time, .set_time = spear_rtc_set_time, .read_alarm = spear_rtc_read_alarm, .set_alarm = spear_rtc_set_alarm, + .alarm_irq_enable = spear_alarm_irq_enable, }; static int __devinit spear_rtc_probe(struct platform_device *pdev) -- cgit v1.2.3 From ee6c54ca64416c75aa6f5021e139f270192bae49 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 23 Mar 2012 15:02:30 -0700 Subject: rtc/rtc-spear: call platform_set_drvdata() before registering rtc device rtc_device_register() calls rtc-spear routines internally. These routines call dev_get_drvdata() to get struct spear_rtc_config. Currently, platform_set_drvdata is called after rtc device is registered. This causes system to crash, as dev_get_drvdata returns NULL. For this we need to call platform_set_drvdata() before registering rtc device. This requires further cleanup, that leads to removal of dev_set_drvdata on rtc->dev, which was just not required at all. Also, we change the parameter to request_irq and pass pointer to config instead of pointer to rtc struct. This patch brings all above changes. Signed-off-by: Viresh Kumar Cc: Shiraz Hashim Cc: Deepak Sikri Acked-by: Rajeev Kumar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-spear.c | 61 +++++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 40 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index 646937473515..e38da0dc4187 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c @@ -77,6 +77,7 @@ #define STATUS_FAIL (LOST_WR_TIME | LOST_WR_DATE) struct spear_rtc_config { + struct rtc_device *rtc; struct clk *clk; spinlock_t lock; void __iomem *ioaddr; @@ -150,8 +151,7 @@ static void rtc_wait_not_busy(struct spear_rtc_config *config) static irqreturn_t spear_rtc_irq(int irq, void *dev_id) { - struct rtc_device *rtc = (struct rtc_device *)dev_id; - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = dev_id; unsigned long flags, events = 0; unsigned int irq_data; @@ -162,7 +162,7 @@ static irqreturn_t spear_rtc_irq(int irq, void *dev_id) if ((irq_data & RTC_INT_MASK)) { spear_rtc_clear_interrupt(config); events = RTC_IRQF | RTC_AF; - rtc_update_irq(rtc, 1, events); + rtc_update_irq(config->rtc, 1, events); return IRQ_HANDLED; } else return IRQ_NONE; @@ -204,9 +204,7 @@ static void bcd2tm(struct rtc_time *tm) */ static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc = platform_get_drvdata(pdev); - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = dev_get_drvdata(dev); unsigned int time, date; /* we don't report wday/yday/isdst ... */ @@ -235,9 +233,7 @@ static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm) */ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc = platform_get_drvdata(pdev); - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = dev_get_drvdata(dev); unsigned int time, date, err = 0; if (tm2bcd(tm) < 0) @@ -267,9 +263,7 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) */ static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc = platform_get_drvdata(pdev); - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = dev_get_drvdata(dev); unsigned int time, date; rtc_wait_not_busy(config); @@ -299,9 +293,7 @@ static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) */ static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) { - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc = platform_get_drvdata(pdev); - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = dev_get_drvdata(dev); unsigned int time, date, err = 0; if (tm2bcd(&alm->time) < 0) @@ -330,9 +322,7 @@ static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled) { - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc = platform_get_drvdata(pdev); - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = dev_get_drvdata(dev); int ret = 0; spear_rtc_clear_interrupt(config); @@ -365,7 +355,6 @@ static struct rtc_class_ops spear_rtc_ops = { static int __devinit spear_rtc_probe(struct platform_device *pdev) { struct resource *res; - struct rtc_device *rtc; struct spear_rtc_config *config; unsigned int status = 0; int irq; @@ -405,19 +394,17 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev) } spin_lock_init(&config->lock); + platform_set_drvdata(pdev, config); - rtc = rtc_device_register(pdev->name, &pdev->dev, &spear_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) { + config->rtc = rtc_device_register(pdev->name, &pdev->dev, + &spear_rtc_ops, THIS_MODULE); + if (IS_ERR(config->rtc)) { dev_err(&pdev->dev, "can't register RTC device, err %ld\n", - PTR_ERR(rtc)); - status = PTR_ERR(rtc); + PTR_ERR(config->rtc)); + status = PTR_ERR(config->rtc); goto err_iounmap; } - platform_set_drvdata(pdev, rtc); - dev_set_drvdata(&rtc->dev, config); - /* alarm irqs */ irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -426,7 +413,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev) goto err_clear_platdata; } - status = request_irq(irq, spear_rtc_irq, 0, pdev->name, rtc); + status = request_irq(irq, spear_rtc_irq, 0, pdev->name, config); if (status) { dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \ claimed\n", irq); @@ -440,8 +427,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev) err_clear_platdata: platform_set_drvdata(pdev, NULL); - dev_set_drvdata(&rtc->dev, NULL); - rtc_device_unregister(rtc); + rtc_device_unregister(config->rtc); err_iounmap: iounmap(config->ioaddr); err_disable_clock: @@ -458,8 +444,7 @@ err_release_region: static int __devexit spear_rtc_remove(struct platform_device *pdev) { - struct rtc_device *rtc = platform_get_drvdata(pdev); - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = platform_get_drvdata(pdev); int irq; struct resource *res; @@ -477,8 +462,7 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev) if (res) release_mem_region(res->start, resource_size(res)); platform_set_drvdata(pdev, NULL); - dev_set_drvdata(&rtc->dev, NULL); - rtc_device_unregister(rtc); + rtc_device_unregister(config->rtc); return 0; } @@ -487,8 +471,7 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev) static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) { - struct rtc_device *rtc = platform_get_drvdata(pdev); - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = platform_get_drvdata(pdev); int irq; irq = platform_get_irq(pdev, 0); @@ -505,8 +488,7 @@ static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) static int spear_rtc_resume(struct platform_device *pdev) { - struct rtc_device *rtc = platform_get_drvdata(pdev); - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = platform_get_drvdata(pdev); int irq; irq = platform_get_irq(pdev, 0); @@ -531,8 +513,7 @@ static int spear_rtc_resume(struct platform_device *pdev) static void spear_rtc_shutdown(struct platform_device *pdev) { - struct rtc_device *rtc = platform_get_drvdata(pdev); - struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); + struct spear_rtc_config *config = platform_get_drvdata(pdev); spear_rtc_disable_interrupt(config); clk_disable(config->clk); -- cgit v1.2.3 From 109e941843893cb1b4f7bed24c615ba84ce00ff5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 23 Mar 2012 15:02:30 -0700 Subject: rtc: convert rtc spi drivers to module_spi_driver Factor out some boilerplate code for spi driver registration into module_spi_driver. Signed-off-by: Axel Lin Cc: Mark Jackson Cc: Dennis Aberilla Cc: Nikolaus Voss Cc: "Kim B. Heino" Cc: Raphael Assenat Cc: Chris Verges Cc: Magnus Damm Cc: Atsushi Nemoto Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1305.c | 12 +----------- drivers/rtc/rtc-ds1390.c | 12 +----------- drivers/rtc/rtc-ds3234.c | 12 +----------- drivers/rtc/rtc-m41t93.c | 12 +----------- drivers/rtc/rtc-m41t94.c | 14 +------------- drivers/rtc/rtc-max6902.c | 12 +----------- drivers/rtc/rtc-pcf2123.c | 13 +------------ drivers/rtc/rtc-r9701.c | 12 +----------- drivers/rtc/rtc-rs5c348.c | 13 +------------ 9 files changed, 9 insertions(+), 103 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 3a33b1fdbe0f..686a865913e1 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -814,17 +814,7 @@ static struct spi_driver ds1305_driver = { /* REVISIT add suspend/resume */ }; -static int __init ds1305_init(void) -{ - return spi_register_driver(&ds1305_driver); -} -module_init(ds1305_init); - -static void __exit ds1305_exit(void) -{ - spi_unregister_driver(&ds1305_driver); -} -module_exit(ds1305_exit); +module_spi_driver(ds1305_driver); MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips"); MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index b038d2cfef26..b0a99e1b25be 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c @@ -175,17 +175,7 @@ static struct spi_driver ds1390_driver = { .remove = __devexit_p(ds1390_remove), }; -static __init int ds1390_init(void) -{ - return spi_register_driver(&ds1390_driver); -} -module_init(ds1390_init); - -static __exit void ds1390_exit(void) -{ - spi_unregister_driver(&ds1390_driver); -} -module_exit(ds1390_exit); +module_spi_driver(ds1390_driver); MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver"); MODULE_AUTHOR("Mark Jackson "); diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c index bbd26228f532..fda707926f02 100644 --- a/drivers/rtc/rtc-ds3234.c +++ b/drivers/rtc/rtc-ds3234.c @@ -173,17 +173,7 @@ static struct spi_driver ds3234_driver = { .remove = __devexit_p(ds3234_remove), }; -static __init int ds3234_init(void) -{ - return spi_register_driver(&ds3234_driver); -} -module_init(ds3234_init); - -static __exit void ds3234_exit(void) -{ - spi_unregister_driver(&ds3234_driver); -} -module_exit(ds3234_exit); +module_spi_driver(ds3234_driver); MODULE_DESCRIPTION("DS3234 SPI RTC driver"); MODULE_AUTHOR("Dennis Aberilla "); diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c index ef71132ff205..10f1c29436ec 100644 --- a/drivers/rtc/rtc-m41t93.c +++ b/drivers/rtc/rtc-m41t93.c @@ -206,17 +206,7 @@ static struct spi_driver m41t93_driver = { .remove = __devexit_p(m41t93_remove), }; -static __init int m41t93_init(void) -{ - return spi_register_driver(&m41t93_driver); -} -module_init(m41t93_init); - -static __exit void m41t93_exit(void) -{ - spi_unregister_driver(&m41t93_driver); -} -module_exit(m41t93_exit); +module_spi_driver(m41t93_driver); MODULE_AUTHOR("Nikolaus Voss "); MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC"); diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c index 2a4721f61797..6e78193e026b 100644 --- a/drivers/rtc/rtc-m41t94.c +++ b/drivers/rtc/rtc-m41t94.c @@ -153,19 +153,7 @@ static struct spi_driver m41t94_driver = { .remove = __devexit_p(m41t94_remove), }; -static __init int m41t94_init(void) -{ - return spi_register_driver(&m41t94_driver); -} - -module_init(m41t94_init); - -static __exit void m41t94_exit(void) -{ - spi_unregister_driver(&m41t94_driver); -} - -module_exit(m41t94_exit); +module_spi_driver(m41t94_driver); MODULE_AUTHOR("Kim B. Heino "); MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC"); diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 1f6b3cc58e8a..36c74d22e8b5 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c @@ -160,17 +160,7 @@ static struct spi_driver max6902_driver = { .remove = __devexit_p(max6902_remove), }; -static __init int max6902_init(void) -{ - return spi_register_driver(&max6902_driver); -} -module_init(max6902_init); - -static __exit void max6902_exit(void) -{ - spi_unregister_driver(&max6902_driver); -} -module_exit(max6902_exit); +module_spi_driver(max6902_driver); MODULE_DESCRIPTION ("max6902 spi RTC driver"); MODULE_AUTHOR ("Raphael Assenat"); diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index b46c4004d8fe..836118795c0b 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -346,20 +346,9 @@ static struct spi_driver pcf2123_driver = { .remove = __devexit_p(pcf2123_remove), }; -static int __init pcf2123_init(void) -{ - return spi_register_driver(&pcf2123_driver); -} - -static void __exit pcf2123_exit(void) -{ - spi_unregister_driver(&pcf2123_driver); -} +module_spi_driver(pcf2123_driver); MODULE_AUTHOR("Chris Verges "); MODULE_DESCRIPTION("NXP PCF2123 RTC driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(pcf2123_init); -module_exit(pcf2123_exit); diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c index 2853c2a6f10f..7f8e6c247935 100644 --- a/drivers/rtc/rtc-r9701.c +++ b/drivers/rtc/rtc-r9701.c @@ -159,17 +159,7 @@ static struct spi_driver r9701_driver = { .remove = __devexit_p(r9701_remove), }; -static __init int r9701_init(void) -{ - return spi_register_driver(&r9701_driver); -} -module_init(r9701_init); - -static __exit void r9701_exit(void) -{ - spi_unregister_driver(&r9701_driver); -} -module_exit(r9701_exit); +module_spi_driver(r9701_driver); MODULE_DESCRIPTION("r9701 spi RTC driver"); MODULE_AUTHOR("Magnus Damm "); diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index ce2ca8523ddd..77074ccd2850 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c @@ -235,18 +235,7 @@ static struct spi_driver rs5c348_driver = { .remove = __devexit_p(rs5c348_remove), }; -static __init int rs5c348_init(void) -{ - return spi_register_driver(&rs5c348_driver); -} - -static __exit void rs5c348_exit(void) -{ - spi_unregister_driver(&rs5c348_driver); -} - -module_init(rs5c348_init); -module_exit(rs5c348_exit); +module_spi_driver(rs5c348_driver); MODULE_AUTHOR("Atsushi Nemoto "); MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver"); -- cgit v1.2.3 From 0abc920116303e81702a38429a1b61a896e02b37 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 23 Mar 2012 15:02:31 -0700 Subject: rtc: convert rtc i2c drivers to module_i2c_driver Factor out some boilerplate code for i2c driver registration into module_i2c_driver. Signed-off-by: Axel Lin Cc: Piotr Ziecik Cc: Alessandro Zummo Cc: Scott Wood Cc: Srikanth Srinivasan Cc: Mike Rapoport Cc: Sergey Lapin Cc: Roman Fietze Cc: Herbert Valerio Riedel Cc: Alexander Bigga Cc: Dale Farnsworth Cc: Gregory Hermant Cc: Wolfgang Grandegger Cc: Martyn Welch Cc: Byron Bradley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-bq32k.c | 12 +----------- drivers/rtc/rtc-ds1307.c | 12 +----------- drivers/rtc/rtc-ds1374.c | 13 +------------ drivers/rtc/rtc-ds1672.c | 13 +------------ drivers/rtc/rtc-ds3232.c | 13 +------------ drivers/rtc/rtc-em3027.c | 13 +------------ drivers/rtc/rtc-fm3130.c | 12 +----------- drivers/rtc/rtc-isl12022.c | 13 +------------ drivers/rtc/rtc-isl1208.c | 15 +-------------- drivers/rtc/rtc-m41t80.c | 13 +------------ drivers/rtc/rtc-max6900.c | 13 +------------ drivers/rtc/rtc-pcf8563.c | 13 +------------ drivers/rtc/rtc-pcf8583.c | 13 +------------ drivers/rtc/rtc-rs5c372.c | 13 +------------ drivers/rtc/rtc-rv3029c2.c | 13 +------------ drivers/rtc/rtc-rx8025.c | 13 +------------ drivers/rtc/rtc-rx8581.c | 13 +------------ drivers/rtc/rtc-s35390a.c | 13 +------------ drivers/rtc/rtc-x1205.c | 13 +------------ 19 files changed, 19 insertions(+), 227 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 408cc8f735be..f090159dce4a 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -187,17 +187,7 @@ static struct i2c_driver bq32k_driver = { .id_table = bq32k_id, }; -static __init int bq32k_init(void) -{ - return i2c_add_driver(&bq32k_driver); -} -module_init(bq32k_init); - -static __exit void bq32k_exit(void) -{ - i2c_del_driver(&bq32k_driver); -} -module_exit(bq32k_exit); +module_i2c_driver(bq32k_driver); MODULE_AUTHOR("Semihalf, Piotr Ziecik "); MODULE_DESCRIPTION("TI BQ32000 I2C RTC driver"); diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 62b0763b7b9a..58edcb076742 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -938,17 +938,7 @@ static struct i2c_driver ds1307_driver = { .id_table = ds1307_id, }; -static int __init ds1307_init(void) -{ - return i2c_add_driver(&ds1307_driver); -} -module_init(ds1307_init); - -static void __exit ds1307_exit(void) -{ - i2c_del_driver(&ds1307_driver); -} -module_exit(ds1307_exit); +module_i2c_driver(ds1307_driver); MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips"); MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index e6e71deb188f..966316088b7f 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -446,18 +446,7 @@ static struct i2c_driver ds1374_driver = { .id_table = ds1374_id, }; -static int __init ds1374_init(void) -{ - return i2c_add_driver(&ds1374_driver); -} - -static void __exit ds1374_exit(void) -{ - i2c_del_driver(&ds1374_driver); -} - -module_init(ds1374_init); -module_exit(ds1374_exit); +module_i2c_driver(ds1374_driver); MODULE_AUTHOR("Scott Wood "); MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver"); diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index a319402a5447..7fa67d0df172 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -202,20 +202,9 @@ static struct i2c_driver ds1672_driver = { .id_table = ds1672_id, }; -static int __init ds1672_init(void) -{ - return i2c_add_driver(&ds1672_driver); -} - -static void __exit ds1672_exit(void) -{ - i2c_del_driver(&ds1672_driver); -} +module_i2c_driver(ds1672_driver); MODULE_AUTHOR("Alessandro Zummo "); MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(ds1672_init); -module_exit(ds1672_exit); diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 27b7bf672ac6..e1945095814e 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -473,18 +473,7 @@ static struct i2c_driver ds3232_driver = { .id_table = ds3232_id, }; -static int __init ds3232_init(void) -{ - return i2c_add_driver(&ds3232_driver); -} - -static void __exit ds3232_exit(void) -{ - i2c_del_driver(&ds3232_driver); -} - -module_init(ds3232_init); -module_exit(ds3232_exit); +module_i2c_driver(ds3232_driver); MODULE_AUTHOR("Srikanth Srinivasan "); MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver"); diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index 8414dea5fb14..0104ea7ebe50 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c @@ -144,19 +144,8 @@ static struct i2c_driver em3027_driver = { .id_table = em3027_id, }; -static int __init em3027_init(void) -{ - return i2c_add_driver(&em3027_driver); -} - -static void __exit em3027_exit(void) -{ - i2c_del_driver(&em3027_driver); -} +module_i2c_driver(em3027_driver); MODULE_AUTHOR("Mike Rapoport "); MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver"); MODULE_LICENSE("GPL"); - -module_init(em3027_init); -module_exit(em3027_exit); diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index 4cf2e70c5078..86b6ecce99f0 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -565,17 +565,7 @@ static struct i2c_driver fm3130_driver = { .id_table = fm3130_id, }; -static int __init fm3130_init(void) -{ - return i2c_add_driver(&fm3130_driver); -} -module_init(fm3130_init); - -static void __exit fm3130_exit(void) -{ - i2c_del_driver(&fm3130_driver); -} -module_exit(fm3130_exit); +module_i2c_driver(fm3130_driver); MODULE_DESCRIPTION("RTC driver for FM3130"); MODULE_AUTHOR("Sergey Lapin "); diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 6186833973ee..1850104705c0 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -309,18 +309,7 @@ static struct i2c_driver isl12022_driver = { .id_table = isl12022_id, }; -static int __init isl12022_init(void) -{ - return i2c_add_driver(&isl12022_driver); -} - -static void __exit isl12022_exit(void) -{ - i2c_del_driver(&isl12022_driver); -} - -module_init(isl12022_init); -module_exit(isl12022_exit); +module_i2c_driver(isl12022_driver); MODULE_AUTHOR("roman.fietze@telemotive.de"); MODULE_DESCRIPTION("ISL 12022 RTC driver"); diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index da8beb8cae51..dd2aeee6c66a 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -710,22 +710,9 @@ static struct i2c_driver isl1208_driver = { .id_table = isl1208_id, }; -static int __init -isl1208_init(void) -{ - return i2c_add_driver(&isl1208_driver); -} - -static void __exit -isl1208_exit(void) -{ - i2c_del_driver(&isl1208_driver); -} +module_i2c_driver(isl1208_driver); MODULE_AUTHOR("Herbert Valerio Riedel "); MODULE_DESCRIPTION("Intersil ISL1208 RTC driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(isl1208_init); -module_exit(isl1208_exit); diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 64aedd8cc095..4e0f84af99a7 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -900,20 +900,9 @@ static struct i2c_driver m41t80_driver = { .id_table = m41t80_id, }; -static int __init m41t80_rtc_init(void) -{ - return i2c_add_driver(&m41t80_driver); -} - -static void __exit m41t80_rtc_exit(void) -{ - i2c_del_driver(&m41t80_driver); -} +module_i2c_driver(m41t80_driver); MODULE_AUTHOR("Alexander Bigga "); MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(m41t80_rtc_init); -module_exit(m41t80_rtc_exit); diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 486142c2637a..a00e33204b91 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c @@ -261,20 +261,9 @@ static struct i2c_driver max6900_driver = { .id_table = max6900_id, }; -static int __init max6900_init(void) -{ - return i2c_add_driver(&max6900_driver); -} - -static void __exit max6900_exit(void) -{ - i2c_del_driver(&max6900_driver); -} +module_i2c_driver(max6900_driver); MODULE_DESCRIPTION("Maxim MAX6900 RTC driver"); MODULE_AUTHOR("Dale Farnsworth "); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(max6900_init); -module_exit(max6900_exit); diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 606fdfab34e2..bc0677de1996 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -252,20 +252,9 @@ static struct i2c_driver pcf8563_driver = { .id_table = pcf8563_id, }; -static int __init pcf8563_init(void) -{ - return i2c_add_driver(&pcf8563_driver); -} - -static void __exit pcf8563_exit(void) -{ - i2c_del_driver(&pcf8563_driver); -} +module_i2c_driver(pcf8563_driver); MODULE_AUTHOR("Alessandro Zummo "); MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(pcf8563_init); -module_exit(pcf8563_exit); diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 2d201afead3b..019ff3571168 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c @@ -320,18 +320,7 @@ static struct i2c_driver pcf8583_driver = { .id_table = pcf8583_id, }; -static __init int pcf8583_init(void) -{ - return i2c_add_driver(&pcf8583_driver); -} - -static __exit void pcf8583_exit(void) -{ - i2c_del_driver(&pcf8583_driver); -} - -module_init(pcf8583_init); -module_exit(pcf8583_exit); +module_i2c_driver(pcf8583_driver); MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("PCF8583 I2C RTC driver"); diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index d29f5432c6e8..fb4842c3544e 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -689,18 +689,7 @@ static struct i2c_driver rs5c372_driver = { .id_table = rs5c372_id, }; -static __init int rs5c372_init(void) -{ - return i2c_add_driver(&rs5c372_driver); -} - -static __exit void rs5c372_exit(void) -{ - i2c_del_driver(&rs5c372_driver); -} - -module_init(rs5c372_init); -module_exit(rs5c372_exit); +module_i2c_driver(rs5c372_driver); MODULE_AUTHOR( "Pavel Mironchik , " diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index ea09ff211dc6..0fbe57b2f6d2 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -436,18 +436,7 @@ static struct i2c_driver rv3029c2_driver = { .id_table = rv3029c2_id, }; -static int __init rv3029c2_init(void) -{ - return i2c_add_driver(&rv3029c2_driver); -} - -static void __exit rv3029c2_exit(void) -{ - i2c_del_driver(&rv3029c2_driver); -} - -module_init(rv3029c2_init); -module_exit(rv3029c2_exit); +module_i2c_driver(rv3029c2_driver); MODULE_AUTHOR("Gregory Hermant "); MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver"); diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index fde172fb2abe..0de902dc1cd5 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -644,19 +644,8 @@ static struct i2c_driver rx8025_driver = { .id_table = rx8025_id, }; -static int __init rx8025_init(void) -{ - return i2c_add_driver(&rx8025_driver); -} - -static void __exit rx8025_exit(void) -{ - i2c_del_driver(&rx8025_driver); -} +module_i2c_driver(rx8025_driver); MODULE_AUTHOR("Wolfgang Grandegger "); MODULE_DESCRIPTION("RX-8025 SA/NB RTC driver"); MODULE_LICENSE("GPL"); - -module_init(rx8025_init); -module_exit(rx8025_exit); diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index 600b890a3c15..d84825124a7a 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c @@ -276,20 +276,9 @@ static struct i2c_driver rx8581_driver = { .id_table = rx8581_id, }; -static int __init rx8581_init(void) -{ - return i2c_add_driver(&rx8581_driver); -} - -static void __exit rx8581_exit(void) -{ - i2c_del_driver(&rx8581_driver); -} +module_i2c_driver(rx8581_driver); MODULE_AUTHOR("Martyn Welch "); MODULE_DESCRIPTION("Epson RX-8581 RTC driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(rx8581_init); -module_exit(rx8581_exit); diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index f789e002c9b0..c9562ceedef3 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -304,19 +304,8 @@ static struct i2c_driver s35390a_driver = { .id_table = s35390a_id, }; -static int __init s35390a_rtc_init(void) -{ - return i2c_add_driver(&s35390a_driver); -} - -static void __exit s35390a_rtc_exit(void) -{ - i2c_del_driver(&s35390a_driver); -} +module_i2c_driver(s35390a_driver); MODULE_AUTHOR("Byron Bradley "); MODULE_DESCRIPTION("S35390A RTC driver"); MODULE_LICENSE("GPL"); - -module_init(s35390a_rtc_init); -module_exit(s35390a_rtc_exit); diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 8c051d3179db..403b3d41d101 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -623,15 +623,7 @@ static struct i2c_driver x1205_driver = { .id_table = x1205_id, }; -static int __init x1205_init(void) -{ - return i2c_add_driver(&x1205_driver); -} - -static void __exit x1205_exit(void) -{ - i2c_del_driver(&x1205_driver); -} +module_i2c_driver(x1205_driver); MODULE_AUTHOR( "Karen Spearel , " @@ -639,6 +631,3 @@ MODULE_AUTHOR( MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(x1205_init); -module_exit(x1205_exit); -- cgit v1.2.3 From b4f0b880c8d7eb225b79dec663780b4dcdea7fbc Mon Sep 17 00:00:00 2001 From: zhao zhang Date: Fri, 23 Mar 2012 15:02:32 -0700 Subject: MIPS: add RTC support for loongson1B Add RTC support(TOY counter0) for loongson1B SOC Signed-off-by: zhao zhang Cc: Alessandro Zummo Cc: Ralf Baechle Acked-by: Linus Walleij Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 10 +++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-ls1x.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 drivers/rtc/rtc-ls1x.c (limited to 'drivers/rtc') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 3a125b835546..850febcbaf73 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1070,4 +1070,14 @@ config RTC_DRV_PUV3 This drive can also be built as a module. If so, the module will be called rtc-puv3. +config RTC_DRV_LOONGSON1 + tristate "loongson1 RTC support" + depends on MACH_LOONGSON1 + help + This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year + counter) to be used as a RTC. + + This driver can also be built as a module. If so, the module + will be called rtc-ls1x. + endif # RTC_CLASS diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 6e6982335c10..6c9387a3a3ad 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -53,6 +53,7 @@ obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o +obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c new file mode 100644 index 000000000000..07e81c5f8247 --- /dev/null +++ b/drivers/rtc/rtc-ls1x.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2011 Zhao Zhang + * + * Derived from driver/rtc/rtc-au1xxx.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LS1X_RTC_REG_OFFSET (LS1X_RTC_BASE + 0x20) +#define LS1X_RTC_REGS(x) \ + ((void __iomem *)KSEG1ADDR(LS1X_RTC_REG_OFFSET + (x))) + +/*RTC programmable counters 0 and 1*/ +#define SYS_COUNTER_CNTRL (LS1X_RTC_REGS(0x20)) +#define SYS_CNTRL_ERS (1 << 23) +#define SYS_CNTRL_RTS (1 << 20) +#define SYS_CNTRL_RM2 (1 << 19) +#define SYS_CNTRL_RM1 (1 << 18) +#define SYS_CNTRL_RM0 (1 << 17) +#define SYS_CNTRL_RS (1 << 16) +#define SYS_CNTRL_BP (1 << 14) +#define SYS_CNTRL_REN (1 << 13) +#define SYS_CNTRL_BRT (1 << 12) +#define SYS_CNTRL_TEN (1 << 11) +#define SYS_CNTRL_BTT (1 << 10) +#define SYS_CNTRL_E0 (1 << 8) +#define SYS_CNTRL_ETS (1 << 7) +#define SYS_CNTRL_32S (1 << 5) +#define SYS_CNTRL_TTS (1 << 4) +#define SYS_CNTRL_TM2 (1 << 3) +#define SYS_CNTRL_TM1 (1 << 2) +#define SYS_CNTRL_TM0 (1 << 1) +#define SYS_CNTRL_TS (1 << 0) + +/* Programmable Counter 0 Registers */ +#define SYS_TOYTRIM (LS1X_RTC_REGS(0)) +#define SYS_TOYWRITE0 (LS1X_RTC_REGS(4)) +#define SYS_TOYWRITE1 (LS1X_RTC_REGS(8)) +#define SYS_TOYREAD0 (LS1X_RTC_REGS(0xC)) +#define SYS_TOYREAD1 (LS1X_RTC_REGS(0x10)) +#define SYS_TOYMATCH0 (LS1X_RTC_REGS(0x14)) +#define SYS_TOYMATCH1 (LS1X_RTC_REGS(0x18)) +#define SYS_TOYMATCH2 (LS1X_RTC_REGS(0x1C)) + +/* Programmable Counter 1 Registers */ +#define SYS_RTCTRIM (LS1X_RTC_REGS(0x40)) +#define SYS_RTCWRITE0 (LS1X_RTC_REGS(0x44)) +#define SYS_RTCREAD0 (LS1X_RTC_REGS(0x48)) +#define SYS_RTCMATCH0 (LS1X_RTC_REGS(0x4C)) +#define SYS_RTCMATCH1 (LS1X_RTC_REGS(0x50)) +#define SYS_RTCMATCH2 (LS1X_RTC_REGS(0x54)) + +#define LS1X_SEC_OFFSET (4) +#define LS1X_MIN_OFFSET (10) +#define LS1X_HOUR_OFFSET (16) +#define LS1X_DAY_OFFSET (21) +#define LS1X_MONTH_OFFSET (26) + + +#define LS1X_SEC_MASK (0x3f) +#define LS1X_MIN_MASK (0x3f) +#define LS1X_HOUR_MASK (0x1f) +#define LS1X_DAY_MASK (0x1f) +#define LS1X_MONTH_MASK (0x3f) +#define LS1X_YEAR_MASK (0xffffffff) + +#define ls1x_get_sec(t) (((t) >> LS1X_SEC_OFFSET) & LS1X_SEC_MASK) +#define ls1x_get_min(t) (((t) >> LS1X_MIN_OFFSET) & LS1X_MIN_MASK) +#define ls1x_get_hour(t) (((t) >> LS1X_HOUR_OFFSET) & LS1X_HOUR_MASK) +#define ls1x_get_day(t) (((t) >> LS1X_DAY_OFFSET) & LS1X_DAY_MASK) +#define ls1x_get_month(t) (((t) >> LS1X_MONTH_OFFSET) & LS1X_MONTH_MASK) + +#define RTC_CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S) + +static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm) +{ + unsigned long v, t; + + v = readl(SYS_TOYREAD0); + t = readl(SYS_TOYREAD1); + + memset(rtm, 0, sizeof(struct rtc_time)); + t = mktime((t & LS1X_YEAR_MASK), ls1x_get_month(v), + ls1x_get_day(v), ls1x_get_hour(v), + ls1x_get_min(v), ls1x_get_sec(v)); + rtc_time_to_tm(t, rtm); + + return rtc_valid_tm(rtm); +} + +static int ls1x_rtc_set_time(struct device *dev, struct rtc_time *rtm) +{ + unsigned long v, t, c; + int ret = -ETIMEDOUT; + + v = ((rtm->tm_mon + 1) << LS1X_MONTH_OFFSET) + | (rtm->tm_mday << LS1X_DAY_OFFSET) + | (rtm->tm_hour << LS1X_HOUR_OFFSET) + | (rtm->tm_min << LS1X_MIN_OFFSET) + | (rtm->tm_sec << LS1X_SEC_OFFSET); + + writel(v, SYS_TOYWRITE0); + c = 0x10000; + /* add timeout check counter, for more safe */ + while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c) + usleep_range(1000, 3000); + + if (!c) { + dev_err(dev, "set time timeout!\n"); + goto err; + } + + t = rtm->tm_year + 1900; + writel(t, SYS_TOYWRITE1); + c = 0x10000; + while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c) + usleep_range(1000, 3000); + + if (!c) { + dev_err(dev, "set time timeout!\n"); + goto err; + } + return 0; +err: + return ret; +} + +static struct rtc_class_ops ls1x_rtc_ops = { + .read_time = ls1x_rtc_read_time, + .set_time = ls1x_rtc_set_time, +}; + +static int __devinit ls1x_rtc_probe(struct platform_device *pdev) +{ + struct rtc_device *rtcdev; + unsigned long v; + int ret; + + v = readl(SYS_COUNTER_CNTRL); + if (!(v & RTC_CNTR_OK)) { + dev_err(&pdev->dev, "rtc counters not working\n"); + ret = -ENODEV; + goto err; + } + ret = -ETIMEDOUT; + /* set to 1 HZ if needed */ + if (readl(SYS_TOYTRIM) != 32767) { + v = 0x100000; + while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) && --v) + usleep_range(1000, 3000); + + if (!v) { + dev_err(&pdev->dev, "time out\n"); + goto err; + } + writel(32767, SYS_TOYTRIM); + } + /* this loop coundn't be endless */ + while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) + usleep_range(1000, 3000); + + rtcdev = rtc_device_register("ls1x-rtc", &pdev->dev, + &ls1x_rtc_ops , THIS_MODULE); + if (IS_ERR(rtcdev)) { + ret = PTR_ERR(rtcdev); + goto err; + } + + platform_set_drvdata(pdev, rtcdev); + return 0; +err: + return ret; +} + +static int __devexit ls1x_rtc_remove(struct platform_device *pdev) +{ + struct rtc_device *rtcdev = platform_get_drvdata(pdev); + + rtc_device_unregister(rtcdev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver ls1x_rtc_driver = { + .driver = { + .name = "ls1x-rtc", + .owner = THIS_MODULE, + }, + .remove = __devexit_p(ls1x_rtc_remove), + .probe = ls1x_rtc_probe, +}; + +module_platform_driver(ls1x_rtc_driver); + +MODULE_AUTHOR("zhao zhang "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From ce9f650636d310e4c8febc821b0038e9918a12db Mon Sep 17 00:00:00 2001 From: Venu Byravarasu Date: Fri, 23 Mar 2012 15:02:32 -0700 Subject: drivers/rtc/rtc-twl.c: optimize IRQ bit access As the TWL RTC driver has a cached copy of enabled RTC interrupt bits in variable rtc_irq_bits, that can be checked before really setting or masking any of the interrupt bits. Signed-off-by: Venu Byravarasu Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-twl.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index d43b4f6eb4e4..18dff5255670 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -176,6 +176,10 @@ static int set_rtc_irq_bit(unsigned char bit) unsigned char val; int ret; + /* if the bit is set, return from here */ + if (rtc_irq_bits & bit) + return 0; + val = rtc_irq_bits | bit; val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M; ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); @@ -193,6 +197,10 @@ static int mask_rtc_irq_bit(unsigned char bit) unsigned char val; int ret; + /* if the bit is clear, return from here */ + if (!(rtc_irq_bits & bit)) + return 0; + val = rtc_irq_bits & ~bit; ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); if (ret == 0) -- cgit v1.2.3 From f7439bcb74aca4234fedc336a21e169e6e33bb2e Mon Sep 17 00:00:00 2001 From: Venu Byravarasu Date: Fri, 23 Mar 2012 15:02:33 -0700 Subject: drivers/rtc/rtc-twl.c: enable RTC irrespective of its prior state As part of probe, before enabling RTC, RTC_CTRL register is read to check if it is already running. If RTC is used by kernel alone, then this read is not required. Even if RTC was enabled already by boot loader, setting STOP_RTC bit again should not harm. Hence removed unwanted read operation. Signed-off-by: Venu Byravarasu Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-twl.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 18dff5255670..18e4c0138a40 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -457,19 +457,11 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) REG_INT_MSK_STS_A); } - /* Check RTC module status, Enable if it is off */ - ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG); + dev_info(&pdev->dev, "Enabling TWL-RTC\n"); + ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG); if (ret < 0) goto out1; - if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) { - dev_info(&pdev->dev, "Enabling TWL-RTC.\n"); - rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M; - ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG); - if (ret < 0) - goto out1; - } - /* init cached IRQ enable bits */ ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); if (ret < 0) -- cgit v1.2.3 From 94a339d016e26f96a1bd9e08306c857825c91a66 Mon Sep 17 00:00:00 2001 From: Venu Byravarasu Date: Fri, 23 Mar 2012 15:02:33 -0700 Subject: drivers/rtc/rtc-twl.c: simplify RTC interrupt clearing For clearing RTC interrupt, programming ALARM bit only is sufficient, as all other bits are any way not affected by writing 0 to them. Hence removed unwanted OR operation. Signed-off-by: Venu Byravarasu Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-twl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 18e4c0138a40..cedb6c145fc4 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -384,7 +384,7 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) else events |= RTC_IRQF | RTC_UF; - res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M, + res = twl_rtc_write_u8(BIT_RTC_STATUS_REG_ALARM_M, REG_RTC_STATUS_REG); if (res) goto out; -- cgit v1.2.3 From 2778ebcc09c002cccdbd6b5509b5cbf4161b486d Mon Sep 17 00:00:00 2001 From: Venu Byravarasu Date: Fri, 23 Mar 2012 15:02:34 -0700 Subject: drivers/rtc/rtc-twl.c: return correct RTC event from ISR Following changes are made as part of this change: 1. As TWL RTC supports periodic interrupt, the correct event should be RTC_PF instead of RTC_UF. 2. No need to initialize variable "events" to 0 & then OR it with the event values. Hence fixing it. Signed-off-by: Venu Byravarasu Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-twl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index cedb6c145fc4..4c2c6df2a9ef 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -365,7 +365,7 @@ out: static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) { - unsigned long events = 0; + unsigned long events; int ret = IRQ_NONE; int res; u8 rd_reg; @@ -380,9 +380,9 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM] */ if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) - events |= RTC_IRQF | RTC_AF; + events = RTC_IRQF | RTC_AF; else - events |= RTC_IRQF | RTC_UF; + events = RTC_IRQF | RTC_PF; res = twl_rtc_write_u8(BIT_RTC_STATUS_REG_ALARM_M, REG_RTC_STATUS_REG); -- cgit v1.2.3 From 2f6e5f9458646263d3d9ffadd5e11e3d8d15a7d0 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Fri, 23 Mar 2012 15:02:34 -0700 Subject: drivers/rtc: remove IRQF_DISABLED Since commit e58aa3d2d0cc ("genirq: run irq handlers with interrupts disabled") we run all interrupt handlers with interrupts disabled and we even check and yell when an interrupt handler returns with interrupts enabled - see commit b738a50a2026 ("genirq: warn when handler enables interrupts"). So now this flag is a NOOP and can be removed. Signed-off-by: Yong Zhang Acked-by: Linus Walleij Acked-by: Wan ZongShun Cc: Alessandro Zummo Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-at91sam9.c | 2 +- drivers/rtc/rtc-cmos.c | 2 +- drivers/rtc/rtc-coh901331.c | 2 +- drivers/rtc/rtc-davinci.c | 2 +- drivers/rtc/rtc-ds1511.c | 2 +- drivers/rtc/rtc-ds1553.c | 2 +- drivers/rtc/rtc-lpc32xx.c | 2 +- drivers/rtc/rtc-mpc5121.c | 4 ++-- drivers/rtc/rtc-mrst.c | 2 +- drivers/rtc/rtc-mv.c | 2 +- drivers/rtc/rtc-nuc900.c | 2 +- drivers/rtc/rtc-omap.c | 4 ++-- drivers/rtc/rtc-pl030.c | 2 +- drivers/rtc/rtc-pl031.c | 2 +- drivers/rtc/rtc-pxa.c | 4 ++-- drivers/rtc/rtc-s3c.c | 4 ++-- drivers/rtc/rtc-sa1100.c | 7 +++---- drivers/rtc/rtc-sh.c | 8 ++++---- drivers/rtc/rtc-stk17ta8.c | 2 +- drivers/rtc/rtc-tx4939.c | 2 +- drivers/rtc/rtc-vr41xx.c | 4 ++-- 21 files changed, 31 insertions(+), 32 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index ee3c122c0599..274a0aafe42b 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -335,7 +335,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) /* register irq handler after we know what name we'll use */ ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, - IRQF_DISABLED | IRQF_SHARED, + IRQF_SHARED, dev_name(&rtc->rtcdev->dev), rtc); if (ret) { dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index d7782aa09943..7d5f56edb8ef 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -714,7 +714,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) rtc_cmos_int_handler = cmos_interrupt; retval = request_irq(rtc_irq, rtc_cmos_int_handler, - IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev), + 0, dev_name(&cmos_rtc.rtc->dev), cmos_rtc.rtc); if (retval < 0) { dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 80f9c88214c5..a5b8a0c4ea84 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c @@ -199,7 +199,7 @@ static int __init coh901331_probe(struct platform_device *pdev) } rtap->irq = platform_get_irq(pdev, 0); - if (request_irq(rtap->irq, coh901331_interrupt, IRQF_DISABLED, + if (request_irq(rtap->irq, coh901331_interrupt, 0, "RTC COH 901 331 Alarm", rtap)) { ret = -EIO; goto out_no_irq; diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 755e1fe914af..14c2109dbaa3 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -542,7 +542,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL); ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt, - IRQF_DISABLED, "davinci_rtc", davinci_rtc); + 0, "davinci_rtc", davinci_rtc); if (ret < 0) { dev_err(dev, "unable to register davinci RTC interrupt\n"); goto fail4; diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 761f36bc83a9..1f675f5294f5 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -532,7 +532,7 @@ ds1511_rtc_probe(struct platform_device *pdev) if (pdata->irq > 0) { rtc_read(RTC_CMD1); if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt, - IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) { + IRQF_SHARED, pdev->name, pdev) < 0) { dev_warn(&pdev->dev, "interrupt not available.\n"); pdata->irq = 0; diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 6f0a1b530f2e..6ccedbbf923c 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -320,7 +320,7 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev) writeb(0, ioaddr + RTC_INTERRUPTS); if (devm_request_irq(&pdev->dev, pdata->irq, ds1553_rtc_interrupt, - IRQF_DISABLED, pdev->name, pdev) < 0) { + 0, pdev->name, pdev) < 0) { dev_warn(&pdev->dev, "interrupt not available.\n"); pdata->irq = 0; } diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c index ecc1713b2b4f..63c72189c64b 100644 --- a/drivers/rtc/rtc-lpc32xx.c +++ b/drivers/rtc/rtc-lpc32xx.c @@ -287,7 +287,7 @@ static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev) if (rtc->irq >= 0) { if (devm_request_irq(&pdev->dev, rtc->irq, lpc32xx_rtc_alarm_interrupt, - IRQF_DISABLED, pdev->name, rtc) < 0) { + 0, pdev->name, rtc) < 0) { dev_warn(&pdev->dev, "Can't request interrupt.\n"); rtc->irq = -1; } else { diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 9d3caccfc250..e954a759ba85 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -327,7 +327,7 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op) dev_set_drvdata(&op->dev, rtc); rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1); - err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED, + err = request_irq(rtc->irq, mpc5121_rtc_handler, 0, "mpc5121-rtc", &op->dev); if (err) { dev_err(&op->dev, "%s: could not request irq: %i\n", @@ -337,7 +337,7 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op) rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0); err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd, - IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev); + 0, "mpc5121-rtc_upd", &op->dev); if (err) { dev_err(&op->dev, "%s: could not request irq: %i\n", __func__, rtc->irq_periodic); diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index 6cd6c7235344..f51719bf4a75 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -366,7 +366,7 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq) if (rtc_irq) { retval = request_irq(rtc_irq, mrst_rtc_irq, - IRQF_DISABLED, dev_name(&mrst_rtc.rtc->dev), + 0, dev_name(&mrst_rtc.rtc->dev), mrst_rtc.rtc); if (retval < 0) { dev_dbg(dev, "IRQ %d is already in use, err %d\n", diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 768e2edb9678..1300962486d1 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -273,7 +273,7 @@ static int __devinit mv_rtc_probe(struct platform_device *pdev) if (pdata->irq >= 0) { writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt, - IRQF_DISABLED | IRQF_SHARED, + IRQF_SHARED, pdev->name, pdata) < 0) { dev_warn(&pdev->dev, "interrupt not available.\n"); pdata->irq = -1; diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c index 781068d62f23..b79010987d1e 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c @@ -269,7 +269,7 @@ static int __devinit nuc900_rtc_probe(struct platform_device *pdev) nuc900_rtc->irq_num = platform_get_irq(pdev, 0); if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt, - IRQF_DISABLED, "nuc900rtc", nuc900_rtc)) { + 0, "nuc900rtc", nuc900_rtc)) { dev_err(&pdev->dev, "NUC900 RTC request irq failed\n"); err = -EBUSY; goto fail4; diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 7789002bdd5c..0b614e32653d 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -348,14 +348,14 @@ static int __init omap_rtc_probe(struct platform_device *pdev) rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); /* handle periodic and alarm irqs */ - if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, + if (request_irq(omap_rtc_timer, rtc_irq, 0, dev_name(&rtc->dev), rtc)) { pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_timer); goto fail1; } if ((omap_rtc_timer != omap_rtc_alarm) && - (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, + (request_irq(omap_rtc_alarm, rtc_irq, 0, dev_name(&rtc->dev), rtc))) { pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_alarm); diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index 02111fee077e..a4a1e534ed42 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c @@ -123,7 +123,7 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id) amba_set_drvdata(dev, rtc); - ret = request_irq(dev->irq[0], pl030_interrupt, IRQF_DISABLED, + ret = request_irq(dev->irq[0], pl030_interrupt, 0, "rtc-pl030", rtc); if (ret) goto err_irq; diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index a952c8de1dd7..3a470e291282 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -352,7 +352,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) } if (request_irq(adev->irq[0], pl031_interrupt, - IRQF_DISABLED, "rtc-pl031", ldata)) { + 0, "rtc-pl031", ldata)) { ret = -EIO; goto out_no_irq; } diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index fc9f4991574b..0075c8fd93d8 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -174,14 +174,14 @@ static int pxa_rtc_open(struct device *dev) struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); int ret; - ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, IRQF_DISABLED, + ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, 0, "rtc 1Hz", dev); if (ret < 0) { dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz, ret); goto err_irq_1Hz; } - ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, IRQF_DISABLED, + ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, 0, "rtc Alrm", dev); if (ret < 0) { dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm, diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index aef40bd2957b..c543f6f1eec2 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -543,14 +543,14 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) s3c_rtc_setfreq(&pdev->dev, 1); ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq, - IRQF_DISABLED, "s3c2410-rtc alarm", rtc); + 0, "s3c2410-rtc alarm", rtc); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); goto err_alarm_irq; } ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, - IRQF_DISABLED, "s3c2410-rtc tick", rtc); + 0, "s3c2410-rtc tick", rtc); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); free_irq(s3c_rtc_alarmno, rtc); diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index cb9a585312cc..fb758db9d0f4 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -160,14 +160,13 @@ static int sa1100_rtc_open(struct device *dev) struct platform_device *plat_dev = to_platform_device(dev); struct rtc_device *rtc = platform_get_drvdata(plat_dev); - ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, - "rtc 1Hz", dev); + ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev); if (ret) { dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); goto fail_ui; } - ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, - "rtc Alrm", dev); + ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, 0, + "rtc Alrm", dev); if (ret) { dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); goto fail_ai; diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 6ac55fd48413..e55a7635ae5f 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -666,7 +666,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) if (rtc->carry_irq <= 0) { /* register shared periodic/carry/alarm irq */ ret = request_irq(rtc->periodic_irq, sh_rtc_shared, - IRQF_DISABLED, "sh-rtc", rtc); + 0, "sh-rtc", rtc); if (unlikely(ret)) { dev_err(&pdev->dev, "request IRQ failed with %d, IRQ %d\n", ret, @@ -676,7 +676,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) } else { /* register periodic/carry/alarm irqs */ ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, - IRQF_DISABLED, "sh-rtc period", rtc); + 0, "sh-rtc period", rtc); if (unlikely(ret)) { dev_err(&pdev->dev, "request period IRQ failed with %d, IRQ %d\n", @@ -685,7 +685,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) } ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, - IRQF_DISABLED, "sh-rtc carry", rtc); + 0, "sh-rtc carry", rtc); if (unlikely(ret)) { dev_err(&pdev->dev, "request carry IRQ failed with %d, IRQ %d\n", @@ -695,7 +695,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) } ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, - IRQF_DISABLED, "sh-rtc alarm", rtc); + 0, "sh-rtc alarm", rtc); if (unlikely(ret)) { dev_err(&pdev->dev, "request alarm IRQ failed with %d, IRQ %d\n", diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 7621116bd20d..279f5cfa691a 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -329,7 +329,7 @@ static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev) writeb(0, ioaddr + RTC_INTERRUPTS); if (devm_request_irq(&pdev->dev, pdata->irq, stk17ta8_rtc_interrupt, - IRQF_DISABLED | IRQF_SHARED, + IRQF_SHARED, pdev->name, pdev) < 0) { dev_warn(&pdev->dev, "interrupt not available.\n"); pdata->irq = 0; diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index aac0ffed4345..a12bfac49d36 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -266,7 +266,7 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev) spin_lock_init(&pdata->lock); tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt, - IRQF_DISABLED, pdev->name, &pdev->dev) < 0) + 0, pdev->name, &pdev->dev) < 0) return -EBUSY; rtc = rtc_device_register(pdev->name, &pdev->dev, &tx4939_rtc_ops, THIS_MODULE); diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index fcbfdda2993b..5f60a7c6a155 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -333,7 +333,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) goto err_device_unregister; } - retval = request_irq(aie_irq, elapsedtime_interrupt, IRQF_DISABLED, + retval = request_irq(aie_irq, elapsedtime_interrupt, 0, "elapsed_time", pdev); if (retval < 0) goto err_device_unregister; @@ -342,7 +342,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) if (pie_irq <= 0) goto err_free_irq; - retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, + retval = request_irq(pie_irq, rtclong1_interrupt, 0, "rtclong1", pdev); if (retval < 0) goto err_free_irq; -- cgit v1.2.3 From aa19689bfaaa26f2d85588a8774e194de5e7be54 Mon Sep 17 00:00:00 2001 From: Navin P Date: Fri, 23 Mar 2012 15:02:34 -0700 Subject: drivers/rtc/rtc-pm8xxx.c: make pm8xxx_rtc_pm_ops static Signed-off-by: Navin P Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pm8xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index 9f1d6bcbdf6c..d00bd24342a3 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -520,7 +520,7 @@ static int pm8xxx_rtc_suspend(struct device *dev) } #endif -SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume); +static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume); static struct platform_driver pm8xxx_rtc_driver = { .probe = pm8xxx_rtc_probe, -- cgit v1.2.3 From 0cf30bdd919685b201f715ea347dd96d590942e8 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Fri, 23 Mar 2012 15:02:35 -0700 Subject: drivers/rtc/rtc-max8925.c: fix max8925_rtc_read_alarm() return value error max8925_rtc_read_alarm should always return 0 with success Signed-off-by: Kevin Liu Signed-off-by: Haojian Zhuang Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-max8925.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c index 2d71943bc436..ff6b9a2cb8e3 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c @@ -204,6 +204,7 @@ static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) alrm->pending = 1; else alrm->pending = 0; + return 0; out: return ret; } -- cgit v1.2.3 From fad0738dcf6feccf601f5a24b8ccd3b26894b337 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Fri, 23 Mar 2012 15:02:36 -0700 Subject: drivers/rtc/rtc-max8925.c: fix alarm->enabled mistake in max8925_rtc_read_alarm/max8925_rtc_set_alarm max8925_rtc_read_alarm() should set alrm->enabled based on both ALARM_IRQ_MASK and ALARM_CTRL setting. max8925_rtc_set_alarm() should enable/disable alarm according to ALARM_CTRL reg setting. Signed-off-by: Kevin Liu Signed-off-by: Haojian Zhuang Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-max8925.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c index ff6b9a2cb8e3..1459055a83aa 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c @@ -193,10 +193,17 @@ static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK); if (ret < 0) goto out; - if ((ret & ALARM0_IRQ) == 0) - alrm->enabled = 1; - else + if (ret & ALARM0_IRQ) { alrm->enabled = 0; + } else { + ret = max8925_reg_read(info->rtc, MAX8925_ALARM0_CNTL); + if (ret < 0) + goto out; + if (!ret) + alrm->enabled = 0; + else + alrm->enabled = 1; + } ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS); if (ret < 0) goto out; @@ -221,8 +228,11 @@ static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf); if (ret < 0) goto out; - /* only enable alarm on year/month/day/hour/min/sec */ - ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77); + if (alrm->enabled) + /* only enable alarm on year/month/day/hour/min/sec */ + ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77); + else + ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x0); if (ret < 0) goto out; out: -- cgit v1.2.3 From fef931ff98fe78bea804d9b4c49d410a7a97988c Mon Sep 17 00:00:00 2001 From: Ashish Jangam Date: Fri, 23 Mar 2012 15:02:36 -0700 Subject: rtc: driver for DA9052/53 PMIC v1 RTC Driver for Dialog Semiconductor DA9052/53 PMICs. This patch is functionally tested on Samsung SMDKV6410. [akpm@linux-foundation.org: clean up file header layout, remove unneeded initialisation of local arrays] Signed-off-by: David Dajun Chen Signed-off-by: Ashish Jangam Cc: Paul Gortmaker Cc: David Dajun Chen Cc: Samuel Ortiz Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 7 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-da9052.c | 293 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 301 insertions(+) create mode 100644 drivers/rtc/rtc-da9052.c (limited to 'drivers/rtc') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 850febcbaf73..4f9fb25f945b 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -554,6 +554,13 @@ config RTC_DRV_DS1742 This driver can also be built as a module. If so, the module will be called rtc-ds1742. +config RTC_DRV_DA9052 + tristate "Dialog DA9052/DA9053 RTC" + depends on PMIC_DA9052 + help + Say y here to support the RTC driver for Dialog Semiconductor + DA9052-BC and DA9053-AA/Bx PMICs. + config RTC_DRV_EFI tristate "EFI RTC" depends on IA64 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 6c9387a3a3ad..727ae7786e6c 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o +obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c new file mode 100644 index 000000000000..da6ab5291a41 --- /dev/null +++ b/drivers/rtc/rtc-da9052.c @@ -0,0 +1,293 @@ +/* + * Real time clock driver for DA9052 + * + * Copyright(c) 2012 Dialog Semiconductor Ltd. + * + * Author: Dajun Dajun Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include + +#include +#include + +#define rtc_err(da9052, fmt, ...) \ + dev_err(da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__) + +struct da9052_rtc { + struct rtc_device *rtc; + struct da9052 *da9052; + int irq; +}; + +static int da9052_rtc_enable_alarm(struct da9052 *da9052, bool enable) +{ + int ret; + if (enable) { + ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, + DA9052_ALARM_Y_ALARM_ON, + DA9052_ALARM_Y_ALARM_ON); + if (ret != 0) + rtc_err(da9052, "Failed to enable ALM: %d\n", ret); + } else { + ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, + DA9052_ALARM_Y_ALARM_ON, 0); + if (ret != 0) + rtc_err(da9052, "Write error: %d\n", ret); + } + return ret; +} + +static irqreturn_t da9052_rtc_irq(int irq, void *data) +{ + struct da9052_rtc *rtc = data; + int ret; + + ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_MI_REG); + if (ret < 0) { + rtc_err(rtc->da9052, "Read error: %d\n", ret); + return IRQ_NONE; + } + + if (ret & DA9052_ALARMMI_ALARMTYPE) { + da9052_rtc_enable_alarm(rtc->da9052, 0); + rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); + } else + rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_PF); + + return IRQ_HANDLED; +} + +static int da9052_read_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm) +{ + int ret; + uint8_t v[5]; + + ret = da9052_group_read(da9052, DA9052_ALARM_MI_REG, 5, v); + if (ret != 0) { + rtc_err(da9052, "Failed to group read ALM: %d\n", ret); + return ret; + } + + rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100; + rtc_tm->tm_mon = (v[3] & DA9052_RTC_MONTH) - 1; + rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY; + rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR; + rtc_tm->tm_min = v[0] & DA9052_RTC_MIN; + + ret = rtc_valid_tm(rtc_tm); + if (ret != 0) + return ret; + return ret; +} + +static int da9052_set_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm) +{ + int ret; + uint8_t v[3]; + + rtc_tm->tm_year -= 100; + rtc_tm->tm_mon += 1; + + ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG, + DA9052_RTC_MIN, rtc_tm->tm_min); + if (ret != 0) { + rtc_err(da9052, "Failed to write ALRM MIN: %d\n", ret); + return ret; + } + + v[0] = rtc_tm->tm_hour; + v[1] = rtc_tm->tm_mday; + v[2] = rtc_tm->tm_mon; + + ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v); + if (ret < 0) + return ret; + + ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, + DA9052_RTC_YEAR, rtc_tm->tm_year); + if (ret != 0) + rtc_err(da9052, "Failed to write ALRM YEAR: %d\n", ret); + + return ret; +} + +static int da9052_rtc_get_alarm_status(struct da9052 *da9052) +{ + int ret; + + ret = da9052_reg_read(da9052, DA9052_ALARM_Y_REG); + if (ret < 0) { + rtc_err(da9052, "Failed to read ALM: %d\n", ret); + return ret; + } + ret &= DA9052_ALARM_Y_ALARM_ON; + return (ret > 0) ? 1 : 0; +} + +static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) +{ + struct da9052_rtc *rtc = dev_get_drvdata(dev); + uint8_t v[6]; + int ret; + + ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v); + if (ret < 0) { + rtc_err(rtc->da9052, "Failed to read RTC time : %d\n", ret); + return ret; + } + + rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100; + rtc_tm->tm_mon = (v[4] & DA9052_RTC_MONTH) - 1; + rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY; + rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR; + rtc_tm->tm_min = v[1] & DA9052_RTC_MIN; + rtc_tm->tm_sec = v[0] & DA9052_RTC_SEC; + + ret = rtc_valid_tm(rtc_tm); + if (ret != 0) { + rtc_err(rtc->da9052, "rtc_valid_tm failed: %d\n", ret); + return ret; + } + + return 0; +} + +static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct da9052_rtc *rtc; + uint8_t v[6]; + + rtc = dev_get_drvdata(dev); + + v[0] = tm->tm_sec; + v[1] = tm->tm_min; + v[2] = tm->tm_hour; + v[3] = tm->tm_mday; + v[4] = tm->tm_mon + 1; + v[5] = tm->tm_year - 100; + + return da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v); +} + +static int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + int ret; + struct rtc_time *tm = &alrm->time; + struct da9052_rtc *rtc = dev_get_drvdata(dev); + + ret = da9052_read_alarm(rtc->da9052, tm); + + if (ret) + return ret; + + alrm->enabled = da9052_rtc_get_alarm_status(rtc->da9052); + + return 0; +} + +static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + int ret; + struct rtc_time *tm = &alrm->time; + struct da9052_rtc *rtc = dev_get_drvdata(dev); + + ret = da9052_rtc_enable_alarm(rtc->da9052, 0); + if (ret < 0) + return ret; + + ret = da9052_set_alarm(rtc->da9052, tm); + if (ret) + return ret; + + ret = da9052_rtc_enable_alarm(rtc->da9052, 1); + + return ret; +} + +static int da9052_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct da9052_rtc *rtc = dev_get_drvdata(dev); + + return da9052_rtc_enable_alarm(rtc->da9052, enabled); +} + +static const struct rtc_class_ops da9052_rtc_ops = { + .read_time = da9052_rtc_read_time, + .set_time = da9052_rtc_set_time, + .read_alarm = da9052_rtc_read_alarm, + .set_alarm = da9052_rtc_set_alarm, + .alarm_irq_enable = da9052_rtc_alarm_irq_enable, +}; + +static int __devinit da9052_rtc_probe(struct platform_device *pdev) +{ + struct da9052_rtc *rtc; + int ret; + + rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9052_rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + rtc->da9052 = dev_get_drvdata(pdev->dev.parent); + platform_set_drvdata(pdev, rtc); + rtc->irq = platform_get_irq_byname(pdev, "ALM"); + ret = request_threaded_irq(rtc->irq, NULL, da9052_rtc_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "ALM", rtc); + if (ret != 0) { + rtc_err(rtc->da9052, "irq registration failed: %d\n", ret); + goto err_mem; + } + + rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, + &da9052_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc->rtc)) { + ret = PTR_ERR(rtc->rtc); + goto err_free_irq; + } + + return 0; + +err_free_irq: + free_irq(rtc->irq, rtc); +err_mem: + devm_kfree(&pdev->dev, rtc); + return ret; +} + +static int __devexit da9052_rtc_remove(struct platform_device *pdev) +{ + struct da9052_rtc *rtc = pdev->dev.platform_data; + + rtc_device_unregister(rtc->rtc); + free_irq(rtc->irq, rtc); + platform_set_drvdata(pdev, NULL); + devm_kfree(&pdev->dev, rtc); + + return 0; +} + +static struct platform_driver da9052_rtc_driver = { + .probe = da9052_rtc_probe, + .remove = __devexit_p(da9052_rtc_remove), + .driver = { + .name = "da9052-rtc", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(da9052_rtc_driver); + +MODULE_AUTHOR("David Dajun Chen "); +MODULE_DESCRIPTION("RTC driver for Dialog DA9052 PMIC"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:da9052-rtc"); -- cgit v1.2.3 From 32d322bcb0d6886084197247e30aa130956d5978 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 23 Mar 2012 15:02:36 -0700 Subject: rtc: ds1307: refactor chip_desc table The chip_desc table is suboptimal. Currently it requires an entry for every new chip type, even if it is empty. This has already been forgotten for the ds1388. Refactor the code, so new entries are only needed, when they chip type really needs a (non-empty) description. Also make the table visually more appealing. Signed-off-by: Wolfram Sang Cc: Austin Boyle Cc: David Anders Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 58edcb076742..5098e1ad3a3e 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -36,6 +36,7 @@ enum ds_type { m41t00, mcp7941x, rx_8025, + last_ds_type /* always last */ // rs5c372 too? different address... }; @@ -120,30 +121,23 @@ struct chip_desc { unsigned alarm:1; }; -static const struct chip_desc chips[] = { -[ds_1307] = { - .nvram56 = 1, -}, -[ds_1337] = { - .alarm = 1, -}, -[ds_1338] = { - .nvram56 = 1, -}, -[ds_1339] = { - .alarm = 1, -}, -[ds_1340] = { -}, -[ds_3231] = { - .alarm = 1, -}, -[m41t00] = { -}, -[mcp7941x] = { -}, -[rx_8025] = { -}, }; +static const struct chip_desc chips[last_ds_type] = { + [ds_1307] = { + .nvram56 = 1, + }, + [ds_1337] = { + .alarm = 1, + }, + [ds_1338] = { + .nvram56 = 1, + }, + [ds_1339] = { + .alarm = 1, + }, + [ds_3231] = { + .alarm = 1, + }, +}; static const struct i2c_device_id ds1307_id[] = { { "ds1307", ds_1307 }, @@ -836,11 +830,7 @@ read_rtc: } break; - case rx_8025: - case ds_1337: - case ds_1339: - case ds_1388: - case ds_3231: + default: break; } -- cgit v1.2.3 From b24a7267709bb0adb694364572478f919e9c7390 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 23 Mar 2012 15:02:37 -0700 Subject: rtc: ds1307: simplify irq setup code No need to have two seperate if-blocks for setting up the irq. Signed-off-by: Wolfram Sang Tested-by: David Anders Cc: Austin Boyle Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 5098e1ad3a3e..d4543e8730cb 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -646,11 +646,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, case ds_1337: case ds_1339: case ds_3231: - /* has IRQ? */ - if (ds1307->client->irq > 0 && chip->alarm) { - INIT_WORK(&ds1307->work, ds1307_work); - want_irq = true; - } /* get registers that the "rtc" read below won't read... */ tmp = ds1307->read_block_data(ds1307->client, DS1337_REG_CONTROL, 2, buf); @@ -668,10 +663,14 @@ static int __devinit ds1307_probe(struct i2c_client *client, * For some variants, be sure alarms can trigger when we're * running on Vbackup (BBSQI/BBSQW) */ - if (want_irq) { + if (ds1307->client->irq > 0 && chip->alarm) { + INIT_WORK(&ds1307->work, ds1307_work); + ds1307->regs[0] |= DS1337_BIT_INTCN | bbsqi_bitpos[ds1307->type]; ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); + + want_irq = true; } i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, -- cgit v1.2.3 From 40ce972d59fcfd4979e5de04456122447b40c1cf Mon Sep 17 00:00:00 2001 From: David Anders Date: Fri, 23 Mar 2012 15:02:37 -0700 Subject: rtc: ds1307: comment and format cleanup Do some cleanup of the comment sections as well as correct some formatting issues reported by checkpatch.pl. Signed-off-by: David Anders Signed-off-by: Wolfram Sang Cc: Austin Boyle Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index d4543e8730cb..84ab971978cf 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -20,7 +20,8 @@ -/* We can't determine type by probing, but if we expect pre-Linux code +/* + * We can't determine type by probing, but if we expect pre-Linux code * to have set the chip up as a clock (turning on the oscillator and * setting the date and time), Linux can ignore the non-clock features. * That's a natural job for a factory or repair bench. @@ -37,7 +38,7 @@ enum ds_type { mcp7941x, rx_8025, last_ds_type /* always last */ - // rs5c372 too? different address... + /* rs5c372 too? different address... */ }; @@ -59,7 +60,8 @@ enum ds_type { # define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */ #define DS1307_REG_YEAR 0x06 /* 00-99 */ -/* Other registers (control, status, alarms, trickle charge, NVRAM, etc) +/* + * Other registers (control, status, alarms, trickle charge, NVRAM, etc) * start at 7, and they differ a LOT. Only control and status matter for * basic RTC date and time functionality; be careful using them. */ @@ -366,6 +368,11 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | DS1340_BIT_CENTURY; break; case mcp7941x: + /* + * these bits were cleared when preparing the date/time + * values and need to be set again before writing the + * buffer out to the device. + */ buf[DS1307_REG_SECS] |= MCP7941X_BIT_ST; buf[DS1307_REG_WDAY] |= MCP7941X_BIT_VBATEN; break; @@ -411,7 +418,8 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) ds1307->regs[6], ds1307->regs[7], ds1307->regs[8]); - /* report alarm time (ALARM1); assume 24 hour and day-of-month modes, + /* + * report alarm time (ALARM1); assume 24 hour and day-of-month modes, * and that all four fields are checked matches */ t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f); @@ -439,7 +447,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) { - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = to_i2c_client(dev); struct ds1307 *ds1307 = i2c_get_clientdata(client); unsigned char *buf = ds1307->regs; u8 control, status; @@ -602,8 +610,6 @@ static struct bin_attribute nvram = { /*----------------------------------------------------------------------*/ -static struct i2c_driver ds1307_driver; - static int __devinit ds1307_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -624,7 +630,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return -EIO; - if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) + ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL); + if (!ds1307) return -ENOMEM; i2c_set_clientdata(client, ds1307); @@ -659,7 +666,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, if (ds1307->regs[0] & DS1337_BIT_nEOSC) ds1307->regs[0] &= ~DS1337_BIT_nEOSC; - /* Using IRQ? Disable the square wave and both alarms. + /* + * Using IRQ? Disable the square wave and both alarms. * For some variants, be sure alarms can trigger when we're * running on Vbackup (BBSQI/BBSQW) */ @@ -765,7 +773,8 @@ read_rtc: goto exit_free; } - /* minimal sanity checking; some chips (like DS1340) don't + /* + * minimal sanity checking; some chips (like DS1340) don't * specify the extra bits as must-be-zero, but there are * still a few values that are clearly out-of-range. */ @@ -837,7 +846,8 @@ read_rtc: switch (ds1307->type) { case ds_1340: case m41t00: - /* NOTE: ignores century bits; fix before deploying + /* + * NOTE: ignores century bits; fix before deploying * systems that will run through year 2100. */ break; @@ -847,7 +857,8 @@ read_rtc: if (!(tmp & DS1307_BIT_12HR)) break; - /* Be sure we're in 24 hour mode. Multi-master systems + /* + * Be sure we're in 24 hour mode. Multi-master systems * take note... */ tmp = bcd2bin(tmp & 0x1f); @@ -902,7 +913,7 @@ exit_free: static int __devexit ds1307_remove(struct i2c_client *client) { - struct ds1307 *ds1307 = i2c_get_clientdata(client); + struct ds1307 *ds1307 = i2c_get_clientdata(client); if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) { free_irq(client->irq, client); -- cgit v1.2.3 From 9eab0a788d2d6e513f43b7c0e5bb9d60446233cb Mon Sep 17 00:00:00 2001 From: Austin Boyle Date: Fri, 23 Mar 2012 15:02:38 -0700 Subject: rtc: ds1307: generalise ram size and offset Generalise NVRAM to support RAM with other size and offset, such as the 64 bytes of SRAM on the mcp7941x. [rdunlap@xenotime.net: fix printk format warning] Signed-off-by: Austin Boyle Signed-off-by: Wolfram Sang Signed-off-by: Randy Dunlap Cc: David Anders Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 78 +++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 31 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 84ab971978cf..cd188ab72f79 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -105,6 +105,8 @@ enum ds_type { struct ds1307 { u8 offset; /* register's offset */ u8 regs[11]; + u16 nvram_offset; + struct bin_attribute *nvram; enum ds_type type; unsigned long flags; #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ @@ -119,19 +121,22 @@ struct ds1307 { }; struct chip_desc { - unsigned nvram56:1; unsigned alarm:1; + u16 nvram_offset; + u16 nvram_size; }; static const struct chip_desc chips[last_ds_type] = { [ds_1307] = { - .nvram56 = 1, + .nvram_offset = 8, + .nvram_size = 56, }, [ds_1337] = { .alarm = 1, }, [ds_1338] = { - .nvram56 = 1, + .nvram_offset = 8, + .nvram_size = 56, }, [ds_1339] = { .alarm = 1, @@ -139,6 +144,11 @@ static const struct chip_desc chips[last_ds_type] = { [ds_3231] = { .alarm = 1, }, + [mcp7941x] = { + /* this is battery backed SRAM */ + .nvram_offset = 0x20, + .nvram_size = 0x40, + }, }; static const struct i2c_device_id ds1307_id[] = { @@ -543,8 +553,6 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { /*----------------------------------------------------------------------*/ -#define NVRAM_SIZE 56 - static ssize_t ds1307_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, @@ -557,14 +565,15 @@ ds1307_nvram_read(struct file *filp, struct kobject *kobj, client = kobj_to_i2c_client(kobj); ds1307 = i2c_get_clientdata(client); - if (unlikely(off >= NVRAM_SIZE)) + if (unlikely(off >= ds1307->nvram->size)) return 0; - if ((off + count) > NVRAM_SIZE) - count = NVRAM_SIZE - off; + if ((off + count) > ds1307->nvram->size) + count = ds1307->nvram->size - off; if (unlikely(!count)) return count; - result = ds1307->read_block_data(client, 8 + off, count, buf); + result = ds1307->read_block_data(client, ds1307->nvram_offset + off, + count, buf); if (result < 0) dev_err(&client->dev, "%s error %d\n", "nvram read", result); return result; @@ -582,14 +591,15 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, client = kobj_to_i2c_client(kobj); ds1307 = i2c_get_clientdata(client); - if (unlikely(off >= NVRAM_SIZE)) + if (unlikely(off >= ds1307->nvram->size)) return -EFBIG; - if ((off + count) > NVRAM_SIZE) - count = NVRAM_SIZE - off; + if ((off + count) > ds1307->nvram->size) + count = ds1307->nvram->size - off; if (unlikely(!count)) return count; - result = ds1307->write_block_data(client, 8 + off, count, buf); + result = ds1307->write_block_data(client, ds1307->nvram_offset + off, + count, buf); if (result < 0) { dev_err(&client->dev, "%s error %d\n", "nvram write", result); return result; @@ -597,17 +607,6 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, return count; } -static struct bin_attribute nvram = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - }, - - .read = ds1307_nvram_read, - .write = ds1307_nvram_write, - .size = NVRAM_SIZE, -}; - /*----------------------------------------------------------------------*/ static int __devinit ds1307_probe(struct i2c_client *client, @@ -894,16 +893,31 @@ read_rtc: dev_dbg(&client->dev, "got IRQ %d\n", client->irq); } - if (chip->nvram56) { - err = sysfs_create_bin_file(&client->dev.kobj, &nvram); - if (err == 0) { - set_bit(HAS_NVRAM, &ds1307->flags); - dev_info(&client->dev, "56 bytes nvram\n"); + if (chip->nvram_size) { + ds1307->nvram = kzalloc(sizeof(struct bin_attribute), + GFP_KERNEL); + if (!ds1307->nvram) { + err = -ENOMEM; + goto exit_nvram; + } + ds1307->nvram->attr.name = "nvram"; + ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; + ds1307->nvram->read = ds1307_nvram_read, + ds1307->nvram->write = ds1307_nvram_write, + ds1307->nvram->size = chip->nvram_size; + ds1307->nvram_offset = chip->nvram_offset; + err = sysfs_create_bin_file(&client->dev.kobj, ds1307->nvram); + if (err) { + kfree(ds1307->nvram); + goto exit_nvram; } + set_bit(HAS_NVRAM, &ds1307->flags); + dev_info(&client->dev, "%zu bytes nvram\n", ds1307->nvram->size); } return 0; +exit_nvram: exit_irq: rtc_device_unregister(ds1307->rtc); exit_free: @@ -920,8 +934,10 @@ static int __devexit ds1307_remove(struct i2c_client *client) cancel_work_sync(&ds1307->work); } - if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) - sysfs_remove_bin_file(&client->dev.kobj, &nvram); + if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) { + sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram); + kfree(ds1307->nvram); + } rtc_device_unregister(ds1307->rtc); kfree(ds1307); -- cgit v1.2.3