diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 2 | ||||
-rw-r--r-- | drivers/rtc/class.c | 32 | ||||
-rw-r--r-- | drivers/rtc/interface.c | 5 | ||||
-rw-r--r-- | drivers/rtc/rtc-dm355evm.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1305.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 27 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1511.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1553.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1672.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1742.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-em3027.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-ep93xx.c | 16 | ||||
-rw-r--r-- | drivers/rtc/rtc-imxdi.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-isl12022.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-lib.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-mc13xxx.c | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-mrst.c | 19 | ||||
-rw-r--r-- | drivers/rtc/rtc-mv.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf2123.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf8563.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-puv3.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-rs5c348.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-rs5c372.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 105 | ||||
-rw-r--r-- | drivers/rtc/rtc-stk17ta8.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-twl.c | 60 | ||||
-rw-r--r-- | drivers/rtc/rtc-tx4939.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-x1205.c | 1 |
28 files changed, 164 insertions, 131 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 5a538fc1cc8..53eb4e55b28 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -8,7 +8,7 @@ config RTC_LIB menuconfig RTC_CLASS bool "Real Time Clock" default n - depends on !S390 + depends on !S390 && !UML select RTC_LIB help Generic RTC class support. If you say yes here, you will diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index b82a1554cdc..dc4c2748bbc 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -21,16 +21,13 @@ #include "rtc-core.h" -static DEFINE_IDR(rtc_idr); -static DEFINE_MUTEX(idr_lock); +static DEFINE_IDA(rtc_ida); struct class *rtc_class; static void rtc_device_release(struct device *dev) { struct rtc_device *rtc = to_rtc_device(dev); - mutex_lock(&idr_lock); - idr_remove(&rtc_idr, rtc->id); - mutex_unlock(&idr_lock); + ida_simple_remove(&rtc_ida, rtc->id); kfree(rtc); } @@ -146,25 +143,16 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, struct rtc_wkalrm alrm; int id, err; - if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { - err = -ENOMEM; + id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL); + if (id < 0) { + err = id; goto exit; } - - mutex_lock(&idr_lock); - err = idr_get_new(&rtc_idr, NULL, &id); - mutex_unlock(&idr_lock); - - if (err < 0) - goto exit; - - id = id & MAX_ID_MASK; - rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL); if (rtc == NULL) { err = -ENOMEM; - goto exit_idr; + goto exit_ida; } rtc->id = id; @@ -222,10 +210,8 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, exit_kfree: kfree(rtc); -exit_idr: - mutex_lock(&idr_lock); - idr_remove(&rtc_idr, id); - mutex_unlock(&idr_lock); +exit_ida: + ida_simple_remove(&rtc_ida, id); exit: dev_err(dev, "rtc core: unable to register %s, err = %d\n", @@ -276,7 +262,7 @@ static void __exit rtc_exit(void) { rtc_dev_exit(); class_destroy(rtc_class); - idr_destroy(&rtc_idr); + ida_destroy(&rtc_ida); } subsys_initcall(rtc_init); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index e3cf2f54221..fa4d9f32418 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -13,6 +13,7 @@ #include <linux/rtc.h> #include <linux/sched.h> +#include <linux/module.h> #include <linux/log2.h> #include <linux/workqueue.h> @@ -646,7 +647,7 @@ EXPORT_SYMBOL_GPL(rtc_irq_unregister); static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled) { /* - * We unconditionally cancel the timer here, because otherwise + * We always cancel the timer here first, because otherwise * we could run into BUG_ON(timer->state != HRTIMER_STATE_CALLBACK); * when we manage to start the timer before the callback * returns HRTIMER_RESTART. @@ -715,7 +716,7 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) int err = 0; unsigned long flags; - if (freq <= 0 || freq > 5000) + if (freq <= 0 || freq > RTC_MAX_FREQ) return -EINVAL; retry: spin_lock_irqsave(&rtc->irq_task_lock, flags); diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c index 58d4e18530d..2322c43af20 100644 --- a/drivers/rtc/rtc-dm355evm.c +++ b/drivers/rtc/rtc-dm355evm.c @@ -14,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/i2c/dm355evm_msp.h> +#include <linux/module.h> /* diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 57fbcc149ba..3a33b1fdbe0 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -17,6 +17,7 @@ #include <linux/spi/spi.h> #include <linux/spi/ds1305.h> +#include <linux/module.h> /* diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index b2005b44e4f..62b0763b7b9 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -34,6 +34,7 @@ enum ds_type { ds_1388, ds_3231, m41t00, + mcp7941x, rx_8025, // rs5c372 too? different address... }; @@ -43,6 +44,7 @@ enum ds_type { #define DS1307_REG_SECS 0x00 /* 00-59 */ # define DS1307_BIT_CH 0x80 # define DS1340_BIT_nEOSC 0x80 +# define MCP7941X_BIT_ST 0x80 #define DS1307_REG_MIN 0x01 /* 00-59 */ #define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */ # define DS1307_BIT_12HR 0x40 /* in REG_HOUR */ @@ -50,6 +52,7 @@ enum ds_type { # define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */ # define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */ #define DS1307_REG_WDAY 0x03 /* 01-07 */ +# define MCP7941X_BIT_VBATEN 0x08 #define DS1307_REG_MDAY 0x04 /* 01-31 */ #define DS1307_REG_MONTH 0x05 /* 01-12 */ # define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */ @@ -137,6 +140,8 @@ static const struct chip_desc chips[] = { }, [m41t00] = { }, +[mcp7941x] = { +}, [rx_8025] = { }, }; @@ -149,6 +154,7 @@ static const struct i2c_device_id ds1307_id[] = { { "ds1340", ds_1340 }, { "ds3231", ds_3231 }, { "m41t00", m41t00 }, + { "mcp7941x", mcp7941x }, { "pt7c4338", ds_1307 }, { "rx8025", rx_8025 }, { } @@ -365,6 +371,10 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN | DS1340_BIT_CENTURY; break; + case mcp7941x: + buf[DS1307_REG_SECS] |= MCP7941X_BIT_ST; + buf[DS1307_REG_WDAY] |= MCP7941X_BIT_VBATEN; + break; default: break; } @@ -809,6 +819,23 @@ read_rtc: dev_warn(&client->dev, "SET TIME!\n"); } break; + case mcp7941x: + /* make sure that the backup battery is enabled */ + if (!(ds1307->regs[DS1307_REG_WDAY] & MCP7941X_BIT_VBATEN)) { + i2c_smbus_write_byte_data(client, DS1307_REG_WDAY, + ds1307->regs[DS1307_REG_WDAY] + | MCP7941X_BIT_VBATEN); + } + + /* clock halted? turn it on, so clock can tick. */ + if (!(tmp & MCP7941X_BIT_ST)) { + i2c_smbus_write_byte_data(client, DS1307_REG_SECS, + MCP7941X_BIT_ST); + dev_warn(&client->dev, "SET TIME!\n"); + goto read_rtc; + } + + break; case rx_8025: case ds_1337: case ds_1339: diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 568ad30617e..586c244a05d 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -23,6 +23,7 @@ #include <linux/rtc.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/module.h> #define DRV_VERSION "0.6" diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index fee41b97c9e..1350029044e 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -18,6 +18,7 @@ #include <linux/rtc.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/module.h> #define DRV_VERSION "0.3" diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 06dfb54f99b..a319402a544 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -11,6 +11,7 @@ #include <linux/i2c.h> #include <linux/rtc.h> +#include <linux/module.h> #define DRV_VERSION "0.4" diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index d84a448dd75..e3e0f92b60f 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -21,6 +21,7 @@ #include <linux/rtc.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/module.h> #define DRV_VERSION "0.4" diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index d8e1c257855..8414dea5fb1 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c @@ -14,6 +14,7 @@ #include <linux/i2c.h> #include <linux/rtc.h> #include <linux/bcd.h> +#include <linux/module.h> /* Registers */ #define EM3027_REG_ON_OFF_CTRL 0x00 diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 335551d333b..14a42a1edc6 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c @@ -36,6 +36,7 @@ */ struct ep93xx_rtc { void __iomem *mmio_base; + struct rtc_device *rtc; }; static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload, @@ -130,7 +131,6 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) { struct ep93xx_rtc *ep93xx_rtc; struct resource *res; - struct rtc_device *rtc; int err; ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL); @@ -151,12 +151,12 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) return -ENXIO; pdev->dev.platform_data = ep93xx_rtc; - platform_set_drvdata(pdev, rtc); + platform_set_drvdata(pdev, ep93xx_rtc); - rtc = rtc_device_register(pdev->name, + ep93xx_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); + if (IS_ERR(ep93xx_rtc->rtc)) { + err = PTR_ERR(ep93xx_rtc->rtc); goto exit; } @@ -167,7 +167,7 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) return 0; fail: - rtc_device_unregister(rtc); + rtc_device_unregister(ep93xx_rtc->rtc); exit: platform_set_drvdata(pdev, NULL); pdev->dev.platform_data = NULL; @@ -176,11 +176,11 @@ exit: static int __exit ep93xx_rtc_remove(struct platform_device *pdev) { - struct rtc_device *rtc = platform_get_drvdata(pdev); + struct ep93xx_rtc *ep93xx_rtc = platform_get_drvdata(pdev); sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); platform_set_drvdata(pdev, NULL); - rtc_device_unregister(rtc); + rtc_device_unregister(ep93xx_rtc->rtc); pdev->dev.platform_data = NULL; return 0; diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 2dd3c016327..d93a9608b1f 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -35,6 +35,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/rtc.h> +#include <linux/sched.h> #include <linux/workqueue.h> /* DryIce Register Definitions */ diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index ddbc797ea6c..6186833973e 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -15,6 +15,7 @@ #include <linux/bcd.h> #include <linux/rtc.h> #include <linux/slab.h> +#include <linux/module.h> #define DRV_VERSION "0.1" diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index 075f1708dea..c4cf0573111 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c @@ -85,6 +85,8 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) time -= tm->tm_hour * 3600; tm->tm_min = time / 60; tm->tm_sec = time - tm->tm_min * 60; + + tm->tm_isdst = 0; } EXPORT_SYMBOL(rtc_time_to_tm); diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index a1a278bc340..9d0c3b478d5 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -309,7 +309,7 @@ static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) return IRQ_HANDLED; } -static int __devinit mc13xxx_rtc_probe(struct platform_device *pdev) +static int __init mc13xxx_rtc_probe(struct platform_device *pdev) { int ret; struct mc13xxx_rtc *priv; @@ -378,7 +378,7 @@ err_reset_irq_request: return ret; } -static int __devexit mc13xxx_rtc_remove(struct platform_device *pdev) +static int __exit mc13xxx_rtc_remove(struct platform_device *pdev) { struct mc13xxx_rtc *priv = platform_get_drvdata(pdev); @@ -410,7 +410,7 @@ const struct platform_device_id mc13xxx_rtc_idtable[] = { static struct platform_driver mc13xxx_rtc_driver = { .id_table = mc13xxx_rtc_idtable, - .remove = __devexit_p(mc13xxx_rtc_remove), + .remove = __exit_p(mc13xxx_rtc_remove), .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index d33544802a2..bb21f443fb7 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -76,12 +76,15 @@ static inline unsigned char vrtc_is_updating(void) /* * rtc_time's year contains the increment over 1900, but vRTC's YEAR * register can't be programmed to value larger than 0x64, so vRTC - * driver chose to use 1960 (1970 is UNIX time start point) as the base, + * driver chose to use 1972 (1970 is UNIX time start point) as the base, * and does the translation at read/write time. * - * Why not just use 1970 as the offset? it's because using 1960 will + * Why not just use 1970 as the offset? it's because using 1972 will * make it consistent in leap year setting for both vrtc and low-level - * physical rtc devices. + * physical rtc devices. Then why not use 1960 as the offset? If we use + * 1960, for a device's first use, its YEAR register is 0 and the system + * year will be parsed as 1960 which is not a valid UNIX time and will + * cause many applications to fail mysteriously. */ static int mrst_read_time(struct device *dev, struct rtc_time *time) { @@ -99,10 +102,10 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time) time->tm_year = vrtc_cmos_read(RTC_YEAR); spin_unlock_irqrestore(&rtc_lock, flags); - /* Adjust for the 1960/1900 */ - time->tm_year += 60; + /* Adjust for the 1972/1900 */ + time->tm_year += 72; time->tm_mon--; - return RTC_24H; + return rtc_valid_tm(time); } static int mrst_set_time(struct device *dev, struct rtc_time *time) @@ -119,9 +122,9 @@ static int mrst_set_time(struct device *dev, struct rtc_time *time) min = time->tm_min; sec = time->tm_sec; - if (yrs < 70 || yrs > 138) + if (yrs < 72 || yrs > 138) return -EINVAL; - yrs -= 60; + yrs -= 72; spin_lock_irqsave(&rtc_lock, flags); diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 60627a76451..768e2edb967 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -14,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/gfp.h> +#include <linux/module.h> #define RTC_TIME_REG_OFFS 0 diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 71bab0ef544..2ee3bbf7e5e 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -42,6 +42,7 @@ #include <linux/slab.h> #include <linux/rtc.h> #include <linux/spi/spi.h> +#include <linux/module.h> #define DRV_VERSION "0.6" diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index b42c0c67926..606fdfab34e 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -18,6 +18,7 @@ #include <linux/bcd.h> #include <linux/rtc.h> #include <linux/slab.h> +#include <linux/module.h> #define DRV_VERSION "0.4.3" diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c index b3eba3cddd4..e4b6880aabd 100644 --- a/drivers/rtc/rtc-puv3.c +++ b/drivers/rtc/rtc-puv3.c @@ -220,7 +220,7 @@ static void puv3_rtc_enable(struct platform_device *pdev, int en) } } -static int puv3_rtc_remove(struct platform_device *dev) +static int __devexit puv3_rtc_remove(struct platform_device *dev) { struct rtc_device *rtc = platform_get_drvdata(dev); @@ -236,7 +236,7 @@ static int puv3_rtc_remove(struct platform_device *dev) return 0; } -static int puv3_rtc_probe(struct platform_device *pdev) +static int __devinit puv3_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct resource *res; diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 368d0e63cf8..971bc8e08da 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c @@ -23,6 +23,7 @@ #include <linux/rtc.h> #include <linux/workqueue.h> #include <linux/spi/spi.h> +#include <linux/module.h> #define DRV_VERSION "0.2" diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 85c1b848dd7..d29f5432c6e 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -14,6 +14,7 @@ #include <linux/rtc.h> #include <linux/bcd.h> #include <linux/slab.h> +#include <linux/module.h> #define DRV_VERSION "0.6" diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 9329dbb9eba..7639ab906f0 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -51,6 +51,27 @@ static enum s3c_cpu_type s3c_rtc_cpu_type; static DEFINE_SPINLOCK(s3c_rtc_pie_lock); +static void s3c_rtc_alarm_clk_enable(bool enable) +{ + static DEFINE_SPINLOCK(s3c_rtc_alarm_clk_lock); + static bool alarm_clk_enabled; + unsigned long irq_flags; + + spin_lock_irqsave(&s3c_rtc_alarm_clk_lock, irq_flags); + if (enable) { + if (!alarm_clk_enabled) { + clk_enable(rtc_clk); + alarm_clk_enabled = true; + } + } else { + if (alarm_clk_enabled) { + clk_disable(rtc_clk); + alarm_clk_enabled = false; + } + } + spin_unlock_irqrestore(&s3c_rtc_alarm_clk_lock, irq_flags); +} + /* IRQ Handlers */ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) @@ -64,6 +85,9 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP); clk_disable(rtc_clk); + + s3c_rtc_alarm_clk_enable(false); + return IRQ_HANDLED; } @@ -97,6 +121,8 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); clk_disable(rtc_clk); + s3c_rtc_alarm_clk_enable(enabled); + return 0; } @@ -152,10 +178,6 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) goto retry_get_time; } - pr_debug("read time %04d.%02d.%02d %02d:%02d:%02d\n", - 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, - rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); - rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); @@ -164,6 +186,11 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); rtc_tm->tm_year += 100; + + pr_debug("read time %04d.%02d.%02d %02d:%02d:%02d\n", + 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, + rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); + rtc_tm->tm_mon -= 1; clk_disable(rtc_clk); @@ -269,10 +296,9 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) clk_enable(rtc_clk); pr_debug("s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", alrm->enabled, - 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, + 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; writeb(0x00, base + S3C2410_RTCALM); @@ -319,49 +345,7 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) return 0; } -static int s3c_rtc_open(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc_dev = platform_get_drvdata(pdev); - int ret; - - ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq, - IRQF_DISABLED, "s3c2410-rtc alarm", rtc_dev); - - if (ret) { - dev_err(dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); - return ret; - } - - ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, - IRQF_DISABLED, "s3c2410-rtc tick", rtc_dev); - - if (ret) { - dev_err(dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); - goto tick_err; - } - - return ret; - - tick_err: - free_irq(s3c_rtc_alarmno, rtc_dev); - return ret; -} - -static void s3c_rtc_release(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc_dev = platform_get_drvdata(pdev); - - /* do not clear AIE here, it may be needed for wake */ - - free_irq(s3c_rtc_alarmno, rtc_dev); - free_irq(s3c_rtc_tickno, rtc_dev); -} - static const struct rtc_class_ops s3c_rtcops = { - .open = s3c_rtc_open, - .release = s3c_rtc_release, .read_time = s3c_rtc_gettime, .set_time = s3c_rtc_settime, .read_alarm = s3c_rtc_getalarm, @@ -425,6 +409,9 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) { struct rtc_device *rtc = platform_get_drvdata(dev); + free_irq(s3c_rtc_alarmno, rtc); + free_irq(s3c_rtc_tickno, rtc); + platform_set_drvdata(dev, NULL); rtc_device_unregister(rtc); @@ -548,10 +535,32 @@ 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); + 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); + if (ret) { + dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); + free_irq(s3c_rtc_alarmno, rtc); + goto err_tick_irq; + } + clk_disable(rtc_clk); return 0; + err_tick_irq: + free_irq(s3c_rtc_alarmno, rtc); + + err_alarm_irq: + platform_set_drvdata(pdev, NULL); + rtc_device_unregister(rtc); + err_nortc: s3c_rtc_enable(pdev, 0); clk_disable(rtc_clk); diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 3b943673cd3..ed3e9b59903 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -21,6 +21,7 @@ #include <linux/rtc.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/module.h> #define DRV_VERSION "0.1" diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 9a81f778d6b..20687d55e7a 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -362,14 +362,6 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) int res; u8 rd_reg; -#ifdef CONFIG_LOCKDEP - /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which - * we don't want and can't tolerate. Although it might be - * friendlier not to borrow this thread context... - */ - local_irq_enable(); -#endif - res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (res) goto out; @@ -428,24 +420,12 @@ static struct rtc_class_ops twl_rtc_ops = { static int __devinit twl_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; - int ret = 0; + int ret = -EINVAL; int irq = platform_get_irq(pdev, 0); u8 rd_reg; if (irq <= 0) - return -EINVAL; - - rtc = rtc_device_register(pdev->name, - &pdev->dev, &twl_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - dev_err(&pdev->dev, "can't register RTC device, err %ld\n", - PTR_ERR(rtc)); - goto out0; - - } - - platform_set_drvdata(pdev, rtc); + goto out1; ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (ret < 0) @@ -462,14 +442,6 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) if (ret < 0) goto out1; - ret = request_irq(irq, twl_rtc_interrupt, - IRQF_TRIGGER_RISING, - dev_name(&rtc->dev), rtc); - if (ret < 0) { - dev_err(&pdev->dev, "IRQ is not free.\n"); - goto out1; - } - if (twl_class_is_6030()) { twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK, REG_INT_MSK_LINE_A); @@ -480,28 +452,44 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) /* Check RTC module status, Enable if it is off */ ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG); if (ret < 0) - goto out2; + 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 out2; + goto out1; } /* init cached IRQ enable bits */ ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); if (ret < 0) + goto out1; + + rtc = rtc_device_register(pdev->name, + &pdev->dev, &twl_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc)) { + ret = PTR_ERR(rtc); + dev_err(&pdev->dev, "can't register RTC device, err %ld\n", + PTR_ERR(rtc)); + goto out1; + } + + ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt, + IRQF_TRIGGER_RISING, + dev_name(&rtc->dev), rtc); + if (ret < 0) { + dev_err(&pdev->dev, "IRQ is not free.\n"); goto out2; + } - return ret; + platform_set_drvdata(pdev, rtc); + return 0; out2: - free_irq(irq, rtc); -out1: rtc_device_unregister(rtc); -out0: +out1: return ret; } diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index ec6313d1535..aac0ffed434 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -11,6 +11,7 @@ #include <linux/rtc.h> #include <linux/platform_device.h> #include <linux/interrupt.h> +#include <linux/module.h> #include <linux/io.h> #include <linux/gfp.h> #include <asm/txx9/tx4939.h> diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index b00aad2620d..8c051d3179d 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -21,6 +21,7 @@ #include <linux/bcd.h> #include <linux/rtc.h> #include <linux/delay.h> +#include <linux/module.h> #define DRV_VERSION "1.0.8" |