diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 94 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1302.c | 85 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1305.c | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1511.c | 10 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1553.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1742.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-isl1208.c | 45 | ||||
-rw-r--r-- | drivers/rtc/rtc-m41t80.c | 16 | ||||
-rw-r--r-- | drivers/rtc/rtc-m48t59.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-mxc.c | 25 | ||||
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 107 | ||||
-rw-r--r-- | drivers/rtc/rtc-stk17ta8.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-tx4939.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-wm831x.c | 16 |
16 files changed, 267 insertions, 165 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 50ac047cd13..f1598324344 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -640,7 +640,7 @@ config RTC_DRV_OMAP config RTC_DRV_S3C tristate "Samsung S3C series SoC RTC" - depends on ARCH_S3C2410 + depends on ARCH_S3C2410 || ARCH_S3C64XX help RTC (Realtime Clock) driver for the clock inbuilt into the Samsung S3C24XX series of SoCs. This can provide periodic diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index e9aa814ddd2..11b8ea29d2b 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -238,31 +238,32 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) rtc_control = CMOS_READ(RTC_CONTROL); spin_unlock_irq(&rtc_lock); - /* REVISIT this assumes PC style usage: always BCD */ - - if (((unsigned)t->time.tm_sec) < 0x60) - t->time.tm_sec = bcd2bin(t->time.tm_sec); - else - t->time.tm_sec = -1; - if (((unsigned)t->time.tm_min) < 0x60) - t->time.tm_min = bcd2bin(t->time.tm_min); - else - t->time.tm_min = -1; - if (((unsigned)t->time.tm_hour) < 0x24) - t->time.tm_hour = bcd2bin(t->time.tm_hour); - else - t->time.tm_hour = -1; - - if (cmos->day_alrm) { - if (((unsigned)t->time.tm_mday) <= 0x31) - t->time.tm_mday = bcd2bin(t->time.tm_mday); + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + if (((unsigned)t->time.tm_sec) < 0x60) + t->time.tm_sec = bcd2bin(t->time.tm_sec); else - t->time.tm_mday = -1; - if (cmos->mon_alrm) { - if (((unsigned)t->time.tm_mon) <= 0x12) - t->time.tm_mon = bcd2bin(t->time.tm_mon) - 1; + t->time.tm_sec = -1; + if (((unsigned)t->time.tm_min) < 0x60) + t->time.tm_min = bcd2bin(t->time.tm_min); + else + t->time.tm_min = -1; + if (((unsigned)t->time.tm_hour) < 0x24) + t->time.tm_hour = bcd2bin(t->time.tm_hour); + else + t->time.tm_hour = -1; + + if (cmos->day_alrm) { + if (((unsigned)t->time.tm_mday) <= 0x31) + t->time.tm_mday = bcd2bin(t->time.tm_mday); else - t->time.tm_mon = -1; + t->time.tm_mday = -1; + + if (cmos->mon_alrm) { + if (((unsigned)t->time.tm_mon) <= 0x12) + t->time.tm_mon = bcd2bin(t->time.tm_mon)-1; + else + t->time.tm_mon = -1; + } } } t->time.tm_year = -1; @@ -322,29 +323,26 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) { struct cmos_rtc *cmos = dev_get_drvdata(dev); - unsigned char mon, mday, hrs, min, sec; + unsigned char mon, mday, hrs, min, sec, rtc_control; if (!is_valid_irq(cmos->irq)) return -EIO; - /* REVISIT this assumes PC style usage: always BCD */ - - /* Writing 0xff means "don't care" or "match all". */ - mon = t->time.tm_mon + 1; - mon = (mon <= 12) ? bin2bcd(mon) : 0xff; - mday = t->time.tm_mday; - mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; - hrs = t->time.tm_hour; - hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; - min = t->time.tm_min; - min = (min < 60) ? bin2bcd(min) : 0xff; - sec = t->time.tm_sec; - sec = (sec < 60) ? bin2bcd(sec) : 0xff; + + rtc_control = CMOS_READ(RTC_CONTROL); + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + /* Writing 0xff means "don't care" or "match all". */ + mon = (mon <= 12) ? bin2bcd(mon) : 0xff; + mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; + hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; + min = (min < 60) ? bin2bcd(min) : 0xff; + sec = (sec < 60) ? bin2bcd(sec) : 0xff; + } spin_lock_irq(&rtc_lock); @@ -478,7 +476,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) "update_IRQ\t: %s\n" "HPET_emulated\t: %s\n" // "square_wave\t: %s\n" - // "BCD\t\t: %s\n" + "BCD\t\t: %s\n" "DST_enable\t: %s\n" "periodic_freq\t: %d\n" "batt_status\t: %s\n", @@ -486,7 +484,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) (rtc_control & RTC_UIE) ? "yes" : "no", is_hpet_enabled() ? "yes" : "no", // (rtc_control & RTC_SQWE) ? "yes" : "no", - // (rtc_control & RTC_DM_BINARY) ? "no" : "yes", + (rtc_control & RTC_DM_BINARY) ? "no" : "yes", (rtc_control & RTC_DST_EN) ? "yes" : "no", cmos->rtc->irq_freq, (valid & RTC_VRT) ? "okay" : "dead"); @@ -519,7 +517,8 @@ static const struct rtc_class_ops cmos_rtc_ops = { #define NVRAM_OFFSET (RTC_REG_D + 1) static ssize_t -cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +cmos_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { int retval; @@ -547,7 +546,8 @@ cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +cmos_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct cmos_rtc *cmos; @@ -719,6 +719,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) } } + cmos_rtc.dev = dev; + dev_set_drvdata(dev, &cmos_rtc); + cmos_rtc.rtc = rtc_device_register(driver_name, dev, &cmos_rtc_ops, THIS_MODULE); if (IS_ERR(cmos_rtc.rtc)) { @@ -726,8 +729,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) goto cleanup0; } - cmos_rtc.dev = dev; - dev_set_drvdata(dev, &cmos_rtc); rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); spin_lock_irq(&rtc_lock); @@ -749,12 +750,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) spin_unlock_irq(&rtc_lock); - /* FIXME teach the alarm code how to handle binary mode; + /* FIXME: * <asm-generic/rtc.h> doesn't know 12-hour mode either. */ - if (is_valid_irq(rtc_irq) && - (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { - dev_dbg(dev, "only 24-hr BCD mode supported\n"); + if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) { + dev_warn(dev, "only 24-hr supported\n"); retval = -ENXIO; goto cleanup1; } diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 532acf9b05d..359d1e04626 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -16,7 +16,6 @@ #include <linux/rtc.h> #include <linux/io.h> #include <linux/bcd.h> -#include <asm/rtc.h> #define DRV_NAME "rtc-ds1302" #define DRV_VERSION "0.1.1" @@ -34,14 +33,55 @@ #define RTC_ADDR_MIN 0x01 /* Address of minute register */ #define RTC_ADDR_SEC 0x00 /* Address of second register */ +#ifdef CONFIG_SH_SECUREEDGE5410 +#include <asm/rtc.h> +#include <mach/snapgear.h> + #define RTC_RESET 0x1000 #define RTC_IODATA 0x0800 #define RTC_SCLK 0x0400 -#ifdef CONFIG_SH_SECUREEDGE5410 -#include <mach/snapgear.h> #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) #define get_dp() SECUREEDGE_READ_IOPORT() +#define ds1302_set_tx() +#define ds1302_set_rx() + +static inline int ds1302_hw_init(void) +{ + return 0; +} + +static inline void ds1302_reset(void) +{ + set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); +} + +static inline void ds1302_clock(void) +{ + set_dp(get_dp() | RTC_SCLK); /* clock high */ + set_dp(get_dp() & ~RTC_SCLK); /* clock low */ +} + +static inline void ds1302_start(void) +{ + set_dp(get_dp() | RTC_RESET); +} + +static inline void ds1302_stop(void) +{ + set_dp(get_dp() & ~RTC_RESET); +} + +static inline void ds1302_txbit(int bit) +{ + set_dp((get_dp() & ~RTC_IODATA) | (bit ? RTC_IODATA : 0)); +} + +static inline int ds1302_rxbit(void) +{ + return !!(get_dp() & RTC_IODATA); +} + #else #error "Add support for your platform" #endif @@ -50,11 +90,11 @@ static void ds1302_sendbits(unsigned int val) { int i; + ds1302_set_tx(); + for (i = 8; (i); i--, val >>= 1) { - set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? - RTC_IODATA : 0)); - set_dp(get_dp() | RTC_SCLK); /* clock high */ - set_dp(get_dp() & ~RTC_SCLK); /* clock low */ + ds1302_txbit(val & 0x1); + ds1302_clock(); } } @@ -63,10 +103,11 @@ static unsigned int ds1302_recvbits(void) unsigned int val; int i; + ds1302_set_rx(); + for (i = 0, val = 0; (i < 8); i++) { - val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i); - set_dp(get_dp() | RTC_SCLK); /* clock high */ - set_dp(get_dp() & ~RTC_SCLK); /* clock low */ + val |= (ds1302_rxbit() << i); + ds1302_clock(); } return val; @@ -76,23 +117,24 @@ static unsigned int ds1302_readbyte(unsigned int addr) { unsigned int val; - set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); + ds1302_reset(); - set_dp(get_dp() | RTC_RESET); + ds1302_start(); ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); val = ds1302_recvbits(); - set_dp(get_dp() & ~RTC_RESET); + ds1302_stop(); return val; } static void ds1302_writebyte(unsigned int addr, unsigned int val) { - set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); - set_dp(get_dp() | RTC_RESET); + ds1302_reset(); + + ds1302_start(); ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); ds1302_sendbits(val); - set_dp(get_dp() & ~RTC_RESET); + ds1302_stop(); } static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) @@ -167,13 +209,20 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; + if (ds1302_hw_init()) { + dev_err(&pdev->dev, "Failed to init communication channel"); + return -EINVAL; + } + /* Reset */ - set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); + ds1302_reset(); /* Write a magic value to the DS1302 RAM, and see if it sticks. */ ds1302_writebyte(RTC_ADDR_RAM0, 0x42); - if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) + if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) { + dev_err(&pdev->dev, "Failed to probe"); return -ENODEV; + } rtc = rtc_device_register("ds1302", &pdev->dev, &ds1302_rtc_ops, THIS_MODULE); diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 7836c9cec55..48da85e97ca 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -542,7 +542,8 @@ static void msg_init(struct spi_message *m, struct spi_transfer *x, } static ssize_t -ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +ds1305_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct spi_device *spi; @@ -572,7 +573,8 @@ ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +ds1305_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct spi_device *spi; diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index c4ec5c158aa..de033b7ac21 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -556,7 +556,8 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { #define NVRAM_SIZE 56 static ssize_t -ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +ds1307_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client; @@ -580,7 +581,8 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +ds1307_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client; diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 06b8566c453..37268e97de4 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -423,8 +423,9 @@ static const struct rtc_class_ops ds1511_rtc_ops = { }; static ssize_t -ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, - char *buf, loff_t pos, size_t size) +ds1511_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *ba, + char *buf, loff_t pos, size_t size) { ssize_t count; @@ -452,8 +453,9 @@ ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, } static ssize_t -ds1511_nvram_write(struct kobject *kobj, struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +ds1511_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t pos, size_t size) { ssize_t count; diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 244f9994bcb..ff432e2ca27 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -252,7 +252,7 @@ static const struct rtc_class_ops ds1553_rtc_ops = { .update_irq_enable = ds1553_rtc_update_irq_enable, }; -static ssize_t ds1553_nvram_read(struct kobject *kobj, +static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -267,7 +267,7 @@ static ssize_t ds1553_nvram_read(struct kobject *kobj, return count; } -static ssize_t ds1553_nvram_write(struct kobject *kobj, +static ssize_t ds1553_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 2b4b0bc42d6..042630c90dd 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -128,7 +128,7 @@ static const struct rtc_class_ops ds1742_rtc_ops = { .set_time = ds1742_rtc_set_time, }; -static ssize_t ds1742_nvram_read(struct kobject *kobj, +static ssize_t ds1742_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -143,7 +143,7 @@ static ssize_t ds1742_nvram_read(struct kobject *kobj, return count; } -static ssize_t ds1742_nvram_write(struct kobject *kobj, +static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 054e05294af..468200c38ec 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -462,39 +462,16 @@ isl1208_sysfs_store_usr(struct device *dev, static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, isl1208_sysfs_store_usr); -static int -isl1208_sysfs_register(struct device *dev) -{ - int err; - - err = device_create_file(dev, &dev_attr_atrim); - if (err) - return err; - - err = device_create_file(dev, &dev_attr_dtrim); - if (err) { - device_remove_file(dev, &dev_attr_atrim); - return err; - } - - err = device_create_file(dev, &dev_attr_usr); - if (err) { - device_remove_file(dev, &dev_attr_atrim); - device_remove_file(dev, &dev_attr_dtrim); - } - - return 0; -} - -static int -isl1208_sysfs_unregister(struct device *dev) -{ - device_remove_file(dev, &dev_attr_dtrim); - device_remove_file(dev, &dev_attr_atrim); - device_remove_file(dev, &dev_attr_usr); +static struct attribute *isl1208_rtc_attrs[] = { + &dev_attr_atrim.attr, + &dev_attr_dtrim.attr, + &dev_attr_usr.attr, + NULL +}; - return 0; -} +static const struct attribute_group isl1208_rtc_sysfs_files = { + .attrs = isl1208_rtc_attrs, +}; static int isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -529,7 +506,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) dev_warn(&client->dev, "rtc power failure detected, " "please set clock.\n"); - rc = isl1208_sysfs_register(&client->dev); + rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); if (rc) goto exit_unregister; @@ -546,7 +523,7 @@ isl1208_remove(struct i2c_client *client) { struct rtc_device *rtc = i2c_get_clientdata(client); - isl1208_sysfs_unregister(&client->dev); + sysfs_remove_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); rtc_device_unregister(rtc); return 0; diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 60fe266f0f4..038095d9997 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -623,7 +623,7 @@ static ssize_t wdt_read(struct file *file, char __user *buf, * according to their available features. We only actually usefully support * querying capabilities and current status. */ -static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, +static int wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int new_margin, rv; @@ -676,6 +676,18 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return -ENOTTY; } +static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = wdt_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + /** * wdt_open: * @inode: inode of device @@ -736,7 +748,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .read = wdt_read, - .ioctl = wdt_ioctl, + .unlocked_ioctl = wdt_unlocked_ioctl, .write = wdt_write, .open = wdt_open, .release = wdt_release, diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 365ff3ac234..be8359fdb65 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -343,7 +343,7 @@ static const struct rtc_class_ops m48t02_rtc_ops = { .set_time = m48t59_rtc_set_time, }; -static ssize_t m48t59_nvram_read(struct kobject *kobj, +static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -363,7 +363,7 @@ static ssize_t m48t59_nvram_read(struct kobject *kobj, return cnt; } -static ssize_t m48t59_nvram_write(struct kobject *kobj, +static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index d71fe61db1d..25ec921db07 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -379,7 +379,6 @@ static struct rtc_class_ops mxc_rtc_ops = { static int __init mxc_rtc_probe(struct platform_device *pdev) { - struct clk *clk; struct resource *res; struct rtc_device *rtc; struct rtc_plat_data *pdata = NULL; @@ -402,14 +401,15 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - clk = clk_get(&pdev->dev, "ckil"); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); + pdata->clk = clk_get(&pdev->dev, "rtc"); + if (IS_ERR(pdata->clk)) { + dev_err(&pdev->dev, "unable to get clock!\n"); + ret = PTR_ERR(pdata->clk); goto exit_free_pdata; } - rate = clk_get_rate(clk); - clk_put(clk); + clk_enable(pdata->clk); + rate = clk_get_rate(pdata->clk); if (rate == 32768) reg = RTC_INPUT_CLK_32768HZ; @@ -420,7 +420,7 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) else { dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); ret = -EINVAL; - goto exit_free_pdata; + goto exit_put_clk; } reg |= RTC_ENABLE_BIT; @@ -428,18 +428,9 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { dev_err(&pdev->dev, "hardware module can't be enabled!\n"); ret = -EIO; - goto exit_free_pdata; - } - - pdata->clk = clk_get(&pdev->dev, "rtc"); - if (IS_ERR(pdata->clk)) { - dev_err(&pdev->dev, "unable to get clock!\n"); - ret = PTR_ERR(pdata->clk); - goto exit_free_pdata; + goto exit_put_clk; } - clk_enable(pdata->clk); - rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 4969b6059c8..e5972b2c17b 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -29,6 +29,11 @@ #include <asm/irq.h> #include <plat/regs-rtc.h> +enum s3c_cpu_type { + TYPE_S3C2410, + TYPE_S3C64XX, +}; + /* I have yet to find an S3C implementation with more than one * of these rtc blocks in */ @@ -37,6 +42,7 @@ static struct resource *s3c_rtc_mem; static void __iomem *s3c_rtc_base; static int s3c_rtc_alarmno = NO_IRQ; static int s3c_rtc_tickno = NO_IRQ; +static enum s3c_cpu_type s3c_rtc_cpu_type; static DEFINE_SPINLOCK(s3c_rtc_pie_lock); @@ -80,12 +86,25 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) pr_debug("%s: pie=%d\n", __func__, enabled); spin_lock_irq(&s3c_rtc_pie_lock); - tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; - if (enabled) - tmp |= S3C2410_TICNT_ENABLE; + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + tmp = readb(s3c_rtc_base + S3C2410_RTCCON); + tmp &= ~S3C64XX_RTCCON_TICEN; + + if (enabled) + tmp |= S3C64XX_RTCCON_TICEN; + + writeb(tmp, s3c_rtc_base + S3C2410_RTCCON); + } else { + tmp = readb(s3c_rtc_base + S3C2410_TICNT); + tmp &= ~S3C2410_TICNT_ENABLE; + + if (enabled) + tmp |= S3C2410_TICNT_ENABLE; + + writeb(tmp, s3c_rtc_base + S3C2410_TICNT); + } - writeb(tmp, s3c_rtc_base + S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); return 0; @@ -93,15 +112,21 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) static int s3c_rtc_setfreq(struct device *dev, int freq) { - unsigned int tmp; + struct platform_device *pdev = to_platform_device(dev); + struct rtc_device *rtc_dev = platform_get_drvdata(pdev); + unsigned int tmp = 0; if (!is_power_of_2(freq)) return -EINVAL; spin_lock_irq(&s3c_rtc_pie_lock); - tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; - tmp |= (128 / freq)-1; + if (s3c_rtc_cpu_type == TYPE_S3C2410) { + tmp = readb(s3c_rtc_base + S3C2410_TICNT); + tmp &= S3C2410_TICNT_ENABLE; + } + + tmp |= (rtc_dev->max_user_freq / freq)-1; writeb(tmp, s3c_rtc_base + S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); @@ -283,10 +308,17 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) { - unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); + unsigned int ticnt; - seq_printf(seq, "periodic_IRQ\t: %s\n", - (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + ticnt = readb(s3c_rtc_base + S3C2410_RTCCON); + ticnt &= S3C64XX_RTCCON_TICEN; + } else { + ticnt = readb(s3c_rtc_base + S3C2410_TICNT); + ticnt &= S3C2410_TICNT_ENABLE; + } + + seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); return 0; } @@ -353,10 +385,16 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) if (!en) { tmp = readb(base + S3C2410_RTCCON); - writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON); - - tmp = readb(base + S3C2410_TICNT); - writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) + tmp &= ~S3C64XX_RTCCON_TICEN; + tmp &= ~S3C2410_RTCCON_RTCEN; + writeb(tmp, base + S3C2410_RTCCON); + + if (s3c_rtc_cpu_type == TYPE_S3C2410) { + tmp = readb(base + S3C2410_TICNT); + tmp &= ~S3C2410_TICNT_ENABLE; + writeb(tmp, base + S3C2410_TICNT); + } } else { /* re-enable the device, and check it is ok */ @@ -472,7 +510,12 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) goto err_nortc; } - rtc->max_user_freq = 128; + if (s3c_rtc_cpu_type == TYPE_S3C64XX) + rtc->max_user_freq = 32768; + else + rtc->max_user_freq = 128; + + s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; platform_set_drvdata(pdev, rtc); return 0; @@ -492,20 +535,30 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) /* RTC Power management control */ -static int ticnt_save; +static int ticnt_save, ticnt_en_save; static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) { /* save TICNT for anyone using periodic interrupts */ ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + ticnt_en_save = readb(s3c_rtc_base + S3C2410_RTCCON); + ticnt_en_save &= S3C64XX_RTCCON_TICEN; + } s3c_rtc_enable(pdev, 0); return 0; } static int s3c_rtc_resume(struct platform_device *pdev) { + unsigned int tmp; + s3c_rtc_enable(pdev, 1); writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); + if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { + tmp = readb(s3c_rtc_base + S3C2410_RTCCON); + writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); + } return 0; } #else @@ -513,13 +566,27 @@ static int s3c_rtc_resume(struct platform_device *pdev) #define s3c_rtc_resume NULL #endif -static struct platform_driver s3c2410_rtc_driver = { +static struct platform_device_id s3c_rtc_driver_ids[] = { + { + .name = "s3c2410-rtc", + .driver_data = TYPE_S3C2410, + }, { + .name = "s3c64xx-rtc", + .driver_data = TYPE_S3C64XX, + }, + { } +}; + +MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); + +static struct platform_driver s3c_rtc_driver = { .probe = s3c_rtc_probe, .remove = __devexit_p(s3c_rtc_remove), .suspend = s3c_rtc_suspend, .resume = s3c_rtc_resume, + .id_table = s3c_rtc_driver_ids, .driver = { - .name = "s3c2410-rtc", + .name = "s3c-rtc", .owner = THIS_MODULE, }, }; @@ -529,12 +596,12 @@ static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics static int __init s3c_rtc_init(void) { printk(banner); - return platform_driver_register(&s3c2410_rtc_driver); + return platform_driver_register(&s3c_rtc_driver); } static void __exit s3c_rtc_exit(void) { - platform_driver_unregister(&s3c2410_rtc_driver); + platform_driver_unregister(&s3c_rtc_driver); } module_init(s3c_rtc_init); diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index b53a00198db..3b943673cd3 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -244,7 +244,7 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = { .alarm_irq_enable = stk17ta8_rtc_alarm_irq_enable, }; -static ssize_t stk17ta8_nvram_read(struct kobject *kobj, +static ssize_t stk17ta8_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t pos, size_t size) { @@ -259,7 +259,7 @@ static ssize_t stk17ta8_nvram_read(struct kobject *kobj, return count; } -static ssize_t stk17ta8_nvram_write(struct kobject *kobj, +static ssize_t stk17ta8_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 20bfc64a15c..ec6313d1535 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -188,7 +188,7 @@ static const struct rtc_class_ops tx4939_rtc_ops = { .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, }; -static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, +static ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -207,7 +207,7 @@ static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, return count; } -static ssize_t tx4939_rtc_nvram_write(struct kobject *kobj, +static ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index b16cfe57a48..82931dc65c0 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c @@ -449,17 +449,17 @@ static int wm831x_rtc_probe(struct platform_device *pdev) goto err; } - ret = wm831x_request_irq(wm831x, per_irq, wm831x_per_irq, - IRQF_TRIGGER_RISING, "wm831x_rtc_per", - wm831x_rtc); + ret = request_threaded_irq(per_irq, NULL, wm831x_per_irq, + IRQF_TRIGGER_RISING, "RTC period", + wm831x_rtc); if (ret != 0) { dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n", per_irq, ret); } - ret = wm831x_request_irq(wm831x, alm_irq, wm831x_alm_irq, - IRQF_TRIGGER_RISING, "wm831x_rtc_alm", - wm831x_rtc); + ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq, + IRQF_TRIGGER_RISING, "RTC alarm", + wm831x_rtc); if (ret != 0) { dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", alm_irq, ret); @@ -478,8 +478,8 @@ static int __devexit wm831x_rtc_remove(struct platform_device *pdev) int per_irq = platform_get_irq_byname(pdev, "PER"); int alm_irq = platform_get_irq_byname(pdev, "ALM"); - wm831x_free_irq(wm831x_rtc->wm831x, alm_irq, wm831x_rtc); - wm831x_free_irq(wm831x_rtc->wm831x, per_irq, wm831x_rtc); + free_irq(alm_irq, wm831x_rtc); + free_irq(per_irq, wm831x_rtc); rtc_device_unregister(wm831x_rtc->rtc); kfree(wm831x_rtc); |