From 695794ae0c5bdd9bd06e35b118801e2e9be04f9e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 22 May 2008 17:21:08 -0400 Subject: Driver Core: add ability for class_find_device to start in middle of list This mirrors the functionality that driver_find_device has as well. We add a start variable, and all callers of the function are fixed up at the same time. The block layer will be using this new functionality in a follow-on patch. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 58b7336640ff..d397fa5f3a91 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -345,7 +345,7 @@ struct rtc_device *rtc_class_open(char *name) struct device *dev; struct rtc_device *rtc = NULL; - dev = class_find_device(rtc_class, name, __rtc_match); + dev = class_find_device(rtc_class, NULL, name, __rtc_match); if (dev) rtc = to_rtc_device(dev); -- cgit v1.2.3 From 35aa64f3a117a16c466f688f52ac3847b3b572e8 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Wed, 23 Jul 2008 21:30:29 -0700 Subject: rtc: m41t80: sort header inclusions for readability Sort the header inclusions for readability. No functional changes. Signed-off-by: Maciej W. Rozycki Cc: Alessandro Zummo Cc: Alexander Bigga Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-m41t80.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 0a19c06019be..4b260664547d 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -13,21 +13,21 @@ * */ -#include +#include +#include #include #include +#include +#include #include #include #include -#include -#include -#include #ifdef CONFIG_RTC_DRV_M41T80_WDT -#include -#include -#include #include #include +#include +#include +#include #endif #define M41T80_REG_SSEC 0 -- cgit v1.2.3 From 4c228db0b30fa12d65ae7461ce29ed1f4da12c5b Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Wed, 23 Jul 2008 21:30:32 -0700 Subject: rtc: m41t80: use pr_info() as appropriate Replace printk(KERN_INFO ...) calls with appropriate pr_info(...) equivalents. Signed-off-by: Maciej W. Rozycki Cc: Alessandro Zummo Cc: Alexander Bigga Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-m41t80.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 4b260664547d..24bc1689fc74 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -631,14 +631,12 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return -EFAULT; if (rv & WDIOS_DISABLECARD) { - printk(KERN_INFO - "rtc-m41t80: disable watchdog\n"); + pr_info("rtc-m41t80: disable watchdog\n"); wdt_disable(); } if (rv & WDIOS_ENABLECARD) { - printk(KERN_INFO - "rtc-m41t80: enable watchdog\n"); + pr_info("rtc-m41t80: enable watchdog\n"); wdt_ping(); } -- cgit v1.2.3 From 5ad31a575157147b43fa84ef1e21471661653878 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 23 Jul 2008 21:30:33 -0700 Subject: rtc: remove BKL for ioctl() Remove implicit use of BKL in ioctl() from the RTC framework. Instead, the rtc->ops_lock is used. That's the same lock that already protects the RTC operations when they're issued through the exported rtc_*() calls in drivers/rtc/interface.c ... making this a bugfix, not just a cleanup, since both ioctl calls and set_alarm() need to update IRQ enable flags and that implies a common lock (which RTC drivers as a rule do not provide on their own). A new comment at the declaration of "struct rtc_class_ops" summarizes current locking rules. It's not clear to me that the exceptions listed there should exist ... if not, those are pre-existing problems which can be fixed in a patch that doesn't relate to BKL removal. Signed-off-by: David Brownell Cc: Alan Cox Cc: Jonathan Corbet Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-dev.c | 58 +++++++++++++++++++++++++++++++++------------------ include/linux/rtc.h | 17 +++++++++++++++ 2 files changed, 55 insertions(+), 20 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 0114a78b7cbb..0a870b7e5c32 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -209,7 +209,7 @@ static unsigned int rtc_dev_poll(struct file *file, poll_table *wait) return (data != 0) ? (POLLIN | POLLRDNORM) : 0; } -static int rtc_dev_ioctl(struct inode *inode, struct file *file, +static long rtc_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; @@ -219,6 +219,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, struct rtc_wkalrm alarm; void __user *uarg = (void __user *) arg; + err = mutex_lock_interruptible(&rtc->ops_lock); + if (err) + return -EBUSY; + /* check that the calling task has appropriate permissions * for certain ioctls. doing this check here is useful * to avoid duplicate code in each driver. @@ -227,26 +231,31 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, case RTC_EPOCH_SET: case RTC_SET_TIME: if (!capable(CAP_SYS_TIME)) - return -EACCES; + err = -EACCES; break; case RTC_IRQP_SET: if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) - return -EACCES; + err = -EACCES; break; case RTC_PIE_ON: if (rtc->irq_freq > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) - return -EACCES; + err = -EACCES; break; } + if (err) + goto done; + /* try the driver's ioctl interface */ if (ops->ioctl) { err = ops->ioctl(rtc->dev.parent, cmd, arg); - if (err != -ENOIOCTLCMD) + if (err != -ENOIOCTLCMD) { + mutex_unlock(&rtc->ops_lock); return err; + } } /* if the driver does not provide the ioctl interface @@ -265,15 +274,19 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, switch (cmd) { case RTC_ALM_READ: + mutex_unlock(&rtc->ops_lock); + err = rtc_read_alarm(rtc, &alarm); if (err < 0) return err; if (copy_to_user(uarg, &alarm.time, sizeof(tm))) - return -EFAULT; - break; + err = -EFAULT; + return err; case RTC_ALM_SET: + mutex_unlock(&rtc->ops_lock); + if (copy_from_user(&alarm.time, uarg, sizeof(tm))) return -EFAULT; @@ -321,24 +334,26 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, } } - err = rtc_set_alarm(rtc, &alarm); - break; + return rtc_set_alarm(rtc, &alarm); case RTC_RD_TIME: + mutex_unlock(&rtc->ops_lock); + err = rtc_read_time(rtc, &tm); if (err < 0) return err; if (copy_to_user(uarg, &tm, sizeof(tm))) - return -EFAULT; - break; + err = -EFAULT; + return err; case RTC_SET_TIME: + mutex_unlock(&rtc->ops_lock); + if (copy_from_user(&tm, uarg, sizeof(tm))) return -EFAULT; - err = rtc_set_time(rtc, &tm); - break; + return rtc_set_time(rtc, &tm); case RTC_PIE_ON: err = rtc_irq_set_state(rtc, NULL, 1); @@ -376,34 +391,37 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, break; #endif case RTC_WKALM_SET: + mutex_unlock(&rtc->ops_lock); if (copy_from_user(&alarm, uarg, sizeof(alarm))) return -EFAULT; - err = rtc_set_alarm(rtc, &alarm); - break; + return rtc_set_alarm(rtc, &alarm); case RTC_WKALM_RD: + mutex_unlock(&rtc->ops_lock); err = rtc_read_alarm(rtc, &alarm); if (err < 0) return err; if (copy_to_user(uarg, &alarm, sizeof(alarm))) - return -EFAULT; - break; + err = -EFAULT; + return err; #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL case RTC_UIE_OFF: clear_uie(rtc); - return 0; + break; case RTC_UIE_ON: - return set_uie(rtc); + err = set_uie(rtc); #endif default: err = -ENOTTY; break; } +done: + mutex_unlock(&rtc->ops_lock); return err; } @@ -432,7 +450,7 @@ static const struct file_operations rtc_dev_fops = { .llseek = no_llseek, .read = rtc_dev_read, .poll = rtc_dev_poll, - .ioctl = rtc_dev_ioctl, + .unlocked_ioctl = rtc_dev_ioctl, .open = rtc_dev_open, .release = rtc_dev_release, .fasync = rtc_dev_fasync, diff --git a/include/linux/rtc.h b/include/linux/rtc.h index f2d0d1527721..b01fe004cb5e 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -115,6 +115,23 @@ extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm); extern struct class *rtc_class; +/* + * For these RTC methods the device parameter is the physical device + * on whatever bus holds the hardware (I2C, Platform, SPI, etc), which + * was passed to rtc_device_register(). Its driver_data normally holds + * device state, including the rtc_device pointer for the RTC. + * + * Most of these methods are called with rtc_device.ops_lock held, + * through the rtc_*(struct rtc_device *, ...) calls. + * + * The (current) exceptions are mostly filesystem hooks: + * - the proc() hook for procfs + * - non-ioctl() chardev hooks: open(), release(), read_callback() + * - periodic irq calls: irq_set_state(), irq_set_freq() + * + * REVISIT those periodic irq calls *do* have ops_lock when they're + * issued through ioctl() ... + */ struct rtc_class_ops { int (*open)(struct device *); void (*release)(struct device *); -- cgit v1.2.3 From 8fc2c767b06067b417c565c4e75731e68ed41fd8 Mon Sep 17 00:00:00 2001 From: "Kim B. Heino" Date: Wed, 23 Jul 2008 21:30:34 -0700 Subject: rtc: add support for ST M41T94 SPI RTC This patch adds kernel driver for M41T94 RTC chip connected via SPI. I've tested it on two different AT91-based hardwares. This is third revision of the patch: some comments made by Alessandro Zummo fixed. Revision two added support for century bit and fixes. Signed-off-by: Kim B. Heino Signed-off-by: Alessandro Zummo Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 9 +++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-m41t94.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 drivers/rtc/rtc-m41t94.c (limited to 'drivers/rtc') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index fc85bf2e4a97..beffb834c440 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -273,6 +273,15 @@ comment "SPI RTC drivers" if SPI_MASTER +config RTC_DRV_M41T94 + tristate "ST M41T94" + help + If you say yes here you will get support for the + ST M41T94 SPI RTC chip. + + This driver can also be built as a module. If so, the module + will be called rtc-m41t94. + config RTC_DRV_MAX6902 tristate "Maxim MAX6902" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index b5d9d67df887..b0e1af54f800 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o +obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c new file mode 100644 index 000000000000..9b19499c829e --- /dev/null +++ b/drivers/rtc/rtc-m41t94.c @@ -0,0 +1,173 @@ +/* + * Driver for ST M41T94 SPI RTC + * + * Copyright (C) 2008 Kim B. Heino + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#define M41T94_REG_SECONDS 0x01 +#define M41T94_REG_MINUTES 0x02 +#define M41T94_REG_HOURS 0x03 +#define M41T94_REG_WDAY 0x04 +#define M41T94_REG_DAY 0x05 +#define M41T94_REG_MONTH 0x06 +#define M41T94_REG_YEAR 0x07 +#define M41T94_REG_HT 0x0c + +#define M41T94_BIT_HALT 0x40 +#define M41T94_BIT_STOP 0x80 +#define M41T94_BIT_CB 0x40 +#define M41T94_BIT_CEB 0x80 + +static int m41t94_set_time(struct device *dev, struct rtc_time *tm) +{ + struct spi_device *spi = to_spi_device(dev); + u8 buf[8]; /* write cmd + 7 registers */ + + dev_dbg(dev, "%s secs=%d, mins=%d, " + "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", + "write", tm->tm_sec, tm->tm_min, + tm->tm_hour, tm->tm_mday, + tm->tm_mon, tm->tm_year, tm->tm_wday); + + buf[0] = 0x80 | M41T94_REG_SECONDS; /* write time + date */ + buf[M41T94_REG_SECONDS] = BIN2BCD(tm->tm_sec); + buf[M41T94_REG_MINUTES] = BIN2BCD(tm->tm_min); + buf[M41T94_REG_HOURS] = BIN2BCD(tm->tm_hour); + buf[M41T94_REG_WDAY] = BIN2BCD(tm->tm_wday + 1); + buf[M41T94_REG_DAY] = BIN2BCD(tm->tm_mday); + buf[M41T94_REG_MONTH] = BIN2BCD(tm->tm_mon + 1); + + buf[M41T94_REG_HOURS] |= M41T94_BIT_CEB; + if (tm->tm_year >= 100) + buf[M41T94_REG_HOURS] |= M41T94_BIT_CB; + buf[M41T94_REG_YEAR] = BIN2BCD(tm->tm_year % 100); + + return spi_write(spi, buf, 8); +} + +static int m41t94_read_time(struct device *dev, struct rtc_time *tm) +{ + struct spi_device *spi = to_spi_device(dev); + u8 buf[2]; + int ret, hour; + + /* clear halt update bit */ + ret = spi_w8r8(spi, M41T94_REG_HT); + if (ret < 0) + return ret; + if (ret & M41T94_BIT_HALT) { + buf[0] = 0x80 | M41T94_REG_HT; + buf[1] = ret & ~M41T94_BIT_HALT; + spi_write(spi, buf, 2); + } + + /* clear stop bit */ + ret = spi_w8r8(spi, M41T94_REG_SECONDS); + if (ret < 0) + return ret; + if (ret & M41T94_BIT_STOP) { + buf[0] = 0x80 | M41T94_REG_SECONDS; + buf[1] = ret & ~M41T94_BIT_STOP; + spi_write(spi, buf, 2); + } + + tm->tm_sec = BCD2BIN(spi_w8r8(spi, M41T94_REG_SECONDS)); + tm->tm_min = BCD2BIN(spi_w8r8(spi, M41T94_REG_MINUTES)); + hour = spi_w8r8(spi, M41T94_REG_HOURS); + tm->tm_hour = BCD2BIN(hour & 0x3f); + tm->tm_wday = BCD2BIN(spi_w8r8(spi, M41T94_REG_WDAY)) - 1; + tm->tm_mday = BCD2BIN(spi_w8r8(spi, M41T94_REG_DAY)); + tm->tm_mon = BCD2BIN(spi_w8r8(spi, M41T94_REG_MONTH)) - 1; + tm->tm_year = BCD2BIN(spi_w8r8(spi, M41T94_REG_YEAR)); + if ((hour & M41T94_BIT_CB) || !(hour & M41T94_BIT_CEB)) + tm->tm_year += 100; + + dev_dbg(dev, "%s secs=%d, mins=%d, " + "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", + "read", tm->tm_sec, tm->tm_min, + tm->tm_hour, tm->tm_mday, + tm->tm_mon, tm->tm_year, tm->tm_wday); + + /* initial clock setting can be undefined */ + return rtc_valid_tm(tm); +} + +static const struct rtc_class_ops m41t94_rtc_ops = { + .read_time = m41t94_read_time, + .set_time = m41t94_set_time, +}; + +static struct spi_driver m41t94_driver; + +static int __devinit m41t94_probe(struct spi_device *spi) +{ + struct rtc_device *rtc; + int res; + + spi->bits_per_word = 8; + spi_setup(spi); + + res = spi_w8r8(spi, M41T94_REG_SECONDS); + if (res < 0) { + dev_err(&spi->dev, "not found.\n"); + return res; + } + + rtc = rtc_device_register(m41t94_driver.driver.name, + &spi->dev, &m41t94_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + dev_set_drvdata(&spi->dev, rtc); + + return 0; +} + +static int __devexit m41t94_remove(struct spi_device *spi) +{ + struct rtc_device *rtc = platform_get_drvdata(spi); + + if (rtc) + rtc_device_unregister(rtc); + + return 0; +} + +static struct spi_driver m41t94_driver = { + .driver = { + .name = "rtc-m41t94", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = m41t94_probe, + .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_AUTHOR("Kim B. Heino "); +MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 53e84b672c1a8190af2b376c35c7a39cf1214f59 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 23 Jul 2008 21:30:36 -0700 Subject: rtc: ds1305/ds1306 driver Support the Dallas/Maxim DS1305 and DS1306 RTC chips. These use SPI, and support alarms, NVRAM, and a trickle charger for use when their backup power supply is a supercap or rechargeable cell. This basic driver doesn't yet support suspend/resume or wakealarms. Signed-off-by: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 10 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-ds1305.c | 847 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/spi/ds1305.h | 35 ++ 4 files changed, 893 insertions(+) create mode 100644 drivers/rtc/rtc-ds1305.c create mode 100644 include/linux/spi/ds1305.h (limited to 'drivers/rtc') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index beffb834c440..90ab73825401 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -282,6 +282,16 @@ config RTC_DRV_M41T94 This driver can also be built as a module. If so, the module will be called rtc-m41t94. +config RTC_DRV_DS1305 + tristate "Dallas/Maxim DS1305/DS1306" + help + Select this driver to get support for the Dallas/Maxim DS1305 + and DS1306 real time clock chips. These support a trickle + charger, alarms, and NVRAM in addition to the clock. + + This driver can also be built as a module. If so, the module + will be called rtc-ds1305. + config RTC_DRV_MAX6902 tristate "Maxim MAX6902" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index b0e1af54f800..18622ef84cab 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o +obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c new file mode 100644 index 000000000000..b91d02a3ace9 --- /dev/null +++ b/drivers/rtc/rtc-ds1305.c @@ -0,0 +1,847 @@ +/* + * rtc-ds1305.c -- driver for DS1305 and DS1306 SPI RTC chips + * + * Copyright (C) 2008 David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include + +#include +#include + + +/* + * Registers ... mask DS1305_WRITE into register address to write, + * otherwise you're reading it. All non-bitmask values are BCD. + */ +#define DS1305_WRITE 0x80 + + +/* RTC date/time ... the main special cases are that we: + * - Need fancy "hours" encoding in 12hour mode + * - Don't rely on the "day-of-week" field (or tm_wday) + * - Are a 21st-century clock (2000 <= year < 2100) + */ +#define DS1305_RTC_LEN 7 /* bytes for RTC regs */ + +#define DS1305_SEC 0x00 /* register addresses */ +#define DS1305_MIN 0x01 +#define DS1305_HOUR 0x02 +# define DS1305_HR_12 0x40 /* set == 12 hr mode */ +# define DS1305_HR_PM 0x20 /* set == PM (12hr mode) */ +#define DS1305_WDAY 0x03 +#define DS1305_MDAY 0x04 +#define DS1305_MON 0x05 +#define DS1305_YEAR 0x06 + + +/* The two alarms have only sec/min/hour/wday fields (ALM_LEN). + * DS1305_ALM_DISABLE disables a match field (some combos are bad). + * + * NOTE that since we don't use WDAY, we limit ourselves to alarms + * only one day into the future (vs potentially up to a week). + * + * NOTE ALSO that while we could generate once-a-second IRQs (UIE), we + * don't currently support them. We'd either need to do it only when + * no alarm is pending (not the standard model), or to use the second + * alarm (implying that this is a DS1305 not DS1306, *and* that either + * it's wired up a second IRQ we know, or that INTCN is set) + */ +#define DS1305_ALM_LEN 4 /* bytes for ALM regs */ +#define DS1305_ALM_DISABLE 0x80 + +#define DS1305_ALM0(r) (0x07 + (r)) /* register addresses */ +#define DS1305_ALM1(r) (0x0b + (r)) + + +/* three control registers */ +#define DS1305_CONTROL_LEN 3 /* bytes of control regs */ + +#define DS1305_CONTROL 0x0f /* register addresses */ +# define DS1305_nEOSC 0x80 /* low enables oscillator */ +# define DS1305_WP 0x40 /* write protect */ +# define DS1305_INTCN 0x04 /* clear == only int0 used */ +# define DS1306_1HZ 0x04 /* enable 1Hz output */ +# define DS1305_AEI1 0x02 /* enable ALM1 IRQ */ +# define DS1305_AEI0 0x01 /* enable ALM0 IRQ */ +#define DS1305_STATUS 0x10 +/* status has just AEIx bits, mirrored as IRQFx */ +#define DS1305_TRICKLE 0x11 +/* trickle bits are defined in */ + +/* a bunch of NVRAM */ +#define DS1305_NVRAM_LEN 96 /* bytes of NVRAM */ + +#define DS1305_NVRAM 0x20 /* register addresses */ + + +struct ds1305 { + struct spi_device *spi; + struct rtc_device *rtc; + + struct work_struct work; + + unsigned long flags; +#define FLAG_EXITING 0 + + bool hr12; + u8 ctrl[DS1305_CONTROL_LEN]; +}; + + +/*----------------------------------------------------------------------*/ + +/* + * Utilities ... tolerate 12-hour AM/PM notation in case of non-Linux + * software (like a bootloader) which may require it. + */ + +static unsigned bcd2hour(u8 bcd) +{ + if (bcd & DS1305_HR_12) { + unsigned hour = 0; + + bcd &= ~DS1305_HR_12; + if (bcd & DS1305_HR_PM) { + hour = 12; + bcd &= ~DS1305_HR_PM; + } + hour += BCD2BIN(bcd); + return hour - 1; + } + return BCD2BIN(bcd); +} + +static u8 hour2bcd(bool hr12, int hour) +{ + if (hr12) { + hour++; + if (hour <= 12) + return DS1305_HR_12 | BIN2BCD(hour); + hour -= 12; + return DS1305_HR_12 | DS1305_HR_PM | BIN2BCD(hour); + } + return BIN2BCD(hour); +} + +/*----------------------------------------------------------------------*/ + +/* + * Interface to RTC framework + */ + +#ifdef CONFIG_RTC_INTF_DEV + +/* + * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) + */ +static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg) +{ + struct ds1305 *ds1305 = dev_get_drvdata(dev); + u8 buf[2]; + int status = -ENOIOCTLCMD; + + buf[0] = DS1305_WRITE | DS1305_CONTROL; + buf[1] = ds1305->ctrl[0]; + + switch (cmd) { + case RTC_AIE_OFF: + status = 0; + if (!(buf[1] & DS1305_AEI0)) + goto done; + buf[1] &= ~DS1305_AEI0; + break; + + case RTC_AIE_ON: + status = 0; + if (ds1305->ctrl[0] & DS1305_AEI0) + goto done; + buf[1] |= DS1305_AEI0; + break; + } + if (status == 0) { + status = spi_write_then_read(ds1305->spi, buf, sizeof buf, + NULL, 0); + if (status >= 0) + ds1305->ctrl[0] = buf[1]; + } + +done: + return status; +} + +#else +#define ds1305_ioctl NULL +#endif + +/* + * Get/set of date and time is pretty normal. + */ + +static int ds1305_get_time(struct device *dev, struct rtc_time *time) +{ + struct ds1305 *ds1305 = dev_get_drvdata(dev); + u8 addr = DS1305_SEC; + u8 buf[DS1305_RTC_LEN]; + int status; + + /* Use write-then-read to get all the date/time registers + * since dma from stack is nonportable + */ + status = spi_write_then_read(ds1305->spi, &addr, sizeof addr, + buf, sizeof buf); + if (status < 0) + return status; + + dev_vdbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", + "read", buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6]); + + /* Decode the registers */ + time->tm_sec = BCD2BIN(buf[DS1305_SEC]); + time->tm_min = BCD2BIN(buf[DS1305_MIN]); + time->tm_hour = bcd2hour(buf[DS1305_HOUR]); + time->tm_wday = buf[DS1305_WDAY] - 1; + time->tm_mday = BCD2BIN(buf[DS1305_MDAY]); + time->tm_mon = BCD2BIN(buf[DS1305_MON]) - 1; + time->tm_year = BCD2BIN(buf[DS1305_YEAR]) + 100; + + dev_vdbg(dev, "%s secs=%d, mins=%d, " + "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", + "read", time->tm_sec, time->tm_min, + time->tm_hour, time->tm_mday, + time->tm_mon, time->tm_year, time->tm_wday); + + /* Time may not be set */ + return rtc_valid_tm(time); +} + +static int ds1305_set_time(struct device *dev, struct rtc_time *time) +{ + struct ds1305 *ds1305 = dev_get_drvdata(dev); + u8 buf[1 + DS1305_RTC_LEN]; + u8 *bp = buf; + + dev_vdbg(dev, "%s secs=%d, mins=%d, " + "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", + "write", time->tm_sec, time->tm_min, + time->tm_hour, time->tm_mday, + time->tm_mon, time->tm_year, time->tm_wday); + + /* Write registers starting at the first time/date address. */ + *bp++ = DS1305_WRITE | DS1305_SEC; + + *bp++ = BIN2BCD(time->tm_sec); + *bp++ = BIN2BCD(time->tm_min); + *bp++ = hour2bcd(ds1305->hr12, time->tm_hour); + *bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1; + *bp++ = BIN2BCD(time->tm_mday); + *bp++ = BIN2BCD(time->tm_mon + 1); + *bp++ = BIN2BCD(time->tm_year - 100); + + dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", + "write", buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + + /* use write-then-read since dma from stack is nonportable */ + return spi_write_then_read(ds1305->spi, buf, sizeof buf, + NULL, 0); +} + +/* + * Get/set of alarm is a bit funky: + * + * - First there's the inherent raciness of getting the (partitioned) + * status of an alarm that could trigger while we're reading parts + * of that status. + * + * - Second there's its limited range (we could increase it a bit by + * relying on WDAY), which means it will easily roll over. + * + * - Third there's the choice of two alarms and alarm signals. + * Here we use ALM0 and expect that nINT0 (open drain) is used; + * that's the only real option for DS1306 runtime alarms, and is + * natural on DS1305. + * + * - Fourth, there's also ALM1, and a second interrupt signal: + * + On DS1305 ALM1 uses nINT1 (when INTCN=1) else nINT0; + * + On DS1306 ALM1 only uses INT1 (an active high pulse) + * and it won't work when VCC1 is active. + * + * So to be most general, we should probably set both alarms to the + * same value, letting ALM1 be the wakeup event source on DS1306 + * and handling several wiring options on DS1305. + * + * - Fifth, we support the polled mode (as well as possible; why not?) + * even when no interrupt line is wired to an IRQ. + */ + +/* + * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) + */ +static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct ds1305 *ds1305 = dev_get_drvdata(dev); + struct spi_device *spi = ds1305->spi; + u8 addr; + int status; + u8 buf[DS1305_ALM_LEN]; + + /* Refresh control register cache BEFORE reading ALM0 registers, + * since reading alarm registers acks any pending IRQ. That + * makes returning "pending" status a bit of a lie, but that bit + * of EFI status is at best fragile anyway (given IRQ handlers). + */ + addr = DS1305_CONTROL; + status = spi_write_then_read(spi, &addr, sizeof addr, + ds1305->ctrl, sizeof ds1305->ctrl); + if (status < 0) + return status; + + alm->enabled = !!(ds1305->ctrl[0] & DS1305_AEI0); + alm->pending = !!(ds1305->ctrl[1] & DS1305_AEI0); + + /* get and check ALM0 registers */ + addr = DS1305_ALM0(DS1305_SEC); + status = spi_write_then_read(spi, &addr, sizeof addr, + buf, sizeof buf); + if (status < 0) + return status; + + dev_vdbg(dev, "%s: %02x %02x %02x %02x\n", + "alm0 read", buf[DS1305_SEC], buf[DS1305_MIN], + buf[DS1305_HOUR], buf[DS1305_WDAY]); + + if ((DS1305_ALM_DISABLE & buf[DS1305_SEC]) + || (DS1305_ALM_DISABLE & buf[DS1305_MIN]) + || (DS1305_ALM_DISABLE & buf[DS1305_HOUR])) + return -EIO; + + /* Stuff these values into alm->time and let RTC framework code + * fill in the rest ... and also handle rollover to tomorrow when + * that's needed. + */ + alm->time.tm_sec = BCD2BIN(buf[DS1305_SEC]); + alm->time.tm_min = BCD2BIN(buf[DS1305_MIN]); + alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); + alm->time.tm_mday = -1; + alm->time.tm_mon = -1; + alm->time.tm_year = -1; + /* next three fields are unused by Linux */ + alm->time.tm_wday = -1; + alm->time.tm_mday = -1; + alm->time.tm_isdst = -1; + + return 0; +} + +/* + * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) + */ +static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct ds1305 *ds1305 = dev_get_drvdata(dev); + struct spi_device *spi = ds1305->spi; + unsigned long now, later; + struct rtc_time tm; + int status; + u8 buf[1 + DS1305_ALM_LEN]; + + /* convert desired alarm to time_t */ + status = rtc_tm_to_time(&alm->time, &later); + if (status < 0) + return status; + + /* Read current time as time_t */ + status = ds1305_get_time(dev, &tm); + if (status < 0) + return status; + status = rtc_tm_to_time(&tm, &now); + if (status < 0) + return status; + + /* make sure alarm fires within the next 24 hours */ + if (later <= now) + return -EINVAL; + if ((later - now) > 24 * 60 * 60) + return -EDOM; + + /* disable alarm if needed */ + if (ds1305->ctrl[0] & DS1305_AEI0) { + ds1305->ctrl[0] &= ~DS1305_AEI0; + + buf[0] = DS1305_WRITE | DS1305_CONTROL; + buf[1] = ds1305->ctrl[0]; + status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); + if (status < 0) + return status; + } + + /* write alarm */ + buf[0] = DS1305_WRITE | DS1305_ALM0(DS1305_SEC); + buf[1 + DS1305_SEC] = BIN2BCD(alm->time.tm_sec); + buf[1 + DS1305_MIN] = BIN2BCD(alm->time.tm_min); + buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour); + buf[1 + DS1305_WDAY] = DS1305_ALM_DISABLE; + + dev_dbg(dev, "%s: %02x %02x %02x %02x\n", + "alm0 write", buf[1 + DS1305_SEC], buf[1 + DS1305_MIN], + buf[1 + DS1305_HOUR], buf[1 + DS1305_WDAY]); + + status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); + if (status < 0) + return status; + + /* enable alarm if requested */ + if (alm->enabled) { + ds1305->ctrl[0] |= DS1305_AEI0; + + buf[0] = DS1305_WRITE | DS1305_CONTROL; + buf[1] = ds1305->ctrl[0]; + status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); + } + + return status; +} + +#ifdef CONFIG_PROC_FS + +static int ds1305_proc(struct device *dev, struct seq_file *seq) +{ + struct ds1305 *ds1305 = dev_get_drvdata(dev); + char *diodes = "no"; + char *resistors = ""; + + /* ctrl[2] is treated as read-only; no locking needed */ + if ((ds1305->ctrl[2] & 0xf0) == DS1305_TRICKLE_MAGIC) { + switch (ds1305->ctrl[2] & 0x0c) { + case DS1305_TRICKLE_DS2: + diodes = "2 diodes, "; + break; + case DS1305_TRICKLE_DS1: + diodes = "1 diode, "; + break; + default: + goto done; + } + switch (ds1305->ctrl[2] & 0x03) { + case DS1305_TRICKLE_2K: + resistors = "2k Ohm"; + break; + case DS1305_TRICKLE_4K: + resistors = "4k Ohm"; + break; + case DS1305_TRICKLE_8K: + resistors = "8k Ohm"; + break; + default: + diodes = "no"; + break; + } + } + +done: + return seq_printf(seq, + "trickle_charge\t: %s%s\n", + diodes, resistors); +} + +#else +#define ds1305_proc NULL +#endif + +static const struct rtc_class_ops ds1305_ops = { + .ioctl = ds1305_ioctl, + .read_time = ds1305_get_time, + .set_time = ds1305_set_time, + .read_alarm = ds1305_get_alarm, + .set_alarm = ds1305_set_alarm, + .proc = ds1305_proc, +}; + +static void ds1305_work(struct work_struct *work) +{ + struct ds1305 *ds1305 = container_of(work, struct ds1305, work); + struct mutex *lock = &ds1305->rtc->ops_lock; + struct spi_device *spi = ds1305->spi; + u8 buf[3]; + int status; + + /* lock to protect ds1305->ctrl */ + mutex_lock(lock); + + /* Disable the IRQ, and clear its status ... for now, we "know" + * that if more than one alarm is active, they're in sync. + * Note that reading ALM data registers also clears IRQ status. + */ + ds1305->ctrl[0] &= ~(DS1305_AEI1 | DS1305_AEI0); + ds1305->ctrl[1] = 0; + + buf[0] = DS1305_WRITE | DS1305_CONTROL; + buf[1] = ds1305->ctrl[0]; + buf[2] = 0; + + status = spi_write_then_read(spi, buf, sizeof buf, + NULL, 0); + if (status < 0) + dev_dbg(&spi->dev, "clear irq --> %d\n", status); + + mutex_unlock(lock); + + if (!test_bit(FLAG_EXITING, &ds1305->flags)) + enable_irq(spi->irq); + + /* rtc_update_irq() requires an IRQ-disabled context */ + local_irq_disable(); + rtc_update_irq(ds1305->rtc, 1, RTC_AF | RTC_IRQF); + local_irq_enable(); +} + +/* + * This "real" IRQ handler hands off to a workqueue mostly to allow + * mutex locking for ds1305->ctrl ... unlike I2C, we could issue async + * I/O requests in IRQ context (to clear the IRQ status). + */ +static irqreturn_t ds1305_irq(int irq, void *p) +{ + struct ds1305 *ds1305 = p; + + disable_irq(irq); + schedule_work(&ds1305->work); + return IRQ_HANDLED; +} + +/*----------------------------------------------------------------------*/ + +/* + * Interface for NVRAM + */ + +static void msg_init(struct spi_message *m, struct spi_transfer *x, + u8 *addr, size_t count, char *tx, char *rx) +{ + spi_message_init(m); + memset(x, 0, 2 * sizeof(*x)); + + x->tx_buf = addr; + x->len = 1; + spi_message_add_tail(x, m); + + x++; + + x->tx_buf = tx; + x->rx_buf = rx; + x->len = count; + spi_message_add_tail(x, m); +} + +static ssize_t +ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct spi_device *spi; + u8 addr; + struct spi_message m; + struct spi_transfer x[2]; + int status; + + spi = container_of(kobj, struct spi_device, dev.kobj); + + if (unlikely(off >= DS1305_NVRAM_LEN)) + return 0; + if (count >= DS1305_NVRAM_LEN) + count = DS1305_NVRAM_LEN; + if ((off + count) > DS1305_NVRAM_LEN) + count = DS1305_NVRAM_LEN - off; + if (unlikely(!count)) + return count; + + addr = DS1305_NVRAM + off; + msg_init(&m, x, &addr, count, NULL, buf); + + status = spi_sync(spi, &m); + if (status < 0) + dev_err(&spi->dev, "nvram %s error %d\n", "read", status); + return (status < 0) ? status : count; +} + +static ssize_t +ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct spi_device *spi; + u8 addr; + struct spi_message m; + struct spi_transfer x[2]; + int status; + + spi = container_of(kobj, struct spi_device, dev.kobj); + + if (unlikely(off >= DS1305_NVRAM_LEN)) + return -EFBIG; + if (count >= DS1305_NVRAM_LEN) + count = DS1305_NVRAM_LEN; + if ((off + count) > DS1305_NVRAM_LEN) + count = DS1305_NVRAM_LEN - off; + if (unlikely(!count)) + return count; + + addr = (DS1305_WRITE | DS1305_NVRAM) + off; + msg_init(&m, x, &addr, count, buf, NULL); + + status = spi_sync(spi, &m); + if (status < 0) + dev_err(&spi->dev, "nvram %s error %d\n", "write", status); + return (status < 0) ? status : count; +} + +static struct bin_attribute nvram = { + .attr.name = "nvram", + .attr.mode = S_IRUGO | S_IWUSR, + .attr.owner = THIS_MODULE, + .read = ds1305_nvram_read, + .write = ds1305_nvram_write, + .size = DS1305_NVRAM_LEN, +}; + +/*----------------------------------------------------------------------*/ + +/* + * Interface to SPI stack + */ + +static int __devinit ds1305_probe(struct spi_device *spi) +{ + struct ds1305 *ds1305; + struct rtc_device *rtc; + int status; + u8 addr, value; + struct ds1305_platform_data *pdata = spi->dev.platform_data; + bool write_ctrl = false; + + /* Sanity check board setup data. This may be hooked up + * in 3wire mode, but we don't care. Note that unless + * there's an inverter in place, this needs SPI_CS_HIGH! + */ + if ((spi->bits_per_word && spi->bits_per_word != 8) + || (spi->max_speed_hz > 2000000) + || !(spi->mode & SPI_CPHA)) + return -EINVAL; + + /* set up driver data */ + ds1305 = kzalloc(sizeof *ds1305, GFP_KERNEL); + if (!ds1305) + return -ENOMEM; + ds1305->spi = spi; + spi_set_drvdata(spi, ds1305); + + /* read and cache control registers */ + addr = DS1305_CONTROL; + status = spi_write_then_read(spi, &addr, sizeof addr, + ds1305->ctrl, sizeof ds1305->ctrl); + if (status < 0) { + dev_dbg(&spi->dev, "can't %s, %d\n", + "read", status); + goto fail0; + } + + dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", + "read", ds1305->ctrl[0], + ds1305->ctrl[1], ds1305->ctrl[2]); + + /* Sanity check register values ... partially compensating for the + * fact that SPI has no device handshake. A pullup on MISO would + * make these tests fail; but not all systems will have one. If + * some register is neither 0x00 nor 0xff, a chip is likely there. + */ + if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) { + dev_dbg(&spi->dev, "RTC chip is not present\n"); + status = -ENODEV; + goto fail0; + } + if (ds1305->ctrl[2] == 0) + dev_dbg(&spi->dev, "chip may not be present\n"); + + /* enable writes if needed ... if we were paranoid it would + * make sense to enable them only when absolutely necessary. + */ + if (ds1305->ctrl[0] & DS1305_WP) { + u8 buf[2]; + + ds1305->ctrl[0] &= ~DS1305_WP; + + buf[0] = DS1305_WRITE | DS1305_CONTROL; + buf[1] = ds1305->ctrl[0]; + status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); + + dev_dbg(&spi->dev, "clear WP --> %d\n", status); + if (status < 0) + goto fail0; + } + + /* on DS1305, maybe start oscillator; like most low power + * oscillators, it may take a second to stabilize + */ + if (ds1305->ctrl[0] & DS1305_nEOSC) { + ds1305->ctrl[0] &= ~DS1305_nEOSC; + write_ctrl = true; + dev_warn(&spi->dev, "SET TIME!\n"); + } + + /* ack any pending IRQs */ + if (ds1305->ctrl[1]) { + ds1305->ctrl[1] = 0; + write_ctrl = true; + } + + /* this may need one-time (re)init */ + if (pdata) { + /* maybe enable trickle charge */ + if (((ds1305->ctrl[2] & 0xf0) != DS1305_TRICKLE_MAGIC)) { + ds1305->ctrl[2] = DS1305_TRICKLE_MAGIC + | pdata->trickle; + write_ctrl = true; + } + + /* on DS1306, configure 1 Hz signal */ + if (pdata->is_ds1306) { + if (pdata->en_1hz) { + if (!(ds1305->ctrl[0] & DS1306_1HZ)) { + ds1305->ctrl[0] |= DS1306_1HZ; + write_ctrl = true; + } + } else { + if (ds1305->ctrl[0] & DS1306_1HZ) { + ds1305->ctrl[0] &= ~DS1306_1HZ; + write_ctrl = true; + } + } + } + } + + if (write_ctrl) { + u8 buf[4]; + + buf[0] = DS1305_WRITE | DS1305_CONTROL; + buf[1] = ds1305->ctrl[0]; + buf[2] = ds1305->ctrl[1]; + buf[3] = ds1305->ctrl[2]; + status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); + if (status < 0) { + dev_dbg(&spi->dev, "can't %s, %d\n", + "write", status); + goto fail0; + } + + dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", + "write", ds1305->ctrl[0], + ds1305->ctrl[1], ds1305->ctrl[2]); + } + + /* see if non-Linux software set up AM/PM mode */ + addr = DS1305_HOUR; + status = spi_write_then_read(spi, &addr, sizeof addr, + &value, sizeof value); + if (status < 0) { + dev_dbg(&spi->dev, "read HOUR --> %d\n", status); + goto fail0; + } + + ds1305->hr12 = (DS1305_HR_12 & value) != 0; + if (ds1305->hr12) + dev_dbg(&spi->dev, "AM/PM\n"); + + /* register RTC ... from here on, ds1305->ctrl needs locking */ + rtc = rtc_device_register("ds1305", &spi->dev, + &ds1305_ops, THIS_MODULE); + if (IS_ERR(rtc)) { + status = PTR_ERR(rtc); + dev_dbg(&spi->dev, "register rtc --> %d\n", status); + goto fail0; + } + ds1305->rtc = rtc; + + /* Maybe set up alarm IRQ; be ready to handle it triggering right + * away. NOTE that we don't share this. The signal is active low, + * and we can't ack it before a SPI message delay. We temporarily + * disable the IRQ until it's acked, which lets us work with more + * IRQ trigger modes (not all IRQ controllers can do falling edge). + */ + if (spi->irq) { + INIT_WORK(&ds1305->work, ds1305_work); + status = request_irq(spi->irq, ds1305_irq, + 0, dev_name(&rtc->dev), ds1305); + if (status < 0) { + dev_dbg(&spi->dev, "request_irq %d --> %d\n", + spi->irq, status); + goto fail1; + } + } + + /* export NVRAM */ + status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); + if (status < 0) { + dev_dbg(&spi->dev, "register nvram --> %d\n", status); + goto fail2; + } + + return 0; + +fail2: + free_irq(spi->irq, ds1305); +fail1: + rtc_device_unregister(rtc); +fail0: + kfree(ds1305); + return status; +} + +static int __devexit ds1305_remove(struct spi_device *spi) +{ + struct ds1305 *ds1305 = spi_get_drvdata(spi); + + sysfs_remove_bin_file(&spi->dev.kobj, &nvram); + + /* carefully shut down irq and workqueue, if present */ + if (spi->irq) { + set_bit(FLAG_EXITING, &ds1305->flags); + free_irq(spi->irq, ds1305); + flush_scheduled_work(); + } + + rtc_device_unregister(ds1305->rtc); + spi_set_drvdata(spi, NULL); + kfree(ds1305); + return 0; +} + +static struct spi_driver ds1305_driver = { + .driver.name = "rtc-ds1305", + .driver.owner = THIS_MODULE, + .probe = ds1305_probe, + .remove = __devexit_p(ds1305_remove), + /* 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_DESCRIPTION("RTC driver for DS1305 and DS1306 chips"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/spi/ds1305.h b/include/linux/spi/ds1305.h new file mode 100644 index 000000000000..287ec830eab7 --- /dev/null +++ b/include/linux/spi/ds1305.h @@ -0,0 +1,35 @@ +#ifndef __LINUX_SPI_DS1305_H +#define __LINUX_SPI_DS1305_H + +/* + * One-time configuration for ds1305 and ds1306 RTC chips. + * + * Put a pointer to this in spi_board_info.platform_data if you want to + * be sure that Linux (re)initializes this as needed ... after losing + * backup power, and potentially on the first boot. + */ +struct ds1305_platform_data { + + /* Trickle charge configuration: it's OK to leave out the MAGIC + * bitmask; mask in either DS1 or DS2, and then one of 2K/4k/8K. + */ +#define DS1305_TRICKLE_MAGIC 0xa0 +#define DS1305_TRICKLE_DS2 0x08 /* two diodes */ +#define DS1305_TRICKLE_DS1 0x04 /* one diode */ +#define DS1305_TRICKLE_2K 0x01 /* 2 KOhm resistance */ +#define DS1305_TRICKLE_4K 0x02 /* 4 KOhm resistance */ +#define DS1305_TRICKLE_8K 0x03 /* 8 KOhm resistance */ + u8 trickle; + + /* set only on ds1306 parts */ + bool is_ds1306; + + /* ds1306 only: enable 1 Hz output */ + bool en_1hz; + + /* REVISIT: the driver currently expects nINT0 to be wired + * as the alarm IRQ. ALM1 may also need to be set up ... + */ +}; + +#endif /* __LINUX_SPI_DS1305_H */ -- cgit v1.2.3 From 71fc822455ccb63a66be0b6e97a415aceb0062c6 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 23 Jul 2008 21:30:38 -0700 Subject: rtc: rtc-omap footprint shrinkage Shrink the runtime footprint of the OMAP1 RTC driver a bunch by removing some old hacks and switching to platform_driver_probe(). Signed-off-by: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-omap.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index eb23d8423f42..8876605d4d4b 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -92,18 +92,6 @@ #define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr)) -/* platform_bus isn't hotpluggable, so for static linkage it'd be safe - * to get rid of probe() and remove() code ... too bad the driver struct - * remembers probe(), that's about 25% of the runtime footprint!! - */ -#ifndef MODULE -#undef __devexit -#undef __devexit_p -#define __devexit __exit -#define __devexit_p __exit_p -#endif - - /* we rely on the rtc framework to handle locking (rtc->ops_lock), * so the only other requirement is that register accesses which * require BUSY to be clear are made with IRQs locally disabled @@ -324,7 +312,7 @@ static struct rtc_class_ops omap_rtc_ops = { static int omap_rtc_alarm; static int omap_rtc_timer; -static int __devinit omap_rtc_probe(struct platform_device *pdev) +static int __init omap_rtc_probe(struct platform_device *pdev) { struct resource *res, *mem; struct rtc_device *rtc; @@ -440,7 +428,7 @@ fail: return -EIO; } -static int __devexit omap_rtc_remove(struct platform_device *pdev) +static int __exit omap_rtc_remove(struct platform_device *pdev) { struct rtc_device *rtc = platform_get_drvdata(pdev);; @@ -498,8 +486,7 @@ static void omap_rtc_shutdown(struct platform_device *pdev) MODULE_ALIAS("platform:omap_rtc"); static struct platform_driver omap_rtc_driver = { - .probe = omap_rtc_probe, - .remove = __devexit_p(omap_rtc_remove), + .remove = __exit_p(omap_rtc_remove), .suspend = omap_rtc_suspend, .resume = omap_rtc_resume, .shutdown = omap_rtc_shutdown, @@ -511,7 +498,7 @@ static struct platform_driver omap_rtc_driver = { static int __init rtc_init(void) { - return platform_driver_register(&omap_rtc_driver); + return platform_driver_probe(&omap_rtc_driver, omap_rtc_probe); } module_init(rtc_init); -- cgit v1.2.3 From 02bb584f3b1cfc8188522a4d2c8881b65073a4f1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Jul 2008 21:30:39 -0700 Subject: rtc: convert the PCF8583 driver to the new I2C style framework with device_ids Convert the PCF8583 driver to the new I2C style framework with device_ids Signed-off-by: Juergen Beisert Signed-off-by: Wolfram Sang Signed-off-by: Alessandro Zummo Cc: David Brownell Acked-by: Jean Delvare Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pcf8583.c | 129 ++++++++++++++-------------------------------- 1 file changed, 39 insertions(+), 90 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 3d09d8f0b1f0..d388c662bf4b 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c @@ -2,6 +2,7 @@ * drivers/rtc/rtc-pcf8583.c * * Copyright (C) 2000 Russell King + * Copyright (C) 2008 Wolfram Sang & Juergen Beisert, Pengutronix * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -14,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -27,7 +27,6 @@ struct rtc_mem { }; struct pcf8583 { - struct i2c_client client; struct rtc_device *rtc; unsigned char ctrl; }; @@ -40,10 +39,6 @@ struct pcf8583 { #define CTRL_ALARM 0x02 #define CTRL_TIMER 0x01 -static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; - -/* Module parameters */ -I2C_CLIENT_INSMOD; static struct i2c_driver pcf8583_driver; @@ -269,106 +264,60 @@ static const struct rtc_class_ops pcf8583_rtc_ops = { .set_time = pcf8583_rtc_set_time, }; -static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind); - -static int pcf8583_attach(struct i2c_adapter *adap) -{ - return i2c_probe(adap, &addr_data, pcf8583_probe); -} - -static int pcf8583_detach(struct i2c_client *client) -{ - int err; - struct pcf8583 *pcf = i2c_get_clientdata(client); - struct rtc_device *rtc = pcf->rtc; - - if (rtc) - rtc_device_unregister(rtc); - - if ((err = i2c_detach_client(client))) - return err; - - kfree(pcf); - return 0; -} - -static struct i2c_driver pcf8583_driver = { - .driver = { - .name = "pcf8583", - }, - .id = I2C_DRIVERID_PCF8583, - .attach_adapter = pcf8583_attach, - .detach_client = pcf8583_detach, -}; - -static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind) +static int pcf8583_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - struct pcf8583 *pcf; - struct i2c_client *client; - struct rtc_device *rtc; - unsigned char buf[1], ad[1] = { 0 }; + struct pcf8583 *pcf8583; int err; - struct i2c_msg msgs[2] = { - { - .addr = addr, - .flags = 0, - .len = 1, - .buf = ad, - }, { - .addr = addr, - .flags = I2C_M_RD, - .len = 1, - .buf = buf, - } - }; - if (!i2c_check_functionality(adap, I2C_FUNC_I2C)) - return 0; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; - pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); - if (!pcf) + pcf8583 = kzalloc(sizeof(struct pcf8583), GFP_KERNEL); + if (!pcf8583) return -ENOMEM; - client = &pcf->client; + pcf8583->rtc = rtc_device_register(pcf8583_driver.driver.name, + &client->dev, &pcf8583_rtc_ops, THIS_MODULE); - client->addr = addr; - client->adapter = adap; - client->driver = &pcf8583_driver; - - strlcpy(client->name, pcf8583_driver.driver.name, I2C_NAME_SIZE); - - if (i2c_transfer(client->adapter, msgs, 2) != 2) { - err = -EIO; + if (IS_ERR(pcf8583->rtc)) { + err = PTR_ERR(pcf8583->rtc); goto exit_kfree; } - err = i2c_attach_client(client); - - if (err) - goto exit_kfree; - - rtc = rtc_device_register(pcf8583_driver.driver.name, &client->dev, - &pcf8583_rtc_ops, THIS_MODULE); + i2c_set_clientdata(client, pcf8583); + return 0; - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - goto exit_detach; - } +exit_kfree: + kfree(pcf8583); + return err; +} - pcf->rtc = rtc; - i2c_set_clientdata(client, pcf); - set_ctrl(client, buf[0]); +static int __devexit pcf8583_remove(struct i2c_client *client) +{ + struct pcf8583 *pcf8583 = i2c_get_clientdata(client); + if (pcf8583->rtc) + rtc_device_unregister(pcf8583->rtc); + kfree(pcf8583); return 0; +} -exit_detach: - i2c_detach_client(client); - -exit_kfree: - kfree(pcf); +static const struct i2c_device_id pcf8583_id[] = { + { "pcf8583", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pcf8583_id); - return err; -} +static struct i2c_driver pcf8583_driver = { + .driver = { + .name = "pcf8583", + .owner = THIS_MODULE, + }, + .probe = pcf8583_probe, + .remove = __devexit_p(pcf8583_remove), + .id_table = pcf8583_id, +}; static __init int pcf8583_init(void) { -- cgit v1.2.3 From c68d07b2da54c941bb36c9d6d35fe8f263ee10ef Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Wed, 23 Jul 2008 21:30:40 -0700 Subject: rtc: remove and clarify unneeded externs When CONFIG_HPET_EMULATE_RTC is defined the external declaration of hpet_rtc_interrupt is redundant due to the inclusion of hpet.h. When !CONFIG_HPET_EMULATE_RTC we make it clear that hpet_rtc_interrupt is not used by defining it to return zero. Signed-off-by: Carlos R. Mafra Cc: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/rtc.c | 2 -- drivers/rtc/rtc-cmos.c | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index d1569a0d0506..dbefbb30ed44 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -121,8 +121,6 @@ static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) return 0; } #endif -#else -extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); #endif /* diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index d7bb9bac71df..94b89a2d9c2e 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -52,7 +52,10 @@ #define hpet_rtc_timer_init() do { } while (0) #define hpet_register_irq_handler(h) 0 #define hpet_unregister_irq_handler(h) do { } while (0) -extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); +static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) +{ + return 0; +} #endif struct cmos_rtc { -- cgit v1.2.3 From 35d3fdd5f304c06654c940921fc045c60df34693 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 23 Jul 2008 21:30:43 -0700 Subject: rtc-cmos: improve HPET IRQ glue Resolve http://bugzilla.kernel.org/show_bug.cgi?id=11051 and other bugs related to the way the HPET glue code in rtc-cmos was incomplete and inconsistent: * Switch the approach so that the basic driver code flow isn't changed by having HPET ... instead, just have HPET shadow the RTC_CONTROL irq enables and RTC_FREQ_SELECT data. It's only coping with IRQ thievery, after all. * Do that consistently (!!) to avoid problems when the HPET code is out of sync with the real RTC intent. Examples include: - cmos_procfs(), which now reports correct data - cmos_irq_set_state() ... also removing the previous PIE_{ON,OFF} ioctl support so only one code path manages "periodic" IRQs - cmos_do_shutdown() ... currently a "just in case" change. - cmos_suspend() and cmos_resume() ... also handling a bug that was specific to HPET's IRQ thievery, where the alarm wasn't disabled after waking the system * Always call that HPET code under the RTC spinlock (it doesn't do its own locking) Also clean up the HPET glue: * Add some comments explaining what's going on. * Switch to having just one #ifdef for the HPET glue, and inline functions (not #defines) to avoid some compiler warnings. * Have the probe message also report when HPET IRQs are involved This still leaves various holes in the HPET glue, like the emulated update IRQs being out of sync with the RTC, alarms never using day or month matches, and many extra IRQs (at 64 Hz). [akpm@linux-foundation.org: fix build] Signed-off-by: David Brownell Cc: Tomas Janousek Cc: Bernhard Walle Cc: Carlos R. Mafra Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-cmos.c | 193 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 131 insertions(+), 62 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 94b89a2d9c2e..e9984650ea95 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -36,28 +36,9 @@ #include #include -#ifdef CONFIG_HPET_EMULATE_RTC -#include -#endif - /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ #include -#ifndef CONFIG_HPET_EMULATE_RTC -#define is_hpet_enabled() 0 -#define hpet_set_alarm_time(hrs, min, sec) do { } while (0) -#define hpet_set_periodic_freq(arg) 0 -#define hpet_mask_rtc_irq_bit(arg) do { } while (0) -#define hpet_set_rtc_irq_bit(arg) do { } while (0) -#define hpet_rtc_timer_init() do { } while (0) -#define hpet_register_irq_handler(h) 0 -#define hpet_unregister_irq_handler(h) do { } while (0) -static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) -{ - return 0; -} -#endif - struct cmos_rtc { struct rtc_device *rtc; struct device *dev; @@ -96,6 +77,72 @@ static inline int is_intr(u8 rtc_intr) /*----------------------------------------------------------------*/ +/* Much modern x86 hardware has HPETs (10+ MHz timers) which, because + * many BIOS programmers don't set up "sane mode" IRQ routing, are mostly + * used in a broken "legacy replacement" mode. The breakage includes + * HPET #1 hijacking the IRQ for this RTC, and being unavailable for + * other (better) use. + * + * When that broken mode is in use, platform glue provides a partial + * emulation of hardware RTC IRQ facilities using HPET #1. We don't + * want to use HPET for anything except those IRQs though... + */ +#ifdef CONFIG_HPET_EMULATE_RTC +#include +#else + +static inline int is_hpet_enabled(void) +{ + return 0; +} + +static inline int hpet_mask_rtc_irq_bit(unsigned long mask) +{ + return 0; +} + +static inline int hpet_set_rtc_irq_bit(unsigned long mask) +{ + return 0; +} + +static inline int +hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec) +{ + return 0; +} + +static inline int hpet_set_periodic_freq(unsigned long freq) +{ + return 0; +} + +static inline int hpet_rtc_dropped_irq(void) +{ + return 0; +} + +static inline int hpet_rtc_timer_init(void) +{ + return 0; +} + +extern irq_handler_t hpet_rtc_interrupt; + +static inline int hpet_register_irq_handler(irq_handler_t handler) +{ + return 0; +} + +static inline int hpet_unregister_irq_handler(irq_handler_t handler) +{ + return 0; +} + +#endif + +/*----------------------------------------------------------------*/ + static int cmos_read_time(struct device *dev, struct rtc_time *t) { /* REVISIT: if the clock has a "century" register, use @@ -216,13 +263,14 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) sec = t->time.tm_sec; sec = (sec < 60) ? BIN2BCD(sec) : 0xff; - hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec); spin_lock_irq(&rtc_lock); /* next rtc irq must not be from previous alarm setting */ rtc_control = CMOS_READ(RTC_CONTROL); rtc_control &= ~RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); + hpet_mask_rtc_irq_bit(RTC_AIE); + rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; if (is_intr(rtc_intr)) @@ -240,9 +288,16 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) CMOS_WRITE(mon, cmos->mon_alrm); } + /* FIXME the HPET alarm glue currently ignores day_alrm + * and mon_alrm ... + */ + hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec); + if (t->enabled) { rtc_control |= RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); + hpet_set_rtc_irq_bit(RTC_AIE); + rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; if (is_intr(rtc_intr)) @@ -270,8 +325,8 @@ static int cmos_irq_set_freq(struct device *dev, int freq) f = 16 - f; spin_lock_irqsave(&rtc_lock, flags); - if (!hpet_set_periodic_freq(freq)) - CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); + hpet_set_periodic_freq(freq); + CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); spin_unlock_irqrestore(&rtc_lock, flags); return 0; @@ -289,11 +344,13 @@ static int cmos_irq_set_state(struct device *dev, int enabled) spin_lock_irqsave(&rtc_lock, flags); rtc_control = CMOS_READ(RTC_CONTROL); - if (enabled) + if (enabled) { rtc_control |= RTC_PIE; - else + hpet_set_rtc_irq_bit(RTC_PIE); + } else { rtc_control &= ~RTC_PIE; - + hpet_mask_rtc_irq_bit(RTC_PIE); + } CMOS_WRITE(rtc_control, RTC_CONTROL); rtc_intr = CMOS_READ(RTC_INTR_FLAGS); @@ -319,11 +376,10 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) case RTC_AIE_ON: case RTC_UIE_OFF: case RTC_UIE_ON: - case RTC_PIE_OFF: - case RTC_PIE_ON: if (!is_valid_irq(cmos->irq)) return -EINVAL; break; + /* PIE ON/OFF is handled by cmos_irq_set_state() */ default: return -ENOIOCTLCMD; } @@ -347,17 +403,8 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) rtc_control |= RTC_UIE; hpet_set_rtc_irq_bit(RTC_UIE); break; - case RTC_PIE_OFF: /* periodic off */ - rtc_control &= ~RTC_PIE; - hpet_mask_rtc_irq_bit(RTC_PIE); - break; - case RTC_PIE_ON: /* periodic on */ - rtc_control |= RTC_PIE; - hpet_set_rtc_irq_bit(RTC_PIE); - break; } - if (!is_hpet_enabled()) - CMOS_WRITE(rtc_control, RTC_CONTROL); + CMOS_WRITE(rtc_control, RTC_CONTROL); rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; @@ -505,18 +552,19 @@ static irqreturn_t cmos_interrupt(int irq, void *p) u8 rtc_control; spin_lock(&rtc_lock); - /* - * In this case it is HPET RTC interrupt handler - * calling us, with the interrupt information - * passed as arg1, instead of irq. + + /* When the HPET interrupt handler calls us, the interrupt + * status is passed as arg1 instead of the irq number. But + * always clear irq status, even when HPET is in the way. + * + * Note that HPET and RTC are almost certainly out of phase, + * giving different IRQ status ... */ + irqstat = CMOS_READ(RTC_INTR_FLAGS); + rtc_control = CMOS_READ(RTC_CONTROL); if (is_hpet_enabled()) irqstat = (unsigned long)irq & 0xF0; - else { - irqstat = CMOS_READ(RTC_INTR_FLAGS); - rtc_control = CMOS_READ(RTC_CONTROL); - irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; - } + irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; /* All Linux RTC alarms should be treated as if they were oneshot. * Similar code may be needed in system wakeup paths, in case the @@ -526,6 +574,8 @@ static irqreturn_t cmos_interrupt(int irq, void *p) rtc_control = CMOS_READ(RTC_CONTROL); rtc_control &= ~RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); + hpet_mask_rtc_irq_bit(RTC_AIE); + CMOS_READ(RTC_INTR_FLAGS); } spin_unlock(&rtc_lock); @@ -632,8 +682,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) * do something about other clock frequencies. */ cmos_rtc.rtc->irq_freq = 1024; - if (!hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq)) - CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); + hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); + CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); /* disable irqs. * @@ -643,6 +693,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) rtc_control = CMOS_READ(RTC_CONTROL); rtc_control &= ~(RTC_PIE | RTC_AIE | RTC_UIE); CMOS_WRITE(rtc_control, RTC_CONTROL); + hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE); + CMOS_READ(RTC_INTR_FLAGS); spin_unlock_irq(&rtc_lock); @@ -690,7 +742,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) goto cleanup2; } - pr_info("%s: alarms up to one %s%s\n", + pr_info("%s: alarms up to one %s%s%s\n", cmos_rtc.rtc->dev.bus_id, is_valid_irq(rtc_irq) ? (cmos_rtc.mon_alrm @@ -698,8 +750,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) : (cmos_rtc.day_alrm ? "month" : "day")) : "no", - cmos_rtc.century ? ", y3k" : "" - ); + cmos_rtc.century ? ", y3k" : "", + is_hpet_enabled() ? ", hpet irqs" : ""); return 0; @@ -720,8 +772,10 @@ static void cmos_do_shutdown(void) spin_lock_irq(&rtc_lock); rtc_control = CMOS_READ(RTC_CONTROL); - rtc_control &= ~(RTC_PIE|RTC_AIE|RTC_UIE); + rtc_control &= ~RTC_IRQMASK; CMOS_WRITE(rtc_control, RTC_CONTROL); + hpet_mask_rtc_irq_bit(RTC_IRQMASK); + CMOS_READ(RTC_INTR_FLAGS); spin_unlock_irq(&rtc_lock); } @@ -764,12 +818,16 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL); if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { unsigned char irqstat; + unsigned char mask; if (do_wake) - tmp &= ~(RTC_PIE|RTC_UIE); + mask = RTC_IRQMASK & ~RTC_AIE; else - tmp &= ~(RTC_PIE|RTC_AIE|RTC_UIE); + mask = RTC_IRQMASK; + tmp &= ~mask; CMOS_WRITE(tmp, RTC_CONTROL); + hpet_mask_rtc_irq_bit(mask); + irqstat = CMOS_READ(RTC_INTR_FLAGS); irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF; if (is_intr(irqstat)) @@ -799,7 +857,8 @@ static int cmos_resume(struct device *dev) unsigned char tmp = cmos->suspend_ctrl; /* re-enable any irqs previously active */ - if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { + if (tmp & RTC_IRQMASK) { + unsigned char mask; if (cmos->enabled_wake) { if (cmos->wake_off) @@ -810,18 +869,28 @@ static int cmos_resume(struct device *dev) } spin_lock_irq(&rtc_lock); - CMOS_WRITE(tmp, RTC_CONTROL); - tmp = CMOS_READ(RTC_INTR_FLAGS); - tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF; - if (is_intr(tmp)) - rtc_update_irq(cmos->rtc, 1, tmp); + do { + CMOS_WRITE(tmp, RTC_CONTROL); + hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK); + + mask = CMOS_READ(RTC_INTR_FLAGS); + mask &= (tmp & RTC_IRQMASK) | RTC_IRQF; + if (!is_intr(mask)) + break; + + /* force one-shot behavior if HPET blocked + * the wake alarm's irq + */ + rtc_update_irq(cmos->rtc, 1, mask); + tmp &= ~RTC_AIE; + hpet_mask_rtc_irq_bit(RTC_AIE); + } while (mask & RTC_AIE); spin_unlock_irq(&rtc_lock); } pr_debug("%s: resume, ctrl %02x\n", cmos_rtc.rtc->dev.bus_id, - cmos->suspend_ctrl); - + tmp); return 0; } -- cgit v1.2.3 From 4cd0c5c40b64ef9fd94fb8382dade2fd28f2b935 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 23 Jul 2008 21:30:44 -0700 Subject: rtc: rtc-s3c: add __devexit and __devinit markers Add the relevant __devinit and __devexit attributes to the rtc-s3c driver. Signed-off-by: Ben Dooks Acked-by: Alessandro Zummo Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s3c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index fed86e507fdf..b81ba7020d92 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -430,7 +430,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) } } -static int s3c_rtc_remove(struct platform_device *dev) +static int __devexit s3c_rtc_remove(struct platform_device *dev) { struct rtc_device *rtc = platform_get_drvdata(dev); @@ -447,7 +447,7 @@ static int s3c_rtc_remove(struct platform_device *dev) return 0; } -static int s3c_rtc_probe(struct platform_device *pdev) +static int __devinit s3c_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct resource *res; @@ -560,7 +560,7 @@ static int s3c_rtc_resume(struct platform_device *pdev) static struct platform_driver s3c2410_rtcdrv = { .probe = s3c_rtc_probe, - .remove = s3c_rtc_remove, + .remove = __devexit_p(s3c_rtc_remove), .suspend = s3c_rtc_suspend, .resume = s3c_rtc_resume, .driver = { -- cgit v1.2.3 From 773be7ee97c11fbb6b8a912a58b268dbe8a6a3fe Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 23 Jul 2008 21:30:45 -0700 Subject: rtc: rtc-s3c: update IRQ handling The rtc-s3c.c driver has been using its own ioctl() handling to deal with alarm and periodic interrupts to handle what should now be done with the rtc core code. Change to using the .irq_set_freq and .irq_set_state driver entries and remove the .ioctl handling. Signed-off-by: Ben Dooks Acked-by: Alessandro Zummo Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s3c.c | 83 ++++++++++----------------------------------------- 1 file changed, 16 insertions(+), 67 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index b81ba7020d92..54b1ebb01502 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -36,10 +36,8 @@ 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 int s3c_rtc_freq = 1; static DEFINE_SPINLOCK(s3c_rtc_pie_lock); -static unsigned int tick_count; /* IRQ Handlers */ @@ -55,7 +53,7 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) { struct rtc_device *rdev = id; - rtc_update_irq(rdev, tick_count++, RTC_PF | RTC_IRQF); + rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); return IRQ_HANDLED; } @@ -74,35 +72,37 @@ static void s3c_rtc_setaie(int to) writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); } -static void s3c_rtc_setpie(int to) +static int s3c_rtc_setpie(struct device *dev, int enabled) { unsigned int tmp; - pr_debug("%s: pie=%d\n", __func__, to); + 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 (to) + if (enabled) tmp |= S3C2410_TICNT_ENABLE; writeb(tmp, s3c_rtc_base + S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); + + return 0; } -static void s3c_rtc_setfreq(int freq) +static int s3c_rtc_setfreq(struct device *dev, int freq) { unsigned int tmp; spin_lock_irq(&s3c_rtc_pie_lock); - tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; - - s3c_rtc_freq = freq; + tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; tmp |= (128 / freq)-1; writeb(tmp, s3c_rtc_base + S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); + + return 0; } /* Time read/write */ @@ -267,12 +267,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) writeb(alrm_en, base + S3C2410_RTCALM); - if (0) { - alrm_en = readb(base + S3C2410_RTCALM); - alrm_en &= ~S3C2410_RTCALM_ALMEN; - writeb(alrm_en, base + S3C2410_RTCALM); - disable_irq_wake(s3c_rtc_alarmno); - } + s3c_rtc_setaie(alrm->enabled); if (alrm->enabled) enable_irq_wake(s3c_rtc_alarmno); @@ -282,59 +277,12 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) return 0; } -static int s3c_rtc_ioctl(struct device *dev, - unsigned int cmd, unsigned long arg) -{ - unsigned int ret = -ENOIOCTLCMD; - - switch (cmd) { - case RTC_AIE_OFF: - case RTC_AIE_ON: - s3c_rtc_setaie((cmd == RTC_AIE_ON) ? 1 : 0); - ret = 0; - break; - - case RTC_PIE_OFF: - case RTC_PIE_ON: - tick_count = 0; - s3c_rtc_setpie((cmd == RTC_PIE_ON) ? 1 : 0); - ret = 0; - break; - - case RTC_IRQP_READ: - ret = put_user(s3c_rtc_freq, (unsigned long __user *)arg); - break; - - case RTC_IRQP_SET: - if (!is_power_of_2(arg)) { - ret = -EINVAL; - goto exit; - } - - pr_debug("s3c2410_rtc: setting frequency %ld\n", arg); - - s3c_rtc_setfreq(arg); - ret = 0; - break; - - case RTC_UIE_ON: - case RTC_UIE_OFF: - ret = -EINVAL; - } - - exit: - return ret; -} - static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) { unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); seq_printf(seq, "periodic_IRQ\t: %s\n", (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); - - seq_printf(seq, "periodic_freq\t: %d\n", s3c_rtc_freq); - return 0; } @@ -374,7 +322,7 @@ static void s3c_rtc_release(struct device *dev) /* do not clear AIE here, it may be needed for wake */ - s3c_rtc_setpie(0); + s3c_rtc_setpie(dev, 0); free_irq(s3c_rtc_alarmno, rtc_dev); free_irq(s3c_rtc_tickno, rtc_dev); } @@ -382,11 +330,12 @@ static void s3c_rtc_release(struct device *dev) static const struct rtc_class_ops s3c_rtcops = { .open = s3c_rtc_open, .release = s3c_rtc_release, - .ioctl = s3c_rtc_ioctl, .read_time = s3c_rtc_gettime, .set_time = s3c_rtc_settime, .read_alarm = s3c_rtc_getalarm, .set_alarm = s3c_rtc_setalarm, + .irq_set_freq = s3c_rtc_setfreq, + .irq_set_state = s3c_rtc_setpie, .proc = s3c_rtc_proc, }; @@ -437,7 +386,7 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) platform_set_drvdata(dev, NULL); rtc_device_unregister(rtc); - s3c_rtc_setpie(0); + s3c_rtc_setpie(&dev->dev, 0); s3c_rtc_setaie(0); iounmap(s3c_rtc_base); @@ -504,7 +453,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(s3c_rtc_base + S3C2410_RTCCON)); - s3c_rtc_setfreq(s3c_rtc_freq); + s3c_rtc_setfreq(&pdev->dev, 1); /* register RTC and exit */ -- cgit v1.2.3 From 449321b39f6c6ebfa15d6da24f134240bd51db29 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 23 Jul 2008 21:30:46 -0700 Subject: rtc-at91rm9200: avoid spurious irqs This fixes kernel http://bugzilla.kernel.org/show_bug.cgi?id=11112 (bogus RTC update IRQs reported) for rtc-at91rm9200 by scrubbing old IRQ status before enabling IRQs. It also removes nonfunctional periodic IRQ support from this driver; only update IRQs are reported, or provided by the hardware. I suspect some other RTCs probably have versions of #11112; it's easy to overlook, since most non-RTC drivers don't care about spurious IRQs: they're not reported to userspace. Signed-off-by: David Brownell Report-by: W Unruh Cc: Andrew Victor Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-at91rm9200.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 9c3db934cc24..cd32d05db773 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -171,8 +171,10 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | BIN2BCD(tm.tm_mday) << 24 | AT91_RTC_DATEEN | AT91_RTC_MTHEN); - if (alrm->enabled) + if (alrm->enabled) { + at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); + } pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, @@ -191,28 +193,22 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __func__, cmd, arg); + /* important: scrub old status before enabling IRQs */ switch (cmd) { case RTC_AIE_OFF: /* alarm off */ at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); break; case RTC_AIE_ON: /* alarm on */ + at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); break; case RTC_UIE_OFF: /* update off */ - case RTC_PIE_OFF: /* periodic off */ at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV); break; case RTC_UIE_ON: /* update on */ - case RTC_PIE_ON: /* periodic on */ + at91_sys_write(AT91_RTC_SCCR, AT91_RTC_SECEV); at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV); break; - case RTC_IRQP_READ: /* read periodic alarm frequency */ - ret = put_user(AT91_RTC_FREQ, (unsigned long *) arg); - break; - case RTC_IRQP_SET: /* set periodic alarm frequency */ - if (arg != AT91_RTC_FREQ) - ret = -EINVAL; - break; default: ret = -ENOIOCTLCMD; break; -- cgit v1.2.3 From 7e2a31da854dcf8324012a83a31b40bc11e52589 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 23 Jul 2008 21:30:47 -0700 Subject: rtc-cmos: avoid spurious irqs This fixes kernel http://bugzilla.kernel.org/show_bug.cgi?id=11112 (bogus RTC update IRQs reported) for rtc-cmos, in two ways: - When HPET is stealing the IRQs, use the first IRQ to grab the seconds counter which will be monitored (instead of using whatever was previously in that memory); - In sane IRQ handling modes, scrub out old IRQ status before enabling IRQs. That latter is done by tightening up IRQ handling for rtc-cmos everywhere, also ensuring that when HPET is used it's the only thing triggering IRQ reports to userspace; net object shrink. Also fix a bogus HPET message related to its RTC emulation. Signed-off-by: David Brownell Report-by: W Unruh Cc: Andrew Victor Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/kernel/hpet.c | 10 ++-- drivers/rtc/rtc-cmos.c | 140 ++++++++++++++++++++++--------------------------- 2 files changed, 70 insertions(+), 80 deletions(-) (limited to 'drivers/rtc') diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 0ea6a19bfdfe..ad2b15a1334d 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -468,7 +468,7 @@ void hpet_disable(void) #define RTC_NUM_INTS 1 static unsigned long hpet_rtc_flags; -static unsigned long hpet_prev_update_sec; +static int hpet_prev_update_sec; static struct rtc_time hpet_alarm_time; static unsigned long hpet_pie_count; static unsigned long hpet_t1_cmp; @@ -575,6 +575,9 @@ int hpet_set_rtc_irq_bit(unsigned long bit_mask) hpet_rtc_flags |= bit_mask; + if ((bit_mask & RTC_UIE) && !(oldbits & RTC_UIE)) + hpet_prev_update_sec = -1; + if (!oldbits) hpet_rtc_timer_init(); @@ -652,7 +655,7 @@ static void hpet_rtc_timer_reinit(void) if (hpet_rtc_flags & RTC_PIE) hpet_pie_count += lost_ints; if (printk_ratelimit()) - printk(KERN_WARNING "rtc: lost %d interrupts\n", + printk(KERN_WARNING "hpet1: lost %d rtc interrupts\n", lost_ints); } } @@ -670,7 +673,8 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) if (hpet_rtc_flags & RTC_UIE && curr_time.tm_sec != hpet_prev_update_sec) { - rtc_int_flag = RTC_UF; + if (hpet_prev_update_sec >= 0) + rtc_int_flag = RTC_UF; hpet_prev_update_sec = curr_time.tm_sec; } diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index e9984650ea95..6ea349aba3ba 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -235,11 +235,56 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) return 0; } +static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control) +{ + unsigned char rtc_intr; + + /* NOTE after changing RTC_xIE bits we always read INTR_FLAGS; + * allegedly some older rtcs need that to handle irqs properly + */ + rtc_intr = CMOS_READ(RTC_INTR_FLAGS); + + if (is_hpet_enabled()) + return; + + rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; + if (is_intr(rtc_intr)) + rtc_update_irq(cmos->rtc, 1, rtc_intr); +} + +static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask) +{ + unsigned char rtc_control; + + /* flush any pending IRQ status, notably for update irqs, + * before we enable new IRQs + */ + rtc_control = CMOS_READ(RTC_CONTROL); + cmos_checkintr(cmos, rtc_control); + + rtc_control |= mask; + CMOS_WRITE(rtc_control, RTC_CONTROL); + hpet_set_rtc_irq_bit(mask); + + cmos_checkintr(cmos, rtc_control); +} + +static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) +{ + unsigned char rtc_control; + + rtc_control = CMOS_READ(RTC_CONTROL); + rtc_control &= ~mask; + CMOS_WRITE(rtc_control, RTC_CONTROL); + hpet_mask_rtc_irq_bit(mask); + + cmos_checkintr(cmos, rtc_control); +} + 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 rtc_control, rtc_intr; if (!is_valid_irq(cmos->irq)) return -EIO; @@ -266,15 +311,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) spin_lock_irq(&rtc_lock); /* next rtc irq must not be from previous alarm setting */ - rtc_control = CMOS_READ(RTC_CONTROL); - rtc_control &= ~RTC_AIE; - CMOS_WRITE(rtc_control, RTC_CONTROL); - hpet_mask_rtc_irq_bit(RTC_AIE); - - rtc_intr = CMOS_READ(RTC_INTR_FLAGS); - rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; - if (is_intr(rtc_intr)) - rtc_update_irq(cmos->rtc, 1, rtc_intr); + cmos_irq_disable(cmos, RTC_AIE); /* update alarm */ CMOS_WRITE(hrs, RTC_HOURS_ALARM); @@ -293,16 +330,8 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) */ hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec); - if (t->enabled) { - rtc_control |= RTC_AIE; - CMOS_WRITE(rtc_control, RTC_CONTROL); - hpet_set_rtc_irq_bit(RTC_AIE); - - rtc_intr = CMOS_READ(RTC_INTR_FLAGS); - rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; - if (is_intr(rtc_intr)) - rtc_update_irq(cmos->rtc, 1, rtc_intr); - } + if (t->enabled) + cmos_irq_enable(cmos, RTC_AIE); spin_unlock_irq(&rtc_lock); @@ -335,28 +364,17 @@ static int cmos_irq_set_freq(struct device *dev, int freq) static int cmos_irq_set_state(struct device *dev, int enabled) { struct cmos_rtc *cmos = dev_get_drvdata(dev); - unsigned char rtc_control, rtc_intr; unsigned long flags; if (!is_valid_irq(cmos->irq)) return -ENXIO; spin_lock_irqsave(&rtc_lock, flags); - rtc_control = CMOS_READ(RTC_CONTROL); - - if (enabled) { - rtc_control |= RTC_PIE; - hpet_set_rtc_irq_bit(RTC_PIE); - } else { - rtc_control &= ~RTC_PIE; - hpet_mask_rtc_irq_bit(RTC_PIE); - } - CMOS_WRITE(rtc_control, RTC_CONTROL); - rtc_intr = CMOS_READ(RTC_INTR_FLAGS); - rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; - if (is_intr(rtc_intr)) - rtc_update_irq(cmos->rtc, 1, rtc_intr); + if (enabled) + cmos_irq_enable(cmos, RTC_PIE); + else + cmos_irq_disable(cmos, RTC_PIE); spin_unlock_irqrestore(&rtc_lock, flags); return 0; @@ -368,7 +386,6 @@ static int cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct cmos_rtc *cmos = dev_get_drvdata(dev); - unsigned char rtc_control, rtc_intr; unsigned long flags; switch (cmd) { @@ -385,32 +402,20 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) } spin_lock_irqsave(&rtc_lock, flags); - rtc_control = CMOS_READ(RTC_CONTROL); switch (cmd) { case RTC_AIE_OFF: /* alarm off */ - rtc_control &= ~RTC_AIE; - hpet_mask_rtc_irq_bit(RTC_AIE); + cmos_irq_disable(cmos, RTC_AIE); break; case RTC_AIE_ON: /* alarm on */ - rtc_control |= RTC_AIE; - hpet_set_rtc_irq_bit(RTC_AIE); + cmos_irq_enable(cmos, RTC_AIE); break; case RTC_UIE_OFF: /* update off */ - rtc_control &= ~RTC_UIE; - hpet_mask_rtc_irq_bit(RTC_UIE); + cmos_irq_disable(cmos, RTC_UIE); break; case RTC_UIE_ON: /* update on */ - rtc_control |= RTC_UIE; - hpet_set_rtc_irq_bit(RTC_UIE); + cmos_irq_enable(cmos, RTC_UIE); break; } - CMOS_WRITE(rtc_control, RTC_CONTROL); - - rtc_intr = CMOS_READ(RTC_INTR_FLAGS); - rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; - if (is_intr(rtc_intr)) - rtc_update_irq(cmos->rtc, 1, rtc_intr); - spin_unlock_irqrestore(&rtc_lock, flags); return 0; } @@ -571,7 +576,6 @@ static irqreturn_t cmos_interrupt(int irq, void *p) * alarm woke the system. */ if (irqstat & RTC_AIE) { - rtc_control = CMOS_READ(RTC_CONTROL); rtc_control &= ~RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); hpet_mask_rtc_irq_bit(RTC_AIE); @@ -685,17 +689,10 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); - /* disable irqs. - * - * NOTE after changing RTC_xIE bits we always read INTR_FLAGS; - * allegedly some older rtcs need that to handle irqs properly - */ - rtc_control = CMOS_READ(RTC_CONTROL); - rtc_control &= ~(RTC_PIE | RTC_AIE | RTC_UIE); - CMOS_WRITE(rtc_control, RTC_CONTROL); - hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE); + /* disable irqs */ + cmos_irq_disable(&cmos_rtc, RTC_PIE | RTC_AIE | RTC_UIE); - CMOS_READ(RTC_INTR_FLAGS); + rtc_control = CMOS_READ(RTC_CONTROL); spin_unlock_irq(&rtc_lock); @@ -768,15 +765,8 @@ cleanup0: static void cmos_do_shutdown(void) { - unsigned char rtc_control; - spin_lock_irq(&rtc_lock); - rtc_control = CMOS_READ(RTC_CONTROL); - rtc_control &= ~RTC_IRQMASK; - CMOS_WRITE(rtc_control, RTC_CONTROL); - hpet_mask_rtc_irq_bit(RTC_IRQMASK); - - CMOS_READ(RTC_INTR_FLAGS); + cmos_irq_disable(&cmos_rtc, RTC_IRQMASK); spin_unlock_irq(&rtc_lock); } @@ -817,7 +807,6 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) spin_lock_irq(&rtc_lock); cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL); if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { - unsigned char irqstat; unsigned char mask; if (do_wake) @@ -828,10 +817,7 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) CMOS_WRITE(tmp, RTC_CONTROL); hpet_mask_rtc_irq_bit(mask); - irqstat = CMOS_READ(RTC_INTR_FLAGS); - irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF; - if (is_intr(irqstat)) - rtc_update_irq(cmos->rtc, 1, irqstat); + cmos_checkintr(cmos, tmp); } spin_unlock_irq(&rtc_lock); @@ -875,7 +861,7 @@ static int cmos_resume(struct device *dev) mask = CMOS_READ(RTC_INTR_FLAGS); mask &= (tmp & RTC_IRQMASK) | RTC_IRQF; - if (!is_intr(mask)) + if (!is_hpet_enabled() || !is_intr(mask)) break; /* force one-shot behavior if HPET blocked -- cgit v1.2.3 From 4cad4431fcd872a1b2efc093b0db6df943f5a898 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 23 Jul 2008 21:30:48 -0700 Subject: rtc-vr41xx: add irq_set_freq() and irq_set_state() Implement the ioctls RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET and RTC_IRQP_READ in the standard RTC way. Thanks Dave for noticing it. Signed-off-by: Yoichi Yuasa Cc: David Brownell Cc: Ralf Baechle Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-vr41xx.c | 65 +++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 31 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index be9c70d0b193..884b635f028b 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -1,7 +1,7 @@ /* * Driver for NEC VR4100 series Real Time Clock unit. * - * Copyright (C) 2003-2006 Yoichi Yuasa + * Copyright (C) 2003-2008 Yoichi Yuasa * * 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 @@ -34,7 +34,7 @@ MODULE_AUTHOR("Yoichi Yuasa "); MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); /* RTC 1 registers */ #define ETIMELREG 0x00 @@ -82,7 +82,6 @@ static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ static DEFINE_SPINLOCK(rtc_lock); static char rtc_name[] = "RTC"; -static unsigned long periodic_frequency; static unsigned long periodic_count; static unsigned int alarm_enabled; static int aie_irq = -1; @@ -207,10 +206,37 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) return 0; } -static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq) { unsigned long count; + count = RTC_FREQUENCY; + do_div(count, freq); + + periodic_count = count; + + spin_lock_irq(&rtc_lock); + + rtc1_write(RTCL1LREG, count); + rtc1_write(RTCL1HREG, count >> 16); + + spin_unlock_irq(&rtc_lock); + + return 0; +} + +static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled) +{ + if (enabled) + enable_irq(pie_irq); + else + disable_irq(pie_irq); + + return 0; +} + +static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ switch (cmd) { case RTC_AIE_ON: spin_lock_irq(&rtc_lock); @@ -230,33 +256,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long alarm_enabled = 0; } - spin_unlock_irq(&rtc_lock); - break; - case RTC_PIE_ON: - enable_irq(pie_irq); - break; - case RTC_PIE_OFF: - disable_irq(pie_irq); - break; - case RTC_IRQP_READ: - return put_user(periodic_frequency, (unsigned long __user *)arg); - break; - case RTC_IRQP_SET: - if (arg > MAX_PERIODIC_RATE) - return -EINVAL; - - periodic_frequency = arg; - - count = RTC_FREQUENCY; - do_div(count, arg); - - periodic_count = count; - - spin_lock_irq(&rtc_lock); - - rtc1_write(RTCL1LREG, count); - rtc1_write(RTCL1HREG, count >> 16); - spin_unlock_irq(&rtc_lock); break; case RTC_EPOCH_READ: @@ -309,6 +308,8 @@ static const struct rtc_class_ops vr41xx_rtc_ops = { .set_time = vr41xx_rtc_set_time, .read_alarm = vr41xx_rtc_read_alarm, .set_alarm = vr41xx_rtc_set_alarm, + .irq_set_freq = vr41xx_rtc_irq_set_freq, + .irq_set_state = vr41xx_rtc_irq_set_state, }; static int __devinit rtc_probe(struct platform_device *pdev) @@ -346,6 +347,8 @@ static int __devinit rtc_probe(struct platform_device *pdev) goto err_iounmap_all; } + rtc->max_user_freq = MAX_PERIODIC_RATE; + spin_lock_irq(&rtc_lock); rtc1_write(ECMPLREG, 0); -- cgit v1.2.3 From b68bb2632453a9ca7d10a00d79adf60968cb4c05 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 29 Jul 2008 22:33:30 -0700 Subject: rtc: don't return -EBUSY when mutex_lock_interruptible() fails It was pointed out that the RTC framework handles its mutex locks oddly ... returning -EBUSY when interrupted. This fixes that by returning the value of mutex_lock_interruptible() (i.e. -EINTR). Signed-off-by: David Brownell Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/interface.c | 10 +++++----- drivers/rtc/rtc-dev.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index d397fa5f3a91..7af60b98d8a4 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -20,7 +20,7 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) err = mutex_lock_interruptible(&rtc->ops_lock); if (err) - return -EBUSY; + return err; if (!rtc->ops) err = -ENODEV; @@ -46,7 +46,7 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) err = mutex_lock_interruptible(&rtc->ops_lock); if (err) - return -EBUSY; + return err; if (!rtc->ops) err = -ENODEV; @@ -66,7 +66,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) err = mutex_lock_interruptible(&rtc->ops_lock); if (err) - return -EBUSY; + return err; if (!rtc->ops) err = -ENODEV; @@ -106,7 +106,7 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al err = mutex_lock_interruptible(&rtc->ops_lock); if (err) - return -EBUSY; + return err; if (rtc->ops == NULL) err = -ENODEV; @@ -293,7 +293,7 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) err = mutex_lock_interruptible(&rtc->ops_lock); if (err) - return -EBUSY; + return err; if (!rtc->ops) err = -ENODEV; diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 0a870b7e5c32..ae3bd4de7675 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -221,7 +221,7 @@ static long rtc_dev_ioctl(struct file *file, err = mutex_lock_interruptible(&rtc->ops_lock); if (err) - return -EBUSY; + return err; /* check that the calling task has appropriate permissions * for certain ioctls. doing this check here is useful -- cgit v1.2.3 From 5cdc98b8f51310f7cca05ad780f18f80dd9571de Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Tue, 29 Jul 2008 22:33:51 -0700 Subject: rtc-dev: stop periodic interrupts on device release Solves http://bugzilla.kernel.org/show_bug.cgi?id=11127 The old rtc.c driver did it and some drivers (like rtc-sh) do it in their release function, though they should not -- because they should provide the irq_set_state op and the rtc framework itself should care about it. This patch makes it do so. I am aware that some drivers, like rtc-sh, handle userspace PIE sets in their ioctl op (instead of having the framework call the op), exporting the irq_set_state op at the same time. The logic in rtc_irq_set_state should make sure it doesn't matter and the driver should not need to care stopping periodic interrupts in its release routine any more. The correct way, in my opinion, should be this: 1) The driver provides the irq_set_state op and does not care closing the interrupts in its release op. 2) If the driver does not provide the op and handles PIE in the ioctl op, it's reponsible for closing them in its release op. 3) Something similar for other IRQs, like UIE -- if there's no in-kernel API like irq_set_state, handle it in ioctl and release ops. The framework will be responsible either for everything or for nothing. (This will probably change later.) Signed-off-by: Tomas Janousek Acked-by: David Brownell Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-dev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index ae3bd4de7675..856cc1af40df 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -432,6 +432,8 @@ static int rtc_dev_release(struct inode *inode, struct file *file) #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL clear_uie(rtc); #endif + rtc_irq_set_state(rtc, NULL, 0); + if (rtc->ops->release) rtc->ops->release(rtc->dev.parent); -- cgit v1.2.3 From dd279f6127c0f64dfb0055bc0adb97a284a08df3 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 5 Aug 2008 13:01:15 -0700 Subject: blackfin RTC driver: if we dont define irq_set_freq, the common rtc-dev layer will give us the same behavior of returning ENOTTY Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Signed-off-by: Bryan Wu Cc: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-bfin.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 8624f55d0560..48ada599477b 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -381,20 +381,6 @@ static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) #undef yesno } -/** - * bfin_irq_set_freq - make sure hardware supports requested freq - * @dev: pointer to RTC device structure - * @freq: requested frequency rate - * - * The Blackfin RTC can only generate periodic events at 1 per - * second (1 Hz), so reject any attempt at changing it. - */ -static int bfin_irq_set_freq(struct device *dev, int freq) -{ - dev_dbg_stamp(dev); - return -ENOTTY; -} - static struct rtc_class_ops bfin_rtc_ops = { .open = bfin_rtc_open, .release = bfin_rtc_release, @@ -404,7 +390,6 @@ static struct rtc_class_ops bfin_rtc_ops = { .read_alarm = bfin_rtc_read_alarm, .set_alarm = bfin_rtc_set_alarm, .proc = bfin_rtc_proc, - .irq_set_freq = bfin_irq_set_freq, }; static int __devinit bfin_rtc_probe(struct platform_device *pdev) -- cgit v1.2.3 From 5aeb776d0c2bb1dd3ef01f4805929e2bc2923e7b Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Tue, 5 Aug 2008 13:01:17 -0700 Subject: blackfin RTC driver: Fix bug Only RTC interrupt can wake up deeper sleep core Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: Bryan Wu Cc: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-bfin.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 48ada599477b..a568d29b0742 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -430,6 +430,30 @@ static int __devexit bfin_rtc_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) +{ +#ifdef PM_WAKEUP_SIC_IWR + struct bfin_rtc *rtc = dev_get_drvdata(&pdev->dev); +#endif + bfin_rtc_reset(&pdev->dev); +#ifdef PM_WAKEUP_SIC_IWR + bfin_write_RTC_SWCNT(10); + bfin_rtc_int_set(rtc, RTC_ISTAT_STOPWATCH); +#endif + return 0; +} + +static int bfin_rtc_resume(struct platform_device *pdev) +{ +#ifdef PM_WAKEUP_SIC_IWR + struct bfin_rtc *rtc = dev_get_drvdata(&pdev->dev); + bfin_rtc_int_clear(rtc, RTC_ISTAT_STOPWATCH); +#endif + return 0; +} +#endif + static struct platform_driver bfin_rtc_driver = { .driver = { .name = "rtc-bfin", @@ -437,6 +461,10 @@ static struct platform_driver bfin_rtc_driver = { }, .probe = bfin_rtc_probe, .remove = __devexit_p(bfin_rtc_remove), +#ifdef CONFIG_PM + .suspend = bfin_rtc_suspend, + .resume = bfin_rtc_resume, +#endif }; static int __init bfin_rtc_init(void) -- cgit v1.2.3 From 813006f4bb4a39afdde8ab2e3559971c029d1dc0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 5 Aug 2008 13:01:18 -0700 Subject: blackfin RTC driver: add support for power management framework Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Signed-off-by: Bryan Wu Cc: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-bfin.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index a568d29b0742..23b991d41ef1 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -2,7 +2,7 @@ * Blackfin On-Chip Real Time Clock Driver * Supports BF52[257]/BF53[123]/BF53[467]/BF54[24789] * - * Copyright 2004-2007 Analog Devices Inc. + * Copyright 2004-2008 Analog Devices Inc. * * Enter bugs at http://blackfin.uclinux.org/ * @@ -412,6 +412,8 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); + device_init_wakeup(&pdev->dev, 1); + return 0; err: @@ -433,25 +435,28 @@ static int __devexit bfin_rtc_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) { -#ifdef PM_WAKEUP_SIC_IWR struct bfin_rtc *rtc = dev_get_drvdata(&pdev->dev); -#endif - bfin_rtc_reset(&pdev->dev); -#ifdef PM_WAKEUP_SIC_IWR - bfin_write_RTC_SWCNT(10); - bfin_rtc_int_set(rtc, RTC_ISTAT_STOPWATCH); -#endif + + if (device_may_wakeup(&pdev->dev)) + enable_irq_wake(IRQ_RTC); + else + bfin_rtc_int_clear(rtc, -1); + return 0; } static int bfin_rtc_resume(struct platform_device *pdev) { -#ifdef PM_WAKEUP_SIC_IWR - struct bfin_rtc *rtc = dev_get_drvdata(&pdev->dev); - bfin_rtc_int_clear(rtc, RTC_ISTAT_STOPWATCH); -#endif + if (device_may_wakeup(&pdev->dev)) + disable_irq_wake(IRQ_RTC); + else + bfin_write_RTC_ISTAT(-1); + return 0; } +#else +# define bfin_rtc_suspend NULL +# define bfin_rtc_resume NULL #endif static struct platform_driver bfin_rtc_driver = { @@ -461,10 +466,8 @@ static struct platform_driver bfin_rtc_driver = { }, .probe = bfin_rtc_probe, .remove = __devexit_p(bfin_rtc_remove), -#ifdef CONFIG_PM .suspend = bfin_rtc_suspend, .resume = bfin_rtc_resume, -#endif }; static int __init bfin_rtc_init(void) -- cgit v1.2.3 From 605eb8b3c05e970caf71c48f693efe33c212fb7b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 5 Aug 2008 13:01:18 -0700 Subject: blackfin RTC driver: don't bother passing the rtc struct down to bfin_rtc_int_{set,clear} since it isnt needed (shaves off ~100bytes) Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Signed-off-by: Bryan Wu Cc: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-bfin.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 23b991d41ef1..56656dd6b2c1 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -238,12 +238,12 @@ static void bfin_rtc_release(struct device *dev) free_irq(IRQ_RTC, dev); } -static void bfin_rtc_int_set(struct bfin_rtc *rtc, u16 rtc_int) +static void bfin_rtc_int_set(u16 rtc_int) { bfin_write_RTC_ISTAT(rtc_int); bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | rtc_int); } -static void bfin_rtc_int_clear(struct bfin_rtc *rtc, u16 rtc_int) +static void bfin_rtc_int_clear(u16 rtc_int) { bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & rtc_int); } @@ -252,7 +252,7 @@ static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc) /* Blackfin has different bits for whether the alarm is * more than 24 hours away. */ - bfin_rtc_int_set(rtc, (rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY)); + bfin_rtc_int_set(rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY); } static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { @@ -266,21 +266,21 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar switch (cmd) { case RTC_PIE_ON: dev_dbg_stamp(dev); - bfin_rtc_int_set(rtc, RTC_ISTAT_STOPWATCH); + bfin_rtc_int_set(RTC_ISTAT_STOPWATCH); bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); break; case RTC_PIE_OFF: dev_dbg_stamp(dev); - bfin_rtc_int_clear(rtc, ~RTC_ISTAT_STOPWATCH); + bfin_rtc_int_clear(~RTC_ISTAT_STOPWATCH); break; case RTC_UIE_ON: dev_dbg_stamp(dev); - bfin_rtc_int_set(rtc, RTC_ISTAT_SEC); + bfin_rtc_int_set(RTC_ISTAT_SEC); break; case RTC_UIE_OFF: dev_dbg_stamp(dev); - bfin_rtc_int_clear(rtc, ~RTC_ISTAT_SEC); + bfin_rtc_int_clear(~RTC_ISTAT_SEC); break; case RTC_AIE_ON: @@ -289,7 +289,7 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar break; case RTC_AIE_OFF: dev_dbg_stamp(dev); - bfin_rtc_int_clear(rtc, ~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); + bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); break; default: @@ -435,12 +435,10 @@ static int __devexit bfin_rtc_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) { - struct bfin_rtc *rtc = dev_get_drvdata(&pdev->dev); - if (device_may_wakeup(&pdev->dev)) enable_irq_wake(IRQ_RTC); else - bfin_rtc_int_clear(rtc, -1); + bfin_rtc_int_clear(-1); return 0; } -- cgit v1.2.3 From 3b128fe04a3087d6e974b87402dc6e75d3142186 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 5 Aug 2008 13:01:19 -0700 Subject: blackfin RTC driver: disable the write complete irq upon close Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Cc: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-bfin.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 56656dd6b2c1..d53772f59ce5 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -144,13 +144,13 @@ static void bfin_rtc_sync_pending(struct device *dev) * Initialize the RTC. Enable pre-scaler to scale RTC clock * to 1Hz and clear interrupt/status registers. */ -static void bfin_rtc_reset(struct device *dev) +static void bfin_rtc_reset(struct device *dev, u16 rtc_ictl) { struct bfin_rtc *rtc = dev_get_drvdata(dev); dev_dbg_stamp(dev); bfin_rtc_sync_pending(dev); bfin_write_RTC_PREN(0x1); - bfin_write_RTC_ICTL(RTC_ISTAT_WRITE_COMPLETE); + bfin_write_RTC_ICTL(rtc_ictl); bfin_write_RTC_SWCNT(0); bfin_write_RTC_ALARM(0); bfin_write_RTC_ISTAT(0xFFFF); @@ -226,7 +226,7 @@ static int bfin_rtc_open(struct device *dev) ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, to_platform_device(dev)->name, dev); if (!ret) - bfin_rtc_reset(dev); + bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE); return ret; } @@ -234,7 +234,7 @@ static int bfin_rtc_open(struct device *dev) static void bfin_rtc_release(struct device *dev) { dev_dbg_stamp(dev); - bfin_rtc_reset(dev); + bfin_rtc_reset(dev, 0); free_irq(IRQ_RTC, dev); } -- cgit v1.2.3 From 140fab14aef093cedf87f69234474c04fdcec99c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 5 Aug 2008 13:01:20 -0700 Subject: blackfin RTC driver: wait for the write complete interrupt complete before sleeping Since we use the write complete interrupt, wait for it to complete before sleeping so we don't wake right back up due to it Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Cc: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-bfin.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index d53772f59ce5..e6b0470063e8 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -435,9 +435,10 @@ static int __devexit bfin_rtc_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) { - if (device_may_wakeup(&pdev->dev)) + if (device_may_wakeup(&pdev->dev)) { enable_irq_wake(IRQ_RTC); - else + bfin_rtc_sync_pending(&pdev->dev); + } else bfin_rtc_int_clear(-1); return 0; -- cgit v1.2.3 From e12af37d9ee09c2ac6da26a51c77754dec09fed4 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 5 Aug 2008 13:01:21 -0700 Subject: blackfin RTC driver: convert PIE handling to irq_set_state() as pointed out by David Brownell Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Cc: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-bfin.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index e6b0470063e8..ceebce7e0a0f 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -264,16 +264,6 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar bfin_rtc_sync_pending(dev); switch (cmd) { - case RTC_PIE_ON: - dev_dbg_stamp(dev); - bfin_rtc_int_set(RTC_ISTAT_STOPWATCH); - bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); - break; - case RTC_PIE_OFF: - dev_dbg_stamp(dev); - bfin_rtc_int_clear(~RTC_ISTAT_STOPWATCH); - break; - case RTC_UIE_ON: dev_dbg_stamp(dev); bfin_rtc_int_set(RTC_ISTAT_SEC); @@ -381,6 +371,23 @@ static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) #undef yesno } +static int bfin_irq_set_state(struct device *dev, int enabled) +{ + struct bfin_rtc *rtc = dev_get_drvdata(dev); + + dev_dbg_stamp(dev); + + bfin_rtc_sync_pending(dev); + + if (enabled) { + bfin_rtc_int_set(RTC_ISTAT_STOPWATCH); + bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); + } else + bfin_rtc_int_clear(~RTC_ISTAT_STOPWATCH); + + return 0; +} + static struct rtc_class_ops bfin_rtc_ops = { .open = bfin_rtc_open, .release = bfin_rtc_release, @@ -390,6 +397,7 @@ static struct rtc_class_ops bfin_rtc_ops = { .read_alarm = bfin_rtc_read_alarm, .set_alarm = bfin_rtc_set_alarm, .proc = bfin_rtc_proc, + .irq_set_state = bfin_irq_set_state, }; static int __devinit bfin_rtc_probe(struct platform_device *pdev) -- cgit v1.2.3 From 26cb8bb21b11245a53f79d9fa766537752f77d88 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 5 Aug 2008 13:01:21 -0700 Subject: blackfin RTC driver: drop PIE/stopwatch code since the hardware can only do a max of 1HZ and this same functionality is provided by UIE Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Cc: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-bfin.c | 46 ++++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index ceebce7e0a0f..a1af4c27939b 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -32,6 +32,15 @@ * writes to clear status registers complete immediately. */ +/* It may seem odd that there is no SWCNT code in here (which would be exposed + * via the periodic interrupt event, or PIE). Since the Blackfin RTC peripheral + * runs in units of seconds (N/HZ) but the Linux framework runs in units of HZ + * (2^N HZ), there is no point in keeping code that only provides 1 HZ PIEs. + * The same exact behavior can be accomplished by using the update interrupt + * event (UIE). Maybe down the line the RTC peripheral will suck less in which + * case we can re-introduce PIE support. + */ + #include #include #include @@ -151,7 +160,6 @@ static void bfin_rtc_reset(struct device *dev, u16 rtc_ictl) bfin_rtc_sync_pending(dev); bfin_write_RTC_PREN(0x1); bfin_write_RTC_ICTL(rtc_ictl); - bfin_write_RTC_SWCNT(0); bfin_write_RTC_ALARM(0); bfin_write_RTC_ISTAT(0xFFFF); rtc->rtc_wrote_regs = 0; @@ -194,14 +202,6 @@ static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) } } - if (rtc_ictl & RTC_ISTAT_STOPWATCH) { - if (rtc_istat & RTC_ISTAT_STOPWATCH) { - bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); - events |= RTC_PF | RTC_IRQF; - bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); - } - } - if (rtc_ictl & RTC_ISTAT_SEC) { if (rtc_istat & RTC_ISTAT_SEC) { bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); @@ -361,33 +361,14 @@ static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) seq_printf(seq, "alarm_IRQ\t: %s\n" "wkalarm_IRQ\t: %s\n" - "seconds_IRQ\t: %s\n" - "periodic_IRQ\t: %s\n", + "seconds_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM), yesno(ictl & RTC_ISTAT_ALARM_DAY), - yesno(ictl & RTC_ISTAT_SEC), - yesno(ictl & RTC_ISTAT_STOPWATCH)); + yesno(ictl & RTC_ISTAT_SEC)); return 0; #undef yesno } -static int bfin_irq_set_state(struct device *dev, int enabled) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - - dev_dbg_stamp(dev); - - bfin_rtc_sync_pending(dev); - - if (enabled) { - bfin_rtc_int_set(RTC_ISTAT_STOPWATCH); - bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); - } else - bfin_rtc_int_clear(~RTC_ISTAT_STOPWATCH); - - return 0; -} - static struct rtc_class_ops bfin_rtc_ops = { .open = bfin_rtc_open, .release = bfin_rtc_release, @@ -397,7 +378,6 @@ static struct rtc_class_ops bfin_rtc_ops = { .read_alarm = bfin_rtc_read_alarm, .set_alarm = bfin_rtc_set_alarm, .proc = bfin_rtc_proc, - .irq_set_state = bfin_irq_set_state, }; static int __devinit bfin_rtc_probe(struct platform_device *pdev) @@ -416,7 +396,9 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) ret = PTR_ERR(rtc->rtc_dev); goto err; } - rtc->rtc_dev->irq_freq = 1; + + /* see comment at top of file about stopwatch/PIE */ + bfin_write_RTC_SWCNT(0); platform_set_drvdata(pdev, rtc); -- cgit v1.2.3 From be509729356b7433f73df2b9a966674a437fbbc1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 4 Aug 2008 10:41:28 +0100 Subject: [ARM] Remove asm/hardware.h, use asm/arch/hardware.h instead Remove includes of asm/hardware.h in addition to asm/arch/hardware.h. Then, since asm/hardware.h only exists to include asm/arch/hardware.h, update everything to directly include asm/arch/hardware.h and remove asm/hardware.h. Signed-off-by: Russell King --- arch/arm/common/locomo.c | 2 +- arch/arm/common/sa1111.c | 2 +- arch/arm/common/sharpsl_pm.c | 2 +- arch/arm/common/time-acorn.c | 2 +- arch/arm/common/uengine.c | 1 - arch/arm/include/asm/hardware.h | 18 ------------------ arch/arm/include/asm/hardware/dec21285.h | 2 +- arch/arm/include/asm/hardware/iop3xx-adma.h | 2 +- arch/arm/include/asm/hardware/iop3xx-gpio.h | 2 +- arch/arm/include/asm/mtd-xip.h | 2 +- arch/arm/include/asm/pci.h | 2 +- arch/arm/include/asm/vga.h | 2 +- arch/arm/kernel/ecard.c | 2 +- arch/arm/lib/ecard.S | 2 +- arch/arm/lib/io-readsw-armv3.S | 2 +- arch/arm/lib/io-writesw-armv3.S | 2 +- arch/arm/mach-aaec2000/aaed2000.c | 2 +- arch/arm/mach-aaec2000/core.c | 2 +- arch/arm/mach-at91/at91x40_time.c | 2 +- arch/arm/mach-at91/board-1arm.c | 2 +- arch/arm/mach-at91/board-cam60.c | 2 +- arch/arm/mach-at91/board-cap9adk.c | 2 +- arch/arm/mach-at91/board-carmeva.c | 2 +- arch/arm/mach-at91/board-csb337.c | 2 +- arch/arm/mach-at91/board-csb637.c | 2 +- arch/arm/mach-at91/board-dk.c | 2 +- arch/arm/mach-at91/board-eb01.c | 2 +- arch/arm/mach-at91/board-eb9200.c | 2 +- arch/arm/mach-at91/board-ecbat91.c | 2 +- arch/arm/mach-at91/board-ek.c | 2 +- arch/arm/mach-at91/board-kafa.c | 2 +- arch/arm/mach-at91/board-kb9202.c | 2 +- arch/arm/mach-at91/board-picotux200.c | 2 +- arch/arm/mach-at91/board-qil-a9260.c | 2 +- arch/arm/mach-at91/board-sam9-l9260.c | 2 +- arch/arm/mach-at91/board-sam9260ek.c | 2 +- arch/arm/mach-at91/board-sam9261ek.c | 2 +- arch/arm/mach-at91/board-sam9263ek.c | 2 +- arch/arm/mach-at91/board-sam9g20ek.c | 2 +- arch/arm/mach-at91/board-sam9rlek.c | 2 +- arch/arm/mach-at91/board-usb-a9260.c | 2 +- arch/arm/mach-at91/board-usb-a9263.c | 2 +- arch/arm/mach-at91/board-yl-9200.c | 2 +- arch/arm/mach-at91/clock.c | 2 +- arch/arm/mach-at91/gpio.c | 2 +- arch/arm/mach-at91/irq.c | 2 +- arch/arm/mach-clps711x/autcpu12.c | 2 +- arch/arm/mach-clps711x/cdb89712.c | 2 +- arch/arm/mach-clps711x/ceiva.c | 2 +- arch/arm/mach-clps711x/edb7211-mm.c | 2 +- arch/arm/mach-clps711x/fortunet.c | 2 +- arch/arm/mach-clps711x/irq.c | 2 +- arch/arm/mach-clps711x/mm.c | 2 +- arch/arm/mach-clps711x/p720t-leds.c | 2 +- arch/arm/mach-clps711x/p720t.c | 2 +- arch/arm/mach-clps711x/time.c | 2 +- arch/arm/mach-clps7500/core.c | 2 +- arch/arm/mach-davinci/board-evm.c | 2 +- arch/arm/mach-davinci/clock.c | 2 +- arch/arm/mach-davinci/irq.c | 2 +- arch/arm/mach-davinci/mux.c | 2 +- arch/arm/mach-davinci/psc.c | 2 +- arch/arm/mach-davinci/serial.c | 2 +- arch/arm/mach-davinci/time.c | 2 +- arch/arm/mach-ebsa110/core.c | 2 +- arch/arm/mach-ebsa110/io.c | 2 +- arch/arm/mach-ebsa110/leds.c | 2 +- arch/arm/mach-ep93xx/adssphere.c | 2 +- arch/arm/mach-ep93xx/clock.c | 2 +- arch/arm/mach-ep93xx/core.c | 2 +- arch/arm/mach-ep93xx/edb9302.c | 2 +- arch/arm/mach-ep93xx/edb9302a.c | 2 +- arch/arm/mach-ep93xx/edb9307.c | 2 +- arch/arm/mach-ep93xx/edb9312.c | 2 +- arch/arm/mach-ep93xx/edb9315.c | 2 +- arch/arm/mach-ep93xx/edb9315a.c | 2 +- arch/arm/mach-ep93xx/gesbc9312.c | 2 +- arch/arm/mach-ep93xx/micro9.c | 2 +- arch/arm/mach-ep93xx/ts72xx.c | 2 +- arch/arm/mach-footbridge/ebsa285-leds.c | 2 +- arch/arm/mach-footbridge/isa-irq.c | 2 +- arch/arm/mach-footbridge/netwinder-leds.c | 2 +- arch/arm/mach-footbridge/time.c | 2 +- arch/arm/mach-h720x/common.c | 2 +- arch/arm/mach-h720x/cpu-h7201.c | 2 +- arch/arm/mach-h720x/cpu-h7202.c | 2 +- arch/arm/mach-h720x/h7201-eval.c | 2 +- arch/arm/mach-h720x/h7202-eval.c | 2 +- arch/arm/mach-imx/cpufreq.c | 2 +- arch/arm/mach-imx/dma.c | 2 +- arch/arm/mach-imx/generic.c | 2 +- arch/arm/mach-imx/irq.c | 2 +- arch/arm/mach-imx/leds-mx1ads.c | 2 +- arch/arm/mach-imx/mx1ads.c | 2 +- arch/arm/mach-imx/time.c | 2 +- arch/arm/mach-integrator/core.c | 2 +- arch/arm/mach-integrator/cpu.c | 2 +- arch/arm/mach-integrator/integrator_ap.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-integrator/leds.c | 2 +- arch/arm/mach-integrator/pci_v3.c | 2 +- arch/arm/mach-iop13xx/io.c | 2 +- arch/arm/mach-iop13xx/iq81340mc.c | 2 +- arch/arm/mach-iop13xx/iq81340sc.c | 2 +- arch/arm/mach-iop13xx/irq.c | 2 +- arch/arm/mach-iop13xx/pci.c | 2 +- arch/arm/mach-iop13xx/setup.c | 2 +- arch/arm/mach-iop32x/em7210.c | 2 +- arch/arm/mach-iop32x/glantank.c | 2 +- arch/arm/mach-iop32x/iq31244.c | 2 +- arch/arm/mach-iop32x/iq80321.c | 2 +- arch/arm/mach-iop32x/irq.c | 2 +- arch/arm/mach-iop32x/n2100.c | 2 +- arch/arm/mach-iop33x/iq80331.c | 2 +- arch/arm/mach-iop33x/iq80332.c | 2 +- arch/arm/mach-iop33x/irq.c | 2 +- arch/arm/mach-iop33x/uart.c | 2 +- arch/arm/mach-ixp2000/core.c | 2 +- arch/arm/mach-ixp2000/enp2611.c | 2 +- arch/arm/mach-ixp2000/ixdp2400.c | 2 +- arch/arm/mach-ixp2000/ixdp2800.c | 2 +- arch/arm/mach-ixp2000/ixdp2x00.c | 2 +- arch/arm/mach-ixp2000/ixdp2x01.c | 2 +- arch/arm/mach-ixp2000/pci.c | 2 +- arch/arm/mach-ixp23xx/core.c | 2 +- arch/arm/mach-ixp23xx/espresso.c | 2 +- arch/arm/mach-ixp23xx/ixdp2351.c | 2 +- arch/arm/mach-ixp23xx/pci.c | 2 +- arch/arm/mach-ixp23xx/roadrunner.c | 2 +- arch/arm/mach-ixp4xx/avila-pci.c | 2 +- arch/arm/mach-ixp4xx/avila-setup.c | 2 +- arch/arm/mach-ixp4xx/common-pci.c | 2 +- arch/arm/mach-ixp4xx/common.c | 2 +- arch/arm/mach-ixp4xx/coyote-pci.c | 2 +- arch/arm/mach-ixp4xx/coyote-setup.c | 2 +- arch/arm/mach-ixp4xx/gateway7001-pci.c | 2 +- arch/arm/mach-ixp4xx/gateway7001-setup.c | 2 +- arch/arm/mach-ixp4xx/gtwx5715-pci.c | 2 +- arch/arm/mach-ixp4xx/gtwx5715-setup.c | 2 +- arch/arm/mach-ixp4xx/ixdp425-pci.c | 2 +- arch/arm/mach-ixp4xx/ixdp425-setup.c | 2 +- arch/arm/mach-ixp4xx/ixdpg425-pci.c | 2 +- arch/arm/mach-ixp4xx/wg302v2-pci.c | 2 +- arch/arm/mach-ixp4xx/wg302v2-setup.c | 2 +- arch/arm/mach-kirkwood/addr-map.c | 2 +- arch/arm/mach-ks8695/cpu.c | 2 +- arch/arm/mach-ks8695/gpio.c | 2 +- arch/arm/mach-ks8695/irq.c | 2 +- arch/arm/mach-ks8695/pci.c | 2 +- arch/arm/mach-l7200/core.c | 2 +- arch/arm/mach-lh7a40x/arch-kev7a400.c | 2 +- arch/arm/mach-lh7a40x/arch-lpd7a40x.c | 2 +- arch/arm/mach-lh7a40x/clcd.c | 3 +-- arch/arm/mach-lh7a40x/clocks.c | 2 +- arch/arm/mach-lh7a40x/irq-lh7a400.c | 2 +- arch/arm/mach-lh7a40x/irq-lh7a404.c | 2 +- arch/arm/mach-lh7a40x/irq-lpd7a40x.c | 2 +- arch/arm/mach-lh7a40x/ssp-cpld.c | 2 +- arch/arm/mach-lh7a40x/time.c | 2 +- arch/arm/mach-loki/addr-map.c | 2 +- arch/arm/mach-msm/board-halibut.c | 2 +- arch/arm/mach-msm/io.c | 2 +- arch/arm/mach-msm/irq.c | 2 +- arch/arm/mach-mx2/cpu_imx27.c | 2 +- arch/arm/mach-mx2/devices.c | 2 +- arch/arm/mach-mx2/generic.c | 2 +- arch/arm/mach-mx2/mx27ads.c | 2 +- arch/arm/mach-mx2/pcm038.c | 2 +- arch/arm/mach-mx2/pcm970-baseboard.c | 2 +- arch/arm/mach-mx2/serial.c | 2 +- arch/arm/mach-mx3/devices.c | 2 +- arch/arm/mach-mx3/iomux.c | 2 +- arch/arm/mach-mx3/mm.c | 2 +- arch/arm/mach-mx3/mx31ads.c | 2 +- arch/arm/mach-mx3/mx31lite.c | 2 +- arch/arm/mach-mx3/pcm037.c | 2 +- arch/arm/mach-netx/fb.c | 2 +- arch/arm/mach-netx/generic.c | 2 +- arch/arm/mach-netx/nxdb500.c | 2 +- arch/arm/mach-netx/nxdkn.c | 2 +- arch/arm/mach-netx/nxeb500hmi.c | 2 +- arch/arm/mach-netx/pfifo.c | 2 +- arch/arm/mach-netx/time.c | 2 +- arch/arm/mach-netx/xc.c | 2 +- arch/arm/mach-omap1/board-ams-delta.c | 2 +- arch/arm/mach-omap1/board-fsample.c | 2 +- arch/arm/mach-omap1/board-generic.c | 2 +- arch/arm/mach-omap1/board-h2.c | 2 +- arch/arm/mach-omap1/board-h3.c | 2 +- arch/arm/mach-omap1/board-innovator.c | 2 +- arch/arm/mach-omap1/board-nokia770.c | 2 +- arch/arm/mach-omap1/board-osk.c | 2 +- arch/arm/mach-omap1/board-palmte.c | 2 +- arch/arm/mach-omap1/board-palmtt.c | 2 +- arch/arm/mach-omap1/board-palmz71.c | 2 +- arch/arm/mach-omap1/board-perseus2.c | 2 +- arch/arm/mach-omap1/board-sx1.c | 2 +- arch/arm/mach-omap1/board-voiceblue.c | 2 +- arch/arm/mach-omap1/devices.c | 2 +- arch/arm/mach-omap1/fpga.c | 2 +- arch/arm/mach-omap1/irq.c | 2 +- arch/arm/mach-omap1/leds-h2p2-debug.c | 2 +- arch/arm/mach-omap1/leds-innovator.c | 2 +- arch/arm/mach-omap1/leds-osk.c | 2 +- arch/arm/mach-omap1/sram.S | 2 +- arch/arm/mach-omap1/time.c | 2 +- arch/arm/mach-omap1/timer32k.c | 2 +- arch/arm/mach-omap2/board-2430sdp.c | 2 +- arch/arm/mach-omap2/board-apollon.c | 2 +- arch/arm/mach-omap2/board-generic.c | 2 +- arch/arm/mach-omap2/board-h4.c | 2 +- arch/arm/mach-omap2/devices.c | 2 +- arch/arm/mach-omap2/irq.c | 2 +- arch/arm/mach-omap2/sram242x.S | 2 +- arch/arm/mach-omap2/sram243x.S | 2 +- arch/arm/mach-orion5x/addr-map.c | 2 +- arch/arm/mach-orion5x/mpp.c | 2 +- arch/arm/mach-pnx4008/clock.c | 2 +- arch/arm/mach-pnx4008/core.c | 2 +- arch/arm/mach-pnx4008/dma.c | 2 +- arch/arm/mach-pnx4008/irq.c | 2 +- arch/arm/mach-pnx4008/serial.c | 2 +- arch/arm/mach-pnx4008/sleep.S | 2 +- arch/arm/mach-pnx4008/time.c | 2 +- arch/arm/mach-pxa/clock.c | 2 +- arch/arm/mach-pxa/colibri.c | 2 +- arch/arm/mach-pxa/corgi.c | 2 +- arch/arm/mach-pxa/corgi_lcd.c | 2 +- arch/arm/mach-pxa/corgi_pm.c | 2 +- arch/arm/mach-pxa/corgi_ssp.c | 2 +- arch/arm/mach-pxa/cpu-pxa.c | 2 +- arch/arm/mach-pxa/dma.c | 2 +- arch/arm/mach-pxa/generic.c | 2 +- arch/arm/mach-pxa/gpio.c | 2 +- arch/arm/mach-pxa/gumstix.c | 2 +- arch/arm/mach-pxa/idp.c | 2 +- arch/arm/mach-pxa/irq.c | 2 +- arch/arm/mach-pxa/leds-idp.c | 2 +- arch/arm/mach-pxa/leds-lubbock.c | 2 +- arch/arm/mach-pxa/leds-mainstone.c | 2 +- arch/arm/mach-pxa/leds-trizeps4.c | 2 +- arch/arm/mach-pxa/littleton.c | 2 +- arch/arm/mach-pxa/lpd270.c | 2 +- arch/arm/mach-pxa/lubbock.c | 2 +- arch/arm/mach-pxa/magician.c | 2 +- arch/arm/mach-pxa/mainstone.c | 2 +- arch/arm/mach-pxa/mfp-pxa3xx.c | 2 +- arch/arm/mach-pxa/pm.c | 2 +- arch/arm/mach-pxa/poodle.c | 2 +- arch/arm/mach-pxa/pxa25x.c | 2 +- arch/arm/mach-pxa/pxa27x.c | 2 +- arch/arm/mach-pxa/pxa300.c | 2 +- arch/arm/mach-pxa/pxa320.c | 2 +- arch/arm/mach-pxa/pxa3xx.c | 2 +- arch/arm/mach-pxa/pxa930.c | 2 +- arch/arm/mach-pxa/saar.c | 2 +- arch/arm/mach-pxa/sharpsl_pm.c | 2 +- arch/arm/mach-pxa/sleep.S | 2 +- arch/arm/mach-pxa/spitz.c | 2 +- arch/arm/mach-pxa/spitz_pm.c | 2 +- arch/arm/mach-pxa/ssp.c | 2 +- arch/arm/mach-pxa/standby.S | 2 +- arch/arm/mach-pxa/tavorevb.c | 2 +- arch/arm/mach-pxa/trizeps4.c | 2 +- arch/arm/mach-pxa/zylonite.c | 2 +- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-realview/localtimer.c | 2 +- arch/arm/mach-realview/platsmp.c | 2 +- arch/arm/mach-realview/realview_eb.c | 2 +- arch/arm/mach-realview/realview_pb1176.c | 2 +- arch/arm/mach-realview/realview_pb11mp.c | 2 +- arch/arm/mach-rpc/dma.c | 2 +- arch/arm/mach-rpc/riscpc.c | 2 +- arch/arm/mach-s3c2400/gpio.c | 2 +- arch/arm/mach-s3c2410/bast-irq.c | 2 +- arch/arm/mach-s3c2410/clock.c | 2 +- arch/arm/mach-s3c2410/gpio.c | 2 +- arch/arm/mach-s3c2410/h1940-bluetooth.c | 2 +- arch/arm/mach-s3c2410/mach-amlm5900.c | 2 +- arch/arm/mach-s3c2410/mach-bast.c | 2 +- arch/arm/mach-s3c2410/mach-h1940.c | 2 +- arch/arm/mach-s3c2410/mach-n30.c | 2 +- arch/arm/mach-s3c2410/mach-otom.c | 2 +- arch/arm/mach-s3c2410/mach-qt2410.c | 2 +- arch/arm/mach-s3c2410/mach-smdk2410.c | 2 +- arch/arm/mach-s3c2410/mach-tct_hammer.c | 2 +- arch/arm/mach-s3c2410/mach-vr1000.c | 2 +- arch/arm/mach-s3c2410/pm-h1940.S | 2 +- arch/arm/mach-s3c2410/pm.c | 2 +- arch/arm/mach-s3c2410/s3c2410.c | 2 +- arch/arm/mach-s3c2410/sleep.S | 2 +- arch/arm/mach-s3c2410/usb-simtec.c | 2 +- arch/arm/mach-s3c2412/clock.c | 2 +- arch/arm/mach-s3c2412/gpio.c | 2 +- arch/arm/mach-s3c2412/irq.c | 2 +- arch/arm/mach-s3c2412/mach-smdk2413.c | 2 +- arch/arm/mach-s3c2412/mach-vstms.c | 2 +- arch/arm/mach-s3c2412/pm.c | 2 +- arch/arm/mach-s3c2412/s3c2412.c | 2 +- arch/arm/mach-s3c2412/sleep.S | 2 +- arch/arm/mach-s3c2440/clock.c | 2 +- arch/arm/mach-s3c2440/dsc.c | 2 +- arch/arm/mach-s3c2440/irq.c | 2 +- arch/arm/mach-s3c2440/mach-anubis.c | 2 +- arch/arm/mach-s3c2440/mach-at2440evb.c | 2 +- arch/arm/mach-s3c2440/mach-nexcoder.c | 2 +- arch/arm/mach-s3c2440/mach-osiris.c | 2 +- arch/arm/mach-s3c2440/mach-rx3715.c | 2 +- arch/arm/mach-s3c2440/mach-smdk2440.c | 2 +- arch/arm/mach-s3c2440/s3c2440.c | 2 +- arch/arm/mach-s3c2442/clock.c | 2 +- arch/arm/mach-s3c2443/clock.c | 2 +- arch/arm/mach-s3c2443/irq.c | 2 +- arch/arm/mach-s3c2443/mach-smdk2443.c | 2 +- arch/arm/mach-s3c2443/s3c2443.c | 2 +- arch/arm/mach-sa1100/assabet.c | 2 +- arch/arm/mach-sa1100/badge4.c | 2 +- arch/arm/mach-sa1100/cerf.c | 2 +- arch/arm/mach-sa1100/clock.c | 2 +- arch/arm/mach-sa1100/collie.c | 2 +- arch/arm/mach-sa1100/collie_pm.c | 2 +- arch/arm/mach-sa1100/cpu-sa1100.c | 2 +- arch/arm/mach-sa1100/cpu-sa1110.c | 2 +- arch/arm/mach-sa1100/dma.c | 2 +- arch/arm/mach-sa1100/generic.c | 2 +- arch/arm/mach-sa1100/gpio.c | 2 +- arch/arm/mach-sa1100/h3600.c | 2 +- arch/arm/mach-sa1100/hackkit.c | 2 +- arch/arm/mach-sa1100/irq.c | 2 +- arch/arm/mach-sa1100/jornada720.c | 2 +- arch/arm/mach-sa1100/jornada720_ssp.c | 2 +- arch/arm/mach-sa1100/lart.c | 2 +- arch/arm/mach-sa1100/leds-assabet.c | 2 +- arch/arm/mach-sa1100/leds-badge4.c | 2 +- arch/arm/mach-sa1100/leds-cerf.c | 2 +- arch/arm/mach-sa1100/leds-hackkit.c | 2 +- arch/arm/mach-sa1100/leds-lart.c | 2 +- arch/arm/mach-sa1100/leds-simpad.c | 2 +- arch/arm/mach-sa1100/neponset.c | 2 +- arch/arm/mach-sa1100/pleb.c | 2 +- arch/arm/mach-sa1100/pm.c | 2 +- arch/arm/mach-sa1100/shannon.c | 2 +- arch/arm/mach-sa1100/simpad.c | 2 +- arch/arm/mach-sa1100/sleep.S | 2 +- arch/arm/mach-sa1100/ssp.c | 2 +- arch/arm/mach-sa1100/time.c | 2 +- arch/arm/mach-shark/leds.c | 2 +- arch/arm/mach-versatile/core.c | 2 +- arch/arm/mach-versatile/pci.c | 2 +- arch/arm/mach-versatile/versatile_ab.c | 2 +- arch/arm/mach-versatile/versatile_pb.c | 2 +- arch/arm/mm/cache-v3.S | 2 +- arch/arm/mm/cache-v4.S | 2 +- arch/arm/mm/cache-v4wt.S | 2 +- arch/arm/mm/proc-sa110.S | 2 +- arch/arm/mm/proc-sa1100.S | 2 +- arch/arm/mm/proc-xsc3.S | 2 +- arch/arm/oprofile/op_model_mpcore.c | 2 +- arch/arm/plat-iop/i2c.c | 2 +- arch/arm/plat-iop/io.c | 2 +- arch/arm/plat-iop/pci.c | 2 +- arch/arm/plat-iop/time.c | 2 +- arch/arm/plat-mxc/gpio.c | 2 +- arch/arm/plat-mxc/iomux-mx1-mx2.c | 2 +- arch/arm/plat-mxc/time.c | 2 +- arch/arm/plat-omap/common.c | 2 +- arch/arm/plat-omap/cpu-omap.c | 2 +- arch/arm/plat-omap/debug-devices.c | 2 +- arch/arm/plat-omap/debug-leds.c | 2 +- arch/arm/plat-omap/devices.c | 2 +- arch/arm/plat-omap/dma.c | 2 +- arch/arm/plat-omap/dmtimer.c | 2 +- arch/arm/plat-omap/fb.c | 2 +- arch/arm/plat-omap/gpio.c | 2 +- arch/arm/plat-omap/ocpi.c | 2 +- arch/arm/plat-omap/usb.c | 2 +- arch/arm/plat-s3c24xx/clock.c | 2 +- arch/arm/plat-s3c24xx/common-smdk.c | 2 +- arch/arm/plat-s3c24xx/cpu.c | 2 +- arch/arm/plat-s3c24xx/devs.c | 2 +- arch/arm/plat-s3c24xx/dma.c | 2 +- arch/arm/plat-s3c24xx/gpio.c | 2 +- arch/arm/plat-s3c24xx/gpiolib.c | 2 +- arch/arm/plat-s3c24xx/irq.c | 2 +- arch/arm/plat-s3c24xx/pm-simtec.c | 2 +- arch/arm/plat-s3c24xx/pm.c | 2 +- arch/arm/plat-s3c24xx/pwm-clock.c | 2 +- arch/arm/plat-s3c24xx/s3c244x-clock.c | 2 +- arch/arm/plat-s3c24xx/s3c244x-irq.c | 2 +- arch/arm/plat-s3c24xx/s3c244x.c | 2 +- arch/arm/plat-s3c24xx/sleep.S | 2 +- drivers/char/ds1620.c | 2 +- drivers/char/hw_random/ixp4xx-rng.c | 2 +- drivers/i2c/busses/i2c-acorn.c | 2 +- drivers/i2c/busses/i2c-davinci.c | 2 +- drivers/i2c/busses/i2c-ixp2000.c | 2 +- drivers/i2c/busses/i2c-pnx.c | 2 +- drivers/i2c/busses/i2c-pxa.c | 2 +- drivers/i2c/busses/i2c-s3c2410.c | 2 +- drivers/input/keyboard/jornada720_kbd.c | 2 +- drivers/input/keyboard/omap-keypad.c | 2 +- drivers/input/misc/ixp4xx-beeper.c | 2 +- drivers/input/mouse/rpcmouse.c | 2 +- drivers/input/serio/rpckbd.c | 2 +- drivers/input/touchscreen/jornada720_ts.c | 2 +- drivers/leds/leds-h1940.c | 2 +- drivers/leds/leds-locomo.c | 2 +- drivers/leds/leds-s3c24xx.c | 2 +- drivers/mfd/mcp-sa11x0.c | 2 +- drivers/mfd/ucb1x00-core.c | 2 +- drivers/mtd/maps/autcpu12-nvram.c | 2 +- drivers/mtd/maps/ceiva.c | 2 +- drivers/mtd/maps/h720x-flash.c | 2 +- drivers/mtd/maps/integrator-flash.c | 2 +- drivers/mtd/maps/ipaq-flash.c | 2 +- drivers/mtd/maps/ixp2000.c | 2 +- drivers/mtd/maps/omap_nor.c | 2 +- drivers/mtd/maps/pxa2xx-flash.c | 2 +- drivers/mtd/maps/sa1100-flash.c | 2 +- drivers/mtd/nand/sharpsl.c | 2 +- drivers/net/arm/am79c961a.c | 2 +- drivers/net/irda/ep7211-sir.c | 2 +- drivers/net/irda/sa1100_ir.c | 2 +- drivers/net/ixp2000/ixp2400-msf.c | 2 +- drivers/net/netx-eth.c | 1 - drivers/pcmcia/at91_cf.c | 2 +- drivers/pcmcia/omap_cf.c | 2 +- drivers/pcmcia/pxa2xx_base.c | 2 +- drivers/pcmcia/pxa2xx_lubbock.c | 2 +- drivers/pcmcia/pxa2xx_mainstone.c | 2 +- drivers/pcmcia/pxa2xx_sharpsl.c | 2 +- drivers/pcmcia/sa1100_assabet.c | 2 +- drivers/pcmcia/sa1100_badge4.c | 2 +- drivers/pcmcia/sa1100_cerf.c | 2 +- drivers/pcmcia/sa1100_h3600.c | 2 +- drivers/pcmcia/sa1100_jornada720.c | 2 +- drivers/pcmcia/sa1100_neponset.c | 2 +- drivers/pcmcia/sa1100_shannon.c | 2 +- drivers/pcmcia/sa1100_simpad.c | 2 +- drivers/pcmcia/sa1111_generic.c | 2 +- drivers/pcmcia/sa11xx_base.c | 2 +- drivers/pcmcia/soc_common.c | 2 +- drivers/rtc/rtc-ep93xx.c | 2 +- drivers/rtc/rtc-s3c.c | 2 +- drivers/rtc/rtc-sa1100.c | 2 +- drivers/scsi/arm/acornscsi-io.S | 2 +- drivers/serial/21285.c | 2 +- drivers/serial/clps711x.c | 2 +- drivers/serial/imx.c | 2 +- drivers/serial/netx-serial.c | 2 +- drivers/serial/pxa.c | 2 +- drivers/serial/s3c2400.c | 2 +- drivers/serial/s3c2410.c | 2 +- drivers/serial/s3c2412.c | 2 +- drivers/serial/s3c2440.c | 2 +- drivers/serial/sa1100.c | 2 +- drivers/serial/samsung.c | 2 +- drivers/spi/omap_uwire.c | 2 +- drivers/spi/pxa2xx_spi.c | 1 - drivers/spi/spi_imx.c | 1 - drivers/spi/spi_s3c24xx.c | 2 +- drivers/spi/spi_s3c24xx_gpio.c | 2 +- drivers/usb/gadget/at91_udc.c | 2 +- drivers/usb/gadget/lh7a40x_udc.h | 2 +- drivers/usb/gadget/pxa27x_udc.c | 2 +- drivers/usb/host/ohci-at91.c | 2 +- drivers/usb/host/ohci-ep93xx.c | 2 +- drivers/usb/host/ohci-lh7a404.c | 2 +- drivers/usb/host/ohci-omap.c | 2 +- drivers/usb/host/ohci-pnx4008.c | 2 +- drivers/usb/host/ohci-pxa27x.c | 2 +- drivers/usb/host/ohci-s3c2410.c | 2 +- drivers/usb/host/ohci-sa1111.c | 2 +- drivers/video/acornfb.c | 2 +- drivers/video/clps711xfb.c | 2 +- drivers/video/imxfb.c | 2 +- drivers/video/pxafb.c | 2 +- drivers/video/sa1100fb.c | 2 +- drivers/watchdog/davinci_wdt.c | 2 +- drivers/watchdog/ep93xx_wdt.c | 2 +- drivers/watchdog/iop_wdt.c | 2 +- drivers/watchdog/ixp2000_wdt.c | 2 +- drivers/watchdog/ixp4xx_wdt.c | 2 +- drivers/watchdog/omap_wdt.c | 2 +- drivers/watchdog/pnx4008_wdt.c | 2 +- drivers/watchdog/sa1100_wdt.c | 2 +- drivers/watchdog/wdt285.c | 2 +- include/asm-arm/arch-aaec2000/io.h | 2 +- include/asm-arm/arch-at91/cpu.h | 2 +- include/asm-arm/arch-at91/debug-macro.S | 2 +- include/asm-arm/arch-at91/entry-macro.S | 2 +- include/asm-arm/arch-at91/memory.h | 2 +- include/asm-arm/arch-at91/system.h | 2 +- include/asm-arm/arch-at91/timex.h | 2 +- include/asm-arm/arch-cl7500/entry-macro.S | 2 +- include/asm-arm/arch-cl7500/io.h | 2 +- include/asm-arm/arch-clps711x/entry-macro.S | 2 +- include/asm-arm/arch-clps711x/io.h | 2 +- include/asm-arm/arch-clps711x/system.h | 2 +- include/asm-arm/arch-clps711x/uncompress.h | 2 +- include/asm-arm/arch-davinci/gpio.h | 2 +- include/asm-arm/arch-davinci/system.h | 2 +- include/asm-arm/arch-ebsa285/entry-macro.S | 2 +- include/asm-arm/arch-ebsa285/io.h | 2 +- include/asm-arm/arch-ebsa285/system.h | 2 +- include/asm-arm/arch-ep93xx/hardware.h | 4 ++++ include/asm-arm/arch-ep93xx/system.h | 2 +- include/asm-arm/arch-h720x/io.h | 2 +- include/asm-arm/arch-h720x/system.h | 2 +- include/asm-arm/arch-h720x/uncompress.h | 2 +- include/asm-arm/arch-imx/entry-macro.S | 2 +- include/asm-arm/arch-imx/io.h | 2 +- include/asm-arm/arch-imx/irqs.h | 2 +- include/asm-arm/arch-integrator/entry-macro.S | 2 +- include/asm-arm/arch-iop13xx/adma.h | 2 +- include/asm-arm/arch-iop13xx/timex.h | 2 +- include/asm-arm/arch-iop13xx/uncompress.h | 2 +- include/asm-arm/arch-iop32x/io.h | 2 +- include/asm-arm/arch-iop32x/memory.h | 2 +- include/asm-arm/arch-iop32x/timex.h | 2 +- include/asm-arm/arch-iop32x/uncompress.h | 2 +- include/asm-arm/arch-iop33x/io.h | 2 +- include/asm-arm/arch-iop33x/memory.h | 2 +- include/asm-arm/arch-iop33x/timex.h | 2 +- include/asm-arm/arch-iop33x/uncompress.h | 2 +- include/asm-arm/arch-ixp2000/io.h | 2 +- include/asm-arm/arch-ixp2000/system.h | 2 +- include/asm-arm/arch-ixp23xx/memory.h | 2 +- include/asm-arm/arch-ixp23xx/system.h | 2 +- include/asm-arm/arch-ixp4xx/avila.h | 2 +- include/asm-arm/arch-ixp4xx/coyote.h | 2 +- include/asm-arm/arch-ixp4xx/dma.h | 2 +- include/asm-arm/arch-ixp4xx/dsmg600.h | 2 +- include/asm-arm/arch-ixp4xx/entry-macro.S | 2 +- include/asm-arm/arch-ixp4xx/fsg.h | 2 +- include/asm-arm/arch-ixp4xx/gpio.h | 2 +- include/asm-arm/arch-ixp4xx/gtwx5715.h | 2 +- include/asm-arm/arch-ixp4xx/io.h | 2 +- include/asm-arm/arch-ixp4xx/ixdp425.h | 2 +- include/asm-arm/arch-ixp4xx/nas100d.h | 2 +- include/asm-arm/arch-ixp4xx/nslu2.h | 2 +- include/asm-arm/arch-ixp4xx/platform.h | 2 +- include/asm-arm/arch-ixp4xx/prpmc1100.h | 2 +- include/asm-arm/arch-ixp4xx/system.h | 2 +- include/asm-arm/arch-ixp4xx/timex.h | 2 +- include/asm-arm/arch-ks8695/debug-macro.S | 2 +- include/asm-arm/arch-ks8695/entry-macro.S | 2 +- include/asm-arm/arch-ks8695/memory.h | 2 +- include/asm-arm/arch-l7200/aux_reg.h | 2 +- include/asm-arm/arch-l7200/entry-macro.S | 2 +- include/asm-arm/arch-l7200/gp_timers.h | 2 +- include/asm-arm/arch-l7200/io.h | 2 +- include/asm-arm/arch-l7200/system.h | 2 +- include/asm-arm/arch-l7200/uncompress.h | 2 +- include/asm-arm/arch-lh7a40x/entry-macro.S | 2 +- include/asm-arm/arch-lh7a40x/io.h | 2 +- include/asm-arm/arch-msm/debug-macro.S | 2 +- include/asm-arm/arch-msm/system.h | 2 +- include/asm-arm/arch-mxc/gpio.h | 2 +- include/asm-arm/arch-mxc/irqs.h | 2 +- include/asm-arm/arch-mxc/memory.h | 2 +- include/asm-arm/arch-mxc/mxc_timer.h | 2 +- include/asm-arm/arch-mxc/timex.h | 2 +- include/asm-arm/arch-mxc/uncompress.h | 2 +- include/asm-arm/arch-netx/entry-macro.S | 2 +- include/asm-arm/arch-netx/system.h | 2 +- include/asm-arm/arch-ns9xxx/debug-macro.S | 2 +- include/asm-arm/arch-ns9xxx/entry-macro.S | 2 +- include/asm-arm/arch-ns9xxx/regs-bbu.h | 2 +- include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h | 2 +- include/asm-arm/arch-ns9xxx/regs-mem.h | 2 +- include/asm-arm/arch-ns9xxx/regs-sys-common.h | 2 +- include/asm-arm/arch-ns9xxx/regs-sys-ns9360.h | 2 +- include/asm-arm/arch-omap/entry-macro.S | 2 +- include/asm-arm/arch-omap/io.h | 2 +- include/asm-arm/arch-omap/irqs.h | 2 +- include/asm-arm/arch-omap/mcbsp.h | 2 +- include/asm-arm/arch-omap/mtd-xip.h | 2 +- include/asm-arm/arch-omap/system.h | 2 +- include/asm-arm/arch-pnx4008/system.h | 2 +- include/asm-arm/arch-pnx4008/timex.h | 2 +- include/asm-arm/arch-pxa/entry-macro.S | 2 +- include/asm-arm/arch-pxa/gpio.h | 2 +- include/asm-arm/arch-pxa/io.h | 2 +- include/asm-arm/arch-realview/entry-macro.S | 2 +- include/asm-arm/arch-realview/system.h | 2 +- include/asm-arm/arch-realview/uncompress.h | 2 +- include/asm-arm/arch-rpc/entry-macro.S | 2 +- include/asm-arm/arch-rpc/io.h | 2 +- include/asm-arm/arch-rpc/system.h | 2 +- include/asm-arm/arch-rpc/uncompress.h | 2 +- include/asm-arm/arch-s3c2410/dma.h | 2 +- include/asm-arm/arch-s3c2410/entry-macro.S | 2 +- include/asm-arm/arch-s3c2410/hardware.h | 4 ---- include/asm-arm/arch-s3c2410/io.h | 2 +- include/asm-arm/arch-s3c2410/system-reset.h | 2 +- include/asm-arm/arch-s3c2410/system.h | 2 +- include/asm-arm/arch-sa1100/badge4.h | 2 +- include/asm-arm/arch-sa1100/debug-macro.S | 2 +- include/asm-arm/arch-sa1100/gpio.h | 2 +- include/asm-arm/arch-sa1100/ide.h | 2 +- include/asm-arm/arch-sa1100/system.h | 2 +- include/asm-arm/arch-shark/io.h | 2 +- include/asm-arm/arch-versatile/entry-macro.S | 2 +- include/asm-arm/arch-versatile/system.h | 2 +- sound/arm/pxa2xx-ac97.c | 2 +- sound/arm/pxa2xx-pcm.c | 2 +- sound/arm/sa11xx-uda1341.c | 2 +- sound/oss/vidc.c | 2 +- sound/oss/vidc_fill.S | 2 +- sound/oss/waveartist.c | 2 +- sound/soc/at91/eti_b1_wm8731.c | 2 +- sound/soc/pxa/pxa2xx-ac97.c | 2 +- sound/soc/pxa/pxa2xx-i2s.c | 2 +- sound/soc/pxa/pxa2xx-pcm.c | 2 +- sound/soc/s3c24xx/neo1973_wm8753.c | 2 +- sound/soc/s3c24xx/s3c2412-i2s.c | 2 +- sound/soc/s3c24xx/s3c2443-ac97.c | 2 +- sound/soc/s3c24xx/s3c24xx-i2s.c | 2 +- sound/soc/s3c24xx/s3c24xx-pcm.c | 2 +- 620 files changed, 617 insertions(+), 640 deletions(-) delete mode 100644 arch/arm/include/asm/hardware.h (limited to 'drivers/rtc') diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 85579654d3b7..1f0f0adeafb3 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index f6d3fdda7067..64c328d1627f 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 7a1f9e3581fd..a0d154006889 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/common/time-acorn.c b/arch/arm/common/time-acorn.c index d544da414731..af37bfd74f9c 100644 --- a/arch/arm/common/time-acorn.c +++ b/arch/arm/common/time-acorn.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/common/uengine.c b/arch/arm/common/uengine.c index 117cab30bd36..3e19985ddecb 100644 --- a/arch/arm/common/uengine.c +++ b/arch/arm/common/uengine.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/include/asm/hardware.h b/arch/arm/include/asm/hardware.h deleted file mode 100644 index eb3b3abb7db7..000000000000 --- a/arch/arm/include/asm/hardware.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * arch/arm/include/asm/hardware.h - * - * Copyright (C) 1996 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Common hardware definitions - */ - -#ifndef __ASM_HARDWARE_H -#define __ASM_HARDWARE_H - -#include - -#endif diff --git a/arch/arm/include/asm/hardware/dec21285.h b/arch/arm/include/asm/hardware/dec21285.h index 7068a1c1e4e4..cf2578ffd54d 100644 --- a/arch/arm/include/asm/hardware/dec21285.h +++ b/arch/arm/include/asm/hardware/dec21285.h @@ -19,7 +19,7 @@ #define DC21285_PCI_MEM 0x80000000 #ifndef __ASSEMBLY__ -#include +#include #define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x))) #else #define DC21285_IO(x) (x) diff --git a/arch/arm/include/asm/hardware/iop3xx-adma.h b/arch/arm/include/asm/hardware/iop3xx-adma.h index af64676650a2..df31b15cf6e0 100644 --- a/arch/arm/include/asm/hardware/iop3xx-adma.h +++ b/arch/arm/include/asm/hardware/iop3xx-adma.h @@ -19,7 +19,7 @@ #define _ADMA_H #include #include -#include +#include #include /* Memory copy units */ diff --git a/arch/arm/include/asm/hardware/iop3xx-gpio.h b/arch/arm/include/asm/hardware/iop3xx-gpio.h index 222e74b7c463..0ebc91cb42f9 100644 --- a/arch/arm/include/asm/hardware/iop3xx-gpio.h +++ b/arch/arm/include/asm/hardware/iop3xx-gpio.h @@ -25,7 +25,7 @@ #ifndef __ASM_ARM_HARDWARE_IOP3XX_GPIO_H #define __ASM_ARM_HARDWARE_IOP3XX_GPIO_H -#include +#include #include #define IOP3XX_N_GPIOS 8 diff --git a/arch/arm/include/asm/mtd-xip.h b/arch/arm/include/asm/mtd-xip.h index 9eb127cc7db2..4bc50f9abe38 100644 --- a/arch/arm/include/asm/mtd-xip.h +++ b/arch/arm/include/asm/mtd-xip.h @@ -17,7 +17,7 @@ #ifndef __ARM_MTD_XIP_H__ #define __ARM_MTD_XIP_H__ -#include +#include #include /* fill instruction prefetch */ diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index 2d84792f2e12..968b833f3bb7 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -4,7 +4,7 @@ #ifdef __KERNEL__ #include -#include /* for PCIBIOS_MIN_* */ +#include /* for PCIBIOS_MIN_* */ #define pcibios_scan_all_fns(a, b) 0 diff --git a/arch/arm/include/asm/vga.h b/arch/arm/include/asm/vga.h index 1e0b913c3d71..4f767ad3a0bb 100644 --- a/arch/arm/include/asm/vga.h +++ b/arch/arm/include/asm/vga.h @@ -1,7 +1,7 @@ #ifndef ASMARM_VGA_H #define ASMARM_VGA_H -#include +#include #include #define VGA_MAP_MEM(x,s) (PCIMEM_BASE + (x)) diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index f5cfdabcb87d..8192fe8409d3 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -46,7 +46,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/lib/ecard.S b/arch/arm/lib/ecard.S index c55aaa2a2088..79cf247ad525 100644 --- a/arch/arm/lib/ecard.S +++ b/arch/arm/lib/ecard.S @@ -12,7 +12,7 @@ */ #include #include -#include +#include #define CPSR2SPSR(rt) \ mrs rt, cpsr; \ diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S index 4ef904185142..4cc4411595f5 100644 --- a/arch/arm/lib/io-readsw-armv3.S +++ b/arch/arm/lib/io-readsw-armv3.S @@ -9,7 +9,7 @@ */ #include #include -#include +#include .Linsw_bad_alignment: adr r0, .Linsw_bad_align_msg diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S index 1607a29f49b7..0a34752bc448 100644 --- a/arch/arm/lib/io-writesw-armv3.S +++ b/arch/arm/lib/io-writesw-armv3.S @@ -9,7 +9,7 @@ */ #include #include -#include +#include .Loutsw_bad_alignment: adr r0, .Loutsw_bad_align_msg diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c index 83f57da3184c..08f030d506b8 100644 --- a/arch/arm/mach-aaec2000/aaed2000.c +++ b/arch/arm/mach-aaec2000/aaed2000.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index b016be2b0e35..2e0cec2dc997 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c index eddc882f1b4a..44690440e846 100644 --- a/arch/arm/mach-at91/at91x40_time.c +++ b/arch/arm/mach-at91/at91x40_time.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c index 2d3d4b6f7b02..fc0f293174cb 100644 --- a/arch/arm/mach-at91/board-1arm.c +++ b/arch/arm/mach-at91/board-1arm.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index af2c33aff1a8..17faf3cea12f 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 117cf6c9afce..83a4494adc9e 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -33,7 +33,7 @@ #include