aboutsummaryrefslogtreecommitdiff
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig94
-rw-r--r--drivers/rtc/Makefile4
-rw-r--r--drivers/rtc/class.c16
-rw-r--r--drivers/rtc/interface.c16
-rw-r--r--drivers/rtc/rtc-at32ap700x.c4
-rw-r--r--drivers/rtc/rtc-au1xxx.c153
-rw-r--r--drivers/rtc/rtc-bfin.c2
-rw-r--r--drivers/rtc/rtc-cmos.c15
-rw-r--r--drivers/rtc/rtc-ds1216.c30
-rw-r--r--drivers/rtc/rtc-ds1390.c72
-rw-r--r--drivers/rtc/rtc-ds1511.c21
-rw-r--r--drivers/rtc/rtc-ds1553.c15
-rw-r--r--drivers/rtc/rtc-ds1672.c22
-rw-r--r--drivers/rtc/rtc-ds3234.c172
-rw-r--r--drivers/rtc/rtc-ep93xx.c13
-rw-r--r--drivers/rtc/rtc-m48t59.c2
-rw-r--r--drivers/rtc/rtc-max6902.c176
-rw-r--r--drivers/rtc/rtc-mv.c163
-rw-r--r--drivers/rtc/rtc-pxa.c489
-rw-r--r--drivers/rtc/rtc-s3c.c3
-rw-r--r--drivers/rtc/rtc-sh.c13
-rw-r--r--drivers/rtc/rtc-stk17ta8.c17
-rw-r--r--drivers/rtc/rtc-test.c8
-rw-r--r--drivers/rtc/rtc-twl4030.c5
-rw-r--r--drivers/rtc/rtc-tx4939.c317
-rw-r--r--drivers/rtc/rtc-vr41xx.c11
26 files changed, 1379 insertions, 474 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 165a8184335..4ad831de41a 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -35,8 +35,8 @@ config RTC_HCTOSYS_DEVICE
default "rtc0"
help
The RTC device that will be used to (re)initialize the system
- clock, usually rtc0. Initialization is done when the system
- starts up, and when it resumes from a low power state. This
+ clock, usually rtc0. Initialization is done when the system
+ starts up, and when it resumes from a low power state. This
device should record time in UTC, since the kernel won't do
timezone correction.
@@ -44,7 +44,7 @@ config RTC_HCTOSYS_DEVICE
functions run, so it must usually be statically linked.
This clock should be battery-backed, so that it reads the correct
- time when the system boots from a power-off state. Otherwise, your
+ time when the system boots from a power-off state. Otherwise, your
system will need an external clock source (like an NTP server).
If the clock you specify here is not battery backed, it may still
@@ -69,8 +69,7 @@ config RTC_INTF_SYSFS
Say yes here if you want to use your RTCs using sysfs interfaces,
/sys/class/rtc/rtc0 through /sys/.../rtcN.
- This driver can also be built as a module. If so, the module
- will be called rtc-sysfs.
+ If unsure, say Y.
config RTC_INTF_PROC
boolean "/proc/driver/rtc (procfs for rtc0)"
@@ -78,11 +77,10 @@ config RTC_INTF_PROC
default RTC_CLASS
help
Say yes here if you want to use your first RTC through the proc
- interface, /proc/driver/rtc. Other RTCs will not be available
+ interface, /proc/driver/rtc. Other RTCs will not be available
through that API.
- This driver can also be built as a module. If so, the module
- will be called rtc-proc.
+ If unsure, say Y.
config RTC_INTF_DEV
boolean "/dev/rtcN (character devices)"
@@ -90,12 +88,14 @@ config RTC_INTF_DEV
help
Say yes here if you want to use your RTCs using the /dev
interfaces, which "udev" sets up as /dev/rtc0 through
- /dev/rtcN. You may want to set up a symbolic link so one
- of these can be accessed as /dev/rtc, which is a name
- expected by "hwclock" and some other programs.
+ /dev/rtcN.
- This driver can also be built as a module. If so, the module
- will be called rtc-dev.
+ You may want to set up a symbolic link so one of these
+ can be accessed as /dev/rtc, which is a name
+ expected by "hwclock" and some other programs. Recent
+ versions of "udev" are known to set up the symlink for you.
+
+ If unsure, say Y.
config RTC_INTF_DEV_UIE_EMUL
bool "RTC UIE emulation on dev interface"
@@ -132,14 +132,14 @@ config RTC_DRV_DS1307
tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
help
If you say yes here you get support for various compatible RTC
- chips (often with battery backup) connected with I2C. This driver
+ chips (often with battery backup) connected with I2C. This driver
should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
- and probably other chips. In some cases the RTC must already
+ and probably other chips. In some cases the RTC must already
have been initialized (by manufacturing or a bootloader).
The first seven registers on these chips hold an RTC, and other
registers may add features such as NVRAM, a trickle charger for
- the RTC/NVRAM backup power, and alarms. NVRAM is visible in
+ the RTC/NVRAM backup power, and alarms. NVRAM is visible in
sysfs, but other chip features may not be available.
This driver can also be built as a module. If so, the module
@@ -150,10 +150,10 @@ config RTC_DRV_DS1374
depends on RTC_CLASS && I2C
help
If you say yes here you get support for Dallas Semiconductor
- DS1374 real-time clock chips. If an interrupt is associated
+ DS1374 real-time clock chips. If an interrupt is associated
with the device, the alarm functionality is supported.
- This driver can also be built as a module. If so, the module
+ This driver can also be built as a module. If so, the module
will be called rtc-ds1374.
config RTC_DRV_DS1672
@@ -247,7 +247,7 @@ config RTC_DRV_TWL92330
help
If you say yes here you get support for the RTC on the
TWL92330 "Menelaus" power management chip, used with OMAP2
- platforms. The support is integrated with the rest of
+ platforms. The support is integrated with the rest of
the Menelaus driver; it's not separate module.
config RTC_DRV_TWL4030
@@ -308,7 +308,7 @@ 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
+ 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
@@ -317,7 +317,8 @@ config RTC_DRV_DS1305
config RTC_DRV_DS1390
tristate "Dallas/Maxim DS1390/93/94"
help
- If you say yes here you get support for the DS1390/93/94 chips.
+ If you say yes here you get support for the
+ Dallas/Maxim DS1390/93/94 chips.
This driver only supports the RTC feature, and not other chip
features such as alarms and trickle charging.
@@ -381,7 +382,7 @@ config RTC_DRV_CMOS
or LPC bus chips, and so on.
Your system will need to define the platform device used by
- this driver, otherwise it won't be accessible. This means
+ this driver, otherwise it won't be accessible. This means
you can safely enable this driver if you don't know whether
or not your board has this kind of hardware.
@@ -598,7 +599,7 @@ config RTC_DRV_AT91RM9200
depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL
help
Driver for the internal RTC (Realtime Clock) module found on
- Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips
+ Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips
this is powered by the backup power supply.
config RTC_DRV_AT91SAM9
@@ -620,8 +621,8 @@ config RTC_DRV_AT91SAM9_RTT
prompt "RTT module Number" if ARCH_AT91SAM9263
depends on RTC_DRV_AT91SAM9
help
- More than one RTT module is available. You can choose which
- one will be used as an RTC. The default of zero is normally
+ More than one RTT module is available. You can choose which
+ one will be used as an RTC. The default of zero is normally
OK to use, though some systems use that for non-RTC purposes.
config RTC_DRV_AT91SAM9_GPBR
@@ -633,10 +634,20 @@ config RTC_DRV_AT91SAM9_GPBR
depends on RTC_DRV_AT91SAM9
help
The RTC driver needs to use one of the General Purpose Backup
- Registers (GPBRs) as well as the RTT. You can choose which one
- will be used. The default of zero is normally OK to use, but
+ Registers (GPBRs) as well as the RTT. You can choose which one
+ will be used. The default of zero is normally OK to use, but
on some systems other software needs to use that register.
+config RTC_DRV_AU1XXX
+ tristate "Au1xxx Counter0 RTC support"
+ depends on SOC_AU1X00
+ help
+ This is a driver for the Au1xxx on-chip Counter0 (Time-Of-Year
+ counter) to be used as a RTC.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-au1xxx.
+
config RTC_DRV_BFIN
tristate "Blackfin On-Chip RTC"
depends on BLACKFIN && !BF561
@@ -669,6 +680,17 @@ config RTC_DRV_PPC
the RTC. This exposes that functionality through the generic RTC
class.
+config RTC_DRV_PXA
+ tristate "PXA27x/PXA3xx"
+ depends on ARCH_PXA
+ help
+ If you say Y here you will get access to the real time clock
+ built into your PXA27x or PXA3xx CPU.
+
+ This RTC driver uses PXA RTC registers available since pxa27x
+ series (RDxR, RYxR) instead of legacy RCNR, RTAR.
+
+
config RTC_DRV_SUN4V
bool "SUN4V Hypervisor RTC"
depends on SPARC64
@@ -683,4 +705,22 @@ config RTC_DRV_STARFIRE
If you say Y here you will get support for the RTC found on
Starfire systems.
+config RTC_DRV_TX4939
+ tristate "TX4939 SoC"
+ depends on SOC_TX4939
+ help
+ Driver for the internal RTC (Realtime Clock) module found on
+ Toshiba TX4939 SoC.
+
+config RTC_DRV_MV
+ tristate "Marvell SoC RTC"
+ depends on ARCH_KIRKWOOD
+ help
+ If you say yes here you will get support for the in-chip RTC
+ that can be found in some of Marvell's SoC devices, such as
+ the Kirkwood 88F6281 and 88F6192.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-mv.
+
endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 6e79c912bf9..9a4340d48f2 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -20,6 +20,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
+obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o
obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
@@ -47,6 +48,7 @@ obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
+obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
@@ -54,6 +56,7 @@ obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o
obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o
+obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
@@ -66,6 +69,7 @@ obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o
+obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 4dfdf019fcc..be5a6b73e60 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -48,9 +48,7 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg)
struct rtc_time tm;
struct timespec ts = current_kernel_time();
- if (strncmp(rtc->dev.bus_id,
- CONFIG_RTC_HCTOSYS_DEVICE,
- BUS_ID_SIZE) != 0)
+ if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
return 0;
rtc_read_time(rtc, &tm);
@@ -71,20 +69,18 @@ static int rtc_resume(struct device *dev)
time_t newtime;
struct timespec time;
- if (strncmp(rtc->dev.bus_id,
- CONFIG_RTC_HCTOSYS_DEVICE,
- BUS_ID_SIZE) != 0)
+ if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
return 0;
rtc_read_time(rtc, &tm);
if (rtc_valid_tm(&tm) != 0) {
- pr_debug("%s: bogus resume time\n", rtc->dev.bus_id);
+ pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev));
return 0;
}
rtc_tm_to_time(&tm, &newtime);
if (newtime <= oldtime) {
if (newtime < oldtime)
- pr_debug("%s: time travel!\n", rtc->dev.bus_id);
+ pr_debug("%s: time travel!\n", dev_name(&rtc->dev));
return 0;
}
@@ -156,7 +152,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
init_waitqueue_head(&rtc->irq_queue);
strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
- snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id);
+ dev_set_name(&rtc->dev, "rtc%d", id);
rtc_dev_prepare(rtc);
@@ -169,7 +165,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
rtc_proc_add_device(rtc);
dev_info(dev, "rtc core: registered %s as %s\n",
- rtc->name, rtc->dev.bus_id);
+ rtc->name, dev_name(&rtc->dev));
return rtc;
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index fd2c652504f..4348c4b0d45 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -50,10 +50,15 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
if (!rtc->ops)
err = -ENODEV;
- else if (!rtc->ops->set_time)
- err = -EINVAL;
- else
+ else if (rtc->ops->set_time)
err = rtc->ops->set_time(rtc->dev.parent, tm);
+ else if (rtc->ops->set_mmss) {
+ unsigned long secs;
+ err = rtc_tm_to_time(tm, &secs);
+ if (err == 0)
+ err = rtc->ops->set_mmss(rtc->dev.parent, secs);
+ } else
+ err = -EINVAL;
mutex_unlock(&rtc->ops_lock);
return err;
@@ -389,7 +394,7 @@ static int __rtc_match(struct device *dev, void *data)
{
char *name = (char *)data;
- if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0)
+ if (strcmp(dev_name(dev), name) == 0)
return 1;
return 0;
}
@@ -504,9 +509,6 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
if (rtc->ops->irq_set_freq == NULL)
return -ENXIO;
- if (!is_power_of_2(freq))
- return -EINVAL;
-
spin_lock_irqsave(&rtc->irq_task_lock, flags);
if (rtc->irq_task != NULL && task == NULL)
err = -EBUSY;
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c
index 90b9a6503e1..e1ec33e40e3 100644
--- a/drivers/rtc/rtc-at32ap700x.c
+++ b/drivers/rtc/rtc-at32ap700x.c
@@ -205,7 +205,7 @@ static int __init at32_rtc_probe(struct platform_device *pdev)
{
struct resource *regs;
struct rtc_at32ap700x *rtc;
- int irq = -1;
+ int irq;
int ret;
rtc = kzalloc(sizeof(struct rtc_at32ap700x), GFP_KERNEL);
@@ -222,7 +222,7 @@ static int __init at32_rtc_probe(struct platform_device *pdev)
}
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
+ if (irq <= 0) {
dev_dbg(&pdev->dev, "could not get irq\n");
ret = -ENXIO;
goto out;
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c
new file mode 100644
index 00000000000..8906a688e6a
--- /dev/null
+++ b/drivers/rtc/rtc-au1xxx.c
@@ -0,0 +1,153 @@
+/*
+ * Au1xxx counter0 (aka Time-Of-Year counter) RTC interface driver.
+ *
+ * Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+/* All current Au1xxx SoCs have 2 counters fed by an external 32.768 kHz
+ * crystal. Counter 0, which keeps counting during sleep/powerdown, is
+ * used to count seconds since the beginning of the unix epoch.
+ *
+ * The counters must be configured and enabled by bootloader/board code;
+ * no checks as to whether they really get a proper 32.768kHz clock are
+ * made as this would take far too long.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <asm/mach-au1x00/au1000.h>
+
+/* 32kHz clock enabled and detected */
+#define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S)
+
+static int au1xtoy_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned long t;
+
+ t = au_readl(SYS_TOYREAD);
+
+ rtc_time_to_tm(t, tm);
+
+ return rtc_valid_tm(tm);
+}
+
+static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned long t;
+
+ rtc_tm_to_time(tm, &t);
+
+ au_writel(t, SYS_TOYWRITE);
+ au_sync();
+
+ /* wait for the pending register write to succeed. This can
+ * take up to 6 seconds...
+ */
+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S)
+ msleep(1);
+
+ return 0;
+}
+
+static struct rtc_class_ops au1xtoy_rtc_ops = {
+ .read_time = au1xtoy_rtc_read_time,
+ .set_time = au1xtoy_rtc_set_time,
+};
+
+static int __devinit au1xtoy_rtc_probe(struct platform_device *pdev)
+{
+ struct rtc_device *rtcdev;
+ unsigned long t;
+ int ret;
+
+ t = au_readl(SYS_COUNTER_CNTRL);
+ if (!(t & CNTR_OK)) {
+ dev_err(&pdev->dev, "counters not working; aborting.\n");
+ ret = -ENODEV;
+ goto out_err;
+ }
+
+ ret = -ETIMEDOUT;
+
+ /* set counter0 tickrate to 1Hz if necessary */
+ if (au_readl(SYS_TOYTRIM) != 32767) {
+ /* wait until hardware gives access to TRIM register */
+ t = 0x00100000;
+ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && t--)
+ msleep(1);
+
+ if (!t) {
+ /* timed out waiting for register access; assume
+ * counters are unusable.
+ */
+ dev_err(&pdev->dev, "timeout waiting for access\n");
+ goto out_err;
+ }
+
+ /* set 1Hz TOY tick rate */
+ au_writel(32767, SYS_TOYTRIM);
+ au_sync();
+ }
+
+ /* wait until the hardware allows writes to the counter reg */
+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S)
+ msleep(1);
+
+ rtcdev = rtc_device_register("rtc-au1xxx", &pdev->dev,
+ &au1xtoy_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtcdev)) {
+ ret = PTR_ERR(rtcdev);
+ goto out_err;
+ }
+
+ platform_set_drvdata(pdev, rtcdev);
+
+ return 0;
+
+out_err:
+ return ret;
+}
+
+static int __devexit au1xtoy_rtc_remove(struct platform_device *pdev)
+{
+ struct rtc_device *rtcdev = platform_get_drvdata(pdev);
+
+ rtc_device_unregister(rtcdev);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver au1xrtc_driver = {
+ .driver = {
+ .name = "rtc-au1xxx",
+ .owner = THIS_MODULE,
+ },
+ .remove = __devexit_p(au1xtoy_rtc_remove),
+};
+
+static int __init au1xtoy_rtc_init(void)
+{
+ return platform_driver_probe(&au1xrtc_driver, au1xtoy_rtc_probe);
+}
+
+static void __exit au1xtoy_rtc_exit(void)
+{
+ platform_driver_unregister(&au1xrtc_driver);
+}
+
+module_init(au1xtoy_rtc_init);
+module_exit(au1xtoy_rtc_exit);
+
+MODULE_DESCRIPTION("Au1xxx TOY-counter-based RTC driver");
+MODULE_AUTHOR("Manuel Lauss <manuel.lauss@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:rtc-au1xxx");
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
index 34439ce3967..aafd3e6ebb0 100644
--- a/drivers/rtc/rtc-bfin.c
+++ b/drivers/rtc/rtc-bfin.c
@@ -390,7 +390,7 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev)
/* Register our RTC with the RTC framework */
rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE);
- if (unlikely(IS_ERR(rtc))) {
+ if (unlikely(IS_ERR(rtc->rtc_dev))) {
ret = PTR_ERR(rtc->rtc_dev);
goto err_irq;
}
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 6cf8e282338..b6d35f50e40 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
+#include <linux/log2.h>
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
#include <asm-generic/rtc.h>
@@ -58,7 +59,7 @@ struct cmos_rtc {
};
/* both platform and pnp busses use negative numbers for invalid irqs */
-#define is_valid_irq(n) ((n) >= 0)
+#define is_valid_irq(n) ((n) > 0)
static const char driver_name[] = "rtc_cmos";
@@ -384,6 +385,8 @@ static int cmos_irq_set_freq(struct device *dev, int freq)
if (!is_valid_irq(cmos->irq))
return -ENXIO;
+ if (!is_power_of_2(freq))
+ return -EINVAL;
/* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */
f = ffs(freq);
if (f-- > 16)
@@ -729,7 +732,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
cmos_rtc.dev = dev;
dev_set_drvdata(dev, &cmos_rtc);
- rename_region(ports, cmos_rtc.rtc->dev.bus_id);
+ rename_region(ports, dev_name(&cmos_rtc.rtc->dev));
spin_lock_irq(&rtc_lock);
@@ -777,7 +780,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
rtc_cmos_int_handler = cmos_interrupt;
retval = request_irq(rtc_irq, rtc_cmos_int_handler,
- IRQF_DISABLED, cmos_rtc.rtc->dev.bus_id,
+ IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev),
cmos_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
@@ -795,7 +798,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
}
pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n",
- cmos_rtc.rtc->dev.bus_id,
+ dev_name(&cmos_rtc.rtc->dev),
is_valid_irq(rtc_irq)
? (cmos_rtc.mon_alrm
? "year"
@@ -885,7 +888,7 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)
}
pr_debug("%s: suspend%s, ctrl %02x\n",
- cmos_rtc.rtc->dev.bus_id,
+ dev_name(&cmos_rtc.rtc->dev),
(tmp & RTC_AIE) ? ", alarm may wake" : "",
tmp);
@@ -941,7 +944,7 @@ static int cmos_resume(struct device *dev)
}
pr_debug("%s: resume, ctrl %02x\n",
- cmos_rtc.rtc->dev.bus_id,
+ dev_name(&cmos_rtc.rtc->dev),
tmp);
return 0;
diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c
index 9a234a4ec06..4aedc705518 100644
--- a/drivers/rtc/rtc-ds1216.c
+++ b/drivers/rtc/rtc-ds1216.c
@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/bcd.h>
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
struct ds1216_regs {
u8 tsec;
@@ -101,7 +101,8 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_year = bcd2bin(regs.year);
if (tm->tm_year < 70)
tm->tm_year += 100;
- return 0;
+
+ return rtc_valid_tm(tm);
}
static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -138,9 +139,8 @@ static const struct rtc_class_ops ds1216_rtc_ops = {
.set_time = ds1216_rtc_set_time,
};
-static int __devinit ds1216_rtc_probe(struct platform_device *pdev)
+static int __init ds1216_rtc_probe(struct platform_device *pdev)
{
- struct rtc_device *rtc;
struct resource *res;
struct ds1216_priv *priv;
int ret = 0;
@@ -152,7 +152,10 @@ static int __devinit ds1216_rtc_probe(struct platform_device *pdev)
priv = kzalloc(sizeof *priv, GFP_KERNEL);
if (!priv)
return -ENOMEM;
- priv->size = res->end - res->start + 1;
+
+ platform_set_drvdata(pdev, priv);
+
+ priv->size = resource_size(res);
if (!request_mem_region(res->start, priv->size, pdev->name)) {
ret = -EBUSY;
goto out;
@@ -163,22 +166,18 @@ static int __devinit ds1216_rtc_probe(struct platform_device *pdev)
ret = -ENOMEM;
goto out;
}
- rtc = rtc_device_register("ds1216", &pdev->dev,
+ priv->rtc = rtc_device_register("ds1216", &pdev->dev,
&ds1216_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- ret = PTR_ERR(rtc);
+ if (IS_ERR(priv->rtc)) {
+ ret = PTR_ERR(priv->rtc);
goto out;
}
- priv->rtc = rtc;
- platform_set_drvdata(pdev, priv);
/* dummy read to get clock into a known state */
ds1216_read(priv->ioaddr, dummy);
return 0;
out:
- if (priv->rtc)
- rtc_device_unregister(priv->rtc);
if (priv->ioaddr)
iounmap(priv->ioaddr);
if (priv->baseaddr)
@@ -187,7 +186,7 @@ out:
return ret;
}
-static int __devexit ds1216_rtc_remove(struct platform_device *pdev)
+static int __exit ds1216_rtc_remove(struct platform_device *pdev)
{
struct ds1216_priv *priv = platform_get_drvdata(pdev);
@@ -203,13 +202,12 @@ static struct platform_driver ds1216_rtc_platform_driver = {
.name = "rtc-ds1216",
.owner = THIS_MODULE,
},
- .probe = ds1216_rtc_probe,
- .remove = __devexit_p(ds1216_rtc_remove),
+ .remove = __exit_p(ds1216_rtc_remove),
};
static int __init ds1216_rtc_init(void)
{
- return platform_driver_register(&ds1216_rtc_platform_driver);
+ return platform_driver_probe(&ds1216_rtc_platform_driver, ds1216_rtc_probe);
}
static void __exit ds1216_rtc_exit(void)
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c
index 599e976bf01..e54b5c619bd 100644
--- a/drivers/rtc/rtc-ds1390.c
+++ b/drivers/rtc/rtc-ds1390.c
@@ -1,5 +1,5 @@
/*
- * rtc-ds1390.c -- driver for DS1390/93/94
+ * rtc-ds1390.c -- driver for the Dallas/Maxim DS1390/93/94 SPI RTC
*
* Copyright (C) 2008 Mercury IMC Ltd
* Written by Mark Jackson <mpfj@mimc.co.uk>
@@ -8,11 +8,13 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * NOTE : Currently this driver only supports the bare minimum for read
- * and write the RTC. The extra features provided by the chip family
+ * NOTE: Currently this driver only supports the bare minimum for read
+ * and write the RTC. The extra features provided by the chip family
* (alarms, trickle charger, different control registers) are unavailable.
*/
+#include <linux/init.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/spi/spi.h>
@@ -42,20 +44,6 @@ struct ds1390 {
u8 txrx_buf[9]; /* cmd + 8 registers */
};
-static void ds1390_set_reg(struct device *dev, unsigned char address,
- unsigned char data)
-{
- struct spi_device *spi = to_spi_device(dev);
- struct ds1390 *chip = dev_get_drvdata(dev);
-
- /* Set MSB to indicate write */
- chip->txrx_buf[0] = address | 0x80;
- chip->txrx_buf[1] = data;
-
- /* do the i/o */
- spi_write_then_read(spi, chip->txrx_buf, 2, NULL, 0);
-}
-
static int ds1390_get_reg(struct device *dev, unsigned char address,
unsigned char *data)
{
@@ -78,7 +66,7 @@ static int ds1390_get_reg(struct device *dev, unsigned char address,
return 0;
}
-static int ds1390_get_datetime(struct device *dev, struct rtc_time *dt)
+static int ds1390_read_time(struct device *dev, struct rtc_time *dt)
{
struct spi_device *spi = to_spi_device(dev);
struct ds1390 *chip = dev_get_drvdata(dev);
@@ -107,7 +95,7 @@ static int ds1390_get_datetime(struct device *dev, struct rtc_time *dt)
return rtc_valid_tm(dt);
}
-static int ds1390_set_datetime(struct device *dev, struct rtc_time *dt)
+static int ds1390_set_time(struct device *dev, struct rtc_time *dt)
{
struct spi_device *spi = to_spi_device(dev);
struct ds1390 *chip = dev_get_drvdata(dev);
@@ -127,16 +115,6 @@ static int ds1390_set_datetime(struct device *dev, struct rtc_time *dt)
return spi_write_then_read(spi, chip->txrx_buf, 8, NULL, 0);
}
-static int ds1390_read_time(struct device *dev, struct rtc_time *tm)
-{
- return ds1390_get_datetime(dev, tm);
-}
-
-static int ds1390_set_time(struct device *dev, struct rtc_time *tm)
-{
- return ds1390_set_datetime(dev, tm);
-}
-
static const struct rtc_class_ops ds1390_rtc_ops = {
.read_time = ds1390_read_time,
.set_time = ds1390_set_time,
@@ -149,46 +127,40 @@ static int __devinit ds1390_probe(struct spi_device *spi)
struct ds1390 *chip;
int res;
- printk(KERN_DEBUG "DS1390 SPI RTC driver\n");
-
- rtc = rtc_device_register("ds1390",
- &spi->dev, &ds1390_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- printk(KERN_ALERT "RTC : unable to register device\n");
- return PTR_ERR(rtc);
- }
-
spi->mode = SPI_MODE_3;
spi->bits_per_word = 8;
spi_setup(spi);
chip = kzalloc(sizeof *chip, GFP_KERNEL);
if (!chip) {
- printk(KERN_ALERT "RTC : unable to allocate device memory\n");
- rtc_device_unregister(rtc);
+ dev_err(&spi->dev, "unable to allocate device memory\n");
return -ENOMEM;
}
- chip->rtc = rtc;
dev_set_drvdata(&spi->dev, chip);
res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp);
- if (res) {
- printk(KERN_ALERT "RTC : unable to read device\n");
- rtc_device_unregister(rtc);
+ if (res != 0) {
+ dev_err(&spi->dev, "unable to read device\n");
+ kfree(chip);
return res;
}
- return 0;
+ chip->rtc = rtc_device_register("ds1390",
+ &spi->dev, &ds1390_rtc_ops, THIS_MODULE);
+ if (IS_ERR(chip->rtc)) {
+ dev_err(&spi->dev, "unable to register device\n");
+ res = PTR_ERR(chip->rtc);
+ kfree(chip);
+ }
+
+ return res;
}
static int __devexit ds1390_remove(struct spi_device *spi)
{
struct ds1390 *chip = platform_get_drvdata(spi);
- struct rtc_device *rtc = chip->rtc;
-
- if (rtc)
- rtc_device_unregister(rtc);
+ rtc_device_unregister(chip->rtc);
kfree(chip);
return 0;
@@ -215,6 +187,6 @@ static __exit void ds1390_exit(void)
}
module_exit(ds1390_exit);
-MODULE_DESCRIPTION("DS1390/93/94 SPI RTC driver");
+MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver");
MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 25caada7839..0b6b7730c71 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -326,9 +326,9 @@ ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
- if (pdata->irq < 0) {
+ if (pdata->irq <= 0)
return -EINVAL;
- }
+
pdata->alrm_mday = alrm->time.tm_mday;
pdata->alrm_hour = alrm->time.tm_hour;
pdata->alrm_min = alrm->time.tm_min;
@@ -346,9 +346,9 @@ ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
- if (pda