summaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig76
-rw-r--r--drivers/rtc/Makefile3
-rw-r--r--drivers/rtc/class.c4
-rw-r--r--drivers/rtc/dev.c33
-rw-r--r--drivers/rtc/interface.c69
-rw-r--r--drivers/rtc/rtc-88pm80x.c6
-rw-r--r--drivers/rtc/rtc-88pm860x.c4
-rw-r--r--drivers/rtc/rtc-ab-b5ze-s3.c11
-rw-r--r--drivers/rtc/rtc-ab-eoz9.c24
-rw-r--r--drivers/rtc/rtc-abx80x.c7
-rw-r--r--drivers/rtc/rtc-ac100.c14
-rw-r--r--drivers/rtc/rtc-armada38x.c22
-rw-r--r--drivers/rtc/rtc-asm9260.c11
-rw-r--r--drivers/rtc/rtc-aspeed.c11
-rw-r--r--drivers/rtc/rtc-at91rm9200.c142
-rw-r--r--drivers/rtc/rtc-at91rm9200.h71
-rw-r--r--drivers/rtc/rtc-at91sam9.c8
-rw-r--r--drivers/rtc/rtc-bd70528.c222
-rw-r--r--drivers/rtc/rtc-brcmstb-waketimer.c9
-rw-r--r--drivers/rtc/rtc-cadence.c17
-rw-r--r--drivers/rtc/rtc-cmos.c12
-rw-r--r--drivers/rtc/rtc-coh901331.c4
-rw-r--r--drivers/rtc/rtc-cros-ec.c26
-rw-r--r--drivers/rtc/rtc-da9063.c3
-rw-r--r--drivers/rtc/rtc-davinci.c8
-rw-r--r--drivers/rtc/rtc-digicolor.c4
-rw-r--r--drivers/rtc/rtc-ds1216.c4
-rw-r--r--drivers/rtc/rtc-ds1286.c4
-rw-r--r--drivers/rtc/rtc-ds1302.c2
-rw-r--r--drivers/rtc/rtc-ds1305.c7
-rw-r--r--drivers/rtc/rtc-ds1343.c307
-rw-r--r--drivers/rtc/rtc-ds1347.c102
-rw-r--r--drivers/rtc/rtc-ds1374.c6
-rw-r--r--drivers/rtc/rtc-ds1511.c4
-rw-r--r--drivers/rtc/rtc-ds1553.c4
-rw-r--r--drivers/rtc/rtc-ds1672.c3
-rw-r--r--drivers/rtc/rtc-ds1685.c116
-rw-r--r--drivers/rtc/rtc-em3027.c4
-rw-r--r--drivers/rtc/rtc-ep93xx.c4
-rw-r--r--drivers/rtc/rtc-fsl-ftm-alarm.c325
-rw-r--r--drivers/rtc/rtc-goldfish.c8
-rw-r--r--drivers/rtc/rtc-hym8563.c19
-rw-r--r--drivers/rtc/rtc-imx-sc.c4
-rw-r--r--drivers/rtc/rtc-imxdi.c4
-rw-r--r--drivers/rtc/rtc-isl12026.c6
-rw-r--r--drivers/rtc/rtc-jz4740.c12
-rw-r--r--drivers/rtc/rtc-lpc24xx.c4
-rw-r--r--drivers/rtc/rtc-lpc32xx.c15
-rw-r--r--drivers/rtc/rtc-m41t80.c7
-rw-r--r--drivers/rtc/rtc-m48t35.c11
-rw-r--r--drivers/rtc/rtc-m48t86.c11
-rw-r--r--drivers/rtc/rtc-max77686.c26
-rw-r--r--drivers/rtc/rtc-meson-vrtc.c155
-rw-r--r--drivers/rtc/rtc-meson.c6
-rw-r--r--drivers/rtc/rtc-moxart.c5
-rw-r--r--drivers/rtc/rtc-msm6242.c23
-rw-r--r--drivers/rtc/rtc-mt6397.c158
-rw-r--r--drivers/rtc/rtc-mt7622.c5
-rw-r--r--drivers/rtc/rtc-mv.c4
-rw-r--r--drivers/rtc/rtc-mxc.c5
-rw-r--r--drivers/rtc/rtc-mxc_v2.c4
-rw-r--r--drivers/rtc/rtc-nuc900.c271
-rw-r--r--drivers/rtc/rtc-omap.c6
-rw-r--r--drivers/rtc/rtc-pcf2123.c136
-rw-r--r--drivers/rtc/rtc-pcf2127.c392
-rw-r--r--drivers/rtc/rtc-pcf85063.c16
-rw-r--r--drivers/rtc/rtc-pcf8523.c24
-rw-r--r--drivers/rtc/rtc-pcf85363.c7
-rw-r--r--drivers/rtc/rtc-pcf8563.c86
-rw-r--r--drivers/rtc/rtc-pic32.c8
-rw-r--r--drivers/rtc/rtc-pm8xxx.c6
-rw-r--r--drivers/rtc/rtc-puv3.c12
-rw-r--r--drivers/rtc/rtc-pxa.c8
-rw-r--r--drivers/rtc/rtc-r7301.c7
-rw-r--r--drivers/rtc/rtc-rk808.c6
-rw-r--r--drivers/rtc/rtc-rtd119x.c4
-rw-r--r--drivers/rtc/rtc-rv3028.c166
-rw-r--r--drivers/rtc/rtc-rv3029c2.c454
-rw-r--r--drivers/rtc/rtc-rv8803.c19
-rw-r--r--drivers/rtc/rtc-rx6110.c16
-rw-r--r--drivers/rtc/rtc-rx8010.c25
-rw-r--r--drivers/rtc/rtc-rx8025.c27
-rw-r--r--drivers/rtc/rtc-s35390a.c68
-rw-r--r--drivers/rtc/rtc-s3c.c12
-rw-r--r--drivers/rtc/rtc-s5m.c6
-rw-r--r--drivers/rtc/rtc-sa1100.c4
-rw-r--r--drivers/rtc/rtc-sc27xx.c14
-rw-r--r--drivers/rtc/rtc-sd3078.c4
-rw-r--r--drivers/rtc/rtc-sh.c2
-rw-r--r--drivers/rtc/rtc-sirfsoc.c8
-rw-r--r--drivers/rtc/rtc-snvs.c25
-rw-r--r--drivers/rtc/rtc-spear.c8
-rw-r--r--drivers/rtc/rtc-st-lpc.c5
-rw-r--r--drivers/rtc/rtc-stk17ta8.c4
-rw-r--r--drivers/rtc/rtc-stm32.c10
-rw-r--r--drivers/rtc/rtc-sun6i.c94
-rw-r--r--drivers/rtc/rtc-sunxi.c18
-rw-r--r--drivers/rtc/rtc-tegra.c16
-rw-r--r--drivers/rtc/rtc-tps6586x.c9
-rw-r--r--drivers/rtc/rtc-tps65910.c29
-rw-r--r--drivers/rtc/rtc-tx4939.c4
-rw-r--r--drivers/rtc/rtc-v3020.c3
-rw-r--r--drivers/rtc/rtc-vr41xx.c8
-rw-r--r--drivers/rtc/rtc-vt8500.c36
-rw-r--r--drivers/rtc/rtc-wilco-ec.c8
-rw-r--r--drivers/rtc/rtc-xgene.c10
-rw-r--r--drivers/rtc/rtc-zynqmp.c19
-rw-r--r--drivers/rtc/sysfs.c5
108 files changed, 2285 insertions, 2045 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e72f65b61176..34c8b6c7e095 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -240,6 +240,7 @@ config RTC_DRV_AS3722
config RTC_DRV_DS1307
tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, ISL12057"
+ select REGMAP_I2C
help
If you say yes here you get support for various compatible RTC
chips (often with battery backup) connected with I2C. This driver
@@ -498,11 +499,13 @@ config RTC_DRV_M41T80_WDT
help
If you say Y here you will get support for the
watchdog timer in the ST M41T60 and M41T80 RTC chips series.
+
config RTC_DRV_BD70528
tristate "ROHM BD70528 PMIC RTC"
+ depends on MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG)
help
If you say Y here you will get support for the RTC
- on ROHM BD70528 Power Management IC.
+ block on ROHM BD70528 and BD71828 Power Management IC.
This driver can also be built as a module. If so, the module
will be called rtc-bd70528.
@@ -620,6 +623,7 @@ config RTC_DRV_RX8010
config RTC_DRV_RX8581
tristate "Epson RX-8571/RX-8581"
+ select REGMAP_I2C
help
If you say yes here you will get support for the Epson RX-8571/
RX-8581.
@@ -647,6 +651,7 @@ config RTC_DRV_EM3027
config RTC_DRV_RV3028
tristate "Micro Crystal RV3028"
+ select REGMAP_I2C
help
If you say yes here you get support for the Micro Crystal
RV3028.
@@ -675,13 +680,14 @@ config RTC_DRV_S5M
will be called rtc-s5m.
config RTC_DRV_SD3078
- tristate "ZXW Shenzhen whwave SD3078"
- help
- If you say yes here you get support for the ZXW Shenzhen whwave
- SD3078 RTC chips.
+ tristate "ZXW Shenzhen whwave SD3078"
+ select REGMAP_I2C
+ help
+ If you say yes here you get support for the ZXW Shenzhen whwave
+ SD3078 RTC chips.
- This driver can also be built as a module. If so, the module
- will be called rtc-sd3078
+ This driver can also be built as a module. If so, the module
+ will be called rtc-sd3078
endif # I2C
@@ -847,14 +853,14 @@ config RTC_I2C_AND_SPI
default m if I2C=m
default y if I2C=y
default y if SPI_MASTER=y
- select REGMAP_I2C if I2C
- select REGMAP_SPI if SPI_MASTER
comment "SPI and I2C RTC drivers"
config RTC_DRV_DS3232
tristate "Dallas/Maxim DS3232/DS3234"
depends on RTC_I2C_AND_SPI
+ select REGMAP_I2C if I2C
+ select REGMAP_SPI if SPI_MASTER
help
If you say yes here you get support for Dallas Semiconductor
DS3232 and DS3234 real-time clock chips. If an interrupt is associated
@@ -874,9 +880,17 @@ config RTC_DRV_DS3232_HWMON
config RTC_DRV_PCF2127
tristate "NXP PCF2127"
depends on RTC_I2C_AND_SPI
+ select REGMAP_I2C if I2C
+ select REGMAP_SPI if SPI_MASTER
+ select WATCHDOG_CORE if WATCHDOG
help
If you say yes here you get support for the NXP PCF2127/29 RTC
- chips.
+ chips with integrated quartz crystal for industrial applications.
+ Both chips also have watchdog timer and tamper switch detection
+ features.
+
+ PCF2127 has an additional feature of 512 bytes battery backed
+ memory that's accessible using nvmem interface.
This driver can also be built as a module. If so, the module
will be called rtc-pcf2127.
@@ -884,6 +898,8 @@ config RTC_DRV_PCF2127
config RTC_DRV_RV3029C2
tristate "Micro Crystal RV3029/3049"
depends on RTC_I2C_AND_SPI
+ select REGMAP_I2C if I2C
+ select REGMAP_SPI if SPI_MASTER
help
If you say yes here you get support for the Micro Crystal
RV3029 and RV3049 RTC chips.
@@ -1247,13 +1263,6 @@ config RTC_DRV_AB8500
Select this to enable the ST-Ericsson AB8500 power management IC RTC
support. This chip contains a battery- and capacitor-backed RTC.
-config RTC_DRV_NUC900
- tristate "NUC910/NUC920 RTC driver"
- depends on ARCH_W90X900 || COMPILE_TEST
- help
- If you say yes here you get support for the RTC subsystem of the
- NUC910/NUC920 used in embedded systems.
-
config RTC_DRV_OPAL
tristate "IBM OPAL RTC driver"
depends on PPC_POWERNV
@@ -1274,7 +1283,7 @@ config RTC_DRV_ZYNQMP
config RTC_DRV_CROS_EC
tristate "Chrome OS EC RTC driver"
- depends on MFD_CROS_EC
+ depends on CROS_EC
help
If you say yes here you will get support for the
Chrome OS Embedded Controller's RTC.
@@ -1323,6 +1332,19 @@ config RTC_DRV_IMXDI
This driver can also be built as a module, if so, the module
will be called "rtc-imxdi".
+config RTC_DRV_FSL_FTM_ALARM
+ tristate "Freescale FlexTimer alarm timer"
+ depends on ARCH_LAYERSCAPE || SOC_LS1021A
+ help
+ For the FlexTimer in LS1012A, LS1021A, LS1028A, LS1043A, LS1046A,
+ LS1088A, LS208xA, we can use FTM as the wakeup source.
+
+ Say y here to enable FTM alarm support. The FTM alarm provides
+ alarm functions for wakeup system from deep sleep.
+
+ This driver can also be built as a module, if so, the module
+ will be called "rtc-fsl-ftm-alarm".
+
config RTC_DRV_MESON
tristate "Amlogic Meson RTC"
depends on (ARM && ARCH_MESON) || COMPILE_TEST
@@ -1334,6 +1356,17 @@ config RTC_DRV_MESON
This driver can also be built as a module, if so, the module
will be called "rtc-meson".
+config RTC_DRV_MESON_VRTC
+ tristate "Amlogic Meson Virtual RTC"
+ depends on ARCH_MESON || COMPILE_TEST
+ default m if ARCH_MESON
+ help
+ If you say yes here you will get support for the
+ Virtual RTC of Amlogic SoCs.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-meson-vrtc.
+
config RTC_DRV_OMAP
tristate "TI OMAP Real Time Clock"
depends on ARCH_OMAP || ARCH_DAVINCI || COMPILE_TEST
@@ -1433,6 +1466,7 @@ config RTC_DRV_PL031
config RTC_DRV_AT91RM9200
tristate "AT91RM9200 or some AT91SAM9 RTC"
depends on ARCH_AT91 || COMPILE_TEST
+ depends on OF
help
Driver for the internal RTC (Realtime Clock) module found on
Atmel AT91RM9200's and some AT91SAM9 chips. On AT91SAM9 chips
@@ -1484,9 +1518,9 @@ config RTC_DRV_PXA
depends on ARCH_PXA
select RTC_DRV_SA1100
help
- If you say Y here you will get access to the real time clock
- built into your PXA27x or PXA3xx CPU. This RTC is actually 2 RTCs
- consisting of an SA1100 compatible RTC and the extended PXA RTC.
+ If you say Y here you will get access to the real time clock
+ built into your PXA27x or PXA3xx CPU. This RTC is actually 2 RTCs
+ consisting of an SA1100 compatible RTC and the extended PXA RTC.
This RTC driver uses PXA RTC registers available since pxa27x
series (RDxR, RYxR) instead of legacy RCNR, RTAR.
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 6b09c21dc1b6..4ac8f19fb631 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o
obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
+obj-$(CONFIG_RTC_DRV_FSL_FTM_ALARM) += rtc-fsl-ftm-alarm.o
obj-$(CONFIG_RTC_DRV_FTRTC010) += rtc-ftrtc010.o
obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o
@@ -102,6 +103,7 @@ obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o
obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o
obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o
obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o
+obj-$(CONFIG_RTC_DRV_MESON_VRTC)+= rtc-meson-vrtc.o
obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o
obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o
obj-$(CONFIG_RTC_DRV_MESON) += rtc-meson.o
@@ -113,7 +115,6 @@ obj-$(CONFIG_RTC_DRV_MT7622) += rtc-mt7622.o
obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o
obj-$(CONFIG_RTC_DRV_MXC_V2) += rtc-mxc_v2.o
-obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o
obj-$(CONFIG_RTC_DRV_PALMAS) += rtc-palmas.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 0f492b0940b3..9458e6d6686a 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -346,8 +346,10 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
struct rtc_wkalrm alrm;
int err;
- if (!rtc->ops)
+ if (!rtc->ops) {
+ dev_dbg(&rtc->dev, "no ops set\n");
return -EINVAL;
+ }
rtc->owner = owner;
rtc_device_get_offset(rtc);
diff --git a/drivers/rtc/dev.c b/drivers/rtc/dev.c
index 84feb2565abd..5b8ebe86124a 100644
--- a/drivers/rtc/dev.c
+++ b/drivers/rtc/dev.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/compat.h>
#include <linux/module.h>
#include <linux/rtc.h>
#include <linux/sched/signal.h>
@@ -360,7 +361,6 @@ static long rtc_dev_ioctl(struct file *file,
case RTC_IRQP_SET:
err = rtc_irq_set_freq(rtc, arg);
break;
-
case RTC_IRQP_READ:
err = put_user(rtc->irq_freq, (unsigned long __user *)uarg);
break;
@@ -399,6 +399,34 @@ done:
return err;
}
+#ifdef CONFIG_COMPAT
+#define RTC_IRQP_SET32 _IOW('p', 0x0c, __u32)
+#define RTC_IRQP_READ32 _IOR('p', 0x0b, __u32)
+#define RTC_EPOCH_SET32 _IOW('p', 0x0e, __u32)
+
+static long rtc_dev_compat_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct rtc_device *rtc = file->private_data;
+ void __user *uarg = compat_ptr(arg);
+
+ switch (cmd) {
+ case RTC_IRQP_READ32:
+ return put_user(rtc->irq_freq, (__u32 __user *)uarg);
+
+ case RTC_IRQP_SET32:
+ /* arg is a plain integer, not pointer */
+ return rtc_dev_ioctl(file, RTC_IRQP_SET, arg);
+
+ case RTC_EPOCH_SET32:
+ /* arg is a plain integer, not pointer */
+ return rtc_dev_ioctl(file, RTC_EPOCH_SET, arg);
+ }
+
+ return rtc_dev_ioctl(file, cmd, (unsigned long)uarg);
+}
+#endif
+
static int rtc_dev_fasync(int fd, struct file *file, int on)
{
struct rtc_device *rtc = file->private_data;
@@ -434,6 +462,9 @@ static const struct file_operations rtc_dev_fops = {
.read = rtc_dev_read,
.poll = rtc_dev_poll,
.unlocked_ioctl = rtc_dev_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = rtc_dev_compat_ioctl,
+#endif
.open = rtc_dev_open,
.release = rtc_dev_release,
.fasync = rtc_dev_fasync,
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 72b7ddc43116..794a4f036b99 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -70,7 +70,7 @@ static int rtc_valid_range(struct rtc_device *rtc, struct rtc_time *tm)
time64_t time = rtc_tm_to_time64(tm);
time64_t range_min = rtc->set_start_time ? rtc->start_secs :
rtc->range_min;
- time64_t range_max = rtc->set_start_time ?
+ timeu64_t range_max = rtc->set_start_time ?
(rtc->start_secs + rtc->range_max - rtc->range_min) :
rtc->range_max;
@@ -125,7 +125,7 @@ EXPORT_SYMBOL_GPL(rtc_read_time);
int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
{
- int err;
+ int err, uie;
err = rtc_valid_tm(tm);
if (err != 0)
@@ -137,6 +137,17 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
rtc_subtract_offset(rtc, tm);
+#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
+ uie = rtc->uie_rtctimer.enabled || rtc->uie_irq_active;
+#else
+ uie = rtc->uie_rtctimer.enabled;
+#endif
+ if (uie) {
+ err = rtc_update_irq_enable(rtc, 0);
+ if (err)
+ return err;
+ }
+
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
return err;
@@ -153,6 +164,12 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
/* A timer might have just expired */
schedule_work(&rtc->irqwork);
+ if (uie) {
+ err = rtc_update_irq_enable(rtc, 1);
+ if (err)
+ return err;
+ }
+
trace_rtc_set_time(rtc_tm_to_time64(tm), err);
return err;
}
@@ -528,7 +545,7 @@ EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable);
int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
{
- int err;
+ int rc = 0, err;
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
@@ -553,7 +570,9 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
struct rtc_time tm;
ktime_t now, onesec;
- __rtc_read_time(rtc, &tm);
+ rc = __rtc_read_time(rtc, &tm);
+ if (rc)
+ goto out;
onesec = ktime_set(1, 0);
now = rtc_tm_to_ktime(tm);
rtc->uie_rtctimer.node.expires = ktime_add(now, onesec);
@@ -565,6 +584,16 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
out:
mutex_unlock(&rtc->ops_lock);
+
+ /*
+ * __rtc_read_time() failed, this probably means that the RTC time has
+ * never been set or less probably there is a transient error on the
+ * bus. In any case, avoid enabling emulation has this will fail when
+ * reading the time too.
+ */
+ if (rc)
+ return rc;
+
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
/*
* Enable emulation if the driver returned -EINVAL to signal that it has
@@ -581,6 +610,8 @@ EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
/**
* rtc_handle_legacy_irq - AIE, UIE and PIE event hook
* @rtc: pointer to the rtc device
+ * @num: number of occurence of the event
+ * @mode: type of the event, RTC_AF, RTC_UF of RTC_PF
*
* This function is called when an AIE, UIE or PIE mode interrupt
* has occurred (or been emulated).
@@ -663,21 +694,12 @@ void rtc_update_irq(struct rtc_device *rtc,
}
EXPORT_SYMBOL_GPL(rtc_update_irq);
-static int __rtc_match(struct device *dev, const void *data)
-{
- const char *name = data;
-
- if (strcmp(dev_name(dev), name) == 0)
- return 1;
- return 0;
-}
-
struct rtc_device *rtc_class_open(const char *name)
{
struct device *dev;
struct rtc_device *rtc = NULL;
- dev = class_find_device(rtc_class, NULL, name, __rtc_match);
+ dev = class_find_device_by_name(rtc_class, name);
if (dev)
rtc = to_rtc_device(dev);
@@ -770,8 +792,8 @@ int rtc_irq_set_freq(struct rtc_device *rtc, int freq)
/**
* rtc_timer_enqueue - Adds a rtc_timer to the rtc_device timerqueue
- * @rtc rtc device
- * @timer timer being added.
+ * @rtc: rtc device
+ * @timer: timer being added.
*
* Enqueues a timer onto the rtc devices timerqueue and sets
* the next alarm event appropriately.
@@ -830,8 +852,8 @@ static void rtc_alarm_disable(struct rtc_device *rtc)
/**
* rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue
- * @rtc rtc device
- * @timer timer being removed.
+ * @rtc: rtc device
+ * @timer: timer being removed.
*
* Removes a timer onto the rtc devices timerqueue and sets
* the next alarm event appropriately.
@@ -868,8 +890,7 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
/**
* rtc_timer_do_work - Expires rtc timers
- * @rtc rtc device
- * @timer timer being removed.
+ * @work: work item
*
* Expires rtc timers. Reprograms next alarm event if needed.
* Called via worktask.
@@ -1002,8 +1023,8 @@ void rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer)
/**
* rtc_read_offset - Read the amount of rtc offset in parts per billion
- * @ rtc: rtc device to be used
- * @ offset: the offset in parts per billion
+ * @rtc: rtc device to be used
+ * @offset: the offset in parts per billion
*
* see below for details.
*
@@ -1031,8 +1052,8 @@ int rtc_read_offset(struct rtc_device *rtc, long *offset)
/**
* rtc_set_offset - Adjusts the duration of the average second
- * @ rtc: rtc device to be used
- * @ offset: the offset in parts per billion
+ * @rtc: rtc device to be used
+ * @offset: the offset in parts per billion
*
* Some rtc's allow an adjustment to the average duration of a second
* to compensate for differences in the actual clock rate due to temperature,
diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c
index e4d5a19fd1c9..75779e8501a3 100644
--- a/drivers/rtc/rtc-88pm80x.c
+++ b/drivers/rtc/rtc-88pm80x.c
@@ -264,7 +264,6 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
return -ENOMEM;
info->irq = platform_get_irq(pdev, 0);
if (info->irq < 0) {
- dev_err(&pdev->dev, "No IRQ resource!\n");
ret = -EINVAL;
goto out;
}
@@ -296,10 +295,9 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
info->rtc_dev->range_max = U32_MAX;
ret = rtc_register_device(info->rtc_dev);
- if (ret) {
- dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
+ if (ret)
goto out_rtc;
- }
+
/*
* enable internal XO instead of internal 3.25MHz clock since it can
* free running in PMIC power-down state.
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index 434285f495e0..4743b16a8d84 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -328,10 +328,8 @@ static int pm860x_rtc_probe(struct platform_device *pdev)
if (!info)
return -ENOMEM;
info->irq = platform_get_irq(pdev, 0);
- if (info->irq < 0) {
- dev_err(&pdev->dev, "No IRQ resource!\n");
+ if (info->irq < 0)
return info->irq;
- }
info->chip = chip;
info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c
index cdad6f00debf..811fe2005488 100644
--- a/drivers/rtc/rtc-ab-b5ze-s3.c
+++ b/drivers/rtc/rtc-ab-b5ze-s3.c
@@ -900,16 +900,6 @@ err:
return ret;
}
-static int abb5zes3_remove(struct i2c_client *client)
-{
- struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(&client->dev);
-
- if (rtc_data->irq > 0)
- device_init_wakeup(&client->dev, false);
-
- return 0;
-}
-
#ifdef CONFIG_PM_SLEEP
static int abb5zes3_rtc_suspend(struct device *dev)
{
@@ -956,7 +946,6 @@ static struct i2c_driver abb5zes3_driver = {
.of_match_table = of_match_ptr(abb5zes3_dt_match),
},
.probe = abb5zes3_probe,
- .remove = abb5zes3_remove,
.id_table = abb5zes3_id,
};
module_i2c_driver(abb5zes3_driver);
diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c
index e4f6e0061ccf..d690985caa4c 100644
--- a/drivers/rtc/rtc-ab-eoz9.c
+++ b/drivers/rtc/rtc-ab-eoz9.c
@@ -390,35 +390,31 @@ static int abeoz9_probe(struct i2c_client *client,
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_I2C_BLOCK)) {
- ret = -ENODEV;
- goto err;
- }
+ I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -ENODEV;
regmap = devm_regmap_init_i2c(client, &abeoz9_rtc_regmap_config);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(dev, "regmap allocation failed: %d\n", ret);
- goto err;
+ return ret;
}
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
- if (!data) {
- ret = -ENOMEM;
- goto err;
- }
+ if (!data)
+ return -ENOMEM;
data->regmap = regmap;
dev_set_drvdata(dev, data);
ret = abeoz9_rtc_setup(dev, client->dev.of_node);
if (ret)
- goto err;
+ return ret;
data->rtc = devm_rtc_allocate_device(dev);
ret = PTR_ERR_OR_ZERO(data->rtc);
if (ret)
- goto err;
+ return ret;
data->rtc->ops = &rtc_ops;
data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
@@ -426,14 +422,10 @@ static int abeoz9_probe(struct i2c_client *client,
ret = rtc_register_device(data->rtc);
if (ret)
- goto err;
+ return ret;
abeoz9_hwmon_register(dev, data);
return 0;
-
-err:
- dev_err(dev, "unable to register RTC device (%d)\n", ret);
- return ret;
}
#ifdef CONFIG_OF
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c
index 73830670a41f..3521d8e8dc38 100644
--- a/drivers/rtc/rtc-abx80x.c
+++ b/drivers/rtc/rtc-abx80x.c
@@ -523,12 +523,9 @@ static int abx80x_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
if (status < 0)
return status;
- tmp = !!(status & ABX8XX_STATUS_BLF);
+ tmp = status & ABX8XX_STATUS_BLF ? RTC_VL_BACKUP_LOW : 0;
- if (copy_to_user((void __user *)arg, &tmp, sizeof(int)))
- return -EFAULT;
-
- return 0;
+ return put_user(tmp, (unsigned int __user *)arg);
case RTC_VL_CLR:
status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c
index 2e5a8b15b222..29223931aba7 100644
--- a/drivers/rtc/rtc-ac100.c
+++ b/drivers/rtc/rtc-ac100.c
@@ -578,10 +578,8 @@ static int ac100_rtc_probe(struct platform_device *pdev)
chip->regmap = ac100->regmap;
chip->irq = platform_get_irq(pdev, 0);
- if (chip->irq < 0) {
- dev_err(&pdev->dev, "No IRQ resource\n");
+ if (chip->irq < 0)
return chip->irq;
- }
chip->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(chip->rtc))
@@ -612,15 +610,7 @@ static int ac100_rtc_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = rtc_register_device(chip->rtc);
- if (ret) {
- dev_err(&pdev->dev, "unable to register device\n");
- return ret;
- }
-
- dev_info(&pdev->dev, "RTC enabled\n");
-
- return 0;
+ return rtc_register_device(chip->rtc);
}
static int ac100_rtc_remove(struct platform_device *pdev)
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index 19d6980e90fb..94d7c22fc4f3 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -74,7 +74,7 @@ struct armada38x_rtc {
int irq;
bool initialized;
struct value_to_freq *val_to_freq;
- struct armada38x_rtc_data *data;
+ const struct armada38x_rtc_data *data;
};
#define ALARM1 0
@@ -501,18 +501,14 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
struct armada38x_rtc *rtc;
- const struct of_device_id *match;
- int ret;
-
- match = of_match_device(armada38x_rtc_of_match_table, &pdev->dev);
- if (!match)
- return -ENODEV;
rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc),
GFP_KERNEL);
if (!rtc)
return -ENOMEM;
+ rtc->data = of_device_get_match_data(&pdev->dev);
+
rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR,
sizeof(struct value_to_freq), GFP_KERNEL);
if (!rtc->val_to_freq)
@@ -530,11 +526,8 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
return PTR_ERR(rtc->regs_soc);
rtc->irq = platform_get_irq(pdev, 0);
-
- if (rtc->irq < 0) {
- dev_err(&pdev->dev, "no irq\n");
+ if (rtc->irq < 0)
return rtc->irq;
- }
rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc_dev))
@@ -557,18 +550,13 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
*/
rtc->rtc_dev->ops = &armada38x_rtc_ops_noirq;
}
- rtc->data = (struct armada38x_rtc_data *)match->data;
/* Update RTC-MBUS bridge timing parameters */
rtc->data->update_mbus_timing(rtc);
rtc->rtc_dev->range_max = U32_MAX;
- ret = rtc_register_device(rtc->rtc_dev);
- if (ret)
- dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
-
- return ret;
+ return rtc_register_device(rtc->rtc_dev);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/rtc/rtc-asm9260.c b/drivers/rtc/rtc-asm9260.c
index d45a44936308..3ab81cdec00b 100644
--- a/drivers/rtc/rtc-asm9260.c
+++ b/drivers/rtc/rtc-asm9260.c
@@ -245,7 +245,6 @@ static int asm9260_rtc_probe(struct platform_device *pdev)
{
struct asm9260_rtc_priv *priv;
struct device *dev = &pdev->dev;
- struct resource *res;
int irq_alarm, ret;
u32 ccr;
@@ -257,17 +256,17 @@ static int asm9260_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
irq_alarm = platform_get_irq(pdev, 0);
- if (irq_alarm < 0) {
- dev_err(dev, "No alarm IRQ resource defined\n");
+ if (irq_alarm < 0)
return irq_alarm;
- }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->iobase = devm_ioremap_resource(dev, res);
+ priv->iobase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->iobase))
return PTR_ERR(priv->iobase);
priv->clk = devm_clk_get(dev, "ahb");
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
ret = clk_prepare_enable(priv->clk);
if (ret) {
dev_err(dev, "Failed to enable clk!\n");
diff --git a/drivers/rtc/rtc-aspeed.c b/drivers/rtc/rtc-aspeed.c
index af3eb676d7c3..eacdd0637cce 100644
--- a/drivers/rtc/rtc-aspeed.c
+++ b/drivers/rtc/rtc-aspeed.c
@@ -85,15 +85,12 @@ static const struct rtc_class_ops aspeed_rtc_ops = {
static int aspeed_rtc_probe(struct platform_device *pdev)
{
struct aspeed_rtc *rtc;
- struct resource *res;
- int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtc->base = devm_ioremap_resource(&pdev->dev, res);
+ rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base))
return PTR_ERR(rtc->base);
@@ -107,11 +104,7 @@ static int aspeed_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900;
rtc->rtc_dev->range_max = 38814989399LL; /* 3199-12-31 23:59:59 */
- ret = rtc_register_device(rtc->rtc_dev);
- if (ret)
- return ret;
-
- return 0;
+ return rtc_register_device(rtc->rtc_dev);
}
static const struct of_device_id aspeed_rtc_match[] = {
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 82a54e93ff04..5e811e04cb21 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -14,6 +14,7 @@
*/
#include <linux/bcd.h>
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
@@ -30,7 +31,51 @@
#include <linux/time.h>
#include <linux/uaccess.h>
-#include "rtc-at91rm9200.h"
+#define AT91_RTC_CR 0x00 /* Control Register */
+#define AT91_RTC_UPDTIM BIT(0) /* Update Request Time Register */
+#define AT91_RTC_UPDCAL BIT(1) /* Update Request Calendar Register */
+
+#define AT91_RTC_MR 0x04 /* Mode Register */
+
+#define AT91_RTC_TIMR 0x08 /* Time Register */
+#define AT91_RTC_SEC GENMASK(6, 0) /* Current Second */
+#define AT91_RTC_MIN GENMASK(14, 8) /* Current Minute */
+#define AT91_RTC_HOUR GENMASK(21, 16) /* Current Hour */
+#define AT91_RTC_AMPM BIT(22) /* Ante Meridiem Post Meridiem Indicator */
+
+#define AT91_RTC_CALR 0x0c /* Calendar Register */
+#define AT91_RTC_CENT GENMASK(6, 0) /* Current Century */
+#define AT91_RTC_YEAR GENMASK(15, 8) /* Current Year */
+#define AT91_RTC_MONTH GENMASK(20, 16) /* Current Month */
+#define AT91_RTC_DAY GENMASK(23, 21) /* Current Day */
+#define AT91_RTC_DATE GENMASK(29, 24) /* Current Date */
+
+#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */
+#define AT91_RTC_SECEN BIT(7) /* Second Alarm Enable */
+#define AT91_RTC_MINEN BIT(15) /* Minute Alarm Enable */
+#define AT91_RTC_HOUREN BIT(23) /* Hour Alarm Enable */
+
+#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */
+#define AT91_RTC_MTHEN BIT(23) /* Month Alarm Enable */
+#define AT91_RTC_DATEEN BIT(31) /* Date Alarm Enable */
+
+#define AT91_RTC_SR 0x18 /* Status Register */
+#define AT91_RTC_ACKUPD BIT(0) /* Acknowledge for Update */
+#define AT91_RTC_ALARM BIT(1) /* Alarm Flag */
+#define AT91_RTC_SECEV BIT(2) /* Second Event */
+#define AT91_RTC_TIMEV BIT(3) /* Time Event */
+#define AT91_RTC_CALEV BIT(4) /* Calendar Event */
+
+#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */
+#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */
+#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
+#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
+
+#define AT91_RTC_VER 0x2c /* Valid Entry Register */
+#define AT91_RTC_NVTIM BIT(0) /* Non valid Time */
+#define AT91_RTC_NVCAL BIT(1) /* Non valid Calendar */
+#define AT91_RTC_NVTIMALR BIT(2) /* Non valid Time Alarm */
+#define AT91_RTC_NVCALALR BIT(3) /* Non valid Calendar Alarm */
#define at91_rtc_read(field) \
readl_relaxed(at91_rtc_regs + field)
@@ -117,20 +162,20 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg,
} while ((time != at91_rtc_read(timereg)) ||
(date != at91_rtc_read(calreg)));
- tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0);
- tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8);
- tm->tm_hour = bcd2bin((time & AT91_RTC_HOUR) >> 16);
+ tm->tm_sec = bcd2bin(FIELD_GET(AT91_RTC_SEC, time));
+ tm->tm_min = bcd2bin(FIELD_GET(AT91_RTC_MIN, time));
+ tm->tm_hour = bcd2bin(FIELD_GET(AT91_RTC_HOUR, time));
/*
* The Calendar Alarm register does not have a field for
* the year - so these will return an invalid value.
*/
tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */
- tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */
+ tm->tm_year += bcd2bin(FIELD_GET(AT91_RTC_YEAR, date)); /* year */
- tm->tm_wday = bcd2bin((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */
- tm->tm_mon = bcd2bin((date & AT91_RTC_MONTH) >> 16) - 1;
- tm->tm_mday = bcd2bin((date & AT91_RTC_DATE) >> 24);
+ tm->tm_wday = bcd2bin(FIELD_GET(AT91_RTC_DAY, date)) - 1; /* day of the week [0-6], Sunday=0 */
+ tm->tm_mon = bcd2bin(FIELD_GET(AT91_RTC_MONTH, date)) - 1;
+ tm->tm_mday = bcd2bin(FIELD_GET(AT91_RTC_DATE, date));
}
/*
@@ -167,16 +212,17 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
at91_rtc_write_idr(AT91_RTC_ACKUPD);
at91_rtc_write(AT91_RTC_TIMR,
- bin2bcd(tm->tm_sec) << 0
- | bin2bcd(tm->tm_min) << 8
- | bin2bcd(tm->tm_hour) << 16);
+ FIELD_PREP(AT91_RTC_SEC, bin2bcd(tm->tm_sec))
+ | FIELD_PREP(AT91_RTC_MIN, bin2bcd(tm->tm_min))
+ | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(tm->tm_hour)));
at91_rtc_write(AT91_RTC_CALR,
- bin2bcd((tm->tm_year + 1900) / 100) /* century */
- | bin2bcd(tm->tm_year % 100) << 8 /* year */
- | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */
- | bin2bcd(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */
- | bin2bcd(tm->tm_mday) << 24);
+ FIELD_PREP(AT91_RTC_CENT,
+ bin2bcd((tm->tm_year + 1900) / 100))
+ | FIELD_PREP(AT91_RTC_YEAR, bin2bcd(tm->tm_year % 100))
+ | FIELD_PREP(AT91_RTC_MONTH, bin2bcd(tm->tm_mon + 1))
+ | FIELD_PREP(AT91_RTC_DAY, bin2bcd(tm->tm_wday + 1))
+ | FIELD_PREP(AT91_RTC_DATE, bin2bcd(tm->tm_mday)));
/* Restart Time/Calendar */
cr = at91_rtc_read(AT91_RTC_CR);
@@ -211,25 +257,17 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
*/
static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
- struct rtc_time tm;
-
- at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm);
-
- tm.tm_mon = alrm->time.tm_mon;
- tm.tm_mday = alrm->time.tm_mday;
- tm.tm_hour = alrm->time.tm_hour;
- tm.tm_min = alrm->time.tm_min;
- tm.tm_sec = alrm->time.tm_sec;
+ struct rtc_time tm = alrm->time;
at91_rtc_write_idr(AT91_RTC_ALARM);
at91_rtc_write(AT91_RTC_TIMALR,
- bin2bcd(tm.tm_sec) << 0
- | bin2bcd(tm.tm_min) << 8
- | bin2bcd(tm.tm_hour) << 16
+ FIELD_PREP(AT91_RTC_SEC, bin2bcd(alrm->time.tm_sec))
+ | FIELD_PREP(AT91_RTC_MIN, bin2bcd(alrm->time.tm_min))
+ | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(alrm->time.tm_hour))
| AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN);
at91_rtc_write(AT91_RTC_CALALR,
- bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */
- | bin2bcd(tm.tm_mday) << 24
+ FIELD_PREP(AT91_RTC_MONTH, bin2bcd(alrm->time.tm_mon + 1))
+ | FIELD_PREP(AT91_RTC_DATE, bin2bcd(alrm->time.tm_mday))
| AT91_RTC_DATEEN | AT91_RTC_MTHEN);
if (alrm->enabled) {
@@ -254,20 +292,6 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}
-/*
- * Provide additional RTC information in /proc/driver/rtc
- */
-static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
-{
- unsigned long imr = at91_rtc_read_imr();
-
- seq_printf(seq, "update_IRQ\t: %s\n",
- (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
- seq_printf(seq, "periodic_IRQ\t: %s\n",
- (imr & AT91_RTC_SECEV) ? "yes" : "no");
-
- return 0;
-}
/*
* IRQ handler for the RTC
@@ -319,7 +343,6 @@ static const struct at91_rtc_config at91sam9x5_config = {
.use_shadow_imr = true,
};
-#ifdef CONFIG_OF
static const struct of_device_id at91_rtc_dt_ids[] = {
{
.compatible = "atmel,at91rm9200-rtc",
@@ -328,33 +351,22 @@ static const struct of_device_id at91_rtc_dt_ids[] = {
.compatible = "atmel,at91sam9x5-rtc",
.data = &at91sam9x5_config,
}, {
+ .compatible = "atmel,sama5d4-rtc",
+ .data = &at91rm9200_config,
+ }, {
+ .compatible = "atmel,sama5d2-rtc",
+ .data = &at91rm9200_config,
+ }, {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids);
-#endif
-
-static const struct at91_rtc_config *
-at91_rtc_get_config(struct platform_device *pdev)
-{
- const struct of_device_id *match;
-
- if (pdev->dev.of_node) {
- match = of_match_node(at91_rtc_dt_ids, pdev->dev.of_node);
- if (!match)
- return NULL;
- return (const struct at91_rtc_config *)match->data;
- }
-
- return &at91rm9200_config;
-}
static const struct rtc_class_ops at91_rtc_ops = {
.read_time = at91_rtc_readtime,
.set_time = at91_rtc_settime,
.read_alarm = at91_rtc_readalarm,
.set_alarm = at91_rtc_setalarm,
- .proc = at91_rtc_proc,
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
};
@@ -367,7 +379,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
struct resource *regs;
int ret = 0;
- at91_rtc_config = at91_rtc_get_config(pdev);
+ at91_rtc_config = of_device_get_match_data(&pdev->dev);
if (!at91_rtc_config)
return -ENODEV;
@@ -378,10 +390,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
}
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "no irq resource defined\n");
+ if (irq < 0)
return -ENXIO;
- }
at91_rtc_regs = devm_ioremap(&pdev->dev, regs->start,
resource_size(regs));
diff --git a/drivers/rtc/rtc-at91rm9200.h b/drivers/rtc/rtc-at91rm9200.h
deleted file mode 100644
index 8be5289da8e2..000000000000
--- a/drivers/rtc/rtc-at91rm9200.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-at91/include/mach/at91_rtc.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * Real Time Clock (RTC) - System peripheral registers.
- * Based on AT91RM9200 datasheet revision E.
- */
-
-#ifndef AT91_RTC_H
-#define AT91_RTC_H
-
-#define AT91_RTC_CR 0x00 /* Control Register */
-#define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */
-#define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */
-#define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */
-#define AT91_RTC_TIMEVSEL_MINUTE (0 << 8)
-#define AT91_RTC_TIMEVSEL_HOUR (1 << 8)
-#define AT91_RTC_TIMEVSEL_DAY24 (2 << 8)
-#define AT91_RTC_TIMEVSEL_DAY12 (3 << 8)
-#define AT91_RTC_CALEVSEL (3 << 16) /* Calendar Event Selection */
-#define AT91_RTC_CALEVSEL_WEEK (0 << 16)
-#define AT91_RTC_CALEVSEL_MONTH (1 << 16)
-#define AT91_RTC_CALEVSEL_YEAR (2 << 16)
-
-#define AT91_RTC_MR 0x04 /* Mode Register */
-#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */
-
-#define AT91_RTC_TIMR 0x08 /* Time Register */
-#define AT91_RTC_SEC (0x7f << 0) /* Current Second */
-#define AT91_RTC_MIN (0x7f << 8) /* Current Minute */
-#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */
-#define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */
-
-#define AT91_RTC_CALR 0x0c /* Calendar Register */
-#define AT91_RTC_CENT (0x7f << 0) /* Current Century */
-#define AT91_RTC_YEAR (0xff << 8) /* Current Year */
-#define AT91_RTC_MONTH (0x1f << 16) /* Current Month */
-#define AT91_RTC_DAY (7 << 21) /* Current Day */
-#define AT91_RTC_DATE (0x3f << 24) /* Current Date */
-
-#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */
-#define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */
-#define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */
-#define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */
-
-#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */
-#define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */
-#define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */
-
-#define AT91_RTC_SR 0x18 /* Status Register */
-#define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */
-#define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */
-#define AT91_RTC_SECEV (1 << 2) /* Second Event */
-#define AT91_RTC_TIMEV (1 << 3) /* Time Event */
-#define AT91_RTC_CALEV (1 << 4) /* Calendar Event */
-
-#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */
-#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */
-#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
-#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
-
-#define AT91_RTC_VER 0x2c /* Valid Entry Register */
-#define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */
-#define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */
-#define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */
-#define AT91_RTC_NVCALALR (1 << 3) /* Non valid Calendar Alarm */
-
-#endif
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 4daf3789b978..e39e89867d29 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -334,7 +334,6 @@ static const struct rtc_class_ops at91_rtc_ops = {
*/
static int at91_rtc_probe(struct platform_device *pdev)
{
- struct resource *r;
struct sam9_rtc *rtc;
int ret, irq;
u32 mr;
@@ -342,10 +341,8 @@ static int at91_rtc_probe(struct platform_device *pdev)
struct of_phandle_args args;
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "failed to get interrupt resource\n");
+ if (irq < 0)
return irq;
- }
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
@@ -360,8 +357,7 @@ static int at91_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc);
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtc->rtt = devm_ioremap_resource(&pdev->dev, r);
+ rtc->rtt = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->rtt))
return PTR_ERR(rtc->rtt);
diff --git a/drivers/rtc/rtc-bd70528.c b/drivers/rtc/rtc-bd70528.c
index f9bdd555e1a2..bbbb1f07c91f 100644
--- a/drivers/rtc/rtc-bd70528.c
+++ b/drivers/rtc/rtc-bd70528.c
@@ -6,6 +6,7 @@
#include <linux/bcd.h>
#include <linux/mfd/rohm-bd70528.h>
+#include <linux/mfd/rohm-bd71828.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -15,7 +16,7 @@
/*
* We read regs RTC_SEC => RTC_YEAR
* this struct is ordered according to chip registers.
- * Keep it u8 only to avoid padding issues.
+ * Keep it u8 only (or packed) to avoid padding issues.
*/
struct bd70528_rtc_day {
u8 sec;
@@ -36,6 +37,13 @@ struct bd70528_rtc_wake {
u8 ctrl;
} __packed;
+struct bd71828_rtc_alm {
+ struct bd70528_rtc_data alm0;
+ struct bd70528_rtc_data alm1;
+ u8 alm_mask;
+ u8 alm1_mask;
+} __packed;
+
struct bd70528_rtc_alm {
struct bd70528_rtc_data data;
u8 alm_mask;
@@ -43,8 +51,10 @@ struct bd70528_rtc_alm {
} __packed;
struct bd70528_rtc {
- struct rohm_regmap_dev *mfd;
+ struct rohm_regmap_dev *parent;
struct device *dev;
+ u8 reg_time_start;
+ bool has_rtc_timers;
};
static int bd70528_set_wake(struct rohm_regmap_dev *bd70528,
@@ -123,14 +133,14 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
{
int ret;
- ret = bd70528_wdt_set(r->mfd, new_state & BD70528_WDT_STATE_BIT,
+ ret = bd70528_wdt_set(r->parent, new_state & BD70528_WDT_STATE_BIT,
old_state);
if (ret) {
dev_err(r->dev,
"Failed to disable WDG for RTC setting (%d)\n", ret);
return ret;
}
- ret = bd70528_set_elapsed_tmr(r->mfd,
+ ret = bd70528_set_elapsed_tmr(r->parent,
new_state & BD70528_ELAPSED_STATE_BIT,
old_state);
if (ret) {
@@ -138,7 +148,7 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
"Failed to disable 'elapsed timer' for RTC setting\n");
return ret;
}
- ret = bd70528_set_wake(r->mfd, new_state & BD70528_WAKE_STATE_BIT,
+ ret = bd70528_set_wake(r->parent, new_state & BD70528_WAKE_STATE_BIT,
old_state);
if (ret) {
dev_err(r->dev,
@@ -152,12 +162,18 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
static int bd70528_re_enable_rtc_based_timers(struct bd70528_rtc *r,
int old_state)
{
+ if (!r->has_rtc_timers)
+ return 0;
+
return bd70528_set_rtc_based_timers(r, old_state, NULL);
}
static int bd70528_disable_rtc_based_timers(struct bd70528_rtc *r,
int *old_state)
{
+ if (!r->has_rtc_timers)
+ return 0;
+
return bd70528_set_rtc_based_timers(r, 0, old_state);
}
@@ -213,22 +229,52 @@ static inline void rtc2tm(struct bd70528_rtc_data *r, struct rtc_time *t)
t->tm_wday = bcd2bin(r->week & BD70528_MASK_RTC_WEEK);
}
+static int bd71828_set_alarm(struct device *dev, struct rtc_wkalrm *a)
+{
+ int ret;
+ struct bd71828_rtc_alm alm;
+ struct bd70528_rtc *r = dev_get_drvdata(dev);
+ struct rohm_regmap_dev *parent = r->parent;
+
+ ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START,
+ &alm, sizeof(alm));
+ if (ret) {
+ dev_err(dev, "Failed to read alarm regs\n");
+ return ret;
+ }
+
+ tm2rtc(&a->time, &alm.alm0);
+
+ if (!a->enabled)
+ alm.alm_mask &= ~BD70528_MASK_ALM_EN;
+ else
+ alm.alm_mask |= BD70528_MASK_ALM_EN;
+
+ ret = regmap_bulk_write(parent->regmap, BD71828_REG_RTC_ALM_START,
+ &alm, sizeof(alm));
+ if (ret)
+ dev_err(dev, "Failed to set alarm time\n");
+
+ return ret;
+
+}
+
static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
{
struct bd70528_rtc_wake wake;
struct bd70528_rtc_alm alm;
int ret;
struct bd70528_rtc *r = dev_get_drvdata(dev);
- struct rohm_regmap_dev *bd70528 = r->mfd;
+ struct rohm_regmap_dev *parent = r->parent;
- ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_WAKE_START,
+ ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_WAKE_START,
&wake, sizeof(wake));
if (ret) {
dev_err(dev, "Failed to read wake regs\n");
return ret;
}
- ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START,
+ ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START,
&alm, sizeof(alm));
if (ret) {
dev_err(dev, "Failed to read alarm regs\n");
@@ -246,14 +292,14 @@ static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
wake.ctrl &= ~BD70528_MASK_WAKE_EN;
}
- ret = regmap_bulk_write(bd70528->regmap,
+ ret = regmap_bulk_write(parent->regmap,
BD70528_REG_RTC_WAKE_START, &wake,
sizeof(wake));
if (ret) {
dev_err(dev, "Failed to set wake time\n");
return ret;
}
- ret = regmap_bulk_write(bd70528->regmap, BD70528_REG_RTC_ALM_START,
+ ret = regmap_bulk_write(parent->regmap, BD70528_REG_RTC_ALM_START,
&alm, sizeof(alm));
if (ret)
dev_err(dev, "Failed to set alarm time\n");
@@ -261,14 +307,38 @@ static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
return ret;
}
+static int bd71828_read_alarm(struct device *dev, struct rtc_wkalrm *a)
+{
+ int ret;
+ struct bd71828_rtc_alm alm;
+ struct bd70528_rtc *r = dev_get_drvdata(dev);
+ struct rohm_regmap_dev *parent = r->parent;
+
+ ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START,
+ &alm, sizeof(alm));
+ if (ret) {
+ dev_err(dev, "Failed to read alarm regs\n");
+ return ret;
+ }
+
+ rtc2tm(&alm.alm0, &a->time);
+ a->time.tm_mday = -1;
+ a->time.tm_mon = -1;
+ a->time.tm_year = -1;
+ a->enabled = !!(alm.alm_mask & BD70528_MASK_ALM_EN);
+ a->pending = 0;
+
+ return 0;
+}
+
static int bd70528_read_alarm(struct device *dev, struct rtc_wkalrm *a)
{
struct bd70528_rtc_alm alm;
int ret;
struct bd70528_rtc *r = dev_get_drvdata(dev);
- struct rohm_regmap_dev *bd70528 = r->mfd;
+ struct rohm_regmap_dev *parent = r->parent;
- ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START,
+ ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START,
&alm, sizeof(alm));
if (ret) {
dev_err(dev, "Failed to read alarm regs\n");
@@ -290,14 +360,14 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t)
int ret, tmpret, old_states;
struct bd70528_rtc_data rtc_data;
struct bd70528_rtc *r = dev_get_drvdata(dev);
- struct rohm_regmap_dev *bd70528 = r->mfd;
+ struct rohm_regmap_dev *parent = r->parent;
ret = bd70528_disable_rtc_based_timers(r, &old_states);
if (ret)
return ret;
- tmpret = regmap_bulk_read(bd70528->regmap,
- BD70528_REG_RTC_START, &rtc_data,
+ tmpret = regmap_bulk_read(parent->regmap,
+ r->reg_time_start, &rtc_data,
sizeof(rtc_data));
if (tmpret) {
dev_err(dev, "Failed to read RTC time registers\n");
@@ -305,8 +375,8 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t)
}
tm2rtc(t, &rtc_data);
- tmpret = regmap_bulk_write(bd70528->regmap,
- BD70528_REG_RTC_START, &rtc_data,
+ tmpret = regmap_bulk_write(parent->regmap,
+ r->reg_time_start, &rtc_data,
sizeof(rtc_data));
if (tmpret) {
dev_err(dev, "Failed to set RTC time\n");
@@ -321,27 +391,32 @@ renable_out:
return ret;
}
+static int bd71828_set_time(struct device *dev, struct rtc_time *t)
+{
+ return bd70528_set_time_locked(dev, t);
+}
+
static int bd70528_set_time(struct device *dev, struct rtc_time *t)
{
int ret;
struct bd70528_rtc *r = dev_get_drvdata(dev);
- bd70528_wdt_lock(r->mfd);
+ bd70528_wdt_lock(r->parent);
ret = bd70528_set_time_locked(dev, t);
- bd70528_wdt_unlock(r->mfd);
+ bd70528_wdt_unlock(r->parent);
return ret;
}
static int bd70528_get_time(struct device *dev, struct rtc_time *t)
{
struct bd70528_rtc *r = dev_get_drvdata(dev);
- struct rohm_regmap_dev *bd70528 = r->mfd;
+ struct rohm_regmap_dev *parent = r->parent;
struct bd70528_rtc_data rtc_data;
int ret;
/* read the RTC date and time registers all at once */
- ret = regmap_bulk_read(bd70528->regmap,
- BD70528_REG_RTC_START, &rtc_data,
+ ret = regmap_bulk_read(parent->regmap,
+ r->reg_time_start, &rtc_data,
sizeof(rtc_data));
if (ret) {
dev_err(dev, "Failed to read RTC time (err %d)\n", ret);
@@ -362,19 +437,36 @@ static int bd70528_alm_enable(struct device *dev, unsigned int enabled)
if (enabled)
enableval = 0;
- bd70528_wdt_lock(r->mfd);
- ret = bd70528_set_wake(r->mfd, enabled, NULL);
+ bd70528_wdt_lock(r->parent);
+ ret = bd70528_set_wake(r->parent, enabled, NULL);
if (ret) {
dev_err(dev, "Failed to change wake state\n");
goto out_unlock;
}
- ret = regmap_update_bits(r->mfd->regmap, BD70528_REG_RTC_ALM_MASK,
+ ret = regmap_update_bits(r->parent->regmap, BD70528_REG_RTC_ALM_MASK,
BD70528_MASK_ALM_EN, enableval);
if (ret)
dev_err(dev, "Failed to change alarm state\n");
out_unlock:
- bd70528_wdt_unlock(r->mfd);
+ bd70528_wdt_unlock(r->parent);
+ return ret;
+}
+
+static int bd71828_alm_enable(struct device *dev, unsigned int enabled)
+{
+ int ret;
+ struct bd70528_rtc *r = dev_get_drvdata(dev);
+ unsigned int enableval = BD70528_MASK_ALM_EN;
+
+ if (!enabled)
+ enableval = 0;
+
+ ret = regmap_update_bits(r->parent->regmap, BD71828_REG_RTC_ALM0_MASK,
+ BD70528_MASK_ALM_EN, enableval);
+ if (ret)
+ dev_err(dev, "Failed to change alarm state\n");
+
return ret;
}
@@ -386,6 +478,14 @@ static const struct rtc_class_ops bd70528_rtc_ops = {
.alarm_irq_enable = bd70528_alm_enable,
};
+static const struct rtc_class_ops bd71828_rtc_ops = {
+ .read_time = bd70528_get_time,
+ .set_time = bd71828_set_time,
+ .read_alarm = bd71828_read_alarm,
+ .set_alarm = bd71828_set_alarm,
+ .alarm_irq_enable = bd71828_alm_enable,
+};
+
static irqreturn_t alm_hndlr(int irq, void *data)
{
struct rtc_device *rtc = data;
@@ -397,14 +497,19 @@ static irqreturn_t alm_hndlr(int irq, void *data)
static int bd70528_probe(struct platform_device *pdev)
{
struct bd70528_rtc *bd_rtc;
- struct rohm_regmap_dev *mfd;
+ const struct rtc_class_ops *rtc_ops;
+ struct rohm_regmap_dev *parent;
+ const char *irq_name;
int ret;
struct rtc_device *rtc;
int irq;
unsigned int hr;
+ bool enable_main_irq = false;
+ u8 hour_reg;
+ enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
- mfd = dev_get_drvdata(pdev->dev.parent);
- if (!mfd) {
+ parent = dev_get_drvdata(pdev->dev.parent);
+ if (!parent) {
dev_err(&pdev->dev, "No MFD driver data\n");
return -EINVAL;
}
@@ -412,10 +517,30 @@ static int bd70528_probe(struct platform_device *pdev)
if (!bd_rtc)
return -ENOMEM;
- bd_rtc->mfd = mfd;
+ bd_rtc->parent = parent;
bd_rtc->dev = &pdev->dev;
- irq = platform_get_irq_byname(pdev, "bd70528-rtc-alm");
+ switch (chip) {
+ case ROHM_CHIP_TYPE_BD70528:
+ irq_name = "bd70528-rtc-alm";
+ bd_rtc->has_rtc_timers = true;
+ bd_rtc->reg_time_start = BD70528_REG_RTC_START;
+ hour_reg = BD70528_REG_RTC_HOUR;
+ enable_main_irq = true;
+ rtc_ops = &bd70528_rtc_ops;
+ break;
+ case ROHM_CHIP_TYPE_BD71828:
+ irq_name = "bd71828-rtc-alm-0";
+ bd_rtc->reg_time_start = BD71828_REG_RTC_START;
+ hour_reg = BD71828_REG_RTC_HOUR;
+ rtc_ops = &bd71828_rtc_ops;
+ break;
+ default:
+ dev_err(&pdev->dev, "Unknown chip\n");
+ return -ENOENT;
+ }
+
+ irq = platform_get_irq_byname(pdev, irq_name);
if (irq < 0) {
dev_err(&pdev->dev, "Failed to get irq\n");
@@ -424,7 +549,7 @@ static int bd70528_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, bd_rtc);
- ret = regmap_read(mfd->regmap, BD70528_REG_RTC_HOUR, &hr);
+ ret = regmap_read(parent->regmap, hour_reg, &hr);
if (ret) {
dev_err(&pdev->dev, "Failed to reag RTC clock\n");
@@ -434,10 +559,10 @@ static int bd70528_probe(struct platform_device *pdev)
if (!(hr & BD70528_MASK_RTC_HOUR_24H)) {
struct rtc_time t;
- ret = bd70528_get_time(&pdev->dev, &t);
+ ret = rtc_ops->read_time(&pdev->dev, &t);
if (!ret)
- ret = bd70528_set_time(&pdev->dev, &t);
+ ret = rtc_ops->set_time(&pdev->dev, &t);
if (ret) {
dev_err(&pdev->dev,
@@ -457,7 +582,7 @@ static int bd70528_probe(struct platform_device *pdev)
rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rtc->range_max = RTC_TIMESTAMP_END_2099;
- rtc->ops = &bd70528_rtc_ops;
+ rtc->ops = rtc_ops;
/* Request alarm IRQ prior to registerig the RTC */
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, &alm_hndlr,
@@ -471,30 +596,37 @@ static int bd70528_probe(struct platform_device *pdev)
* leave them enabled as irq-controller should disable irqs
* from sub-registers when IRQ is disabled or freed.
*/
- ret = regmap_update_bits(mfd->regmap,
+ if (enable_main_irq) {
+ ret = regmap_update_bits(parent->regmap,
BD70528_REG_INT_MAIN_MASK,
BD70528_INT_RTC_MASK, 0);
- if (ret) {
- dev_err(&pdev->dev, "Failed to enable RTC interrupts\n");
- return ret;
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to enable RTC interrupts\n");
+ return ret;
+ }
}
- ret = rtc_register_device(rtc);
- if (ret)
- dev_err(&pdev->dev, "Registering RTC failed\n");
-
- return ret;
+ return rtc_register_device(rtc);
}
+static const struct platform_device_id bd718x7_rtc_id[] = {
+ { "bd70528-rtc", ROHM_CHIP_TYPE_BD70528 },
+ { "bd71828-rtc", ROHM_CHIP_TYPE_BD71828 },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, bd718x7_rtc_id);
+
static struct platform_driver bd70528_rtc = {
.driver = {
.name = "bd70528-rtc"
},
.probe = bd70528_probe,
+ .id_table = bd718x7_rtc_id,
};
module_platform_driver(bd70528_rtc);
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
-MODULE_DESCRIPTION("BD70528 RTC driver");
+MODULE_DESCRIPTION("ROHM BD70528 and BD71828 PMIC RTC driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bd70528-rtc");
diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c
index 2f65943867f5..4fee57c51280 100644
--- a/drivers/rtc/rtc-brcmstb-waketimer.c
+++ b/drivers/rtc/rtc-brcmstb-waketimer.c
@@ -200,7 +200,6 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct brcmstb_waketmr *timer;
- struct resource *res;
int ret;
timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL);
@@ -210,8 +209,7 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, timer);
timer->dev = dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- timer->base = devm_ioremap_resource(dev, res);
+ timer->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(timer->base))
return PTR_ERR(timer->base);
@@ -255,10 +253,8 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
timer->rtc->range_max = U32_MAX;
ret = rtc_register_device(timer->rtc);
- if (ret) {
- dev_err(dev, "unable to register device\n");
+ if (ret)
goto err_notifier;
- }
dev_info(dev, "registered, with irq %d\n", timer->irq);
@@ -279,6 +275,7 @@ static int brcmstb_waketmr_remove(struct platform_device *pdev)
struct brcmstb_waketmr *timer = dev_get_drvdata(&pdev->dev);
unregister_reboot_notifier(&timer->reboot_notifier);
+ clk_disable_unprepare(timer->clk);
return 0;
}
diff --git a/drivers/rtc/rtc-cadence.c b/drivers/rtc/rtc-cadence.c
index 3b7d643c8a63..595d5d252850 100644
--- a/drivers/rtc/rtc-cadence.c
+++ b/drivers/rtc/rtc-cadence.c
@@ -255,7 +255,6 @@ static const struct rtc_class_ops cdns_rtc_ops = {
static int cdns_rtc_probe(struct platform_device *pdev)
{
struct cdns_rtc *crtc;
- struct resource *res;
int ret;
unsigned long ref_clk_freq;
@@ -263,8 +262,7 @@ static int cdns_rtc_probe(struct platform_device *pdev)
if (!crtc)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- crtc->regs = devm_ioremap_resource(&pdev->dev, res);
+ crtc->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(crtc->regs))
return PTR_ERR(crtc->regs);
@@ -289,12 +287,8 @@ static int cdns_rtc_probe(struct platform_device *pdev)
}
crtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(crtc->rtc_dev)) {
- ret = PTR_ERR(crtc->rtc_dev);
- dev_err(&pdev->dev,
- "Failed to allocate the RTC device, %d\n", ret);
- return ret;
- }
+ if (IS_ERR(crtc->rtc_dev))
+ return PTR_ERR(crtc->rtc_dev);
platform_set_drvdata(pdev, crtc);
@@ -343,11 +337,8 @@ static int cdns_rtc_probe(struct platform_device *pdev)
writel(CDNS_RTC_KRTCR_KRTC, crtc->regs + CDNS_RTC_KRTCR);
ret = rtc_register_device(crtc->rtc_dev);
- if (ret) {
- dev_err(&pdev->dev,
- "Failed to register the RTC device, %d\n", ret);
+ if (ret)
goto err_disable_wakeup;
- }
return 0;
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 033303708c8b..b795fe4cbd2e 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -850,7 +850,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_SHARED, dev_name(&cmos_rtc.rtc->dev),
+ 0, dev_name(&cmos_rtc.rtc->dev),
cmos_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
@@ -1197,8 +1197,6 @@ static void rtc_wake_off(struct device *dev)
/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
static void use_acpi_alarm_quirks(void)
{
- int year;
-
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
return;
@@ -1208,8 +1206,10 @@ static void use_acpi_alarm_quirks(void)
if (!is_hpet_enabled())
return;
- if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2015)
- use_acpi_alarm = true;
+ if (dmi_get_bios_year() < 2015)
+ return;
+
+ use_acpi_alarm = true;
}
#else
static inline void use_acpi_alarm_quirks(void) { }
@@ -1305,7 +1305,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
* hardcode it on systems with a legacy PIC.
*/
if (nr_legacy_irqs())
- irq = 8;
+ irq = RTC_IRQ;
#endif
return cmos_do_probe(&pnp->dev,
pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 4ac850837153..da59917c9ee8 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -164,15 +164,13 @@ static int __init coh901331_probe(struct platform_device *pdev)
{
int ret;
struct coh901331_port *rtap;
- struct resource *res;
rtap = devm_kzalloc(&pdev->dev,
sizeof(struct coh901331_port), GFP_KERNEL);
if (!rtap)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtap->virtbase = devm_ioremap_resource(&pdev->dev, res);
+ rtap->virtbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtap->virtbase))
return PTR_ERR(rtap->virtbase);
diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c
index 4d6bf9304ceb..f7343c289cab 100644
--- a/drivers/rtc/rtc-cros-ec.c
+++ b/drivers/rtc/rtc-cros-ec.c
@@ -5,9 +5,9 @@
// Author: Stephen Barber <smbarber@chromium.org>
#include <linux/kernel.h>
-#include <linux/mfd/cros_ec.h>
-#include <linux/mfd/cros_ec_commands.h>
#include <linux/module.h>
+#include <linux/platform_data/cros_ec_commands.h>
+#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/slab.h>
@@ -106,11 +106,7 @@ static int cros_ec_rtc_set_time(struct device *dev, struct rtc_time *tm)
struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev);
struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec;
int ret;
- time64_t time;
-
- time = rtc_tm_to_time64(tm);
- if (time < 0 || time > U32_MAX)
- return -EINVAL;
+ time64_t time = rtc_tm_to_time64(tm);
ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_VALUE, (u32)time);
if (ret < 0) {
@@ -347,14 +343,16 @@ static int cros_ec_rtc_probe(struct platform_device *pdev)
return ret;
}
- cros_ec_rtc->rtc = devm_rtc_device_register(&pdev->dev, DRV_NAME,
- &cros_ec_rtc_ops,
- THIS_MODULE);
- if (IS_ERR(cros_ec_rtc->rtc)) {
- ret = PTR_ERR(cros_ec_rtc->rtc);
- dev_err(&pdev->dev, "failed to register rtc device\n");
+ cros_ec_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(cros_ec_rtc->rtc))
+ return PTR_ERR(cros_ec_rtc->rtc);
+
+ cros_ec_rtc->rtc->ops = &cros_ec_rtc_ops;
+ cros_ec_rtc->rtc->range_max = U32_MAX;
+
+ ret = rtc_register_device(cros_ec_rtc->rtc);
+ if (ret)
return ret;
- }
/* Get RTC events from the EC. */
cros_ec_rtc->notifier.notifier_call = cros_ec_rtc_event;
diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c
index 15908d51b1cb..046b1d4c3dae 100644
--- a/drivers/rtc/rtc-da9063.c
+++ b/drivers/rtc/rtc-da9063.c
@@ -483,6 +483,9 @@ static int da9063_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev->uie_unsupported = 1;
irq_alarm = platform_get_irq_byname(pdev, "ALARM");
+ if (irq_alarm < 0)
+ return irq_alarm;
+
ret = devm_request_threaded_irq(&pdev->dev, irq_alarm, NULL,
da9063_alarm_event,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c
index fcb71bf4d492..390b7351e0fe 100644
--- a/drivers/rtc/rtc-davinci.c
+++ b/drivers/rtc/rtc-davinci.c
@@ -469,7 +469,6 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct davinci_rtc *davinci_rtc;
- struct resource *res;
int ret = 0;
davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL);
@@ -477,13 +476,10 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
return -ENOMEM;
davinci_rtc->irq = platform_get_irq(pdev, 0);
- if (davinci_rtc->irq < 0) {
- dev_err(dev, "no RTC irq\n");
+ if (davinci_rtc->irq < 0)
return davinci_rtc->irq;
- }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- davinci_rtc->base = devm_ioremap_resource(dev, res);
+ davinci_rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(davinci_rtc->base))
return PTR_ERR(davinci_rtc->base);
diff --git a/drivers/rtc/rtc-digicolor.c b/drivers/rtc/rtc-digicolor.c
index 0aecc3f8e721..200d85b01e8b 100644
--- a/drivers/rtc/rtc-digicolor.c
+++ b/drivers/rtc/rtc-digicolor.c
@@ -175,7 +175,6 @@ static irqreturn_t dc_rtc_irq(int irq, void *dev_id)
static int __init dc_rtc_probe(struct platform_device *pdev)
{
- struct resource *res;
struct dc_rtc *rtc;
int irq, ret;
@@ -183,8 +182,7 @@ static int __init dc_rtc_probe(struct platform_device *pdev)
if (!rtc)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtc->regs = devm_ioremap_resource(&pdev->dev, res);
+ rtc->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->regs))
return PTR_ERR(rtc->regs);
diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c
index b225bcfef50b..7eeb3f359de8 100644
--- a/drivers/rtc/rtc-ds1216.c
+++ b/drivers/rtc/rtc-ds1216.c
@@ -137,7 +137,6 @@ static const struct rtc_class_ops ds1216_rtc_ops = {
static int __init ds1216_rtc_probe(struct platform_device *pdev)
{
- struct resource *res;
struct ds1216_priv *priv;
u8 dummy[8];
@@ -147,8 +146,7 @@ static int __init ds1216_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ priv->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->ioaddr))
return PTR_ERR(priv->ioaddr);
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c
index a06508b6c404..7acf849d4902 100644
--- a/drivers/rtc/rtc-ds1286.c
+++ b/drivers/rtc/rtc-ds1286.c
@@ -323,15 +323,13 @@ static const struct rtc_class_ops ds1286_ops = {
static int ds1286_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
- struct resource *res;
struct ds1286_priv *priv;
priv = devm_kzalloc(&pdev->dev, sizeof(struct ds1286_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->rtcregs = devm_ioremap_resource(&pdev->dev, res);
+ priv->rtcregs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->rtcregs))
return PTR_ERR(priv->rtcregs);
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index 4faa24c88af5..b3de6d2e680a 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -15,8 +15,6 @@
#include <linux/rtc.h>
#include <linux/spi/spi.h>
-#define DRV_NAME "rtc-ds1302"
-
#define RTC_CMD_READ 0x81 /* Read command */
#define RTC_CMD_WRITE 0x80 /* Write command */
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
index e04d6e862c42..4420fbf2f8fe 100644
--- a/drivers/rtc/rtc-ds1305.c
+++ b/drivers/rtc/rtc-ds1305.c
@@ -690,19 +690,16 @@ static int ds1305_probe(struct spi_device *spi)
/* register RTC ... from here on, ds1305->ctrl needs locking */
ds1305->rtc = devm_rtc_allocate_device(&spi->dev);
- if (IS_ERR(ds1305->rtc)) {
+ if (IS_ERR(ds1305->rtc))
return PTR_ERR(ds1305->rtc);
- }
ds1305->rtc->ops = &ds1305_ops;
ds1305_nvmem_cfg.priv = ds1305;
ds1305->rtc->nvram_old_abi = true;
status = rtc_register_device(ds1305->rtc);
- if (status) {
- dev_dbg(&spi->dev, "register rtc --> %d\n", status);
+ if (status)
return status;
- }
rtc_nvmem_register(ds1305->rtc, &ds1305_nvmem_cfg);
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index fa6de31d5793..ba143423875b 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -75,45 +75,21 @@ static const struct spi_device_id ds1343_id[] = {
MODULE_DEVICE_TABLE(spi, ds1343_id);
struct ds1343_priv {
- struct spi_device *spi;
struct rtc_device *rtc;
struct regmap *map;
- struct mutex mutex;
- unsigned int irqen;
int irq;
- int alarm_sec;
- int alarm_min;
- int alarm_hour;
- int alarm_mday;
};
-static int ds1343_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
-#ifdef RTC_SET_CHARGE
- case RTC_SET_CHARGE:
- {
- int val;
-
- if (copy_from_user(&val, (int __user *)arg, sizeof(int)))
- return -EFAULT;
-
- return regmap_write(priv->map, DS1343_TRICKLE_REG, val);
- }
- break;
-#endif
- }
-
- return -ENOIOCTLCMD;
-}
-
static ssize_t ds1343_show_glitchfilter(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct ds1343_priv *priv = dev_get_drvdata(dev);
+ struct ds1343_priv *priv = dev_get_drvdata(dev->parent);
int glitch_filt_status, data;
+ int res;
- regmap_read(priv->map, DS1343_CONTROL_REG, &data);
+ res = regmap_read(priv->map, DS1343_CONTROL_REG, &data);
+ if (res)
+ return res;
glitch_filt_status = !!(data & DS1343_EGFIL);
@@ -127,21 +103,19 @@ static ssize_t ds1343_store_glitchfilter(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ds1343_priv *priv = dev_get_drvdata(dev);
- int data;
-
- regmap_read(priv->map, DS1343_CONTROL_REG, &data);
+ struct ds1343_priv *priv = dev_get_drvdata(dev->parent);
+ int data = 0;
+ int res;
if (strncmp(buf, "enabled", 7) == 0)
- data |= DS1343_EGFIL;
-
- else if (strncmp(buf, "disabled", 8) == 0)
- data &= ~(DS1343_EGFIL);
-
- else
+ data = DS1343_EGFIL;
+ else if (strncmp(buf, "disabled", 8))
return -EINVAL;
- regmap_write(priv->map, DS1343_CONTROL_REG, data);
+ res = regmap_update_bits(priv->map, DS1343_CONTROL_REG,
+ DS1343_EGFIL, data);
+ if (res)
+ return res;
return count;
}
@@ -168,11 +142,13 @@ static int ds1343_nvram_read(void *priv, unsigned int off, void *val,
static ssize_t ds1343_show_tricklecharger(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct ds1343_priv *priv = dev_get_drvdata(dev);
- int data;
+ struct ds1343_priv *priv = dev_get_drvdata(dev->parent);
+ int res, data;
char *diodes = "disabled", *resistors = " ";
- regmap_read(priv->map, DS1343_TRICKLE_REG, &data);
+ res = regmap_read(priv->map, DS1343_TRICKLE_REG, &data);
+ if (res)
+ return res;
if ((data & 0xf0) == DS1343_TRICKLE_MAGIC) {
switch (data & 0x0c) {
@@ -209,28 +185,15 @@ static ssize_t ds1343_show_tricklecharger(struct device *dev,
static DEVICE_ATTR(trickle_charger, S_IRUGO, ds1343_show_tricklecharger, NULL);
-static int ds1343_sysfs_register(struct device *dev)
-{
- int err;
-
- err = device_create_file(dev, &dev_attr_glitch_filter);
- if (err)
- return err;
-
- err = device_create_file(dev, &dev_attr_trickle_charger);
- if (!err)
- return 0;
-
- device_remove_file(dev, &dev_attr_glitch_filter);
-
- return err;
-}
+static struct attribute *ds1343_attrs[] = {
+ &dev_attr_glitch_filter.attr,
+ &dev_attr_trickle_charger.attr,
+ NULL
+};
-static void ds1343_sysfs_unregister(struct device *dev)
-{
- device_remove_file(dev, &dev_attr_glitch_filter);
- device_remove_file(dev, &dev_attr_trickle_charger);
-}
+static const struct attribute_group ds1343_attr_group = {
+ .attrs = ds1343_attrs,
+};
static int ds1343_read_time(struct device *dev, struct rtc_time *dt)
{
@@ -256,144 +219,78 @@ static int ds1343_read_time(struct device *dev, struct rtc_time *dt)
static int ds1343_set_time(struct device *dev, struct rtc_time *dt)
{
struct ds1343_priv *priv = dev_get_drvdata(dev);
- int res;
-
- res = regmap_write(priv->map, DS1343_SECONDS_REG,
- bin2bcd(dt->tm_sec));
- if (res)
- return res;
-
- res = regmap_write(priv->map, DS1343_MINUTES_REG,
- bin2bcd(dt->tm_min));
- if (res)
- return res;
-
- res = regmap_write(priv->map, DS1343_HOURS_REG,
- bin2bcd(dt->tm_hour) & 0x3F);
- if (res)
- return res;
-
- res = regmap_write(priv->map, DS1343_DAY_REG,
- bin2bcd(dt->tm_wday + 1));
- if (res)
- return res;
-
- res = regmap_write(priv->map, DS1343_DATE_REG,
- bin2bcd(dt->tm_mday));
- if (res)
- return res;
-
- res = regmap_write(priv->map, DS1343_MONTH_REG,
- bin2bcd(dt->tm_mon + 1));
- if (res)
- return res;
-
- dt->tm_year %= 100;
-
- res = regmap_write(priv->map, DS1343_YEAR_REG,
- bin2bcd(dt->tm_year));
- if (res)
- return res;
-
- return 0;
+ u8 buf[7];
+
+ buf[0] = bin2bcd(dt->tm_sec);
+ buf[1] = bin2bcd(dt->tm_min);
+ buf[2] = bin2bcd(dt->tm_hour) & 0x3F;
+ buf[3] = bin2bcd(dt->tm_wday + 1);
+ buf[4] = bin2bcd(dt->tm_mday);
+ buf[5] = bin2bcd(dt->tm_mon + 1);
+ buf[6] = bin2bcd(dt->tm_year - 100);
+
+ return regmap_bulk_write(priv->map, DS1343_SECONDS_REG,
+ buf, sizeof(buf));
}
-static int ds1343_update_alarm(struct device *dev)
+static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct ds1343_priv *priv = dev_get_drvdata(dev);
- unsigned int control, stat;
unsigned char buf[4];
- int res = 0;
+ unsigned int val;
+ int res;
- res = regmap_read(priv->map, DS1343_CONTROL_REG, &control);
- if (res)
- return res;
+ if (priv->irq <= 0)
+ return -EINVAL;
- res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
+ res = regmap_read(priv->map, DS1343_STATUS_REG, &val);
if (res)
return res;
- control &= ~(DS1343_A0IE);
- stat &= ~(DS1343_IRQF0);
+ alarm->pending = !!(val & DS1343_IRQF0);
- res = regmap_write(priv->map, DS1343_CONTROL_REG, control);
+ res = regmap_read(priv->map, DS1343_CONTROL_REG, &val);
if (res)
return res;
+ alarm->enabled = !!(val & DS1343_A0IE);
- res = regmap_write(priv->map, DS1343_STATUS_REG, stat);
+ res = regmap_bulk_read(priv->map, DS1343_ALM0_SEC_REG, buf, 4);
if (res)
return res;
- buf[0] = priv->alarm_sec < 0 || (priv->irqen & RTC_UF) ?
- 0x80 : bin2bcd(priv->alarm_sec) & 0x7F;
- buf[1] = priv->alarm_min < 0 || (priv->irqen & RTC_UF) ?
- 0x80 : bin2bcd(priv->alarm_min) & 0x7F;
- buf[2] = priv->alarm_hour < 0 || (priv->irqen & RTC_UF) ?
- 0x80 : bin2bcd(priv->alarm_hour) & 0x3F;
- buf[3] = priv->alarm_mday < 0 || (priv->irqen & RTC_UF) ?
- 0x80 : bin2bcd(priv->alarm_mday) & 0x7F;
-
- res = regmap_bulk_write(priv->map, DS1343_ALM0_SEC_REG, buf, 4);
- if (res)
- return res;
+ alarm->time.tm_sec = bcd2bin(buf[0]) & 0x7f;
+ alarm->time.tm_min = bcd2bin(buf[1]) & 0x7f;
+ alarm->time.tm_hour = bcd2bin(buf[2]) & 0x3f;
+ alarm->time.tm_mday = bcd2bin(buf[3]) & 0x3f;
- if (priv->irqen) {
- control |= DS1343_A0IE;
- res = regmap_write(priv->map, DS1343_CONTROL_REG, control);
- }
-
- return res;
+ return 0;
}
-static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct ds1343_priv *priv = dev_get_drvdata(dev);
+ unsigned char buf[4];
int res = 0;
- unsigned int stat;
if (priv->irq <= 0)
return -EINVAL;
- mutex_lock(&priv->mutex);
-
- res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
+ res = regmap_update_bits(priv->map, DS1343_CONTROL_REG, DS1343_A0IE, 0);
if (res)
- goto out;
-
- alarm->enabled = !!(priv->irqen & RTC_AF);
- alarm->pending = !!(stat & DS1343_IRQF0);
-
- alarm->time.tm_sec = priv->alarm_sec < 0 ? 0 : priv->alarm_sec;
- alarm->time.tm_min = priv->alarm_min < 0 ? 0 : priv->alarm_min;
- alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour;
- alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday;
-
-out:
- mutex_unlock(&priv->mutex);
- return res;
-}
-
-static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
- struct ds1343_priv *priv = dev_get_drvdata(dev);
- int res = 0;
-
- if (priv->irq <= 0)
- return -EINVAL;
+ return res;
- mutex_lock(&priv->mutex);
+ buf[0] = bin2bcd(alarm->time.tm_sec);
+ buf[1] = bin2bcd(alarm->time.tm_min);
+ buf[2] = bin2bcd(alarm->time.tm_hour);
+ buf[3] = bin2bcd(alarm->time.tm_mday);
- priv->alarm_sec = alarm->time.tm_sec;
- priv->alarm_min = alarm->time.tm_min;
- priv->alarm_hour = alarm->time.tm_hour;
- priv->alarm_mday = alarm->time.tm_mday;
+ res = regmap_bulk_write(priv->map, DS1343_ALM0_SEC_REG, buf, 4);
+ if (res)
+ return res;
if (alarm->enabled)
- priv->irqen |= RTC_AF;
-
- res = ds1343_update_alarm(dev);
-
- mutex_unlock(&priv->mutex);
+ res = regmap_update_bits(priv->map, DS1343_CONTROL_REG,
+ DS1343_A0IE, DS1343_A0IE);
return res;
}
@@ -401,32 +298,21 @@ static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
static int ds1343_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct ds1343_priv *priv = dev_get_drvdata(dev);
- int res = 0;
if (priv->irq <= 0)
return -EINVAL;
- mutex_lock(&priv->mutex);
-
- if (enabled)
- priv->irqen |= RTC_AF;
- else
- priv->irqen &= ~RTC_AF;
-
- res = ds1343_update_alarm(dev);
-
- mutex_unlock(&priv->mutex);
-
- return res;
+ return regmap_update_bits(priv->map, DS1343_CONTROL_REG,
+ DS1343_A0IE, enabled ? DS1343_A0IE : 0);
}
static irqreturn_t ds1343_thread(int irq, void *dev_id)
{
struct ds1343_priv *priv = dev_id;
- unsigned int stat, control;
+ unsigned int stat;
int res = 0;
- mutex_lock(&priv->mutex);
+ rtc_lock(priv->rtc);
res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
if (res)
@@ -436,23 +322,18 @@ static irqreturn_t ds1343_thread(int irq, void *dev_id)
stat &= ~DS1343_IRQF0;
regmap_write(priv->map, DS1343_STATUS_REG, stat);
- res = regmap_read(priv->map, DS1343_CONTROL_REG, &control);
- if (res)
- goto out;
-
- control &= ~DS1343_A0IE;
- regmap_write(priv->map, DS1343_CONTROL_REG, control);
-
rtc_update_irq(priv->rtc, 1, RTC_AF | RTC_IRQF);
+
+ regmap_update_bits(priv->map, DS1343_CONTROL_REG,
+ DS1343_A0IE, 0);
}
out:
- mutex_unlock(&priv->mutex);
+ rtc_unlock(priv->rtc);
return IRQ_HANDLED;
}
static const struct rtc_class_ops ds1343_rtc_ops = {
- .ioctl = ds1343_ioctl,
.read_time = ds1343_read_time,
.set_time = ds1343_set_time,
.read_alarm = ds1343_read_alarm,
@@ -480,13 +361,13 @@ static int ds1343_probe(struct spi_device *spi)
if (!priv)
return -ENOMEM;
- priv->spi = spi;
- mutex_init(&priv->mutex);
-
/* RTC DS1347 works in spi mode 3 and
- * its chip select is active high
+ * its chip select is active high. Active high should be defined as
+ * "inverse polarity" as GPIO-based chip selects can be logically
+ * active high but inverted by the GPIO library.
*/
- spi->mode = SPI_MODE_3 | SPI_CS_HIGH;
+ spi->mode |= SPI_MODE_3;
+ spi->mode ^= SPI_CS_HIGH;
spi->bits_per_word = 8;
res = spi_setup(spi);
if (res)
@@ -520,6 +401,13 @@ static int ds1343_probe(struct spi_device *spi)
priv->rtc->nvram_old_abi = true;
priv->rtc->ops = &ds1343_rtc_ops;
+ priv->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ priv->rtc->range_max = RTC_TIMESTAMP_END_2099;
+
+ res = rtc_add_group(priv->rtc, &ds1343_attr_group);
+ if (res)
+ dev_err(&spi->dev,
+ "unable to create sysfs entries for rtc ds1343\n");
res = rtc_register_device(priv->rtc);
if (res)
@@ -544,31 +432,12 @@ static int ds1343_probe(struct spi_device *spi)
}
}
- res = ds1343_sysfs_register(&spi->dev);
- if (res)
- dev_err(&spi->dev,
- "unable to create sysfs entries for rtc ds1343\n");
-
return 0;
}
static int ds1343_remove(struct spi_device *spi)
{
- struct ds1343_priv *priv = spi_get_drvdata(spi);
-
- if (spi->irq) {
- mutex_lock(&priv->mutex);
- priv->irqen &= ~RTC_AF;
- mutex_unlock(&priv->mutex);
-
- dev_pm_clear_wake_irq(&spi->dev);
- device_init_wakeup(&spi->dev, false);
- devm_free_irq(&spi->dev, spi->irq, priv);
- }
-
- spi_set_drvdata(spi, NULL);
-
- ds1343_sysfs_unregister(&spi->dev);
+ dev_pm_clear_wake_irq(&spi->dev);
return 0;
}
diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c
index d392a7bfdd1c..7025cf3fb9f8 100644
--- a/drivers/rtc/rtc-ds1347.c
+++ b/drivers/rtc/rtc-ds1347.c
@@ -26,9 +26,15 @@
#define DS1347_DAY_REG 0x0B
#define DS1347_YEAR_REG 0x0D
#define DS1347_CONTROL_REG 0x0F
+#define DS1347_CENTURY_REG 0x13
#define DS1347_STATUS_REG 0x17
#define DS1347_CLOCK_BURST 0x3F
+#define DS1347_WP_BIT BIT(7)
+
+#define DS1347_NEOSC_BIT BIT(7)
+#define DS1347_OSF_BIT BIT(2)
+
static const struct regmap_range ds1347_ranges[] = {
{
.range_min = DS1347_SECONDS_REG,
@@ -43,35 +49,54 @@ static const struct regmap_access_table ds1347_access_table = {
static int ds1347_read_time(struct device *dev, struct rtc_time *dt)
{
- struct spi_device *spi = to_spi_device(dev);
- struct regmap *map;
- int err;
+ struct regmap *map = dev_get_drvdata(dev);
+ unsigned int status, century, secs;
unsigned char buf[8];
+ int err;
- map = spi_get_drvdata(spi);
-
- err = regmap_bulk_read(map, DS1347_CLOCK_BURST, buf, 8);
+ err = regmap_read(map, DS1347_STATUS_REG, &status);
if (err)
return err;
+ if (status & DS1347_OSF_BIT)
+ return -EINVAL;
+
+ do {
+ err = regmap_bulk_read(map, DS1347_CLOCK_BURST, buf, 8);
+ if (err)
+ return err;
+
+ err = regmap_read(map, DS1347_CENTURY_REG, &century);
+ if (err)
+ return err;
+
+ err = regmap_read(map, DS1347_SECONDS_REG, &secs);
+ if (err)
+ return err;
+ } while (buf[0] != secs);
+
dt->tm_sec = bcd2bin(buf[0]);
- dt->tm_min = bcd2bin(buf[1]);
+ dt->tm_min = bcd2bin(buf[1] & 0x7f);
dt->tm_hour = bcd2bin(buf[2] & 0x3F);
dt->tm_mday = bcd2bin(buf[3]);
dt->tm_mon = bcd2bin(buf[4]) - 1;
dt->tm_wday = bcd2bin(buf[5]) - 1;
- dt->tm_year = bcd2bin(buf[6]) + 100;
+ dt->tm_year = (bcd2bin(century) * 100) + bcd2bin(buf[6]) - 1900;
return 0;
}
static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
{
- struct spi_device *spi = to_spi_device(dev);
- struct regmap *map;
+ struct regmap *map = dev_get_drvdata(dev);
+ unsigned int century;
unsigned char buf[8];
+ int err;
- map = spi_get_drvdata(spi);
+ err = regmap_update_bits(map, DS1347_STATUS_REG,
+ DS1347_NEOSC_BIT, DS1347_NEOSC_BIT);
+ if (err)
+ return err;
buf[0] = bin2bcd(dt->tm_sec);
buf[1] = bin2bcd(dt->tm_min);
@@ -79,16 +104,20 @@ static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
buf[3] = bin2bcd(dt->tm_mday);
buf[4] = bin2bcd(dt->tm_mon + 1);
buf[5] = bin2bcd(dt->tm_wday + 1);
+ buf[6] = bin2bcd(dt->tm_year % 100);
+ buf[7] = bin2bcd(0x00);
- /* year in linux is from 1900 i.e in range of 100
- in rtc it is from 00 to 99 */
- dt->tm_year = dt->tm_year % 100;
+ err = regmap_bulk_write(map, DS1347_CLOCK_BURST, buf, 8);
+ if (err)
+ return err;
- buf[6] = bin2bcd(dt->tm_year);
- buf[7] = bin2bcd(0x00);
+ century = (dt->tm_year / 100) + 19;
+ err = regmap_write(map, DS1347_CENTURY_REG, century);
+ if (err)
+ return err;
- /* write the rtc settings */
- return regmap_bulk_write(map, DS1347_CLOCK_BURST, buf, 8);
+ return regmap_update_bits(map, DS1347_STATUS_REG,
+ DS1347_NEOSC_BIT | DS1347_OSF_BIT, 0);
}
static const struct rtc_class_ops ds1347_rtc_ops = {
@@ -101,8 +130,7 @@ static int ds1347_probe(struct spi_device *spi)
struct rtc_device *rtc;
struct regmap_config config;
struct regmap *map;
- unsigned int data;
- int res;
+ int err;
memset(&config, 0, sizeof(config));
config.reg_bits = 8;
@@ -125,36 +153,20 @@ static int ds1347_probe(struct spi_device *spi)
spi_set_drvdata(spi, map);
- /* RTC Settings */
- res = regmap_read(map, DS1347_SECONDS_REG, &data);
- if (res)
- return res;
-
/* Disable the write protect of rtc */
- regmap_read(map, DS1347_CONTROL_REG, &data);
- data = data & ~(1<<7);
- regmap_write(map, DS1347_CONTROL_REG, data);
-
- /* Enable the oscillator , disable the oscillator stop flag,
- and glitch filter to reduce current consumption */
- regmap_read(map, DS1347_STATUS_REG, &data);
- data = data & 0x1B;
- regmap_write(map, DS1347_STATUS_REG, data);
-
- /* display the settings */
- regmap_read(map, DS1347_CONTROL_REG, &data);
- dev_info(&spi->dev, "DS1347 RTC CTRL Reg = 0x%02x\n", data);
-
- regmap_read(map, DS1347_STATUS_REG, &data);
- dev_info(&spi->dev, "DS1347 RTC Status Reg = 0x%02x\n", data);
-
- rtc = devm_rtc_device_register(&spi->dev, "ds1347",
- &ds1347_rtc_ops, THIS_MODULE);
+ err = regmap_update_bits(map, DS1347_CONTROL_REG, DS1347_WP_BIT, 0);
+ if (err)
+ return err;
+ rtc = devm_rtc_allocate_device(&spi->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- return 0;
+ rtc->ops = &ds1347_rtc_ops;
+ rtc->range_min = RTC_TIMESTAMP_BEGIN_0000;
+ rtc->range_max = RTC_TIMESTAMP_END_9999;
+
+ return rtc_register_device(rtc);
}
static struct spi_driver ds1347_driver = {
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 225a8df1d4e9..6e9ddcd03992 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -14,7 +14,7 @@
*/
/*
* It would be more efficient to use i2c msgs/i2c_transfer directly but, as
- * recommened in .../Documentation/i2c/writing-clients section
+ * recommended in .../Documentation/i2c/writing-clients.rst section
* "Sending and receiving", using SMBus level communication is preferred.
*/
@@ -439,14 +439,13 @@ static void ds1374_wdt_ping(void)
static void ds1374_wdt_disable(void)
{
- int ret = -ENOIOCTLCMD;
int cr;
cr = i2c_smbus_read_byte_data(save_client, DS1374_REG_CR);
/* Disable watchdog timer */
cr &= ~DS1374_REG_CR_WACE;
- ret = i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
+ i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
}
/*
@@ -586,6 +585,7 @@ static const struct file_operations ds1374_wdt_fops = {
.owner = THIS_MODULE,
.read = ds1374_wdt_read,
.unlocked_ioctl = ds1374_wdt_unlocked_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
.write = ds1374_wdt_write,
.open = ds1374_wdt_open,
.release = ds1374_wdt_release,
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index b6a477519280..a63872c4c76d 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -414,7 +414,6 @@ static int ds1511_nvram_write(void *priv, unsigned int pos, void *buf,
static int ds1511_rtc_probe(struct platform_device *pdev)
{
- struct resource *res;
struct rtc_plat_data *pdata;
int ret = 0;
struct nvmem_config ds1511_nvmem_cfg = {
@@ -431,8 +430,7 @@ static int ds1511_rtc_probe(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- ds1511_base = devm_ioremap_resource(&pdev->dev, res);
+ ds1511_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ds1511_base))
return PTR_ERR(ds1511_base);
pdata->ioaddr = ds1511_base;
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 219d6b520a69..cdf5e05b9489 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -249,7 +249,6 @@ static int ds1553_nvram_write(void *priv, unsigned int pos, void *val,
static int ds1553_rtc_probe(struct platform_device *pdev)
{
- struct resource *res;
unsigned int cen, sec;
struct rtc_plat_data *pdata;
void __iomem *ioaddr;
@@ -268,8 +267,7 @@ static int ds1553_rtc_probe(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ioaddr))
return PTR_ERR(ioaddr);
pdata->ioaddr = ioaddr;
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index e9e8d02743ee..9da84df9f152 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -128,9 +128,6 @@ static int ds1672_probe(struct i2c_client *client,
if (err)
return err;
- if (IS_ERR(rtc))
- return PTR_ERR(rtc);
-
i2c_set_clientdata(client, rtc);
return 0;
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c
index 184e4a3e2bef..56c670af2e50 100644
--- a/drivers/rtc/rtc-ds1685.c
+++ b/drivers/rtc/rtc-ds1685.c
@@ -31,7 +31,10 @@
/* ----------------------------------------------------------------------- */
-/* Standard read/write functions if platform does not provide overrides */
+/*
+ * Standard read/write
+ * all registers are mapped in CPU address space
+ */
/**
* ds1685_read - read a value from an rtc register.
@@ -59,6 +62,35 @@ ds1685_write(struct ds1685_priv *rtc, int reg, u8 value)
}
/* ----------------------------------------------------------------------- */
+/*
+ * Indirect read/write functions
+ * access happens via address and data register mapped in CPU address space
+ */
+
+/**
+ * ds1685_indirect_read - read a value from an rtc register.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @reg: the register address to read.
+ */
+static u8
+ds1685_indirect_read(struct ds1685_priv *rtc, int reg)
+{
+ writeb(reg, rtc->regs);
+ return readb(rtc->data);
+}
+
+/**
+ * ds1685_indirect_write - write a value to an rtc register.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @reg: the register address to write.
+ * @value: value to write to the register.
+ */
+static void
+ds1685_indirect_write(struct ds1685_priv *rtc, int reg, u8 value)
+{
+ writeb(reg, rtc->regs);
+ writeb(value, rtc->data);
+}
/* ----------------------------------------------------------------------- */
/* Inlined functions */
@@ -229,7 +261,7 @@ static int
ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct ds1685_priv *rtc = dev_get_drvdata(dev);
- u8 ctrlb, century;
+ u8 century;
u8 seconds, minutes, hours, wday, mday, month, years;
/* Fetch the time info from the RTC registers. */
@@ -242,7 +274,6 @@ ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
month = rtc->read(rtc, RTC_MONTH);
years = rtc->read(rtc, RTC_YEAR);
century = rtc->read(rtc, RTC_CENTURY);
- ctrlb = rtc->read(rtc, RTC_CTRL_B);
ds1685_rtc_end_data_access(rtc);
/* bcd2bin if needed, perform fixups, and store to rtc_time. */
@@ -723,7 +754,7 @@ static int
ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
{
struct ds1685_priv *rtc = dev_get_drvdata(dev);
- u8 ctrla, ctrlb, ctrlc, ctrld, ctrl4a, ctrl4b, ssn[8];
+ u8 ctrla, ctrlb, ctrld, ctrl4a, ctrl4b, ssn[8];
char *model;
/* Read all the relevant data from the control registers. */
@@ -731,7 +762,6 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
ds1685_rtc_get_ssn(rtc, ssn);
ctrla = rtc->read(rtc, RTC_CTRL_A);
ctrlb = rtc->read(rtc, RTC_CTRL_B);
- ctrlc = rtc->read(rtc, RTC_CTRL_C);
ctrld = rtc->read(rtc, RTC_CTRL_D);
ctrl4a = rtc->read(rtc, RTC_EXT_CTRL_4A);
ctrl4b = rtc->read(rtc, RTC_EXT_CTRL_4B);
@@ -1009,7 +1039,7 @@ ds1685_rtc_sysfs_serial_show(struct device *dev,
}
static DEVICE_ATTR(serial, S_IRUGO, ds1685_rtc_sysfs_serial_show, NULL);
-/**
+/*
* struct ds1685_rtc_sysfs_misc_attrs - list for misc RTC features.
*/
static struct attribute*
@@ -1020,7 +1050,7 @@ ds1685_rtc_sysfs_misc_attrs[] = {
NULL,
};
-/**
+/*
* struct ds1685_rtc_sysfs_misc_grp - attr group for misc RTC features.
*/
static const struct attribute_group
@@ -1040,7 +1070,6 @@ static int
ds1685_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc_dev;
- struct resource *res;
struct ds1685_priv *rtc;
struct ds1685_rtc_platform_data *pdata;
u8 ctrla, ctrlb, hours;
@@ -1063,35 +1092,29 @@ ds1685_rtc_probe(struct platform_device *pdev)
if (!rtc)
return -ENOMEM;
- /*
- * Allocate/setup any IORESOURCE_MEM resources, if required. Not all
- * platforms put the RTC in an easy-access place. Like the SGI Octane,
- * which attaches the RTC to a "ByteBus", hooked to a SuperIO chip
- * that sits behind the IOC3 PCI metadevice.
- */
- if (pdata->alloc_io_resources) {
- /* Get the platform resources. */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
- rtc->size = resource_size(res);
-
- /* Request a memory region. */
- /* XXX: mmio-only for now. */
- if (!devm_request_mem_region(&pdev->dev, res->start, rtc->size,
- pdev->name))
- return -EBUSY;
-
- /*
- * Set the base address for the rtc, and ioremap its
- * registers.
- */
- rtc->baseaddr = res->start;
- rtc->regs = devm_ioremap(&pdev->dev, res->start, rtc->size);
- if (!rtc->regs)
- return -ENOMEM;
+ /* Setup resources and access functions */
+ switch (pdata->access_type) {
+ case ds1685_reg_direct:
+ rtc->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rtc->regs))
+ return PTR_ERR(rtc->regs);
+ rtc->read = ds1685_read;
+ rtc->write = ds1685_write;
+ break;
+ case ds1685_reg_indirect:
+ rtc->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rtc->regs))
+ return PTR_ERR(rtc->regs);
+ rtc->data = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(rtc->data))
+ return PTR_ERR(rtc->data);
+ rtc->read = ds1685_indirect_read;
+ rtc->write = ds1685_indirect_write;
+ break;
}
- rtc->alloc_io_resources = pdata->alloc_io_resources;
+
+ if (!rtc->read || !rtc->write)
+ return -ENXIO;
/* Get the register step size. */
if (pdata->regstep > 0)
@@ -1099,24 +1122,6 @@ ds1685_rtc_probe(struct platform_device *pdev)
else
rtc->regstep = 1;
- /* Platform read function, else default if mmio setup */
- if (pdata->plat_read)
- rtc->read = pdata->plat_read;
- else
- if (pdata->alloc_io_resources)
- rtc->read = ds1685_read;
- else
- return -ENXIO;
-
- /* Platform write function, else default if mmio setup */
- if (pdata->plat_write)
- rtc->write = pdata->plat_write;
- else
- if (pdata->alloc_io_resources)
- rtc->write = ds1685_write;
- else
- return -ENXIO;
-
/* Platform pre-shutdown function, if defined. */
if (pdata->plat_prepare_poweroff)
rtc->prepare_poweroff = pdata->plat_prepare_poweroff;
@@ -1271,7 +1276,6 @@ ds1685_rtc_probe(struct platform_device *pdev)
/* See if the platform doesn't support UIE. */
if (pdata->uie_unsupported)
rtc_dev->uie_unsupported = 1;
- rtc->uie_unsupported = pdata->uie_unsupported;
rtc->dev = rtc_dev;
@@ -1351,7 +1355,7 @@ ds1685_rtc_remove(struct platform_device *pdev)
return 0;
}
-/**
+/*
* ds1685_rtc_driver - rtc driver properties.
*/
static struct platform_driver ds1685_rtc_driver = {
diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c
index 77cca1392253..9f176bce48ba 100644
--- a/drivers/rtc/rtc-em3027.c
+++ b/drivers/rtc/rtc-em3027.c
@@ -71,7 +71,7 @@ static int em3027_get_time(struct device *dev, struct rtc_time *tm)
tm->tm_hour = bcd2bin(buf[2]);
tm->tm_mday = bcd2bin(buf[3]);
tm->tm_wday = bcd2bin(buf[4]);
- tm->tm_mon = bcd2bin(buf[5]);
+ tm->tm_mon = bcd2bin(buf[5]) - 1;
tm->tm_year = bcd2bin(buf[6]) + 100;
return 0;
@@ -94,7 +94,7 @@ static int em3027_set_time(struct device *dev, struct rtc_time *tm)
buf[3] = bin2bcd(tm->tm_hour);
buf[4] = bin2bcd(tm->tm_mday);
buf[5] = bin2bcd(tm->tm_wday);
- buf[6] = bin2bcd(tm->tm_mon);
+ buf[6] = bin2bcd(tm->tm_mon + 1);
buf[7] = bin2bcd(tm->tm_year % 100);
/* write time/date registers */
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index 1766496385fe..8ec9ea1ca72e 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -122,15 +122,13 @@ static const struct attribute_group ep93xx_rtc_sysfs_files = {
static int ep93xx_rtc_probe(struct platform_device *pdev)
{
struct ep93xx_rtc *ep93xx_rtc;
- struct resource *res;
int err;
ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
if (!ep93xx_rtc)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- ep93xx_rtc->mmio_base = devm_ioremap_resource(&pdev->dev, res);
+ ep93xx_rtc->mmio_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ep93xx_rtc->mmio_base))
return PTR_ERR(ep93xx_rtc->mmio_base);
diff --git a/drivers/rtc/rtc-fsl-ftm-alarm.c b/drivers/rtc/rtc-fsl-ftm-alarm.c
new file mode 100644
index 000000000000..9e6e994cce99
--- /dev/null
+++ b/drivers/rtc/rtc-fsl-ftm-alarm.c
@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Freescale FlexTimer Module (FTM) alarm device driver.
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2019 NXP
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/module.h>
+#include <linux/fsl/ftm.h>
+#include <linux/rtc.h>
+#include <linux/time.h>
+
+#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_MASK_SHIFT)
+
+/*
+ * Select Fixed frequency clock (32KHz) as clock source
+ * of FlexTimer Module
+ */
+#define FTM_SC_CLKS_FIXED_FREQ 0x02
+#define FIXED_FREQ_CLK 32000
+
+/* Select 128 (2^7) as divider factor */
+#define MAX_FREQ_DIV (1 << FTM_SC_PS_MASK)
+
+/* Maximum counter value in FlexTimer's CNT registers */
+#define MAX_COUNT_VAL 0xffff
+
+struct ftm_rtc {
+ struct rtc_device *rtc_dev;
+ void __iomem *base;
+ bool big_endian;
+ u32 alarm_freq;
+};
+
+static inline u32 rtc_readl(struct ftm_rtc *dev, u32 reg)
+{
+ if (dev->big_endian)
+ return ioread32be(dev->base + reg);
+ else
+ return ioread32(dev->base + reg);
+}
+
+static inline void rtc_writel(struct ftm_rtc *dev, u32 reg, u32 val)
+{
+ if (dev->big_endian)
+ iowrite32be(val, dev->base + reg);
+ else
+ iowrite32(val, dev->base + reg);
+}
+
+static inline void ftm_counter_enable(struct ftm_rtc *rtc)
+{
+ u32 val;
+
+ /* select and enable counter clock source */
+ val = rtc_readl(rtc, FTM_SC);
+ val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+ val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
+ rtc_writel(rtc, FTM_SC, val);
+}
+
+static inline void ftm_counter_disable(struct ftm_rtc *rtc)
+{
+ u32 val;
+
+ /* disable counter clock source */
+ val = rtc_readl(rtc, FTM_SC);
+ val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+ rtc_writel(rtc, FTM_SC, val);
+}
+
+static inline void ftm_irq_acknowledge(struct ftm_rtc *rtc)
+{
+ unsigned int timeout = 100;
+
+ /*
+ *Fix errata A-007728 for flextimer
+ * If the FTM counter reaches the FTM_MOD value between
+ * the reading of the TOF bit and the writing of 0 to
+ * the TOF bit, the process of clearing the TOF bit
+ * does not work as expected when FTMx_CONF[NUMTOF] != 0
+ * and the current TOF count is less than FTMx_CONF[NUMTOF].
+ * If the above condition is met, the TOF bit remains set.
+ * If the TOF interrupt is enabled (FTMx_SC[TOIE] = 1),the
+ * TOF interrupt also remains asserted.
+ *
+ * Above is the errata discription
+ *
+ * In one word: software clearing TOF bit not works when
+ * FTMx_CONF[NUMTOF] was seted as nonzero and FTM counter
+ * reaches the FTM_MOD value.
+ *
+ * The workaround is clearing TOF bit until it works
+ * (FTM counter doesn't always reache the FTM_MOD anyway),
+ * which may cost some cycles.
+ */
+ while ((FTM_SC_TOF & rtc_readl(rtc, FTM_SC)) && timeout--)
+ rtc_writel(rtc, FTM_SC, rtc_readl(rtc, FTM_SC) & (~FTM_SC_TOF));
+}
+
+static inline void ftm_irq_enable(struct ftm_rtc *rtc)
+{
+ u32 val;
+
+ val = rtc_readl(rtc, FTM_SC);
+ val |= FTM_SC_TOIE;
+ rtc_writel(rtc, FTM_SC, val);
+}
+
+static inline void ftm_irq_disable(struct ftm_rtc *rtc)
+{
+ u32 val;
+
+ val = rtc_readl(rtc, FTM_SC);
+ val &= ~FTM_SC_TOIE;
+ rtc_writel(rtc, FTM_SC, val);
+}
+
+static inline void ftm_reset_counter(struct ftm_rtc *rtc)
+{
+ /*
+ * The CNT register contains the FTM counter value.
+ * Reset clears the CNT register. Writing any value to COUNT
+ * updates the counter with its initial value, CNTIN.
+ */
+ rtc_writel(rtc, FTM_CNT, 0x00);
+}
+
+static void ftm_clean_alarm(struct ftm_rtc *rtc)
+{
+ ftm_counter_disable(rtc);
+
+ rtc_writel(rtc, FTM_CNTIN, 0x00);
+ rtc_writel(rtc, FTM_MOD, ~0U);
+
+ ftm_reset_counter(rtc);
+}
+
+static irqreturn_t ftm_rtc_alarm_interrupt(int irq, void *dev)
+{
+ struct ftm_rtc *rtc = dev;
+
+ ftm_irq_acknowledge(rtc);
+ ftm_irq_disable(rtc);
+ ftm_clean_alarm(rtc);
+
+ return IRQ_HANDLED;
+}
+
+static int ftm_rtc_alarm_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ struct ftm_rtc *rtc = dev_get_drvdata(dev);
+
+ if (enabled)
+ ftm_irq_enable(rtc);
+ else
+ ftm_irq_disable(rtc);
+
+ return 0;
+}
+
+/*
+ * Note:
+ * The function is not really getting time from the RTC
+ * since FlexTimer is not a RTC device, but we need to
+ * get time to setup alarm, so we are using system time
+ * for now.
+ */
+static int ftm_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ rtc_time64_to_tm(ktime_get_real_seconds(), tm);
+
+ return 0;
+}
+
+static int ftm_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ return 0;
+}
+
+/*
+ * 1. Select fixed frequency clock (32KHz) as clock source;
+ * 2. Select 128 (2^7) as divider factor;
+ * So clock is 250 Hz (32KHz/128).
+ *
+ * 3. FlexTimer's CNT register is a 32bit register,
+ * but the register's 16 bit as counter value,it's other 16 bit
+ * is reserved.So minimum counter value is 0x0,maximum counter
+ * value is 0xffff.
+ * So max alarm value is 262 (65536 / 250) seconds
+ */
+static int ftm_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ time64_t alm_time;
+ unsigned long long cycle;
+ struct ftm_rtc *rtc = dev_get_drvdata(dev);
+
+ alm_time = rtc_tm_to_time64(&alm->time);
+
+ ftm_clean_alarm(rtc);
+ cycle = (alm_time - ktime_get_real_seconds()) * rtc->alarm_freq;
+ if (cycle > MAX_COUNT_VAL) {
+ pr_err("Out of alarm range {0~262} seconds.\n");
+ return -ERANGE;
+ }
+
+ ftm_irq_disable(rtc);
+
+ /*
+ * The counter increments until the value of MOD is reached,
+ * at which point the counter is reloaded with the value of CNTIN.
+ * The TOF (the overflow flag) bit is set when the FTM counter
+ * changes from MOD to CNTIN. So we should using the cycle - 1.
+ */
+ rtc_writel(rtc, FTM_MOD, cycle - 1);
+
+ ftm_counter_enable(rtc);
+ ftm_irq_enable(rtc);
+
+ return 0;
+
+}
+
+static const struct rtc_class_ops ftm_rtc_ops = {
+ .read_time = ftm_rtc_read_time,
+ .read_alarm = ftm_rtc_read_alarm,
+ .set_alarm = ftm_rtc_set_alarm,
+ .alarm_irq_enable = ftm_rtc_alarm_irq_enable,
+};
+
+static int ftm_rtc_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int irq;
+ int ret;
+ struct ftm_rtc *rtc;
+
+ rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
+ if (unlikely(!rtc)) {
+ dev_err(&pdev->dev, "cannot alloc memory for rtc\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, rtc);
+
+ rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(rtc->rtc_dev))
+ return PTR_ERR(rtc->rtc_dev);
+
+ rtc->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rtc->base)) {
+ dev_err(&pdev->dev, "cannot ioremap resource for rtc\n");
+ return PTR_ERR(rtc->base);
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq <= 0) {
+ dev_err(&pdev->dev, "unable to get IRQ from DT, %d\n", irq);
+ return -EINVAL;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq, ftm_rtc_alarm_interrupt,
+ IRQF_NO_SUSPEND, dev_name(&pdev->dev), rtc);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to request irq\n");
+ return ret;
+ }
+
+ rtc->big_endian = of_property_read_bool(np, "big-endian");
+ rtc->alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
+ rtc->rtc_dev->ops = &ftm_rtc_ops;
+
+ device_init_wakeup(&pdev->dev, true);
+
+ ret = rtc_register_device(rtc->rtc_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "can't register rtc device\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id ftm_rtc_match[] = {
+ { .compatible = "fsl,ls1012a-ftm-alarm", },
+ { .compatible = "fsl,ls1021a-ftm-alarm", },
+ { .compatible = "fsl,ls1028a-ftm-alarm", },
+ { .compatible = "fsl,ls1043a-ftm-alarm", },
+ { .compatible = "fsl,ls1046a-ftm-alarm", },
+ { .compatible = "fsl,ls1088a-ftm-alarm", },
+ { .compatible = "fsl,ls208xa-ftm-alarm", },
+ { .compatible = "fsl,lx2160a-ftm-alarm", },
+ { },
+};
+
+static struct platform_driver ftm_rtc_driver = {
+ .probe = ftm_rtc_probe,
+ .driver = {
+ .name = "ftm-alarm",
+ .of_match_table = ftm_rtc_match,
+ },
+};
+
+static int __init ftm_alarm_init(void)
+{
+ return platform_driver_register(&ftm_rtc_driver);
+}
+
+device_initcall(ftm_alarm_init);
+
+MODULE_DESCRIPTION("NXP/Freescale FlexTimer alarm driver");
+MODULE_AUTHOR("Biwen Li <biwen.li@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c
index 1a3420ee6a4d..cb6b0ad7ec3f 100644
--- a/drivers/rtc/rtc-goldfish.c
+++ b/drivers/rtc/rtc-goldfish.c
@@ -165,7 +165,6 @@ static const struct rtc_class_ops goldfish_rtc_ops = {
static int goldfish_rtc_probe(struct platform_device *pdev)
{
struct goldfish_rtc *rtcdrv;
- struct resource *r;
int err;
rtcdrv = devm_kzalloc(&pdev->dev, sizeof(*rtcdrv), GFP_KERNEL);
@@ -173,12 +172,7 @@ static int goldfish_rtc_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, rtcdrv);
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r)
- return -ENODEV;
-
- rtcdrv->base = devm_ioremap_resource(&pdev->dev, r);
+ rtcdrv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtcdrv->base))
return -ENODEV;
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c
index 443f6d05ce29..0fb79c4afb46 100644
--- a/drivers/rtc/rtc-hym8563.c
+++ b/drivers/rtc/rtc-hym8563.c
@@ -78,7 +78,6 @@
struct hym8563 {
struct i2c_client *client;
struct rtc_device *rtc;
- bool valid;
#ifdef CONFIG_COMMON_CLK
struct clk_hw clkout_hw;
#endif
@@ -91,19 +90,19 @@ struct hym8563 {
static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
- struct hym8563 *hym8563 = i2c_get_clientdata(client);
u8 buf[7];
int ret;
- if (!hym8563->valid) {
- dev_warn(&client->dev, "no valid clock/calendar values available\n");
- return -EPERM;
- }
-
ret = i2c_smbus_read_i2c_block_data(client, HYM8563_SEC, 7, buf);
if (ret < 0)
return ret;
+ if (buf[0] & HYM8563_SEC_VL) {
+ dev_warn(&client->dev,
+ "no valid clock/calendar values available\n");
+ return -EINVAL;
+ }
+
tm->tm_sec = bcd2bin(buf[0] & HYM8563_SEC_MASK);
tm->tm_min = bcd2bin(buf[1] & HYM8563_MIN_MASK);
tm->tm_hour = bcd2bin(buf[2] & HYM8563_HOUR_MASK);
@@ -118,7 +117,6 @@ static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
- struct hym8563 *hym8563 = i2c_get_clientdata(client);
u8 buf[7];
int ret;
@@ -157,8 +155,6 @@ static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
if (ret < 0)
return ret;
- hym8563->valid = true;
-
return 0;
}
@@ -556,9 +552,8 @@ static int hym8563_probe(struct i2c_client *client,
if (ret < 0)
return ret;
- hym8563->valid = !(ret & HYM8563_SEC_VL);
dev_dbg(&client->dev, "rtc information is %s\n",
- hym8563->valid ? "valid" : "invalid");
+ (ret & HYM8563_SEC_VL) ? "invalid" : "valid");
hym8563->rtc = devm_rtc_device_register(&client->dev, client->name,
&hym8563_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-imx-sc.c b/drivers/rtc/rtc-imx-sc.c
index c933045fe04b..cf2c12107f2b 100644
--- a/drivers/rtc/rtc-imx-sc.c
+++ b/drivers/rtc/rtc-imx-sc.c
@@ -167,10 +167,8 @@ static int imx_sc_rtc_probe(struct platform_device *pdev)
imx_sc_rtc->range_max = U32_MAX;
ret = rtc_register_device(imx_sc_rtc);
- if (ret) {
- dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
+ if (ret)
return ret;
- }
imx_scu_irq_register_notifier(&imx_sc_rtc_alarm_sc_notifier);
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c
index 3f3d652a0b0f..f21dc6b16d88 100644
--- a/drivers/rtc/rtc-imxdi.c
+++ b/drivers/rtc/rtc-imxdi.c
@@ -740,7 +740,6 @@ static void dryice_work(struct work_struct *work)
*/
static int __init dryice_rtc_probe(struct platform_device *pdev)
{
- struct resource *res;
struct imxdi_dev *imxdi;
int norm_irq, sec_irq;
int rc;
@@ -751,8 +750,7 @@ static int __init dryice_rtc_probe(struct platform_device *pdev)
imxdi->pdev = pdev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- imxdi->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ imxdi->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(imxdi->ioaddr))
return PTR_ERR(imxdi->ioaddr);
diff --git a/drivers/rtc/rtc-isl12026.c b/drivers/rtc/rtc-isl12026.c
index 97f594f9667c..5b6b17fb6d62 100644
--- a/drivers/rtc/rtc-isl12026.c
+++ b/drivers/rtc/rtc-isl12026.c
@@ -454,9 +454,9 @@ static int isl12026_probe_new(struct i2c_client *client)
isl12026_force_power_modes(client);
- priv->nvm_client = i2c_new_dummy(client->adapter, ISL12026_EEPROM_ADDR);
- if (!priv->nvm_client)
- return -ENOMEM;
+ priv->nvm_client = i2c_new_dummy_device(client->adapter, ISL12026_EEPROM_ADDR);
+ if (IS_ERR(priv->nvm_client))
+ return PTR_ERR(priv->nvm_client);
priv->rtc = devm_rtc_allocate_device(&client->dev);
ret = PTR_ERR_OR_ZERO(priv->rtc);
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c
index 9e7b3a04debc..18023e472cbc 100644
--- a/drivers/rtc/rtc-jz4740.c
+++ b/drivers/rtc/rtc-jz4740.c
@@ -307,7 +307,6 @@ static int jz4740_rtc_probe(struct platform_device *pdev)
{
int ret;
struct jz4740_rtc *rtc;
- struct resource *mem;
const struct platform_device_id *id = platform_get_device_id(pdev);
const struct of_device_id *of_id = of_match_device(
jz4740_rtc_of_match, &pdev->dev);
@@ -323,13 +322,10 @@ static int jz4740_rtc_probe(struct platform_device *pdev)
rtc->type = id->driver_data;
rtc->irq = platform_get_irq(pdev, 0);
- if (rtc->irq < 0) {
- dev_err(&pdev->dev, "Failed to get platform irq\n");
+ if (rtc->irq < 0)
return -ENOENT;
- }
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtc->base = devm_ioremap_resource(&pdev->dev, mem);
+ rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base))
return PTR_ERR(rtc->base);
@@ -362,10 +358,8 @@ static int jz4740_rtc_probe(struct platform_device *pdev)
rtc->rtc->range_max = U32_MAX;
ret = rtc_register_device(rtc->rtc);
- if (ret) {
- dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret);
+ if (ret)
return ret;
- }
ret = devm_request_irq(&pdev->dev, rtc->irq, jz4740_rtc_irq, 0,
pdev->name, rtc);
diff --git a/drivers/rtc/rtc-lpc24xx.c b/drivers/rtc/rtc-lpc24xx.c
index a8bb15606ec8..00ef16ba9480 100644
--- a/drivers/rtc/rtc-lpc24xx.c
+++ b/drivers/rtc/rtc-lpc24xx.c
@@ -194,15 +194,13 @@ static const struct rtc_class_ops lpc24xx_rtc_ops = {
static int lpc24xx_rtc_probe(struct platform_device *pdev)
{
struct lpc24xx_rtc *rtc;
- struct resource *res;
int irq, ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtc->rtc_base = devm_ioremap_resource(&pdev->dev, res);
+ rtc->rtc_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->rtc_base))
return PTR_ERR(rtc->rtc_base);
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c
index ac393230e592..15d8abda81fe 100644
--- a/drivers/rtc/rtc-lpc32xx.c
+++ b/drivers/rtc/rtc-lpc32xx.c
@@ -185,7 +185,6 @@ static const struct rtc_class_ops lpc32xx_rtc_ops = {
static int lpc32xx_rtc_probe(struct platform_device *pdev)
{
- struct resource *res;
struct lpc32xx_rtc *rtc;
int err;
u32 tmp;
@@ -194,8 +193,7 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev)
if (unlikely(!rtc))
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtc->rtc_base = devm_ioremap_resource(&pdev->dev, res);
+ rtc->rtc_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->rtc_base))
return PTR_ERR(rtc->rtc_base);
@@ -266,16 +264,6 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev)
return 0;
}
-static int lpc32xx_rtc_remove(struct platform_device *pdev)
-{
- struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
-
- if (rtc->irq >= 0)
- device_init_wakeup(&pdev->dev, 0);
-
- return 0;
-}
-
#ifdef CONFIG_PM
static int lpc32xx_rtc_suspend(struct device *dev)
{
@@ -357,7 +345,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_rtc_match);
static struct platform_driver lpc32xx_rtc_driver = {
.probe = lpc32xx_rtc_probe,
- .remove = lpc32xx_rtc_remove,
.driver = {
.name = "rtc-lpc32xx",
.pm = LPC32XX_RTC_PM_OPS,
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 5f46f85f814b..9b70b371bd0c 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -235,9 +235,6 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
unsigned char buf[8];
int err, flags;
- if (tm->tm_year < 100 || tm->tm_year > 199)
- return -EINVAL;
-
buf[M41T80_REG_SSEC] = 0;
buf[M41T80_REG_SEC] = bin2bcd(tm->tm_sec);
buf[M41T80_REG_MIN] = bin2bcd(tm->tm_min);
@@ -705,7 +702,6 @@ static ssize_t wdt_read(struct file *file, char __user *buf,
/**
* wdt_ioctl:
- * @inode: inode of the device
* @file: file handle to the device
* @cmd: watchdog command
* @arg: argument pointer
@@ -840,6 +836,7 @@ static const struct file_operations wdt_fops = {
.owner = THIS_MODULE,
.read = wdt_read,
.unlocked_ioctl = wdt_unlocked_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
.write = wdt_write,
.open = wdt_open,
.release = wdt_release,
@@ -925,6 +922,8 @@ static int m41t80_probe(struct i2c_client *client,
}
m41t80_data->rtc->ops = &m41t80_rtc_ops;
+ m41t80_data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ m41t80_data->rtc->range_max = RTC_TIMESTAMP_END_2099;
if (client->irq <= 0) {
/* We cannot support UIE mode if we do not have an IRQ line */
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
index d3a75d447fce..e8194f1f01a8 100644
--- a/drivers/rtc/rtc-m48t35.c
+++ b/drivers/rtc/rtc-m48t35.c
@@ -20,6 +20,16 @@
struct m48t35_rtc {
u8 pad[0x7ff8]; /* starts at 0x7ff8 */
+#ifdef CONFIG_SGI_IP27
+ u8 hour;
+ u8 min;
+ u8 sec;
+ u8 control;
+ u8 year;
+ u8 month;
+ u8 date;
+ u8 day;
+#else
u8 control;
u8 sec;
u8 min;
@@ -28,6 +38,7 @@ struct m48t35_rtc {
u8 date;
u8 month;
u8 year;
+#endif
};
#define M48T35_RTC_SET 0x80
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index 59b54ed9b841..75a0e73071d8 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -218,7 +218,6 @@ static bool m48t86_verify_chip(struct platform_device *pdev)
static int m48t86_rtc_probe(struct platform_device *pdev)
{
struct m48t86_rtc_info *info;
- struct resource *res;
unsigned char reg;
int err;
struct nvmem_config m48t86_nvmem_cfg = {
@@ -235,17 +234,11 @@ static int m48t86_rtc_probe(struct platform_device *pdev)
if (!info)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENODEV;
- info->index_reg = devm_ioremap_resource(&pdev->dev, res);
+ info->index_reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(info->index_reg))
return PTR_ERR(info->index_reg);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res)
- return -ENODEV;
- info->data_reg = devm_ioremap_resource(&pdev->dev, res);
+ info->data_reg = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(info->data_reg))
return PTR_ERR(info->data_reg);
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 4aff349ae301..d5a0e27dd0a0 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -673,11 +673,8 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info)
struct platform_device *pdev = to_platform_device(info->dev);
info->rtc_irq = platform_get_irq(pdev, 0);
- if (info->rtc_irq < 0) {
- dev_err(info->dev, "Failed to get rtc interrupts: %d\n",
- info->rtc_irq);
+ if (info->rtc_irq < 0)
return info->rtc_irq;
- }
} else {
info->rtc_irq = parent_i2c->irq;
}
@@ -693,11 +690,11 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info)
goto add_rtc_irq;
}
- info->rtc = i2c_new_dummy(parent_i2c->adapter,
- info->drv_data->rtc_i2c_addr);
- if (!info->rtc) {
+ info->rtc = devm_i2c_new_dummy_device(info->dev, parent_i2c->adapter,
+ info->drv_data->rtc_i2c_addr);
+ if (IS_ERR(info->rtc)) {
dev_err(info->dev, "Failed to allocate I2C device for RTC\n");
- return -ENODEV;
+ return PTR_ERR(info->rtc);
}
info->rtc_regmap = devm_regmap_init_i2c(info->rtc,
@@ -705,7 +702,7 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info)
if (IS_ERR(info->rtc_regmap)) {
ret = PTR_ERR(info->rtc_regmap);
dev_err(info->dev, "Failed to allocate RTC regmap: %d\n", ret);
- goto err_unregister_i2c;
+ return ret;
}
add_rtc_irq:
@@ -715,15 +712,10 @@ add_rtc_irq:
&info->rtc_irq_data);
if (ret < 0) {
dev_err(info->dev, "Failed to add RTC irq chip: %d\n", ret);
- goto err_unregister_i2c;
+ return ret;
}
return 0;
-
-err_unregister_i2c:
- if (info->rtc)
- i2c_unregister_device(info->rtc);
- return ret;
}
static int max77686_rtc_probe(struct platform_device *pdev)
@@ -786,8 +778,6 @@ static int max77686_rtc_probe(struct platform_device *pdev)
err_rtc:
regmap_del_irq_chip(info->rtc_irq, info->rtc_irq_data);
- if (info->rtc)
- i2c_unregister_device(info->rtc);
return ret;
}
@@ -798,8 +788,6 @@ static int max77686_rtc_remove(struct platform_device *pdev)
free_irq(info->virq, info);
regmap_del_irq_chip(info->rtc_irq, info->rtc_irq_data);
- if (info->rtc)
- i2c_unregister_device(info->rtc);
return 0;
}
diff --git a/drivers/rtc/rtc-meson-vrtc.c b/drivers/rtc/rtc-meson-vrtc.c
new file mode 100644
index 000000000000..89e5ba0dae69
--- /dev/null
+++ b/drivers/rtc/rtc-meson-vrtc.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/time64.h>
+
+struct meson_vrtc_data {
+ void __iomem *io_alarm;
+ struct rtc_device *rtc;
+ unsigned long alarm_time;
+ bool enabled;
+};
+
+static int meson_vrtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct timespec64 time;
+
+ dev_dbg(dev, "%s\n", __func__);
+ ktime_get_raw_ts64(&time);
+ rtc_time64_to_tm(time.tv_sec, tm);
+
+ return 0;
+}
+
+static void meson_vrtc_set_wakeup_time(struct meson_vrtc_data *vrtc,
+ unsigned long time)
+{
+ writel_relaxed(time, vrtc->io_alarm);
+}
+
+static int meson_vrtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct meson_vrtc_data *vrtc = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "%s: alarm->enabled=%d\n", __func__, alarm->enabled);
+ if (alarm->enabled)
+ vrtc->alarm_time = rtc_tm_to_time64(&alarm->time);
+ else
+ vrtc->alarm_time = 0;
+
+ return 0;
+}
+
+static int meson_vrtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct meson_vrtc_data *vrtc = dev_get_drvdata(dev);
+
+ vrtc->enabled = enabled;
+ return 0;
+}
+
+static const struct rtc_class_ops meson_vrtc_ops = {
+ .read_time = meson_vrtc_read_time,
+ .set_alarm = meson_vrtc_set_alarm,
+ .alarm_irq_enable = meson_vrtc_alarm_irq_enable,
+};
+
+static int meson_vrtc_probe(struct platform_device *pdev)
+{
+ struct meson_vrtc_data *vrtc;
+ int ret;
+
+ vrtc = devm_kzalloc(&pdev->dev, sizeof(*vrtc), GFP_KERNEL);
+ if (!vrtc)
+ return -ENOMEM;
+
+ vrtc->io_alarm = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(vrtc->io_alarm))
+ return PTR_ERR(vrtc->io_alarm);
+
+ device_init_wakeup(&pdev->dev, 1);
+
+ platform_set_drvdata(pdev, vrtc);
+
+ vrtc->rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(vrtc->rtc))
+ return PTR_ERR(vrtc->rtc);
+
+ vrtc->rtc->ops = &meson_vrtc_ops;
+ ret = rtc_register_device(vrtc->rtc);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int __maybe_unused meson_vrtc_suspend(struct device *dev)
+{
+ struct meson_vrtc_data *vrtc = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "%s\n", __func__);
+ if (vrtc->alarm_time) {
+ unsigned long local_time;
+ long alarm_secs;
+ struct timespec64 time;
+
+ ktime_get_raw_ts64(&time);
+ local_time = time.tv_sec;
+
+ dev_dbg(dev, "alarm_time = %lus, local_time=%lus\n",
+ vrtc->alarm_time, local_time);
+ alarm_secs = vrtc->alarm_time - local_time;
+ if (alarm_secs > 0) {
+ meson_vrtc_set_wakeup_time(vrtc, alarm_secs);
+ dev_dbg(dev, "system will wakeup in %lds.\n",
+ alarm_secs);
+ } else {
+ dev_err(dev, "alarm time already passed: %lds.\n",
+ alarm_secs);
+ }
+ }
+
+ return 0;
+}
+
+static int __maybe_unused meson_vrtc_resume(struct device *dev)
+{
+ struct meson_vrtc_data *vrtc = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ vrtc->alarm_time = 0;
+ meson_vrtc_set_wakeup_time(vrtc, 0);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(meson_vrtc_pm_ops,
+ meson_vrtc_suspend, meson_vrtc_resume);
+
+static const struct of_device_id meson_vrtc_dt_match[] = {
+ { .compatible = "amlogic,meson-vrtc"},
+ {},
+};
+MODULE_DEVICE_TABLE(of, meson_vrtc_dt_match);
+
+static struct platform_driver meson_vrtc_driver = {
+ .probe = meson_vrtc_probe,
+ .driver = {
+ .name = "meson-vrtc",
+ .of_match_table = meson_vrtc_dt_match,
+ .pm = &meson_vrtc_pm_ops,
+ },
+};
+
+module_platform_driver(meson_vrtc_driver);
+
+MODULE_DESCRIPTION("Amlogic Virtual Wakeup RTC Timer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-meson.c b/drivers/rtc/rtc-meson.c
index e08b981dfc21..47ebcf834cc2 100644
--- a/drivers/rtc/rtc-meson.c
+++ b/drivers/rtc/rtc-meson.c
@@ -131,7 +131,7 @@ static u32 meson_rtc_get_data(struct meson_rtc *rtc)
static int meson_rtc_get_bus(struct meson_rtc *rtc)
{
- int ret, retries = 3;
+ int ret, retries;
u32 val;
/* prepare bus for transfers, set all lines low */
@@ -292,7 +292,6 @@ static int meson_rtc_probe(struct platform_device *pdev)
};
struct device *dev = &pdev->dev;
struct meson_rtc *rtc;
- struct resource *res;
void __iomem *base;
int ret;
u32 tm;
@@ -312,8 +311,7 @@ static int meson_rtc_probe(struct platform_device *pdev)
rtc->rtc->ops = &meson_rtc_ops;
rtc->rtc->range_max = U32_MAX;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(dev, res);
+ base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
diff --git a/drivers/rtc/rtc-moxart.c b/drivers/rtc/rtc-moxart.c
index 07b30a373a92..6b24ac9e1cfa 100644
--- a/drivers/rtc/rtc-moxart.c
+++ b/drivers/rtc/rtc-moxart.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* MOXA ART RTC driver.
*
@@ -7,10 +8,6 @@
*
* Based on code from
* Moxa Technology Co., Ltd. <www.moxa.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <linux/init.h>
diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c
index 1c2d3c4a4963..80e364baac53 100644
--- a/drivers/rtc/rtc-msm6242.c
+++ b/drivers/rtc/rtc-msm6242.c
@@ -88,28 +88,16 @@ static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val,
__raw_writel(val, &priv->regs[reg]);
}
-static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val,
- unsigned int reg)
-{
- msm6242_write(priv, msm6242_read(priv, reg) | val, reg);
-}
-
-static inline void msm6242_clear(struct msm6242_priv *priv, unsigned int val,
- unsigned int reg)
-{
- msm6242_write(priv, msm6242_read(priv, reg) & ~val, reg);
-}
-
static void msm6242_lock(struct msm6242_priv *priv)
{
int cnt = 5;
- msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
+ msm6242_write(priv, MSM6242_CD_HOLD|MSM6242_CD_IRQ_FLAG, MSM6242_CD);
while ((msm6242_read(priv, MSM6242_CD) & MSM6242_CD_BUSY) && cnt) {
- msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
+ msm6242_write(priv, MSM6242_CD_IRQ_FLAG, MSM6242_CD);
udelay(70);
- msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
+ msm6242_write(priv, MSM6242_CD_HOLD|MSM6242_CD_IRQ_FLAG, MSM6242_CD);
cnt--;
}
@@ -120,7 +108,7 @@ static void msm6242_lock(struct msm6242_priv *priv)
static void msm6242_unlock(struct msm6242_priv *priv)
{
- msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
+ msm6242_write(priv, MSM6242_CD_IRQ_FLAG, MSM6242_CD);
}
static int msm6242_read_time(struct device *dev, struct rtc_time *tm)
@@ -133,7 +121,8 @@ static int msm6242_read_time(struct device *dev, struct rtc_time *tm)
msm6242_read(priv, MSM6242_SECOND1);
tm->tm_min = msm6242_read(priv, MSM6242_MINUTE10) * 10 +
msm6242_read(priv, MSM6242_MINUTE1);
- tm->tm_hour = (msm6242_read(priv, MSM6242_HOUR10 & 3)) * 10 +
+ tm->tm_hour = (msm6242_read(priv, MSM6242_HOUR10) &
+ MSM6242_HOUR10_HR_MASK) * 10 +
msm6242_read(priv, MSM6242_HOUR1);
tm->tm_mday = msm6242_read(priv, MSM6242_DAY10) * 10 +
msm6242_read(priv, MSM6242_DAY1);
diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
index b46ed4dc7015..cda238dfe69b 100644
--- a/drivers/rtc/rtc-mt6397.c
+++ b/drivers/rtc/rtc-mt6397.c
@@ -4,69 +4,19 @@
* Author: Tianping.Fang <tianping.fang@mediatek.com>
*/
-#include <linux/delay.h>
-#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/mt6397/core.h>
#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
-#include <linux/irqdomain.h>
-#include <linux/platform_device.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/io.h>
-#include <linux/mfd/mt6397/core.h>
-
-#define RTC_BBPU 0x0000
-#define RTC_BBPU_CBUSY BIT(6)
-
-#define RTC_WRTGR 0x003c
-
-#define RTC_IRQ_STA 0x0002
-#define RTC_IRQ_STA_AL BIT(0)
-#define RTC_IRQ_STA_LP BIT(3)
-
-#define RTC_IRQ_EN 0x0004
-#define RTC_IRQ_EN_AL BIT(0)
-#define RTC_IRQ_EN_ONESHOT BIT(2)
-#define RTC_IRQ_EN_LP BIT(3)
-#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL)
-
-#define RTC_AL_MASK 0x0008
-#define RTC_AL_MASK_DOW BIT(4)
-
-#define RTC_TC_SEC 0x000a
-/* Min, Hour, Dom... register offset to RTC_TC_SEC */
-#define RTC_OFFSET_SEC 0
-#define RTC_OFFSET_MIN 1
-#define RTC_OFFSET_HOUR 2
-#define RTC_OFFSET_DOM 3
-#define RTC_OFFSET_DOW 4
-#define RTC_OFFSET_MTH 5
-#define RTC_OFFSET_YEAR 6
-#define RTC_OFFSET_COUNT 7
-
-#define RTC_AL_SEC 0x0018
-
-#define RTC_PDN2 0x002e
-#define RTC_PDN2_PWRON_ALARM BIT(4)
-
-#define RTC_MIN_YEAR 1968
-#define RTC_BASE_YEAR 1900
-#define RTC_NUM_YEARS 128
-#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR)
-
-struct mt6397_rtc {
- struct device *dev;
- struct rtc_device *rtc_dev;
- struct mutex lock;
- struct regmap *regmap;
- int irq;
- u32 addr_base;
-};
+#include <linux/mfd/mt6397/rtc.h>
+#include <linux/mod_devicetable.h>
static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
{
- unsigned long timeout = jiffies + HZ;
int ret;
u32 data;
@@ -74,19 +24,13 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
if (ret < 0)
return ret;
- while (1) {
- ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU,
- &data);
- if (ret < 0)
- break;
- if (!(data & RTC_BBPU_CBUSY))
- break;
- if (time_after(jiffies, timeout)) {
- ret = -ETIMEDOUT;
- break;
- }
- cpu_relax();
- }
+ ret = regmap_read_poll_timeout(rtc->regmap,
+ rtc->addr_base + RTC_BBPU, data,
+ !(data & RTC_BBPU_CBUSY),
+ MTK_RTC_POLL_DELAY_US,
+ MTK_RTC_POLL_TIMEOUT);
+ if (ret < 0)
+ dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret);
return ret;
}
@@ -103,7 +47,7 @@ static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data)
irqen = irqsta & ~RTC_IRQ_EN_AL;
mutex_lock(&rtc->lock);
if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN,
- irqen) < 0)
+ irqen) == 0)
mtk_rtc_write_trigger(rtc);
mutex_unlock(&rtc->lock);
@@ -225,12 +169,12 @@ static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM);
mutex_unlock(&rtc->lock);
- tm->tm_sec = data[RTC_OFFSET_SEC];
- tm->tm_min = data[RTC_OFFSET_MIN];
- tm->tm_hour = data[RTC_OFFSET_HOUR];
- tm->tm_mday = data[RTC_OFFSET_DOM];
- tm->tm_mon = data[RTC_OFFSET_MTH];
- tm->tm_year = data[RTC_OFFSET_YEAR];
+ tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK;
+ tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK;
+ tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK;
+ tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK;
+ tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK;
+ tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK;
tm->tm_year += RTC_MIN_YEAR_OFFSET;
tm->tm_mon--;
@@ -251,14 +195,25 @@ static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
tm->tm_year -= RTC_MIN_YEAR_OFFSET;
tm->tm_mon++;
- data[RTC_OFFSET_SEC] = tm->tm_sec;
- data[RTC_OFFSET_MIN] = tm->tm_min;
- data[RTC_OFFSET_HOUR] = tm->tm_hour;
- data[RTC_OFFSET_DOM] = tm->tm_mday;
- data[RTC_OFFSET_MTH] = tm->tm_mon;
- data[RTC_OFFSET_YEAR] = tm->tm_year;
-
mutex_lock(&rtc->lock);
+ ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC,
+ data, RTC_OFFSET_COUNT);
+ if (ret < 0)
+ goto exit;
+
+ data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) |
+ (tm->tm_sec & RTC_AL_SEC_MASK));
+ data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) |
+ (tm->tm_min & RTC_AL_MIN_MASK));
+ data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) |
+ (tm->tm_hour & RTC_AL_HOU_MASK));
+ data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) |
+ (tm->tm_mday & RTC_AL_DOM_MASK));
+ data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) |
+ (tm->tm_mon & RTC_AL_MTH_MASK));
+ data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) |
+ (tm->tm_year & RTC_AL_YEA_MASK));
+
if (alm->enabled) {
ret = regmap_bulk_write(rtc->regmap,
rtc->addr_base + RTC_AL_SEC,
@@ -319,19 +274,19 @@ static int mtk_rtc_probe(struct platform_device *pdev)
return rtc->irq;
rtc->regmap = mt6397_chip->regmap;
- rtc->dev = &pdev->dev;
mutex_init(&rtc->lock);
platform_set_drvdata(pdev, rtc);
- rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev);
+ rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc_dev))
return PTR_ERR(rtc->rtc_dev);
- ret = request_threaded_irq(rtc->irq, NULL,
- mtk_rtc_irq_handler_thread,
- IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
- "mt6397-rtc", rtc);
+ ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
+ mtk_rtc_irq_handler_thread,
+ IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+ "mt6397-rtc", rtc);
+
if (ret) {
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
rtc->irq, ret);
@@ -342,26 +297,7 @@ static int mtk_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev->ops = &mtk_rtc_ops;
- ret = rtc_register_device(rtc->rtc_dev);
- if (ret) {
- dev_err(&pdev->dev, "register rtc device failed\n");
- goto out_free_irq;
- }
-
- return 0;
-
-out_free_irq:
- free_irq(rtc->irq, rtc);
- return ret;
-}
-
-static int mtk_rtc_remove(struct platform_device *pdev)
-{
- struct mt6397_rtc *rtc = platform_get_drvdata(pdev);
-
- free_irq(rtc->irq, rtc);
-
- return 0;
+ return rtc_register_device(rtc->rtc_dev);
}
#ifdef CONFIG_PM_SLEEP
@@ -390,6 +326,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
mt6397_rtc_resume);
static const struct of_device_id mt6397_rtc_of_match[] = {
+ { .compatible = "mediatek,mt6323-rtc", },
{ .compatible = "mediatek,mt6397-rtc", },
{ }
};
@@ -402,7 +339,6 @@ static struct platform_driver mtk_rtc_driver = {
.pm = &mt6397_pm_ops,
},
.probe = mtk_rtc_probe,
- .remove = mtk_rtc_remove,
};
module_platform_driver(mtk_rtc_driver);
diff --git a/drivers/rtc/rtc-mt7622.c b/drivers/rtc/rtc-mt7622.c
index 82b0816ec6c1..f1e356394814 100644
--- a/drivers/rtc/rtc-mt7622.c
+++ b/drivers/rtc/rtc-mt7622.c
@@ -303,7 +303,6 @@ MODULE_DEVICE_TABLE(of, mtk_rtc_match);
static int mtk_rtc_probe(struct platform_device *pdev)
{
struct mtk_rtc *hw;
- struct resource *res;
int ret;
hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL);
@@ -312,8 +311,7 @@ static int mtk_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, hw);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- hw->base = devm_ioremap_resource(&pdev->dev, res);
+ hw->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(hw->base))
return PTR_ERR(hw->base);
@@ -329,7 +327,6 @@ static int mtk_rtc_probe(struct platform_device *pdev)
hw->irq = platform_get_irq(pdev, 0);
if (hw->irq < 0) {
- dev_err(&pdev->dev, "No IRQ resource\n");
ret = hw->irq;
goto err;
}
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index ab9db57a6834..d5f190e578e4 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -212,7 +212,6 @@ static const struct rtc_class_ops mv_rtc_alarm_ops = {
static int __init mv_rtc_probe(struct platform_device *pdev)
{
- struct resource *res;
struct rtc_plat_data *pdata;
u32 rtc_time;
int ret = 0;
@@ -221,8 +220,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->ioaddr))
return PTR_ERR(pdata->ioaddr);
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index e697e96612bb..902d57dcd0d4 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -184,8 +184,9 @@ static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit,
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
u32 reg;
+ unsigned long flags;
- spin_lock_irq(&pdata->rtc->irq_lock);
+ spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
reg = readw(ioaddr + RTC_RTCIENR);
if (enabled)
@@ -194,7 +195,7 @@ static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit,
reg &= ~bit;
writew(reg, ioaddr + RTC_RTCIENR);
- spin_unlock_irq(&pdata->rtc->irq_lock);
+ spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags);
}
/* This function is the RTC interrupt service routine. */
diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c
index 5b970a816631..91534560fe2a 100644
--- a/drivers/rtc/rtc-mxc_v2.c
+++ b/drivers/rtc/rtc-mxc_v2.c
@@ -279,7 +279,6 @@ static int mxc_rtc_wait_for_flag(void __iomem *ioaddr, int flag)
static int mxc_rtc_probe(struct platform_device *pdev)
{
struct mxc_rtc_data *pdata;
- struct resource *res;
void __iomem *ioaddr;
int ret = 0;
@@ -287,8 +286,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->ioaddr))
return PTR_ERR(pdata->ioaddr);
diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c
deleted file mode 100644
index 49cc4058614d..000000000000
--- a/drivers/rtc/rtc-nuc900.c
+++ /dev/null
@@ -1,271 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2008-2009 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/rtc.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/bcd.h>
-
-/* RTC Control Registers */
-#define REG_RTC_INIR 0x00
-#define REG_RTC_AER 0x04
-#define REG_RTC_FCR 0x08
-#define REG_RTC_TLR 0x0C
-#define REG_RTC_CLR 0x10
-#define REG_RTC_TSSR 0x14
-#define REG_RTC_DWR 0x18
-#define REG_RTC_TAR 0x1C
-#define REG_RTC_CAR 0x20
-#define REG_RTC_LIR 0x24
-#define REG_RTC_RIER 0x28
-#define REG_RTC_RIIR 0x2C
-#define REG_RTC_TTR 0x30
-
-#define RTCSET 0x01
-#define AERRWENB 0x10000
-#define INIRRESET 0xa5eb1357
-#define AERPOWERON 0xA965
-#define AERPOWEROFF 0x0000
-#define LEAPYEAR 0x0001
-#define TICKENB 0x80
-#define TICKINTENB 0x0002
-#define ALARMINTENB 0x0001
-#define MODE24 0x0001
-
-struct nuc900_rtc {
- int irq_num;
- void __iomem *rtc_reg;
- struct rtc_device *rtcdev;
-};
-
-struct nuc900_bcd_time {
- int bcd_sec;
- int bcd_min;
- int bcd_hour;
- int bcd_mday;
- int bcd_mon;
- int bcd_year;
-};
-
-static irqreturn_t nuc900_rtc_interrupt(int irq, void *_rtc)
-{
- struct nuc900_rtc *rtc = _rtc;
- unsigned long events = 0, rtc_irq;
-
- rtc_irq = __raw_readl(rtc->rtc_reg + REG_RTC_RIIR);
-
- if (rtc_irq & ALARMINTENB) {
- rtc_irq &= ~ALARMINTENB;
- __raw_writel(rtc_irq, rtc->rtc_reg + REG_RTC_RIIR);
- events |= RTC_AF | RTC_IRQF;
- }
-
- if (rtc_irq & TICKINTENB) {
- rtc_irq &= ~TICKINTENB;
- __raw_writel(rtc_irq, rtc->rtc_reg + REG_RTC_RIIR);
- events |= RTC_UF | RTC_IRQF;
- }
-
- rtc_update_irq(rtc->rtcdev, 1, events);
-
- return IRQ_HANDLED;
-}
-
-static int *check_rtc_access_enable(struct nuc900_rtc *nuc900_rtc)
-{
- unsigned int timeout = 0x1000;
- __raw_writel(INIRRESET, nuc900_rtc->rtc_reg + REG_RTC_INIR);
-
- mdelay(10);
-
- __raw_writel(AERPOWERON, nuc900_rtc->rtc_reg + REG_RTC_AER);
-
- while (!(__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_AER) & AERRWENB)
- && --timeout)
- mdelay(1);
-
- if (!timeout)
- return ERR_PTR(-EPERM);
-
- return NULL;
-}
-
-static void nuc900_rtc_bcd2bin(unsigned int timereg,
- unsigned int calreg, struct rtc_time *tm)
-{
- tm->tm_mday = bcd2bin(calreg >> 0);
- tm->tm_mon = bcd2bin(calreg >> 8);
- tm->tm_year = bcd2bin(calreg >> 16) + 100;
-
- tm->tm_sec = bcd2bin(timereg >> 0);
- tm->tm_min = bcd2bin(timereg >> 8);
- tm->tm_hour = bcd2bin(timereg >> 16);
-}
-
-static void nuc900_rtc_bin2bcd(struct device *dev, struct rtc_time *settm,
- struct nuc900_bcd_time *gettm)
-{
- gettm->bcd_mday = bin2bcd(settm->tm_mday) << 0;
- gettm->bcd_mon = bin2bcd(settm->tm_mon) << 8;
-
- if (settm->tm_year < 100) {
- dev_warn(dev, "The year will be between 1970-1999, right?\n");
- gettm->bcd_year = bin2bcd(settm->tm_year) << 16;
- } else {
- gettm->bcd_year = bin2bcd(settm->tm_year - 100) << 16;
- }
-
- gettm->bcd_sec = bin2bcd(settm->tm_sec) << 0;
- gettm->bcd_min = bin2bcd(settm->tm_min) << 8;
- gettm->bcd_hour = bin2bcd(settm->tm_hour) << 16;
-}
-
-static int nuc900_alarm_irq_enable(struct device *dev, unsigned int enabled)
-{
- struct nuc900_rtc *rtc = dev_get_drvdata(dev);
-
- if (enabled)
- __raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)|
- (ALARMINTENB), rtc->rtc_reg + REG_RTC_RIER);
- else
- __raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)&
- (~ALARMINTENB), rtc->rtc_reg + REG_RTC_RIER);
-
- return 0;
-}
-
-static int nuc900_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- struct nuc900_rtc *rtc = dev_get_drvdata(dev);
- unsigned int timeval, clrval;
-
- timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TLR);
- clrval = __raw_readl(rtc->rtc_reg + REG_RTC_CLR);
-
- nuc900_rtc_bcd2bin(timeval, clrval, tm);
-
- return 0;
-}
-
-static int nuc900_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- struct nuc900_rtc *rtc = dev_get_drvdata(dev);
- struct nuc900_bcd_time gettm;
- unsigned long val;
- int *err;
-
- nuc900_rtc_bin2bcd(dev, tm, &gettm);
-
- err = check_rtc_access_enable(rtc);
- if (IS_ERR(err))
- return PTR_ERR(err);
-
- val = gettm.bcd_mday | gettm.bcd_mon | gettm.bcd_year;
- __raw_writel(val, rtc->rtc_reg + REG_RTC_CLR);
-
- val = gettm.bcd_sec | gettm.bcd_min | gettm.bcd_hour;
- __raw_writel(val, rtc->rtc_reg + REG_RTC_TLR);
-
- return 0;
-}
-
-static int nuc900_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct nuc900_rtc *rtc = dev_get_drvdata(dev);
- unsigned int timeval, carval;
-
- timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TAR);
- carval = __raw_readl(rtc->rtc_reg + REG_RTC_CAR);
-
- nuc900_rtc_bcd2bin(timeval, carval, &alrm->time);
-
- return rtc_valid_tm(&alrm->time);
-}
-
-static int nuc900_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct nuc900_rtc *rtc = dev_get_drvdata(dev);
- struct nuc900_bcd_time tm;
- unsigned long val;
- int *err;
-
- nuc900_rtc_bin2bcd(dev, &alrm->time, &tm);
-
- err = check_rtc_access_enable(rtc);
- if (IS_ERR(err))
- return PTR_ERR(err);
-
- val = tm.bcd_mday | tm.bcd_mon | tm.bcd_year;
- __raw_writel(val, rtc->rtc_reg + REG_RTC_CAR);
-
- val = tm.bcd_sec | tm.bcd_min | tm.bcd_hour;
- __raw_writel(val, rtc->rtc_reg + REG_RTC_TAR);
-
- return 0;
-}
-
-static const struct rtc_class_ops nuc900_rtc_ops = {
- .read_time = nuc900_rtc_read_time,
- .set_time = nuc900_rtc_set_time,
- .read_alarm = nuc900_rtc_read_alarm,
- .set_alarm = nuc900_rtc_set_alarm,
- .alarm_irq_enable = nuc900_alarm_irq_enable,
-};
-
-static int __init nuc900_rtc_probe(struct platform_device *pdev)
-{
- struct resource *res;
- struct nuc900_rtc *nuc900_rtc;
-
- nuc900_rtc = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_rtc),
- GFP_KERNEL);
- if (!nuc900_rtc)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- nuc900_rtc->rtc_reg = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(nuc900_rtc->rtc_reg))
- return PTR_ERR(nuc900_rtc->rtc_reg);
-
- platform_set_drvdata(pdev, nuc900_rtc);
-
- nuc900_rtc->rtcdev = devm_rtc_device_register(&pdev->dev, pdev->name,
- &nuc900_rtc_ops, THIS_MODULE);
- if (IS_ERR(nuc900_rtc->rtcdev)) {
- dev_err(&pdev->dev, "rtc device register failed\n");
- return PTR_ERR(nuc900_rtc->rtcdev);
- }
-
- __raw_writel(__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_TSSR) | MODE24,
- nuc900_rtc->rtc_reg + REG_RTC_TSSR);
-
- nuc900_rtc->irq_num = platform_get_irq(pdev, 0);
- if (devm_request_irq(&pdev->dev, nuc900_rtc->irq_num,
- nuc900_rtc_interrupt, 0, "nuc900rtc", nuc900_rtc)) {
- dev_err(&pdev->dev, "NUC900 RTC request irq failed\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static struct platform_driver nuc900_rtc_driver = {
- .driver = {
- .name = "nuc900-rtc",
- },
-};
-
-module_platform_driver_probe(nuc900_rtc_driver, nuc900_rtc_probe);
-
-MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
-MODULE_DESCRIPTION("nuc910/nuc920 RTC driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:nuc900-rtc");
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index a2941c875a06..d4ed20fb3194 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -616,7 +616,7 @@ static int rtc_pinconf_get(struct pinctrl_dev *pctldev,
break;
default:
return -ENOTSUPP;
- };
+ }
*config = pinconf_to_config_packed(param, arg);
@@ -727,7 +727,6 @@ static struct nvmem_config omap_rtc_nvmem_config = {
static int omap_rtc_probe(struct platform_device *pdev)
{
struct omap_rtc *rtc;
- struct resource *res;
u8 reg, mask, new_ctrl;
const struct platform_device_id *id_entry;
const struct of_device_id *of_id;
@@ -764,8 +763,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
if (!IS_ERR(rtc->clk))
clk_prepare_enable(rtc->clk);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtc->base = devm_ioremap_resource(&pdev->dev, res);
+ rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base)) {
clk_disable_unprepare(rtc->clk);
return PTR_ERR(rtc->base);
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
index fb542a930bf0..c3691fa4210e 100644
--- a/drivers/rtc/rtc-pcf2123.c
+++ b/drivers/rtc/rtc-pcf2123.c
@@ -82,7 +82,7 @@
#define OSC_HAS_STOPPED BIT(7) /* Clock has been stopped */
/* PCF2123_REG_ALRM_XX BITS */
-#define ALRM_ENABLE BIT(7) /* MN, HR, DM, or DW alarm enable */
+#define ALRM_DISABLE BIT(7) /* MN, HR, DM, or DW alarm matching */
/* PCF2123_REG_TMR_CLKOUT BITS */
#define CD_TMR_4096KHZ (0) /* 4096 KHz countdown timer */
@@ -104,7 +104,7 @@
static struct spi_driver pcf2123_driver;
-struct pcf2123_plat_data {
+struct pcf2123_data {
struct rtc_device *rtc;
struct regmap *map;
};
@@ -119,11 +119,11 @@ static const struct regmap_config pcf2123_regmap_config = {
static int pcf2123_read_offset(struct device *dev, long *offset)
{
- struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
+ struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
int ret, val;
unsigned int reg;
- ret = regmap_read(pdata->map, PCF2123_REG_OFFSET, &reg);
+ ret = regmap_read(pcf2123->map, PCF2123_REG_OFFSET, &reg);
if (ret)
return ret;
@@ -149,7 +149,7 @@ static int pcf2123_read_offset(struct device *dev, long *offset)
*/
static int pcf2123_set_offset(struct device *dev, long offset)
{
- struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
+ struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
s8 reg;
if (offset > OFFSET_STEP * 127)
@@ -169,16 +169,16 @@ static int pcf2123_set_offset(struct device *dev, long offset)
reg |= OFFSET_COARSE;
}
- return regmap_write(pdata->map, PCF2123_REG_OFFSET, (unsigned int)reg);
+ return regmap_write(pcf2123->map, PCF2123_REG_OFFSET, (unsigned int)reg);
}
static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
- struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
+ struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
u8 rxbuf[7];
int ret;
- ret = regmap_bulk_read(pdata->map, PCF2123_REG_SC, rxbuf,
+ ret = regmap_bulk_read(pcf2123->map, PCF2123_REG_SC, rxbuf,
sizeof(rxbuf));
if (ret)
return ret;
@@ -194,9 +194,7 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_mday = bcd2bin(rxbuf[3] & 0x3F);
tm->tm_wday = rxbuf[4] & 0x07;
tm->tm_mon = bcd2bin(rxbuf[5] & 0x1F) - 1; /* rtc mn 1-12 */
- tm->tm_year = bcd2bin(rxbuf[6]);
- if (tm->tm_year < 70)
- tm->tm_year += 100; /* assume we are in 1970...2069 */
+ tm->tm_year = bcd2bin(rxbuf[6]) + 100;
dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm);
@@ -205,14 +203,14 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
- struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
+ struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
u8 txbuf[7];
int ret;
dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm);
/* Stop the counter first */
- ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP);
+ ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_STOP);
if (ret)
return ret;
@@ -223,29 +221,37 @@ static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm)
txbuf[3] = bin2bcd(tm->tm_mday & 0x3F);
txbuf[4] = tm->tm_wday & 0x07;
txbuf[5] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */
- txbuf[6] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100);
+ txbuf[6] = bin2bcd(tm->tm_year - 100);
- ret = regmap_bulk_write(pdata->map, PCF2123_REG_SC, txbuf,
+ ret = regmap_bulk_write(pcf2123->map, PCF2123_REG_SC, txbuf,
sizeof(txbuf));
if (ret)
return ret;
/* Start the counter */
- ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
+ ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
if (ret)
return ret;
return 0;
}
+static int pcf2123_rtc_alarm_irq_enable(struct device *dev, unsigned int en)
+{
+ struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
+
+ return regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AIE,
+ en ? CTRL2_AIE : 0);
+}
+
static int pcf2123_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
- struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
+ struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
u8 rxbuf[4];
int ret;
unsigned int val = 0;
- ret = regmap_bulk_read(pdata->map, PCF2123_REG_ALRM_MN, rxbuf,
+ ret = regmap_bulk_read(pcf2123->map, PCF2123_REG_ALRM_MN, rxbuf,
sizeof(rxbuf));
if (ret)
return ret;
@@ -257,7 +263,7 @@ static int pcf2123_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time);
- ret = regmap_read(pdata->map, PCF2123_REG_CTRL2, &val);
+ ret = regmap_read(pcf2123->map, PCF2123_REG_CTRL2, &val);
if (ret)
return ret;
@@ -268,19 +274,19 @@ static int pcf2123_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
static int pcf2123_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
- struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
+ struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
u8 txbuf[4];
int ret;
dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time);
- /* Ensure alarm flag is clear */
- ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AF, 0);
+ /* Disable alarm interrupt */
+ ret = regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AIE, 0);
if (ret)
return ret;
- /* Disable alarm interrupt */
- ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AIE, 0);
+ /* Ensure alarm flag is clear */
+ ret = regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AF, 0);
if (ret)
return ret;
@@ -288,42 +294,34 @@ static int pcf2123_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
txbuf[0] = bin2bcd(alm->time.tm_min & 0x7F);
txbuf[1] = bin2bcd(alm->time.tm_hour & 0x3F);
txbuf[2] = bin2bcd(alm->time.tm_mday & 0x3F);
- txbuf[3] = bin2bcd(alm->time.tm_wday & 0x07);
+ txbuf[3] = ALRM_DISABLE;
- ret = regmap_bulk_write(pdata->map, PCF2123_REG_ALRM_MN, txbuf,
+ ret = regmap_bulk_write(pcf2123->map, PCF2123_REG_ALRM_MN, txbuf,
sizeof(txbuf));
if (ret)
return ret;
- /* Enable alarm interrupt */
- if (alm->enabled) {
- ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2,
- CTRL2_AIE, CTRL2_AIE);
- if (ret)
- return ret;
- }
-
- return 0;
+ return pcf2123_rtc_alarm_irq_enable(dev, alm->enabled);
}
static irqreturn_t pcf2123_rtc_irq(int irq, void *dev)
{
- struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
- struct mutex *lock = &pdata->rtc->ops_lock;
+ struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
+ struct mutex *lock = &pcf2123->rtc->ops_lock;
unsigned int val = 0;
int ret = IRQ_NONE;
mutex_lock(lock);
- regmap_read(pdata->map, PCF2123_REG_CTRL2, &val);
+ regmap_read(pcf2123->map, PCF2123_REG_CTRL2, &val);
/* Alarm? */
if (val & CTRL2_AF) {
ret = IRQ_HANDLED;
/* Clear alarm flag */
- regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AF, 0);
+ regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AF, 0);
- rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF);
+ rtc_update_irq(pcf2123->rtc, 1, RTC_IRQF | RTC_AF);
}
mutex_unlock(lock);
@@ -333,23 +331,23 @@ static irqreturn_t pcf2123_rtc_irq(int irq, void *dev)
static int pcf2123_reset(struct device *dev)
{
- struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
+ struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
int ret;
unsigned int val = 0;
- ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_SW_RESET);
+ ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_SW_RESET);
if (ret)
return ret;
/* Stop the counter */
dev_dbg(dev, "stopping RTC\n");
- ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP);
+ ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_STOP);
if (ret)
return ret;
/* See if the counter was actually stopped */
dev_dbg(dev, "checking for presence of RTC\n");
- ret = regmap_read(pdata->map, PCF2123_REG_CTRL1, &val);
+ ret = regmap_read(pcf2123->map, PCF2123_REG_CTRL1, &val);
if (ret)
return ret;
@@ -358,7 +356,7 @@ static int pcf2123_reset(struct device *dev)
return -ENODEV;
/* Start the counter */
- ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
+ ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
if (ret)
return ret;
@@ -372,26 +370,27 @@ static const struct rtc_class_ops pcf2123_rtc_ops = {
.set_offset = pcf2123_set_offset,
.read_alarm = pcf2123_rtc_read_alarm,
.set_alarm = pcf2123_rtc_set_alarm,
+ .alarm_irq_enable = pcf2123_rtc_alarm_irq_enable,
};
static int pcf2123_probe(struct spi_device *spi)
{
struct rtc_device *rtc;
struct rtc_time tm;
- struct pcf2123_plat_data *pdata;
+ struct pcf2123_data *pcf2123;
int ret = 0;
- pdata = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_plat_data),
+ pcf2123 = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_data),
GFP_KERNEL);
- if (!pdata)
+ if (!pcf2123)
return -ENOMEM;
- spi->dev.platform_data = pdata;
- pdata->map = devm_regmap_init_spi(spi, &pcf2123_regmap_config);
+ dev_set_drvdata(&spi->dev, pcf2123);
- if (IS_ERR(pdata->map)) {
+ pcf2123->map = devm_regmap_init_spi(spi, &pcf2123_regmap_config);
+ if (IS_ERR(pcf2123->map)) {
dev_err(&spi->dev, "regmap init failed.\n");
- goto kfree_exit;
+ return PTR_ERR(pcf2123->map);
}
ret = pcf2123_rtc_read_time(&spi->dev, &tm);
@@ -399,7 +398,7 @@ static int pcf2123_probe(struct spi_device *spi)
ret = pcf2123_reset(&spi->dev);
if (ret < 0) {
dev_err(&spi->dev, "chip not found\n");
- goto kfree_exit;
+ return ret;
}
}
@@ -407,16 +406,11 @@ static int pcf2123_probe(struct spi_device *spi)
(spi->max_speed_hz + 500) / 1000);
/* Finalize the initialization */
- rtc = devm_rtc_device_register(&spi->dev, pcf2123_driver.driver.name,
- &pcf2123_rtc_ops, THIS_MODULE);
-
- if (IS_ERR(rtc)) {
- dev_err(&spi->dev, "failed to register.\n");
- ret = PTR_ERR(rtc);
- goto kfree_exit;
- }
+ rtc = devm_rtc_allocate_device(&spi->dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
- pdata->rtc = rtc;
+ pcf2123->rtc = rtc;
/* Register alarm irq */
if (spi->irq > 0) {
@@ -434,19 +428,25 @@ static int pcf2123_probe(struct spi_device *spi)
* support to this driver to generate interrupts more than once
* per minute.
*/
- pdata->rtc->uie_unsupported = 1;
+ rtc->uie_unsupported = 1;
+ rtc->ops = &pcf2123_rtc_ops;
+ rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rtc->range_max = RTC_TIMESTAMP_END_2099;
+ rtc->set_start_time = true;
- return 0;
+ ret = rtc_register_device(rtc);
+ if (ret)
+ return ret;
-kfree_exit:
- spi->dev.platform_data = NULL;
- return ret;
+ return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id pcf2123_dt_ids[] = {
- { .compatible = "nxp,rtc-pcf2123", },
+ { .compatible = "nxp,pcf2123", },
{ .compatible = "microcrystal,rv2123", },
+ /* Deprecated, do not use */
+ { .compatible = "nxp,rtc-pcf2123", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, pcf2123_dt_ids);
diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c
index 8632f58fed43..4e50d6768f13 100644
--- a/drivers/rtc/rtc-pcf2127.c
+++ b/drivers/rtc/rtc-pcf2127.c
@@ -5,6 +5,9 @@
*
* Author: Renaud Cerrato <r.cerrato@til-technologies.fr>
*
+ * Watchdog and tamper functions
+ * Author: Bruno Thomsen <bruno.thomsen@gmail.com>
+ *
* based on the other drivers in this same directory.
*
* Datasheet: http://cache.nxp.com/documents/data_sheet/PCF2127.pdf
@@ -18,30 +21,67 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
+#include <linux/watchdog.h>
+
+/* Control register 1 */
+#define PCF2127_REG_CTRL1 0x00
+#define PCF2127_BIT_CTRL1_TSF1 BIT(4)
+/* Control register 2 */
+#define PCF2127_REG_CTRL2 0x01
+#define PCF2127_BIT_CTRL2_TSIE BIT(2)
+#define PCF2127_BIT_CTRL2_TSF2 BIT(5)
+/* Control register 3 */
+#define PCF2127_REG_CTRL3 0x02
+#define PCF2127_BIT_CTRL3_BLIE BIT(0)
+#define PCF2127_BIT_CTRL3_BIE BIT(1)
+#define PCF2127_BIT_CTRL3_BLF BIT(2)
+#define PCF2127_BIT_CTRL3_BF BIT(3)
+#define PCF2127_BIT_CTRL3_BTSE BIT(4)
+/* Time and date registers */
+#define PCF2127_REG_SC 0x03
+#define PCF2127_BIT_SC_OSF BIT(7)
+#define PCF2127_REG_MN 0x04
+#define PCF2127_REG_HR 0x05
+#define PCF2127_REG_DM 0x06
+#define PCF2127_REG_DW 0x07
+#define PCF2127_REG_MO 0x08
+#define PCF2127_REG_YR 0x09
+/* Watchdog registers */
+#define PCF2127_REG_WD_CTL 0x10
+#define PCF2127_BIT_WD_CTL_TF0 BIT(0)
+#define PCF2127_BIT_WD_CTL_TF1 BIT(1)
+#define PCF2127_BIT_WD_CTL_CD0 BIT(6)
+#define PCF2127_BIT_WD_CTL_CD1 BIT(7)
+#define PCF2127_REG_WD_VAL 0x11
+/* Tamper timestamp registers */
+#define PCF2127_REG_TS_CTRL 0x12
+#define PCF2127_BIT_TS_CTRL_TSOFF BIT(6)
+#define PCF2127_BIT_TS_CTRL_TSM BIT(7)
+#define PCF2127_REG_TS_SC 0x13
+#define PCF2127_REG_TS_MN 0x14
+#define PCF2127_REG_TS_HR 0x15
+#define PCF2127_REG_TS_DM 0x16
+#define PCF2127_REG_TS_MO 0x17
+#define PCF2127_REG_TS_YR 0x18
+/*
+ * RAM registers
+ * PCF2127 has 512 bytes general-purpose static RAM (SRAM) that is
+ * battery backed and can survive a power outage.
+ * PCF2129 doesn't have this feature.
+ */
+#define PCF2127_REG_RAM_ADDR_MSB 0x1A
+#define PCF2127_REG_RAM_WRT_CMD 0x1C
+#define PCF2127_REG_RAM_RD_CMD 0x1D
-#define PCF2127_REG_CTRL1 (0x00) /* Control Register 1 */
-#define PCF2127_REG_CTRL2 (0x01) /* Control Register 2 */
-
-#define PCF2127_REG_CTRL3 (0x02) /* Control Register 3 */
-#define PCF2127_REG_CTRL3_BLF BIT(2)
-
-#define PCF2127_REG_SC (0x03) /* datetime */
-#define PCF2127_REG_MN (0x04)
-#define PCF2127_REG_HR (0x05)
-#define PCF2127_REG_DM (0x06)
-#define PCF2127_REG_DW (0x07)
-#define PCF2127_REG_MO (0x08)
-#define PCF2127_REG_YR (0x09)
-
-/* the pcf2127 has 512 bytes nvmem, pcf2129 doesn't */
-#define PCF2127_REG_RAM_addr_MSB 0x1a
-#define PCF2127_REG_RAM_wrt_cmd 0x1c
-#define PCF2127_REG_RAM_rd_cmd 0x1d
-
-#define PCF2127_OSF BIT(7) /* Oscillator Fail flag */
+/* Watchdog timer value constants */
+#define PCF2127_WD_VAL_STOP 0
+#define PCF2127_WD_VAL_MIN 2
+#define PCF2127_WD_VAL_MAX 255
+#define PCF2127_WD_VAL_DEFAULT 60
struct pcf2127 {
struct rtc_device *rtc;
+ struct watchdog_device wdd;
struct regmap *regmap;
};
@@ -54,30 +94,25 @@ static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm)
struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
unsigned char buf[10];
int ret;
- int i;
- for (i = 0; i <= PCF2127_REG_CTRL3; i++) {
- ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL1 + i,
- (unsigned int *)(buf + i));
- if (ret) {
- dev_err(dev, "%s: read error\n", __func__);
- return ret;
- }
- }
-
- ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_SC,
- (buf + PCF2127_REG_SC),
- ARRAY_SIZE(buf) - PCF2127_REG_SC);
+ /*
+ * Avoid reading CTRL2 register as it causes WD_VAL register
+ * value to reset to 0 which means watchdog is stopped.
+ */
+ ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_CTRL3,
+ (buf + PCF2127_REG_CTRL3),
+ ARRAY_SIZE(buf) - PCF2127_REG_CTRL3);
if (ret) {
dev_err(dev, "%s: read error\n", __func__);
return ret;
}
- if (buf[PCF2127_REG_CTRL3] & PCF2127_REG_CTRL3_BLF)
+ if (buf[PCF2127_REG_CTRL3] & PCF2127_BIT_CTRL3_BLF)
dev_info(dev,
"low voltage detected, check/replace RTC battery.\n");
- if (buf[PCF2127_REG_SC] & PCF2127_OSF) {
+ /* Clock integrity is not guaranteed when OSF flag is set. */
+ if (buf[PCF2127_REG_SC] & PCF2127_BIT_SC_OSF) {
/*
* no need clear the flag here,
* it will be cleared once the new date is saved
@@ -88,14 +123,12 @@ static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm)
}
dev_dbg(dev,
- "%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, "
- "sec=%02x, min=%02x, hr=%02x, "
+ "%s: raw data is cr3=%02x, sec=%02x, min=%02x, hr=%02x, "
"mday=%02x, wday=%02x, mon=%02x, year=%02x\n",
- __func__,
- buf[0], buf[1], buf[2],
- buf[3], buf[4], buf[5],
- buf[6], buf[7], buf[8], buf[9]);
-
+ __func__, buf[PCF2127_REG_CTRL3], buf[PCF2127_REG_SC],
+ buf[PCF2127_REG_MN], buf[PCF2127_REG_HR],
+ buf[PCF2127_REG_DM], buf[PCF2127_REG_DW],
+ buf[PCF2127_REG_MO], buf[PCF2127_REG_YR]);
tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F);
tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F);
@@ -166,11 +199,9 @@ static int pcf2127_rtc_ioctl(struct device *dev,
if (ret)
return ret;
- touser = touser & PCF2127_REG_CTRL3_BLF ? 1 : 0;
+ touser = touser & PCF2127_BIT_CTRL3_BLF ? RTC_VL_BACKUP_LOW : 0;
- if (copy_to_user((void __user *)arg, &touser, sizeof(int)))
- return -EFAULT;
- return 0;
+ return put_user(touser, (unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
}
@@ -192,12 +223,12 @@ static int pcf2127_nvmem_read(void *priv, unsigned int offset,
int ret;
unsigned char offsetbuf[] = { offset >> 8, offset };
- ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB,
+ ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_ADDR_MSB,
offsetbuf, 2);
if (ret)
return ret;
- ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_rd_cmd,
+ ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_RD_CMD,
val, bytes);
return ret ?: bytes;
@@ -210,21 +241,181 @@ static int pcf2127_nvmem_write(void *priv, unsigned int offset,
int ret;
unsigned char offsetbuf[] = { offset >> 8, offset };
- ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB,
+ ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_ADDR_MSB,
offsetbuf, 2);
if (ret)
return ret;
- ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_wrt_cmd,
+ ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD,
val, bytes);
return ret ?: bytes;
}
+/* watchdog driver */
+
+static int pcf2127_wdt_ping(struct watchdog_device *wdd)
+{
+ struct pcf2127 *pcf2127 = watchdog_get_drvdata(wdd);
+
+ return regmap_write(pcf2127->regmap, PCF2127_REG_WD_VAL, wdd->timeout);
+}
+
+/*
+ * Restart watchdog timer if feature is active.
+ *
+ * Note: Reading CTRL2 register causes watchdog to stop which is unfortunate,
+ * since register also contain control/status flags for other features.
+ * Always call this function after reading CTRL2 register.
+ */
+static int pcf2127_wdt_active_ping(struct watchdog_device *wdd)
+{
+ int ret = 0;
+
+ if (watchdog_active(wdd)) {
+ ret = pcf2127_wdt_ping(wdd);
+ if (ret)
+ dev_err(wdd->parent,
+ "%s: watchdog restart failed, ret=%d\n",
+ __func__, ret);
+ }
+
+ return ret;
+}
+
+static int pcf2127_wdt_start(struct watchdog_device *wdd)
+{
+ return pcf2127_wdt_ping(wdd);
+}
+
+static int pcf2127_wdt_stop(struct watchdog_device *wdd)
+{
+ struct pcf2127 *pcf2127 = watchdog_get_drvdata(wdd);
+
+ return regmap_write(pcf2127->regmap, PCF2127_REG_WD_VAL,
+ PCF2127_WD_VAL_STOP);
+}
+
+static int pcf2127_wdt_set_timeout(struct watchdog_device *wdd,
+ unsigned int new_timeout)
+{
+ dev_dbg(wdd->parent, "new watchdog timeout: %is (old: %is)\n",
+ new_timeout, wdd->timeout);
+
+ wdd->timeout = new_timeout;
+
+ return pcf2127_wdt_active_ping(wdd);
+}
+
+static const struct watchdog_info pcf2127_wdt_info = {
+ .identity = "NXP PCF2127/PCF2129 Watchdog",
+ .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+};
+
+static const struct watchdog_ops pcf2127_watchdog_ops = {
+ .owner = THIS_MODULE,
+ .start = pcf2127_wdt_start,
+ .stop = pcf2127_wdt_stop,
+ .ping = pcf2127_wdt_ping,
+ .set_timeout = pcf2127_wdt_set_timeout,
+};
+
+/* sysfs interface */
+
+static ssize_t timestamp0_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct pcf2127 *pcf2127 = dev_get_drvdata(dev->parent);
+ int ret;
+
+ ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL1,
+ PCF2127_BIT_CTRL1_TSF1, 0);
+ if (ret) {
+ dev_err(dev, "%s: update ctrl1 ret=%d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2,
+ PCF2127_BIT_CTRL2_TSF2, 0);
+ if (ret) {
+ dev_err(dev, "%s: update ctrl2 ret=%d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = pcf2127_wdt_active_ping(&pcf2127->wdd);
+ if (ret)
+ return ret;
+
+ return count;
+};
+
+static ssize_t timestamp0_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pcf2127 *pcf2127 = dev_get_drvdata(dev->parent);
+ struct rtc_time tm;
+ int ret;
+ unsigned char data[25];
+
+ ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_CTRL1, data,
+ sizeof(data));
+ if (ret) {
+ dev_err(dev, "%s: read error ret=%d\n", __func__, ret);
+ return ret;
+ }
+
+ dev_dbg(dev,
+ "%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, ts_sc=%02x, "
+ "ts_mn=%02x, ts_hr=%02x, ts_dm=%02x, ts_mo=%02x, ts_yr=%02x\n",
+ __func__, data[PCF2127_REG_CTRL1], data[PCF2127_REG_CTRL2],
+ data[PCF2127_REG_CTRL3], data[PCF2127_REG_TS_SC],
+ data[PCF2127_REG_TS_MN], data[PCF2127_REG_TS_HR],
+ data[PCF2127_REG_TS_DM], data[PCF2127_REG_TS_MO],
+ data[PCF2127_REG_TS_YR]);
+
+ ret = pcf2127_wdt_active_ping(&pcf2127->wdd);
+ if (ret)
+ return ret;
+
+ if (!(data[PCF2127_REG_CTRL1] & PCF2127_BIT_CTRL1_TSF1) &&
+ !(data[PCF2127_REG_CTRL2] & PCF2127_BIT_CTRL2_TSF2))
+ return 0;
+
+ tm.tm_sec = bcd2bin(data[PCF2127_REG_TS_SC] & 0x7F);
+ tm.tm_min = bcd2bin(data[PCF2127_REG_TS_MN] & 0x7F);
+ tm.tm_hour = bcd2bin(data[PCF2127_REG_TS_HR] & 0x3F);
+ tm.tm_mday = bcd2bin(data[PCF2127_REG_TS_DM] & 0x3F);
+ /* TS_MO register (month) value range: 1-12 */
+ tm.tm_mon = bcd2bin(data[PCF2127_REG_TS_MO] & 0x1F) - 1;
+ tm.tm_year = bcd2bin(data[PCF2127_REG_TS_YR]);
+ if (tm.tm_year < 70)
+ tm.tm_year += 100; /* assume we are in 1970...2069 */
+
+ ret = rtc_valid_tm(&tm);
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%llu\n",
+ (unsigned long long)rtc_tm_to_time64(&tm));
+};
+
+static DEVICE_ATTR_RW(timestamp0);
+
+static struct attribute *pcf2127_attrs[] = {
+ &dev_attr_timestamp0.attr,
+ NULL
+};
+
+static const struct attribute_group pcf2127_attr_group = {
+ .attrs = pcf2127_attrs,
+};
+
static int pcf2127_probe(struct device *dev, struct regmap *regmap,
const char *name, bool has_nvmem)
{
struct pcf2127 *pcf2127;
+ u32 wdd_timeout;
int ret = 0;
dev_dbg(dev, "%s\n", __func__);
@@ -237,11 +428,22 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
dev_set_drvdata(dev, pcf2127);
- pcf2127->rtc = devm_rtc_device_register(dev, name, &pcf2127_rtc_ops,
- THIS_MODULE);
+ pcf2127->rtc = devm_rtc_allocate_device(dev);
if (IS_ERR(pcf2127->rtc))
return PTR_ERR(pcf2127->rtc);
+ pcf2127->rtc->ops = &pcf2127_rtc_ops;
+
+ pcf2127->wdd.parent = dev;
+ pcf2127->wdd.info = &pcf2127_wdt_info;
+ pcf2127->wdd.ops = &pcf2127_watchdog_ops;
+ pcf2127->wdd.min_timeout = PCF2127_WD_VAL_MIN;
+ pcf2127->wdd.max_timeout = PCF2127_WD_VAL_MAX;
+ pcf2127->wdd.timeout = PCF2127_WD_VAL_DEFAULT;
+ pcf2127->wdd.min_hw_heartbeat_ms = 500;
+
+ watchdog_set_drvdata(&pcf2127->wdd, pcf2127);
+
if (has_nvmem) {
struct nvmem_config nvmem_cfg = {
.priv = pcf2127,
@@ -253,7 +455,91 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
ret = rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg);
}
- return ret;
+ /*
+ * Watchdog timer enabled and reset pin /RST activated when timed out.
+ * Select 1Hz clock source for watchdog timer.
+ * Note: Countdown timer disabled and not available.
+ */
+ ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_WD_CTL,
+ PCF2127_BIT_WD_CTL_CD1 |
+ PCF2127_BIT_WD_CTL_CD0 |
+ PCF2127_BIT_WD_CTL_TF1 |
+ PCF2127_BIT_WD_CTL_TF0,
+ PCF2127_BIT_WD_CTL_CD1 |
+ PCF2127_BIT_WD_CTL_CD0 |
+ PCF2127_BIT_WD_CTL_TF1);
+ if (ret) {
+ dev_err(dev, "%s: watchdog config (wd_ctl) failed\n", __func__);
+ return ret;
+ }
+
+ /* Test if watchdog timer is started by bootloader */
+ ret = regmap_read(pcf2127->regmap, PCF2127_REG_WD_VAL, &wdd_timeout);
+ if (ret)
+ return ret;
+
+ if (wdd_timeout)
+ set_bit(WDOG_HW_RUNNING, &pcf2127->wdd.status);
+
+#ifdef CONFIG_WATCHDOG
+ ret = devm_watchdog_register_device(dev, &pcf2127->wdd);
+ if (ret)
+ return ret;
+#endif /* CONFIG_WATCHDOG */
+
+ /*
+ * Disable battery low/switch-over timestamp and interrupts.
+ * Clear battery interrupt flags which can block new trigger events.
+ * Note: This is the default chip behaviour but added to ensure
+ * correct tamper timestamp and interrupt function.
+ */
+ ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3,
+ PCF2127_BIT_CTRL3_BTSE |
+ PCF2127_BIT_CTRL3_BF |
+ PCF2127_BIT_CTRL3_BIE |
+ PCF2127_BIT_CTRL3_BLIE, 0);
+ if (ret) {
+ dev_err(dev, "%s: interrupt config (ctrl3) failed\n",
+ __func__);
+ return ret;
+ }
+
+ /*
+ * Enable timestamp function and store timestamp of first trigger
+ * event until TSF1 and TFS2 interrupt flags are cleared.
+ */
+ ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_TS_CTRL,
+ PCF2127_BIT_TS_CTRL_TSOFF |
+ PCF2127_BIT_TS_CTRL_TSM,
+ PCF2127_BIT_TS_CTRL_TSM);
+ if (ret) {
+ dev_err(dev, "%s: tamper detection config (ts_ctrl) failed\n",
+ __func__);
+ return ret;
+ }
+
+ /*
+ * Enable interrupt generation when TSF1 or TSF2 timestamp flags
+ * are set. Interrupt signal is an open-drain output and can be
+ * left floating if unused.
+ */
+ ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2,
+ PCF2127_BIT_CTRL2_TSIE,
+ PCF2127_BIT_CTRL2_TSIE);
+ if (ret) {
+ dev_err(dev, "%s: tamper detection config (ctrl2) failed\n",
+ __func__);
+ return ret;
+ }
+
+ ret = rtc_add_group(pcf2127->rtc, &pcf2127_attr_group);
+ if (ret) {
+ dev_err(dev, "%s: tamper sysfs registering failed\n",
+ __func__);
+ return ret;
+ }
+
+ return rtc_register_device(pcf2127->rtc);
}
#ifdef CONFIG_OF
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index 1afa6d9fa9fb..1db17ba1fc64 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -289,21 +289,9 @@ static int pcf85063_ioctl(struct device *dev, unsigned int cmd,
if (ret < 0)
return ret;
- if (status & PCF85063_REG_SC_OS)
- dev_warn(&pcf85063->rtc->dev, "Voltage low, data loss detected.\n");
+ status = status & PCF85063_REG_SC_OS ? RTC_VL_DATA_INVALID : 0;
- status &= PCF85063_REG_SC_OS;
-
- if (copy_to_user((void __user *)arg, &status, sizeof(int)))
- return -EFAULT;
-
- return 0;
-
- case RTC_VL_CLR:
- ret = regmap_update_bits(pcf85063->regmap, PCF85063_REG_SC,
- PCF85063_REG_SC_OS, 0);
-
- return ret;
+ return put_user(status, (unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c
index 2f435e533b10..47e0f411dd5c 100644
--- a/drivers/rtc/rtc-pcf8523.c
+++ b/drivers/rtc/rtc-pcf8523.c
@@ -35,10 +35,6 @@
#define REG_OFFSET 0x0e
#define REG_OFFSET_MODE BIT(7)
-struct pcf8523 {
- struct rtc_device *rtc;
-};
-
static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep)
{
struct i2c_msg msgs[2];
@@ -286,11 +282,11 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
ret = pcf8523_voltage_low(client);
if (ret < 0)
return ret;
+ if (ret)
+ ret = RTC_VL_BACKUP_LOW;
- if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
- return -EFAULT;
+ return put_user(ret, (unsigned int __user *)arg);
- return 0;
default:
return -ENOIOCTLCMD;
}
@@ -345,16 +341,12 @@ static const struct rtc_class_ops pcf8523_rtc_ops = {
static int pcf8523_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct pcf8523 *pcf;
+ struct rtc_device *rtc;
int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
- pcf = devm_kzalloc(&client->dev, sizeof(*pcf), GFP_KERNEL);
- if (!pcf)
- return -ENOMEM;
-
err = pcf8523_load_capacitance(client);
if (err < 0)
dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
@@ -364,12 +356,10 @@ static int pcf8523_probe(struct i2c_client *client,
if (err < 0)
return err;
- pcf->rtc = devm_rtc_device_register(&client->dev, DRIVER_NAME,
+ rtc = devm_rtc_device_register(&client->dev, DRIVER_NAME,
&pcf8523_rtc_ops, THIS_MODULE);
- if (IS_ERR(pcf->rtc))
- return PTR_ERR(pcf->rtc);
-
- i2c_set_clientdata(client, pcf);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
return 0;
}
diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c
index a075e77617dc..3450d615974d 100644
--- a/drivers/rtc/rtc-pcf85363.c
+++ b/drivers/rtc/rtc-pcf85363.c
@@ -166,7 +166,12 @@ static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm)
buf[DT_YEARS] = bin2bcd(tm->tm_year % 100);
ret = regmap_bulk_write(pcf85363->regmap, CTRL_STOP_EN,
- tmp, sizeof(tmp));
+ tmp, 2);
+ if (ret)
+ return ret;
+
+ ret = regmap_bulk_write(pcf85363->regmap, DT_100THS,
+ buf, sizeof(tmp) - 2);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index ac159d24286d..2dc30eafa639 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -22,8 +22,8 @@
#define PCF8563_REG_ST1 0x00 /* status */
#define PCF8563_REG_ST2 0x01
-#define PCF8563_BIT_AIE (1 << 1)
-#define PCF8563_BIT_AF (1 << 3)
+#define PCF8563_BIT_AIE BIT(1)
+#define PCF8563_BIT_AF BIT(3)
#define PCF8563_BITS_ST2_N (7 << 5)
#define PCF8563_REG_SC 0x02 /* datetime */
@@ -76,7 +76,6 @@ struct pcf8563 {
* 1970...2069.
*/
int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
- int voltage_low; /* incicates if a low_voltage was detected */
struct i2c_client *client;
#ifdef CONFIG_COMMON_CLK
@@ -196,8 +195,9 @@ static irqreturn_t pcf8563_irq(int irq, void *dev_id)
* In the routines that deal directly with the pcf8563 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
*/
-static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
unsigned char buf[9];
int err;
@@ -207,7 +207,6 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
return err;
if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) {
- pcf8563->voltage_low = 1;
dev_err(&client->dev,
"low voltage detected, date/time is not reliable.\n");
return -EINVAL;
@@ -228,9 +227,7 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_mday = bcd2bin(buf[PCF8563_REG_DM] & 0x3F);
tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
tm->tm_mon = bcd2bin(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
- tm->tm_year = bcd2bin(buf[PCF8563_REG_YR]);
- if (tm->tm_year < 70)
- tm->tm_year += 100; /* assume we are in 1970...2069 */
+ tm->tm_year = bcd2bin(buf[PCF8563_REG_YR]) + 100;
/* detect the polarity heuristically. see note above. */
pcf8563->c_polarity = (buf[PCF8563_REG_MO] & PCF8563_MO_C) ?
(tm->tm_year >= 100) : (tm->tm_year < 100);
@@ -244,8 +241,9 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
return 0;
}
-static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
unsigned char buf[9];
@@ -266,7 +264,7 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
buf[PCF8563_REG_MO] = bin2bcd(tm->tm_mon + 1);
/* year and century */
- buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year % 100);
+ buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year - 100);
if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))
buf[PCF8563_REG_MO] |= PCF8563_MO_C;
@@ -276,53 +274,23 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
9 - PCF8563_REG_SC, buf + PCF8563_REG_SC);
}
-#ifdef CONFIG_RTC_INTF_DEV
static int pcf8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
- struct pcf8563 *pcf8563 = i2c_get_clientdata(to_i2c_client(dev));
- struct rtc_time tm;
+ struct i2c_client *client = to_i2c_client(dev);
+ int ret;
switch (cmd) {
case RTC_VL_READ:
- if (pcf8563->voltage_low)
- dev_info(dev, "low voltage detected, date/time is not reliable.\n");
-
- if (copy_to_user((void __user *)arg, &pcf8563->voltage_low,
- sizeof(int)))
- return -EFAULT;
- return 0;
- case RTC_VL_CLR:
- /*
- * Clear the VL bit in the seconds register in case
- * the time has not been set already (which would
- * have cleared it). This does not really matter
- * because of the cached voltage_low value but do it
- * anyway for consistency.
- */
- if (pcf8563_get_datetime(to_i2c_client(dev), &tm))
- pcf8563_set_datetime(to_i2c_client(dev), &tm);
-
- /* Clear the cached value. */
- pcf8563->voltage_low = 0;
+ ret = i2c_smbus_read_byte_data(client, PCF8563_REG_SC);
+ if (ret < 0)
+ return ret;
- return 0;
+ return put_user(ret & PCF8563_SC_LV ? RTC_VL_DATA_INVALID : 0,
+ (unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
}
}
-#else
-#define pcf8563_rtc_ioctl NULL
-#endif
-
-static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- return pcf8563_get_datetime(to_i2c_client(dev), tm);
-}
-
-static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return pcf8563_set_datetime(to_i2c_client(dev), tm);
-}
static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
{
@@ -400,7 +368,7 @@ static int pcf8563_irq_enable(struct device *dev, unsigned int enabled)
#define clkout_hw_to_pcf8563(_hw) container_of(_hw, struct pcf8563, clkout_hw)
-static int clkout_rates[] = {
+static const int clkout_rates[] = {
32768,
1024,
32,
@@ -591,13 +559,17 @@ static int pcf8563_probe(struct i2c_client *client,
return err;
}
- pcf8563->rtc = devm_rtc_device_register(&client->dev,
- pcf8563_driver.driver.name,
- &pcf8563_rtc_ops, THIS_MODULE);
-
+ pcf8563->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(pcf8563->rtc))
return PTR_ERR(pcf8563->rtc);
+ pcf8563->rtc->ops = &pcf8563_rtc_ops;
+ /* the pcf8563 alarm only supports a minute accuracy */
+ pcf8563->rtc->uie_unsupported = 1;
+ pcf8563->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ pcf8563->rtc->range_max = RTC_TIMESTAMP_END_2099;
+ pcf8563->rtc->set_start_time = true;
+
if (client->irq > 0) {
err = devm_request_threaded_irq(&client->dev, client->irq,
NULL, pcf8563_irq,
@@ -608,17 +580,17 @@ static int pcf8563_probe(struct i2c_client *client,
client->irq);
return err;
}
-
}
+ err = rtc_register_device(pcf8563->rtc);
+ if (err)
+ return err;
+
#ifdef CONFIG_COMMON_CLK
/* register clk in common clk framework */
pcf8563_clkout_register_clk(pcf8563);
#endif
- /* the pcf8563 alarm only supports a minute accuracy */
- pcf8563->rtc->uie_unsupported = 1;
-
return 0;
}
@@ -632,6 +604,8 @@ MODULE_DEVICE_TABLE(i2c, pcf8563_id);
#ifdef CONFIG_OF
static const struct of_device_id pcf8563_of_match[] = {
{ .compatible = "nxp,pcf8563" },
+ { .compatible = "epson,rtc8564" },
+ { .compatible = "microcrystal,rv8564" },
{}
};
MODULE_DEVICE_TABLE(of, pcf8563_of_match);
diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c
index 1c4de6e90da0..2b6946744654 100644
--- a/drivers/rtc/rtc-pic32.c
+++ b/drivers/rtc/rtc-pic32.c
@@ -298,7 +298,6 @@ static int pic32_rtc_remove(struct platform_device *pdev)
static int pic32_rtc_probe(struct platform_device *pdev)
{
struct pic32_rtc_dev *pdata;
- struct resource *res;
int ret;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
@@ -308,13 +307,10 @@ static int pic32_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pdata);
pdata->alarm_irq = platform_get_irq(pdev, 0);
- if (pdata->alarm_irq < 0) {
- dev_err(&pdev->dev, "no irq for alarm\n");
+ if (pdata->alarm_irq < 0)
return pdata->alarm_irq;
- }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pdata->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ pdata->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->reg_base))
return PTR_ERR(pdata->reg_base);
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index 9f9839c47e2f..07ea1be3abb9 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -49,7 +49,7 @@ struct pm8xxx_rtc_regs {
* @regmap: regmap used to access RTC registers
* @allow_set_time: indicates whether writing to the RTC is allowed
* @rtc_alarm_irq: rtc alarm irq number.
- * @ctrl_reg: rtc control register.
+ * @regs: rtc registers description.
* @rtc_dev: device structure.
* @ctrl_reg_lock: spinlock protecting access to ctrl_reg.
*/
@@ -468,10 +468,8 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
}
rtc_dd->rtc_alarm_irq = platform_get_irq(pdev, 0);
- if (rtc_dd->rtc_alarm_irq < 0) {
- dev_err(&pdev->dev, "Alarm IRQ resource absent!\n");
+ if (rtc_dd->rtc_alarm_irq < 0)
return -ENXIO;
- }
rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node,
"allow-set-time");
diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c
index 63b9e73fb97d..89ff713163dd 100644
--- a/drivers/rtc/rtc-puv3.c
+++ b/drivers/rtc/rtc-puv3.c
@@ -186,16 +186,12 @@ static int puv3_rtc_probe(struct platform_device *pdev)
/* find the IRQs */
puv3_rtc_tickno = platform_get_irq(pdev, 1);
- if (puv3_rtc_tickno < 0) {
- dev_err(&pdev->dev, "no irq for rtc tick\n");
+ if (puv3_rtc_tickno < 0)
return -ENOENT;
- }
puv3_rtc_alarmno = platform_get_irq(pdev, 0);
- if (puv3_rtc_alarmno < 0) {
- dev_err(&pdev->dev, "no irq for alarm\n");
+ if (puv3_rtc_alarmno < 0)
return -ENOENT;
- }
dev_dbg(&pdev->dev, "PKUnity_rtc: tick irq %d, alarm irq %d\n",
puv3_rtc_tickno, puv3_rtc_alarmno);
@@ -239,10 +235,8 @@ static int puv3_rtc_probe(struct platform_device *pdev)
/* register RTC and exit */
rtc->ops = &puv3_rtcops;
ret = rtc_register_device(rtc);
- if (ret) {
- dev_err(&pdev->dev, "cannot attach rtc\n");
+ if (ret)
goto err_nortc;
- }
/* platform setup code should have handled this; sigh */
if (!device_can_wakeup(&pdev->dev))
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c
index a7827fe7fb7b..d2f1d8f754bf 100644
--- a/drivers/rtc/rtc-pxa.c
+++ b/drivers/rtc/rtc-pxa.c
@@ -324,15 +324,11 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
}
sa1100_rtc->irq_1hz = platform_get_irq(pdev, 0);
- if (sa1100_rtc->irq_1hz < 0) {
- dev_err(dev, "No 1Hz IRQ resource defined\n");
+ if (sa1100_rtc->irq_1hz < 0)
return -ENXIO;
- }
sa1100_rtc->irq_alarm = platform_get_irq(pdev, 1);
- if (sa1100_rtc->irq_alarm < 0) {
- dev_err(dev, "No alarm IRQ resource defined\n");
+ if (sa1100_rtc->irq_alarm < 0)
return -ENXIO;
- }
pxa_rtc->base = devm_ioremap(dev, pxa_rtc->ress->start,
resource_size(pxa_rtc->ress));
diff --git a/drivers/rtc/rtc-r7301.c b/drivers/rtc/rtc-r7301.c
index 2498278853af..aaf1b95e3990 100644
--- a/drivers/rtc/rtc-r7301.c
+++ b/drivers/rtc/rtc-r7301.c
@@ -354,21 +354,16 @@ static void rtc7301_init(struct rtc7301_priv *priv)
static int __init rtc7301_rtc_probe(struct platform_device *dev)
{
- struct resource *res;
void __iomem *regs;
struct rtc7301_priv *priv;
struct rtc_device *rtc;
int ret;
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENODEV;
-
priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- regs = devm_ioremap_resource(&dev->dev, res);
+ regs = devm_platform_ioremap_resource(dev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index c34540baa12a..c0334c602e88 100644
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -434,12 +434,8 @@ static int rk808_rtc_probe(struct platform_device *pdev)
rk808_rtc->rtc->ops = &rk808_rtc_ops;
rk808_rtc->irq = platform_get_irq(pdev, 0);
- if (rk808_rtc->irq < 0) {
- if (rk808_rtc->irq != -EPROBE_DEFER)
- dev_err(&pdev->dev, "Wake up is not possible as irq = %d\n",
- rk808_rtc->irq);
+ if (rk808_rtc->irq < 0)
return rk808_rtc->irq;
- }
/* request alarm irq of rk808 */
ret = devm_request_threaded_irq(&pdev->dev, rk808_rtc->irq, NULL,
diff --git a/drivers/rtc/rtc-rtd119x.c b/drivers/rtc/rtc-rtd119x.c
index b233559d950b..bb98f2d574a5 100644
--- a/drivers/rtc/rtc-rtd119x.c
+++ b/drivers/rtc/rtc-rtd119x.c
@@ -167,7 +167,6 @@ static const struct of_device_id rtd119x_rtc_dt_ids[] = {
static int rtd119x_rtc_probe(struct platform_device *pdev)
{
struct rtd119x_rtc *data;
- struct resource *res;
u32 val;
int ret;
@@ -178,8 +177,7 @@ static int rtd119x_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
data->base_year = 2014;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- data->base = devm_ioremap_resource(&pdev->dev, res);
+ data->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->base))
return PTR_ERR(data->base);
diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c
index 06884ebb7a61..a0ddc86c975a 100644
--- a/drivers/rtc/rtc-rv3028.c
+++ b/drivers/rtc/rtc-rv3028.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/clk-provider.h>
#include <linux/bcd.h>
#include <linux/bitops.h>
#include <linux/i2c.h>
@@ -52,6 +53,11 @@
#define RV3028_STATUS_CLKF BIT(6)
#define RV3028_STATUS_EEBUSY BIT(7)
+#define RV3028_CLKOUT_FD_MASK GENMASK(2, 0)
+#define RV3028_CLKOUT_PORIE BIT(3)
+#define RV3028_CLKOUT_CLKSY BIT(6)
+#define RV3028_CLKOUT_CLKOE BIT(7)
+
#define RV3028_CTRL1_EERD BIT(3)
#define RV3028_CTRL1_WADA BIT(5)
@@ -84,6 +90,9 @@ struct rv3028_data {
struct regmap *regmap;
struct rtc_device *rtc;
enum rv3028_type type;
+#ifdef CONFIG_COMMON_CLK
+ struct clk_hw clkout_hw;
+#endif
};
static u16 rv3028_trickle_resistors[] = {1000, 3000, 6000, 11000};
@@ -419,21 +428,8 @@ static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
if (ret < 0)
return ret;
- if (status & RV3028_STATUS_PORF)
- dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n");
-
- status &= RV3028_STATUS_PORF;
-
- if (copy_to_user((void __user *)arg, &status, sizeof(int)))
- return -EFAULT;
-
- return 0;
-
- case RTC_VL_CLR:
- ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
- RV3028_STATUS_PORF, 0);
-
- return ret;
+ status = status & RV3028_STATUS_PORF ? RTC_VL_DATA_INVALID : 0;
+ return put_user(status, (unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
@@ -581,6 +577,140 @@ restore_eerd:
return ret;
}
+#ifdef CONFIG_COMMON_CLK
+#define clkout_hw_to_rv3028(hw) container_of(hw, struct rv3028_data, clkout_hw)
+
+static int clkout_rates[] = {
+ 32768,
+ 8192,
+ 1024,
+ 64,
+ 32,
+ 1,
+};
+
+static unsigned long rv3028_clkout_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ int clkout, ret;
+ struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);
+
+ ret = regmap_read(rv3028->regmap, RV3028_CLKOUT, &clkout);
+ if (ret < 0)
+ return 0;
+
+ clkout &= RV3028_CLKOUT_FD_MASK;
+ return clkout_rates[clkout];
+}
+
+static long rv3028_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
+ if (clkout_rates[i] <= rate)
+ return clkout_rates[i];
+
+ return 0;
+}
+
+static int rv3028_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ int i, ret;
+ struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);
+
+ ret = regmap_write(rv3028->regmap, RV3028_CLKOUT, 0x0);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) {
+ if (clkout_rates[i] == rate) {
+ ret = regmap_update_bits(rv3028->regmap,
+ RV3028_CLKOUT,
+ RV3028_CLKOUT_FD_MASK, i);
+ if (ret < 0)
+ return ret;
+
+ return regmap_write(rv3028->regmap, RV3028_CLKOUT,
+ RV3028_CLKOUT_CLKSY | RV3028_CLKOUT_CLKOE);
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int rv3028_clkout_prepare(struct clk_hw *hw)
+{
+ struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);
+
+ return regmap_write(rv3028->regmap, RV3028_CLKOUT,
+ RV3028_CLKOUT_CLKSY | RV3028_CLKOUT_CLKOE);
+}
+
+static void rv3028_clkout_unprepare(struct clk_hw *hw)
+{
+ struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);
+
+ regmap_write(rv3028->regmap, RV3028_CLKOUT, 0x0);
+ regmap_update_bits(rv3028->regmap, RV3028_STATUS,
+ RV3028_STATUS_CLKF, 0);
+}
+
+static int rv3028_clkout_is_prepared(struct clk_hw *hw)
+{
+ int clkout, ret;
+ struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);
+
+ ret = regmap_read(rv3028->regmap, RV3028_CLKOUT, &clkout);
+ if (ret < 0)
+ return ret;
+
+ return !!(clkout & RV3028_CLKOUT_CLKOE);
+}
+
+static const struct clk_ops rv3028_clkout_ops = {
+ .prepare = rv3028_clkout_prepare,
+ .unprepare = rv3028_clkout_unprepare,
+ .is_prepared = rv3028_clkout_is_prepared,
+ .recalc_rate = rv3028_clkout_recalc_rate,
+ .round_rate = rv3028_clkout_round_rate,
+ .set_rate = rv3028_clkout_set_rate,
+};
+
+static int rv3028_clkout_register_clk(struct rv3028_data *rv3028,
+ struct i2c_client *client)
+{
+ int ret;
+ struct clk *clk;
+ struct clk_init_data init;
+ struct device_node *node = client->dev.of_node;
+
+ ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
+ RV3028_STATUS_CLKF, 0);
+ if (ret < 0)
+ return ret;
+
+ init.name = "rv3028-clkout";
+ init.ops = &rv3028_clkout_ops;
+ init.flags = 0;
+ init.parent_names = NULL;
+ init.num_parents = 0;
+ rv3028->clkout_hw.init = &init;
+
+ /* optional override of the clockname */
+ of_property_read_string(node, "clock-output-names", &init.name);
+
+ /* register the clock */
+ clk = devm_clk_register(&client->dev, &rv3028->clkout_hw);
+ if (!IS_ERR(clk))
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+
+ return 0;
+}
+#endif
+
static struct rtc_class_ops rv3028_rtc_ops = {
.read_time = rv3028_get_time,
.set_time = rv3028_set_time,
@@ -639,9 +769,8 @@ static int rv3028_probe(struct i2c_client *client)
dev_warn(&client->dev, "An alarm may have been missed.\n");
rv3028->rtc = devm_rtc_allocate_device(&client->dev);
- if (IS_ERR(rv3028->rtc)) {
+ if (IS_ERR(rv3028->rtc))
return PTR_ERR(rv3028->rtc);
- }
if (client->irq > 0) {
ret = devm_request_threaded_irq(&client->dev, client->irq,
@@ -709,6 +838,9 @@ static int rv3028_probe(struct i2c_client *client)
rv3028->rtc->max_user_freq = 1;
+#ifdef CONFIG_COMMON_CLK
+ rv3028_clkout_register_clk(rv3028, client);
+#endif
return 0;
}
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 4a0e8ec015cc..62718231731b 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -109,10 +109,8 @@
#define RV3029_CONTROL_E2P_TOV_MASK 0x3F /* XTAL turnover temp mask */
/* user ram section */
-#define RV3029_USR1_RAM_PAGE 0x38
-#define RV3029_USR1_SECTION_LEN 0x04
-#define RV3029_USR2_RAM_PAGE 0x3C
-#define RV3029_USR2_SECTION_LEN 0x04
+#define RV3029_RAM_PAGE 0x38
+#define RV3029_RAM_SECTION_LEN 8
struct rv3029_data {
struct device *dev;
@@ -121,77 +119,13 @@ struct rv3029_data {
int irq;
};
-static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
- unsigned int len)
-{
- struct rv3029_data *rv3029 = dev_get_drvdata(dev);
-
- if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
- (reg + len > RV3029_USR1_RAM_PAGE + 8))
- return -EINVAL;
-
- return regmap_bulk_read(rv3029->regmap, reg, buf, len);
-}
-
-static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
- unsigned int len)
-{
- struct rv3029_data *rv3029 = dev_get_drvdata(dev);
-
- if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
- (reg + len > RV3029_USR1_RAM_PAGE + 8))
- return -EINVAL;
-
- return regmap_bulk_write(rv3029->regmap, reg, buf, len);
-}
-
-static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
-{
- u8 buf;
- int ret;
-
- ret = rv3029_read_regs(dev, reg, &buf, 1);
- if (ret < 0)
- return ret;
- buf &= ~mask;
- buf |= set & mask;
- ret = rv3029_write_regs(dev, reg, &buf, 1);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int rv3029_get_sr(struct device *dev, u8 *buf)
-{
- int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
-
- if (ret < 0)
- return -EIO;
- dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
- return 0;
-}
-
-static int rv3029_set_sr(struct device *dev, u8 val)
-{
- u8 buf[1];
- int sr;
-
- buf[0] = val;
- sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
- dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
- if (sr < 0)
- return -EIO;
- return 0;
-}
-
-static int rv3029_eeprom_busywait(struct device *dev)
+static int rv3029_eeprom_busywait(struct rv3029_data *rv3029)
{
+ unsigned int sr;
int i, ret;
- u8 sr;
for (i = 100; i > 0; i--) {
- ret = rv3029_get_sr(dev, &sr);
+ ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
if (ret < 0)
break;
if (!(sr & RV3029_STATUS_EEBUSY))
@@ -199,126 +133,128 @@ static int rv3029_eeprom_busywait(struct device *dev)
usleep_range(1000, 10000);
}
if (i <= 0) {
- dev_err(dev, "EEPROM busy wait timeout.\n");
+ dev_err(rv3029->dev, "EEPROM busy wait timeout.\n");
return -ETIMEDOUT;
}
return ret;
}
-static int rv3029_eeprom_exit(struct device *dev)
+static int rv3029_eeprom_exit(struct rv3029_data *rv3029)
{
/* Re-enable eeprom refresh */
- return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
+ return regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL,
RV3029_ONOFF_CTRL_EERE,
RV3029_ONOFF_CTRL_EERE);
}
-static int rv3029_eeprom_enter(struct device *dev)
+static int rv3029_eeprom_enter(struct rv3029_data *rv3029)
{
+ unsigned int sr;
int ret;
- u8 sr;
/* Check whether we are in the allowed voltage range. */
- ret = rv3029_get_sr(dev, &sr);
+ ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
if (ret < 0)
return ret;
- if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+ if (sr & RV3029_STATUS_VLOW2)
+ return -ENODEV;
+ if (sr & RV3029_STATUS_VLOW1) {
/* We clear the bits and retry once just in case
* we had a brown out in early startup.
*/
- sr &= ~RV3029_STATUS_VLOW1;
- sr &= ~RV3029_STATUS_VLOW2;
- ret = rv3029_set_sr(dev, sr);
+ ret = regmap_update_bits(rv3029->regmap, RV3029_STATUS,
+ RV3029_STATUS_VLOW1, 0);
if (ret < 0)
return ret;
usleep_range(1000, 10000);
- ret = rv3029_get_sr(dev, &sr);
+ ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
if (ret < 0)
return ret;
- if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
- dev_err(dev,
+ if (sr & RV3029_STATUS_VLOW1) {
+ dev_err(rv3029->dev,
"Supply voltage is too low to safely access the EEPROM.\n");
return -ENODEV;
}
}
/* Disable eeprom refresh. */
- ret = rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE,
- 0);
+ ret = regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL,
+ RV3029_ONOFF_CTRL_EERE, 0);
if (ret < 0)
return ret;
/* Wait for any previous eeprom accesses to finish. */
- ret = rv3029_eeprom_busywait(dev);
+ ret = rv3029_eeprom_busywait(rv3029);
if (ret < 0)
- rv3029_eeprom_exit(dev);
+ rv3029_eeprom_exit(rv3029);
return ret;
}
-static int rv3029_eeprom_read(struct device *dev, u8 reg,
+static int rv3029_eeprom_read(struct rv3029_data *rv3029, u8 reg,
u8 buf[], size_t len)
{
int ret, err;
- err = rv3029_eeprom_enter(dev);
+ err = rv3029_eeprom_enter(rv3029);
if (err < 0)
return err;
- ret = rv3029_read_regs(dev, reg, buf, len);
+ ret = regmap_bulk_read(rv3029->regmap, reg, buf, len);
- err = rv3029_eeprom_exit(dev);
+ err = rv3029_eeprom_exit(rv3029);
if (err < 0)
return err;
return ret;
}
-static int rv3029_eeprom_write(struct device *dev, u8 reg,
+static int rv3029_eeprom_write(struct rv3029_data *rv3029, u8 reg,
u8 const buf[], size_t len)
{
- int ret;
+ unsigned int tmp;
+ int ret, err;
size_t i;
- u8 tmp;
- ret = rv3029_eeprom_enter(dev);
- if (ret < 0)
- return ret;
+ err = rv3029_eeprom_enter(rv3029);
+ if (err < 0)
+ return err;
for (i = 0; i < len; i++, reg++) {
- ret = rv3029_read_regs(dev, reg, &tmp, 1);
+ ret = regmap_read(rv3029->regmap, reg, &tmp);
if (ret < 0)
break;
if (tmp != buf[i]) {
- ret = rv3029_write_regs(dev, reg, &buf[i], 1);
+ tmp = buf[i];
+ ret = regmap_write(rv3029->regmap, reg, tmp);
if (ret < 0)
break;
}
- ret = rv3029_eeprom_busywait(dev);
+ ret = rv3029_eeprom_busywait(rv3029);
if (ret < 0)
break;
}
- ret = rv3029_eeprom_exit(dev);
- if (ret < 0)
- return ret;
+ err = rv3029_eeprom_exit(rv3029);
+ if (err < 0)
+ return err;
- return 0;
+ return ret;
}
-static int rv3029_eeprom_update_bits(struct device *dev,
+static int rv3029_eeprom_update_bits(struct rv3029_data *rv3029,
u8 reg, u8 mask, u8 set)
{
u8 buf;
int ret;
- ret = rv3029_eeprom_read(dev, reg, &buf, 1);
+ ret = rv3029_eeprom_read(rv3029, reg, &buf, 1);
if (ret < 0)
return ret;
buf &= ~mask;
buf |= set & mask;
- ret = rv3029_eeprom_write(dev, reg, &buf, 1);
+ ret = rv3029_eeprom_write(rv3029, reg, &buf, 1);
if (ret < 0)
return ret;
@@ -330,20 +266,20 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
struct device *dev = dev_id;
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct mutex *lock = &rv3029->rtc->ops_lock;
+ unsigned int flags, controls;
unsigned long events = 0;
- u8 flags, controls;
int ret;
mutex_lock(lock);
- ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+ ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
if (ret) {
dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
mutex_unlock(lock);
return IRQ_NONE;
}
- ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+ ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
if (ret) {
dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
mutex_unlock(lock);
@@ -358,8 +294,8 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
if (events) {
rtc_update_irq(rv3029->rtc, 1, events);
- rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
- rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+ regmap_write(rv3029->regmap, RV3029_IRQ_FLAGS, flags);
+ regmap_write(rv3029->regmap, RV3029_IRQ_CTRL, controls);
}
mutex_unlock(lock);
@@ -368,22 +304,22 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
{
- u8 buf[1];
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+ unsigned int sr;
int ret;
u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
- ret = rv3029_get_sr(dev, buf);
- if (ret < 0) {
- dev_err(dev, "%s: reading SR failed\n", __func__);
- return -EIO;
- }
+ ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
+ if (ret < 0)
+ return ret;
- ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
+ if (sr & (RV3029_STATUS_VLOW2 | RV3029_STATUS_PON))
+ return -EINVAL;
+
+ ret = regmap_bulk_read(rv3029->regmap, RV3029_W_SEC, regs,
RV3029_WATCH_SECTION_LEN);
- if (ret < 0) {
- dev_err(dev, "%s: reading RTC section failed\n", __func__);
+ if (ret < 0)
return ret;
- }
tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
@@ -411,34 +347,24 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct rtc_time *const tm = &alarm->time;
+ unsigned int controls, flags;
int ret;
- u8 regs[8], controls, flags;
-
- ret = rv3029_get_sr(dev, regs);
- if (ret < 0) {
- dev_err(dev, "%s: reading SR failed\n", __func__);
- return -EIO;
- }
+ u8 regs[8];
- ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
+ ret = regmap_bulk_read(rv3029->regmap, RV3029_A_SC, regs,
RV3029_ALARM_SECTION_LEN);
-
- if (ret < 0) {
- dev_err(dev, "%s: reading alarm section failed\n", __func__);
+ if (ret < 0)
return ret;
- }
- ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
- if (ret) {
- dev_err(dev, "Read IRQ Control Register error %d\n", ret);
+ ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
+ if (ret)
return ret;
- }
- ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
- if (ret < 0) {
- dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
+
+ ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
+ if (ret < 0)
return ret;
- }
tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
@@ -456,50 +382,20 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
{
- int ret;
- u8 controls;
-
- ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
- if (ret < 0) {
- dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
- return ret;
- }
-
- /* enable/disable AIE irq */
- if (enable)
- controls |= RV3029_IRQ_CTRL_AIE;
- else
- controls &= ~RV3029_IRQ_CTRL_AIE;
-
- ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
- if (ret < 0) {
- dev_err(dev, "can't update INT reg\n");
- return ret;
- }
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
- return 0;
+ return regmap_update_bits(rv3029->regmap, RV3029_IRQ_CTRL,
+ RV3029_IRQ_CTRL_AIE,
+ enable ? RV3029_IRQ_CTRL_AIE : 0);
}
static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct rtc_time *const tm = &alarm->time;
int ret;
u8 regs[8];
- /*
- * The clock has an 8 bit wide bcd-coded register (they never learn)
- * for the year. tm_year is an offset from 1900 and we are interested
- * in the 2000-2099 range, so any value less than 100 is invalid.
- */
- if (tm->tm_year < 100)
- return -EINVAL;
-
- ret = rv3029_get_sr(dev, regs);
- if (ret < 0) {
- dev_err(dev, "%s: reading SR failed\n", __func__);
- return -EIO;
- }
-
/* Activate all the alarms with AE_x bit */
regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X;
@@ -515,39 +411,20 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
| RV3029_A_AE_X;
/* Write the alarm */
- ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
+ ret = regmap_bulk_write(rv3029->regmap, RV3029_A_SC, regs,
RV3029_ALARM_SECTION_LEN);
if (ret < 0)
return ret;
- if (alarm->enabled) {
- /* enable AIE irq */
- ret = rv3029_alarm_irq_enable(dev, 1);
- if (ret)
- return ret;
- } else {
- /* disable AIE irq */
- ret = rv3029_alarm_irq_enable(dev, 0);
- if (ret)
- return ret;
- }
-
- return 0;
+ return rv3029_alarm_irq_enable(dev, alarm->enabled);
}
static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
{
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
u8 regs[8];
int ret;
- /*
- * The clock has an 8 bit wide bcd-coded register (they never learn)
- * for the year. tm_year is an offset from 1900 and we are interested
- * in the 2000-2099 range, so any value less than 100 is invalid.
- */
- if (tm->tm_year < 100)
- return -EINVAL;
-
regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
@@ -556,24 +433,55 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
- ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
+ ret = regmap_bulk_write(rv3029->regmap, RV3029_W_SEC, regs,
RV3029_WATCH_SECTION_LEN);
if (ret < 0)
return ret;
- ret = rv3029_get_sr(dev, regs);
- if (ret < 0) {
- dev_err(dev, "%s: reading SR failed\n", __func__);
- return ret;
- }
- /* clear PON bit */
- ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
- if (ret < 0) {
- dev_err(dev, "%s: reading SR failed\n", __func__);
- return ret;
+ /* clear PON and VLOW2 bits */
+ return regmap_update_bits(rv3029->regmap, RV3029_STATUS,
+ RV3029_STATUS_PON | RV3029_STATUS_VLOW2, 0);
+}
+
+static int rv3029_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+ unsigned long vl = 0;
+ int sr, ret = 0;
+
+ switch (cmd) {
+ case RTC_VL_READ:
+ ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
+ if (ret < 0)
+ return ret;
+
+ if (sr & RV3029_STATUS_VLOW1)
+ vl = RTC_VL_ACCURACY_LOW;
+
+ if (sr & (RV3029_STATUS_VLOW2 | RV3029_STATUS_PON))
+ vl |= RTC_VL_DATA_INVALID;
+
+ return put_user(vl, (unsigned int __user *)arg);
+
+ case RTC_VL_CLR:
+ return regmap_update_bits(rv3029->regmap, RV3029_STATUS,
+ RV3029_STATUS_VLOW1, 0);
+
+ default:
+ return -ENOIOCTLCMD;
}
+}
- return 0;
+static int rv3029_nvram_write(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ return regmap_bulk_write(priv, RV3029_RAM_PAGE + offset, val, bytes);
+}
+
+static int rv3029_nvram_read(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ return regmap_bulk_read(priv, RV3029_RAM_PAGE + offset, val, bytes);
}
static const struct rv3029_trickle_tab_elem {
@@ -635,6 +543,7 @@ static const struct rv3029_trickle_tab_elem {
static void rv3029_trickle_config(struct device *dev)
{
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct device_node *of_node = dev->of_node;
const struct rv3029_trickle_tab_elem *elem;
int i, err;
@@ -661,7 +570,7 @@ static void rv3029_trickle_config(struct device *dev)
"Trickle charger enabled at %d ohms resistance.\n",
elem->r);
}
- err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
+ err = rv3029_eeprom_update_bits(rv3029, RV3029_CONTROL_E2P_EECTRL,
RV3029_TRICKLE_MASK,
trickle_set_bits);
if (err < 0)
@@ -670,12 +579,12 @@ static void rv3029_trickle_config(struct device *dev)
#ifdef CONFIG_RTC_DRV_RV3029_HWMON
-static int rv3029_read_temp(struct device *dev, int *temp_mC)
+static int rv3029_read_temp(struct rv3029_data *rv3029, int *temp_mC)
{
+ unsigned int temp;
int ret;
- u8 temp;
- ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
+ ret = regmap_read(rv3029->regmap, RV3029_TEMP_PAGE, &temp);
if (ret < 0)
return ret;
@@ -688,9 +597,10 @@ static ssize_t rv3029_hwmon_show_temp(struct device *dev,
struct device_attribute *attr,
char *buf)
{
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
int ret, temp_mC;
- ret = rv3029_read_temp(dev, &temp_mC);
+ ret = rv3029_read_temp(rv3029, &temp_mC);
if (ret < 0)
return ret;
@@ -702,9 +612,10 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
const char *buf,
size_t count)
{
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+ unsigned int th_set_bits = 0;
unsigned long interval_ms;
int ret;
- u8 th_set_bits = 0;
ret = kstrtoul(buf, 10, &interval_ms);
if (ret < 0)
@@ -715,7 +626,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
if (interval_ms >= 16000)
th_set_bits |= RV3029_EECTRL_THP;
}
- ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
+ ret = rv3029_eeprom_update_bits(rv3029, RV3029_CONTROL_E2P_EECTRL,
RV3029_EECTRL_THE | RV3029_EECTRL_THP,
th_set_bits);
if (ret < 0)
@@ -728,10 +639,11 @@ static ssize_t rv3029_hwmon_show_update_interval(struct device *dev,
struct device_attribute *attr,
char *buf)
{
+ struct rv3029_data *rv3029 = dev_get_drvdata(dev);
int ret, interval_ms;
u8 eectrl;
- ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
+ ret = rv3029_eeprom_read(rv3029, RV3029_CONTROL_E2P_EECTRL,
&eectrl, 1);
if (ret < 0)
return ret;
@@ -785,14 +697,23 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
static struct rtc_class_ops rv3029_rtc_ops = {
.read_time = rv3029_read_time,
.set_time = rv3029_set_time,
+ .ioctl = rv3029_ioctl,
};
static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name)
{
struct rv3029_data *rv3029;
+ struct nvmem_config nvmem_cfg = {
+ .name = "rv3029_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = RV3029_RAM_SECTION_LEN,
+ .type = NVMEM_TYPE_BATTERY_BACKED,
+ .reg_read = rv3029_nvram_read,
+ .reg_write = rv3029_nvram_write,
+ };
int rc = 0;
- u8 buf[1];
rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
if (!rv3029)
@@ -803,21 +724,12 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
rv3029->dev = dev;
dev_set_drvdata(dev, rv3029);
- rc = rv3029_get_sr(dev, buf);
- if (rc < 0) {
- dev_err(dev, "reading status failed\n");
- return rc;
- }
-
rv3029_trickle_config(dev);
rv3029_hwmon_register(dev, name);
- rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
- THIS_MODULE);
- if (IS_ERR(rv3029->rtc)) {
- dev_err(dev, "unable to register the class device\n");
+ rv3029->rtc = devm_rtc_allocate_device(dev);
+ if (IS_ERR(rv3029->rtc))
return PTR_ERR(rv3029->rtc);
- }
if (rv3029->irq > 0) {
rc = devm_request_threaded_irq(dev, rv3029->irq,
@@ -834,20 +746,48 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
}
}
+ rv3029->rtc->ops = &rv3029_rtc_ops;
+ rv3029->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rv3029->rtc->range_max = RTC_TIMESTAMP_END_2079;
+
+ rc = rtc_register_device(rv3029->rtc);
+ if (rc)
+ return rc;
+
+ nvmem_cfg.priv = rv3029->regmap;
+ rtc_nvmem_register(rv3029->rtc, &nvmem_cfg);
+
return 0;
}
+static const struct regmap_range rv3029_holes_range[] = {
+ regmap_reg_range(0x05, 0x07),
+ regmap_reg_range(0x0f, 0x0f),
+ regmap_reg_range(0x17, 0x17),
+ regmap_reg_range(0x1a, 0x1f),
+ regmap_reg_range(0x21, 0x27),
+ regmap_reg_range(0x34, 0x37),
+};
+
+static const struct regmap_access_table rv3029_regs = {
+ .no_ranges = rv3029_holes_range,
+ .n_no_ranges = ARRAY_SIZE(rv3029_holes_range),
+};
+
+static const struct regmap_config config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .rd_table = &rv3029_regs,
+ .wr_table = &rv3029_regs,
+ .max_register = 0x3f,
+};
+
#if IS_ENABLED(CONFIG_I2C)
static int rv3029_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regmap *regmap;
- static const struct regmap_config config = {
- .reg_bits = 8,
- .val_bits = 8,
- };
-
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
I2C_FUNC_SMBUS_BYTE)) {
dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n");
@@ -855,11 +795,8 @@ static int rv3029_i2c_probe(struct i2c_client *client,
}
regmap = devm_regmap_init_i2c(client, &config);
- if (IS_ERR(regmap)) {
- dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
- __func__, PTR_ERR(regmap));
+ if (IS_ERR(regmap))
return PTR_ERR(regmap);
- }
return rv3029_probe(&client->dev, regmap, client->irq, client->name);
}
@@ -873,24 +810,20 @@ MODULE_DEVICE_TABLE(i2c, rv3029_id);
static const struct of_device_id rv3029_of_match[] = {
{ .compatible = "microcrystal,rv3029" },
- /* Backward compatibility only, do not use compatibles below: */
- { .compatible = "rv3029" },
- { .compatible = "rv3029c2" },
- { .compatible = "mc,rv3029c2" },
{ }
};
MODULE_DEVICE_TABLE(of, rv3029_of_match);
static struct i2c_driver rv3029_driver = {
.driver = {
- .name = "rtc-rv3029c2",
+ .name = "rv3029",
.of_match_table = of_match_ptr(rv3029_of_match),
},
.probe = rv3029_i2c_probe,
.id_table = rv3029_id,
};
-static int rv3029_register_driver(void)
+static int __init rv3029_register_driver(void)
{
return i2c_add_driver(&rv3029_driver);
}
@@ -902,7 +835,7 @@ static void rv3029_unregister_driver(void)
#else
-static int rv3029_register_driver(void)
+static int __init rv3029_register_driver(void)
{
return 0;
}
@@ -917,18 +850,11 @@ static void rv3029_unregister_driver(void)
static int rv3049_probe(struct spi_device *spi)
{
- static const struct regmap_config config = {
- .reg_bits = 8,
- .val_bits = 8,
- };
struct regmap *regmap;
regmap = devm_regmap_init_spi(spi, &config);
- if (IS_ERR(regmap)) {
- dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
- __func__, PTR_ERR(regmap));
+ if (IS_ERR(regmap))
return PTR_ERR(regmap);
- }
return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
}
@@ -940,24 +866,24 @@ static struct spi_driver rv3049_driver = {
.probe = rv3049_probe,
};
-static int rv3049_register_driver(void)
+static int __init rv3049_register_driver(void)
{
return spi_register_driver(&rv3049_driver);
}
-static void rv3049_unregister_driver(void)
+static void __exit rv3049_unregister_driver(void)
{
spi_unregister_driver(&rv3049_driver);
}
#else
-static int rv3049_register_driver(void)
+static int __init rv3049_register_driver(void)
{
return 0;
}
-static void rv3049_unregister_driver(void)
+static void __exit rv3049_unregister_driver(void)
{
}
@@ -968,16 +894,12 @@ static int __init rv30x9_init(void)
int ret;
ret = rv3029_register_driver();
- if (ret) {
- pr_err("Failed to register rv3029 driver: %d\n", ret);
+ if (ret)
return ret;
- }
ret = rv3049_register_driver();
- if (ret) {
- pr_err("Failed to register rv3049 driver: %d\n", ret);
+ if (ret)
rv3029_unregister_driver();
- }
return ret;
}
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
index fc5243400108..93c3a6b627bd 100644
--- a/drivers/rtc/rtc-rv8803.c
+++ b/drivers/rtc/rtc-rv8803.c
@@ -411,6 +411,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct i2c_client *client = to_i2c_client(dev);
struct rv8803_data *rv8803 = dev_get_drvdata(dev);
+ unsigned int vl = 0;
int flags, ret = 0;
switch (cmd) {
@@ -419,18 +420,15 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
if (flags < 0)
return flags;
- if (flags & RV8803_FLAG_V1F)
+ if (flags & RV8803_FLAG_V1F) {
dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
+ vl = RTC_VL_ACCURACY_LOW;
+ }
if (flags & RV8803_FLAG_V2F)
- dev_warn(&client->dev, "Voltage low, data loss detected.\n");
-
- flags &= RV8803_FLAG_V1F | RV8803_FLAG_V2F;
+ vl |= RTC_VL_DATA_INVALID;
- if (copy_to_user((void __user *)arg, &flags, sizeof(int)))
- return -EFAULT;
-
- return 0;
+ return put_user(vl, (unsigned int __user *)arg);
case RTC_VL_CLR:
mutex_lock(&rv8803->flags_lock);
@@ -440,7 +438,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
return flags;
}
- flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F);
+ flags &= ~RV8803_FLAG_V1F;
ret = rv8803_write_reg(client, RV8803_FLAG, flags);
mutex_unlock(&rv8803->flags_lock);
if (ret)
@@ -564,9 +562,8 @@ static int rv8803_probe(struct i2c_client *client,
dev_warn(&client->dev, "An alarm maybe have been missed.\n");
rv8803->rtc = devm_rtc_allocate_device(&client->dev);
- if (IS_ERR(rv8803->rtc)) {
+ if (IS_ERR(rv8803->rtc))
return PTR_ERR(rv8803->rtc);
- }
if (client->irq > 0) {
err = devm_request_threaded_irq(&client->dev, client->irq,
diff --git a/drivers/rtc/rtc-rx6110.c b/drivers/rtc/rtc-rx6110.c
index 71e20a6bd387..3a9eb7043f01 100644
--- a/drivers/rtc/rtc-rx6110.c
+++ b/drivers/rtc/rtc-rx6110.c
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Driver for the Epson RTC module RX-6110 SA
*
* Copyright(C) 2015 Pengutronix, Steffen Trumtrar <kernel@pengutronix.de>
* Copyright(C) SEIKO EPSON CORPORATION 2013. All rights reserved.
- *
- * This driver software is distributed as is, without any warranty of any kind,
- * either express or implied as further specified in the GNU Public License.
- * This software may be used and distributed according to the terms of the GNU
- * Public License, version 2 as published by the Free Software Foundation.
- * See the file COPYING in the main directory of this archive for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/bcd.h>
@@ -370,11 +362,6 @@ static int rx6110_probe(struct spi_device *spi)
return 0;
}
-static int rx6110_remove(struct spi_device *spi)
-{
- return 0;
-}
-
static const struct spi_device_id rx6110_id[] = {
{ "rx6110", 0 },
{ }
@@ -393,7 +380,6 @@ static struct spi_driver rx6110_driver = {
.of_match_table = of_match_ptr(rx6110_spi_of_match),
},
.probe = rx6110_probe,
- .remove = rx6110_remove,
.id_table = rx6110_id,
};
diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c
index 8102469e27c0..fe010151ec8f 100644
--- a/drivers/rtc/rtc-rx8010.c
+++ b/drivers/rtc/rtc-rx8010.c
@@ -389,9 +389,8 @@ static int rx8010_alarm_irq_enable(struct device *dev,
static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
- struct i2c_client *client = to_i2c_client(dev);
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
- int ret, tmp;
+ int tmp;
int flagreg;
switch (cmd) {
@@ -400,24 +399,8 @@ static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
if (flagreg < 0)
return flagreg;
- tmp = !!(flagreg & RX8010_FLAG_VLF);
- if (copy_to_user((void __user *)arg, &tmp, sizeof(int)))
- return -EFAULT;
-
- return 0;
-
- case RTC_VL_CLR:
- flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG);
- if (flagreg < 0) {
- return flagreg;
- }
-
- flagreg &= ~RX8010_FLAG_VLF;
- ret = i2c_smbus_write_byte_data(client, RX8010_FLAG, flagreg);
- if (ret < 0)
- return ret;
-
- return 0;
+ tmp = flagreg & RX8010_FLAG_VLF ? RTC_VL_DATA_INVALID : 0;
+ return put_user(tmp, (unsigned int __user *)arg);
default:
return -ENOIOCTLCMD;
@@ -482,7 +465,7 @@ static int rx8010_probe(struct i2c_client *client,
rx8010->rtc->max_user_freq = 1;
- return err;
+ return 0;
}
static struct i2c_driver rx8010_driver = {
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index b9bda10589e0..a24f85893f90 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -67,7 +67,6 @@ static const struct i2c_device_id rx8025_id[] = {
MODULE_DEVICE_TABLE(i2c, rx8025_id);
struct rx8025_data {
- struct i2c_client *client;
struct rtc_device *rtc;
u8 ctrl1;
};
@@ -103,10 +102,10 @@ static s32 rx8025_write_regs(const struct i2c_client *client,
static int rx8025_check_validity(struct device *dev)
{
- struct rx8025_data *rx8025 = dev_get_drvdata(dev);
+ struct i2c_client *client = to_i2c_client(dev);
int ctrl2;
- ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2);
+ ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2);
if (ctrl2 < 0)
return ctrl2;
@@ -178,6 +177,7 @@ out:
static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct rx8025_data *rx8025 = dev_get_drvdata(dev);
u8 date[7];
int err;
@@ -186,7 +186,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
if (err)
return err;
- err = rx8025_read_regs(rx8025->client, RX8025_REG_SEC, 7, date);
+ err = rx8025_read_regs(client, RX8025_REG_SEC, 7, date);
if (err)
return err;
@@ -211,6 +211,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct rx8025_data *rx8025 = dev_get_drvdata(dev);
u8 date[7];
int ret;
@@ -237,11 +238,11 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
dev_dbg(dev, "%s: write %7ph\n", __func__, date);
- ret = rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date);
+ ret = rx8025_write_regs(client, RX8025_REG_SEC, 7, date);
if (ret < 0)
return ret;
- return rx8025_reset_validity(rx8025->client);
+ return rx8025_reset_validity(client);
}
static int rx8025_init_client(struct i2c_client *client)
@@ -251,7 +252,7 @@ static int rx8025_init_client(struct i2c_client *client)
int need_clear = 0;
int err;
- err = rx8025_read_regs(rx8025->client, RX8025_REG_CTRL1, 2, ctrl);
+ err = rx8025_read_regs(client, RX8025_REG_CTRL1, 2, ctrl);
if (err)
goto out;
@@ -280,8 +281,8 @@ out:
/* Alarm support */
static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct rx8025_data *rx8025 = dev_get_drvdata(dev);
- struct i2c_client *client = rx8025->client;
u8 ald[2];
int ctrl2, err;
@@ -347,18 +348,18 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
if (rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE) {
rx8025->ctrl1 &= ~RX8025_BIT_CTRL1_DALE;
- err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1,
+ err = rx8025_write_reg(client, RX8025_REG_CTRL1,
rx8025->ctrl1);
if (err)
return err;
}
- err = rx8025_write_regs(rx8025->client, RX8025_REG_ALDMIN, 2, ald);
+ err = rx8025_write_regs(client, RX8025_REG_ALDMIN, 2, ald);
if (err)
return err;
if (t->enabled) {
rx8025->ctrl1 |= RX8025_BIT_CTRL1_DALE;
- err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1,
+ err = rx8025_write_reg(client, RX8025_REG_CTRL1,
rx8025->ctrl1);
if (err)
return err;
@@ -369,6 +370,7 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct rx8025_data *rx8025 = dev_get_drvdata(dev);
u8 ctrl1;
int err;
@@ -381,7 +383,7 @@ static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)
if (ctrl1 != rx8025->ctrl1) {
rx8025->ctrl1 = ctrl1;
- err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1,
+ err = rx8025_write_reg(client, RX8025_REG_CTRL1,
rx8025->ctrl1);
if (err)
return err;
@@ -516,7 +518,6 @@ static int rx8025_probe(struct i2c_client *client,
if (!rx8025)
return -ENOMEM;
- rx8025->client = client;
i2c_set_clientdata(client, rx8025);
err = rx8025_init_client(client);
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index 84806ff763cf..03672a246356 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -423,8 +423,6 @@ static const struct rtc_class_ops s35390a_rtc_ops = {
.ioctl = s35390a_rtc_ioctl,
};
-static struct i2c_driver s35390a_driver;
-
static int s35390a_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -434,37 +432,36 @@ static int s35390a_probe(struct i2c_client *client,
char buf, status1;
struct device *dev = &client->dev;
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- err = -ENODEV;
- goto exit;
- }
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -ENODEV;
s35390a = devm_kzalloc(dev, sizeof(struct s35390a), GFP_KERNEL);
- if (!s35390a) {
- err = -ENOMEM;
- goto exit;
- }
+ if (!s35390a)
+ return -ENOMEM;
s35390a->client[0] = client;
i2c_set_clientdata(client, s35390a);
/* This chip uses multiple addresses, use dummy devices for them */
for (i = 1; i < 8; ++i) {
- s35390a->client[i] = i2c_new_dummy(client->adapter,
- client->addr + i);
- if (!s35390a->client[i]) {
+ s35390a->client[i] = devm_i2c_new_dummy_device(dev,
+ client->adapter,
+ client->addr + i);
+ if (IS_ERR(s35390a->client[i])) {
dev_err(dev, "Address %02x unavailable\n",
client->addr + i);
- err = -EBUSY;
- goto exit_dummy;
+ return PTR_ERR(s35390a->client[i]);
}
}
+ s35390a->rtc = devm_rtc_allocate_device(dev);
+ if (IS_ERR(s35390a->rtc))
+ return PTR_ERR(s35390a->rtc);
+
err_read = s35390a_read_status(s35390a, &status1);
if (err_read < 0) {
- err = err_read;
dev_err(dev, "error resetting chip\n");
- goto exit_dummy;
+ return err_read;
}
if (status1 & S35390A_FLAG_24H)
@@ -478,25 +475,21 @@ static int s35390a_probe(struct i2c_client *client,
err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1);
if (err < 0) {
dev_err(dev, "error disabling alarm");
- goto exit_dummy;
+ return err;
}
} else {
err = s35390a_disable_test_mode(s35390a);
if (err < 0) {
dev_err(dev, "error disabling test mode\n");
- goto exit_dummy;
+ return err;
}
}
device_set_wakeup_capable(dev, 1);
- s35390a->rtc = devm_rtc_device_register(dev, s35390a_driver.driver.name,
- &s35390a_rtc_ops, THIS_MODULE);
-
- if (IS_ERR(s35390a->rtc)) {
- err = PTR_ERR(s35390a->rtc);
- goto exit_dummy;
- }
+ s35390a->rtc->ops = &s35390a_rtc_ops;
+ s35390a->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ s35390a->rtc->range_max = RTC_TIMESTAMP_END_2099;
/* supports per-minute alarms only, therefore set uie_unsupported */
s35390a->rtc->uie_unsupported = 1;
@@ -504,27 +497,7 @@ static int s35390a_probe(struct i2c_client *client,
if (status1 & S35390A_FLAG_INT2)
rtc_update_irq(s35390a->rtc, 1, RTC_AF);
- return 0;
-
-exit_dummy:
- for (i = 1; i < 8; ++i)
- if (s35390a->client[i])
- i2c_unregister_device(s35390a->client[i]);
-
-exit:
- return err;
-}
-
-static int s35390a_remove(struct i2c_client *client)
-{
- unsigned int i;
- struct s35390a *s35390a = i2c_get_clientdata(client);
-
- for (i = 1; i < 8; ++i)
- if (s35390a->client[i])
- i2c_unregister_device(s35390a->client[i]);
-
- return 0;
+ return rtc_register_device(s35390a->rtc);
}
static struct i2c_driver s35390a_driver = {
@@ -533,7 +506,6 @@ static struct i2c_driver s35390a_driver = {
.of_match_table = of_match_ptr(s35390a_of_match),
},
.probe = s35390a_probe,
- .remove = s35390a_remove,
.id_table = s35390a_id,
};
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 74bf6473a05d..e1b50e682fc4 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -444,7 +444,6 @@ static int s3c_rtc_probe(struct platform_device *pdev)
{
struct s3c_rtc *info = NULL;
struct rtc_time rtc_tm;
- struct resource *res;
int ret;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
@@ -453,10 +452,8 @@ static int s3c_rtc_probe(struct platform_device *pdev)
/* find the IRQs */
info->irq_tick = platform_get_irq(pdev, 1);
- if (info->irq_tick < 0) {
- dev_err(&pdev->dev, "no irq for rtc tick\n");
+ if (info->irq_tick < 0)
return info->irq_tick;
- }
info->dev = &pdev->dev;
info->data = of_device_get_match_data(&pdev->dev);
@@ -470,17 +467,14 @@ static int s3c_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, info);
info->irq_alarm = platform_get_irq(pdev, 0);
- if (info->irq_alarm < 0) {
- dev_err(&pdev->dev, "no irq for alarm\n");
+ if (info->irq_alarm < 0)
return info->irq_alarm;
- }
dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n",
info->irq_tick, info->irq_alarm);
/* get the memory region */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- info->base = devm_ioremap_resource(&pdev->dev, res);
+ info->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(info->base))
return PTR_ERR(info->base);
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
index c7f1bf823ea0..eb9dde4095a9 100644
--- a/drivers/rtc/rtc-s5m.c
+++ b/drivers/rtc/rtc-s5m.c
@@ -760,10 +760,10 @@ static int s5m_rtc_probe(struct platform_device *pdev)
return -ENODEV;
}
- info->i2c = i2c_new_dummy(s5m87xx->i2c->adapter, RTC_I2C_ADDR);
- if (!info->i2c) {
+ info->i2c = i2c_new_dummy_device(s5m87xx->i2c->adapter, RTC_I2C_ADDR);
+ if (IS_ERR(info->i2c)) {
dev_err(&pdev->dev, "Failed to allocate I2C for RTC\n");
- return -ENODEV;
+ return PTR_ERR(info->i2c);
}
info->regmap = devm_regmap_init_i2c(info->i2c, regmap_cfg);
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 86fa723b3b76..d37893f6eaee 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -252,7 +252,6 @@ EXPORT_SYMBOL_GPL(sa1100_rtc_init);
static int sa1100_rtc_probe(struct platform_device *pdev)
{
struct sa1100_rtc *info;
- struct resource *iores;
void __iomem *base;
int irq_1hz, irq_alarm;
int ret;
@@ -281,8 +280,7 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
return ret;
}
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&pdev->dev, iores);
+ base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
diff --git a/drivers/rtc/rtc-sc27xx.c b/drivers/rtc/rtc-sc27xx.c
index b4eb3b3c6c2c..36810dd40cd3 100644
--- a/drivers/rtc/rtc-sc27xx.c
+++ b/drivers/rtc/rtc-sc27xx.c
@@ -138,7 +138,7 @@ static int sprd_rtc_lock_alarm(struct sprd_rtc *rtc, bool lock)
if (ret)
return ret;
- val &= ~(SPRD_RTC_ALMLOCK_MASK | SPRD_RTC_POWEROFF_ALM_FLAG);
+ val &= ~SPRD_RTC_ALMLOCK_MASK;
if (lock)
val |= SPRD_RTC_ALM_LOCK;
else
@@ -614,10 +614,8 @@ static int sprd_rtc_probe(struct platform_device *pdev)
}
rtc->irq = platform_get_irq(pdev, 0);
- if (rtc->irq < 0) {
- dev_err(&pdev->dev, "failed to get RTC irq number\n");
+ if (rtc->irq < 0)
return rtc->irq;
- }
rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc))
@@ -656,7 +654,6 @@ static int sprd_rtc_probe(struct platform_device *pdev)
rtc->rtc->range_max = 5662310399LL;
ret = rtc_register_device(rtc->rtc);
if (ret) {
- dev_err(&pdev->dev, "failed to register rtc device\n");
device_init_wakeup(&pdev->dev, 0);
return ret;
}
@@ -664,12 +661,6 @@ static int sprd_rtc_probe(struct platform_device *pdev)
return 0;
}
-static int sprd_rtc_remove(struct platform_device *pdev)
-{
- device_init_wakeup(&pdev->dev, 0);
- return 0;
-}
-
static const struct of_device_id sprd_rtc_of_match[] = {
{ .compatible = "sprd,sc2731-rtc", },
{ },
@@ -682,7 +673,6 @@ static struct platform_driver sprd_rtc_driver = {
.of_match_table = sprd_rtc_of_match,
},
.probe = sprd_rtc_probe,
- .remove = sprd_rtc_remove,
};
module_platform_driver(sprd_rtc_driver);
diff --git a/drivers/rtc/rtc-sd3078.c b/drivers/rtc/rtc-sd3078.c
index 42cb90db7f94..a7aa943c1183 100644
--- a/drivers/rtc/rtc-sd3078.c
+++ b/drivers/rtc/rtc-sd3078.c
@@ -193,10 +193,8 @@ static int sd3078_probe(struct i2c_client *client,
sd3078->rtc->range_max = RTC_TIMESTAMP_END_2099;
ret = rtc_register_device(sd3078->rtc);
- if (ret) {
- dev_err(&client->dev, "failed to register rtc device\n");
+ if (ret)
return ret;
- }
sd3078_enable_reg_write(sd3078);
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 579b3ff5c644..feb1f8e52c00 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -504,7 +504,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
if (unlikely(!rtc->res))
return -EBUSY;
- rtc->regbase = devm_ioremap_nocache(&pdev->dev, rtc->res->start,
+ rtc->regbase = devm_ioremap(&pdev->dev, rtc->res->start,
rtc->regsize);
if (unlikely(!rtc->regbase))
return -EINVAL;
diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c
index c759c55359a1..a2c9c55667cd 100644
--- a/drivers/rtc/rtc-sirfsoc.c
+++ b/drivers/rtc/rtc-sirfsoc.c
@@ -365,13 +365,6 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev)
return 0;
}
-static int sirfsoc_rtc_remove(struct platform_device *pdev)
-{
- device_init_wakeup(&pdev->dev, 0);
-
- return 0;
-}
-
#ifdef CONFIG_PM_SLEEP
static int sirfsoc_rtc_suspend(struct device *dev)
{
@@ -450,7 +443,6 @@ static struct platform_driver sirfsoc_rtc_driver = {
.of_match_table = sirfsoc_rtc_of_match,
},
.probe = sirfsoc_rtc_probe,
- .remove = sirfsoc_rtc_remove,
};
module_platform_driver(sirfsoc_rtc_driver);
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
index 7ee673a25fd0..757f4daa7181 100644
--- a/drivers/rtc/rtc-snvs.c
+++ b/drivers/rtc/rtc-snvs.c
@@ -151,7 +151,7 @@ static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
struct snvs_rtc_data *data = dev_get_drvdata(dev);
unsigned long time = rtc_read_lp_counter(data);
- rtc_time_to_tm(time, tm);
+ rtc_time64_to_tm(time, tm);
return 0;
}
@@ -159,11 +159,9 @@ static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct snvs_rtc_data *data = dev_get_drvdata(dev);
- unsigned long time;
+ unsigned long time = rtc_tm_to_time64(tm);
int ret;
- rtc_tm_to_time(tm, &time);
-
/* Disable RTC first */
ret = snvs_rtc_enable(data, false);
if (ret)
@@ -185,7 +183,7 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
u32 lptar, lpsr;
regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar);
- rtc_time_to_tm(lptar, &alrm->time);
+ rtc_time64_to_tm(lptar, &alrm->time);
regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
@@ -207,12 +205,9 @@ static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct snvs_rtc_data *data = dev_get_drvdata(dev);
- struct rtc_time *alrm_tm = &alrm->time;
- unsigned long time;
+ unsigned long time = rtc_tm_to_time64(&alrm->time);
int ret;
- rtc_tm_to_time(alrm_tm, &time);
-
regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0);
ret = rtc_write_sync_lp(data);
if (ret)
@@ -279,6 +274,10 @@ static int snvs_rtc_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
+ data->rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(data->rtc))
+ return PTR_ERR(data->rtc);
+
data->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap");
if (IS_ERR(data->regmap)) {
@@ -343,10 +342,10 @@ static int snvs_rtc_probe(struct platform_device *pdev)
goto error_rtc_device_register;
}
- data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
- &snvs_rtc_ops, THIS_MODULE);
- if (IS_ERR(data->rtc)) {
- ret = PTR_ERR(data->rtc);
+ data->rtc->ops = &snvs_rtc_ops;
+ data->rtc->range_max = U32_MAX;
+ ret = rtc_register_device(data->rtc);
+ if (ret) {
dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
goto error_rtc_device_register;
}
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
index 0567944fd4f8..833daeb7b60e 100644
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -347,7 +347,6 @@ static const struct rtc_class_ops spear_rtc_ops = {
static int spear_rtc_probe(struct platform_device *pdev)
{
- struct resource *res;
struct spear_rtc_config *config;
int status = 0;
int irq;
@@ -358,10 +357,8 @@ static int spear_rtc_probe(struct platform_device *pdev)
/* alarm irqs */
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "no update irq?\n");
+ if (irq < 0)
return irq;
- }
status = devm_request_irq(&pdev->dev, irq, spear_rtc_irq, 0, pdev->name,
config);
@@ -371,8 +368,7 @@ static int spear_rtc_probe(struct platform_device *pdev)
return status;
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- config->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ config->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(config->ioaddr))
return PTR_ERR(config->ioaddr);
diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index 49474a31c66d..51041dc08af4 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -41,7 +41,6 @@
struct st_rtc {
struct rtc_device *rtc_dev;
struct rtc_wkalrm alarm;
- struct resource *res;
struct clk *clk;
unsigned long clkrate;
void __iomem *ioaddr;
@@ -186,7 +185,6 @@ static int st_rtc_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct st_rtc *rtc;
- struct resource *res;
uint32_t mode;
int ret = 0;
@@ -210,8 +208,7 @@ static int st_rtc_probe(struct platform_device *pdev)
spin_lock_init(&rtc->lock);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtc->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ rtc->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->ioaddr))
return PTR_ERR(rtc->ioaddr);
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index a833ebc4ecb9..01a45044f468 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -256,7 +256,6 @@ static int stk17ta8_nvram_write(void *priv, unsigned int pos, void *val,
static int stk17ta8_rtc_probe(struct platform_device *pdev)
{
- struct resource *res;
unsigned int cal;
unsigned int flags;
struct rtc_plat_data *pdata;
@@ -275,8 +274,7 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ioaddr))
return PTR_ERR(ioaddr);
pdata->ioaddr = ioaddr;
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 773a1990b93f..d774aa18f57a 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -693,15 +693,13 @@ static int stm32_rtc_probe(struct platform_device *pdev)
{
struct stm32_rtc *rtc;
const struct stm32_rtc_registers *regs;
- struct resource *res;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rtc->base = devm_ioremap_resource(&pdev->dev, res);
+ rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base))
return PTR_ERR(rtc->base);
@@ -776,7 +774,6 @@ static int stm32_rtc_probe(struct platform_device *pdev)
rtc->irq_alarm = platform_get_irq(pdev, 0);
if (rtc->irq_alarm <= 0) {
- dev_err(&pdev->dev, "no alarm irq\n");
ret = rtc->irq_alarm;
goto err;
}
@@ -900,8 +897,11 @@ static int stm32_rtc_resume(struct device *dev)
}
ret = stm32_rtc_wait_sync(rtc);
- if (ret < 0)
+ if (ret < 0) {
+ if (rtc->data->has_pclk)
+ clk_disable_unprepare(rtc->pclk);
return ret;
+ }
if (device_may_wakeup(dev))
return disable_irq_wake(rtc->irq_alarm);
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index c0e75c373605..852f5f3b3592 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -32,9 +32,11 @@
/* Control register */
#define SUN6I_LOSC_CTRL 0x0000
#define SUN6I_LOSC_CTRL_KEY (0x16aa << 16)
+#define SUN6I_LOSC_CTRL_AUTO_SWT_BYPASS BIT(15)
#define SUN6I_LOSC_CTRL_ALM_DHMS_ACC BIT(9)
#define SUN6I_LOSC_CTRL_RTC_HMS_ACC BIT(8)
#define SUN6I_LOSC_CTRL_RTC_YMD_ACC BIT(7)
+#define SUN6I_LOSC_CTRL_EXT_LOSC_EN BIT(4)
#define SUN6I_LOSC_CTRL_EXT_OSC BIT(0)
#define SUN6I_LOSC_CTRL_ACC_MASK GENMASK(9, 7)
@@ -128,11 +130,12 @@ struct sun6i_rtc_clk_data {
unsigned int has_prescaler : 1;
unsigned int has_out_clk : 1;
unsigned int export_iosc : 1;
+ unsigned int has_losc_en : 1;
+ unsigned int has_auto_swt : 1;
};
struct sun6i_rtc_dev {
struct rtc_device *rtc;
- struct device *dev;
const struct sun6i_rtc_clk_data *data;
void __iomem *base;
int irq;
@@ -190,6 +193,10 @@ static int sun6i_rtc_osc_set_parent(struct clk_hw *hw, u8 index)
val &= ~SUN6I_LOSC_CTRL_EXT_OSC;
val |= SUN6I_LOSC_CTRL_KEY;
val |= index ? SUN6I_LOSC_CTRL_EXT_OSC : 0;
+ if (rtc->data->has_losc_en) {
+ val &= ~SUN6I_LOSC_CTRL_EXT_LOSC_EN;
+ val |= index ? SUN6I_LOSC_CTRL_EXT_LOSC_EN : 0;
+ }
writel(val, rtc->base + SUN6I_LOSC_CTRL);
spin_unlock_irqrestore(&rtc->lock, flags);
@@ -215,6 +222,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
const char *iosc_name = "rtc-int-osc";
const char *clkout_name = "osc32k-out";
const char *parents[2];
+ u32 reg;
rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
if (!rtc)
@@ -235,9 +243,18 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
goto err;
}
+ reg = SUN6I_LOSC_CTRL_KEY;
+ if (rtc->data->has_auto_swt) {
+ /* Bypass auto-switch to int osc, on ext losc failure */
+ reg |= SUN6I_LOSC_CTRL_AUTO_SWT_BYPASS;
+ writel(reg, rtc->base + SUN6I_LOSC_CTRL);
+ }
+
/* Switch to the external, more precise, oscillator */
- writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
- rtc->base + SUN6I_LOSC_CTRL);
+ reg |= SUN6I_LOSC_CTRL_EXT_OSC;
+ if (rtc->data->has_losc_en)
+ reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN;
+ writel(reg, rtc->base + SUN6I_LOSC_CTRL);
/* Yes, I know, this is ugly. */
sun6i_rtc = rtc;
@@ -279,7 +296,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
of_property_read_string_index(node, "clock-output-names", 1,
&clkout_name);
- rtc->ext_losc = clk_register_gate(NULL, clkout_name, rtc->hw.init->name,
+ rtc->ext_losc = clk_register_gate(NULL, clkout_name, init.name,
0, rtc->base + SUN6I_LOSC_OUT_GATING,
SUN6I_LOSC_OUT_GATING_EN_OFFSET, 0,
&rtc->lock);
@@ -345,6 +362,39 @@ CLK_OF_DECLARE_DRIVER(sun8i_h3_rtc_clk, "allwinner,sun8i-h3-rtc",
CLK_OF_DECLARE_DRIVER(sun50i_h5_rtc_clk, "allwinner,sun50i-h5-rtc",
sun8i_h3_rtc_clk_init);
+static const struct sun6i_rtc_clk_data sun50i_h6_rtc_data = {
+ .rc_osc_rate = 16000000,
+ .fixed_prescaler = 32,
+ .has_prescaler = 1,
+ .has_out_clk = 1,
+ .export_iosc = 1,
+ .has_losc_en = 1,
+ .has_auto_swt = 1,
+};
+
+static void __init sun50i_h6_rtc_clk_init(struct device_node *node)
+{
+ sun6i_rtc_clk_init(node, &sun50i_h6_rtc_data);
+}
+CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc",
+ sun50i_h6_rtc_clk_init);
+
+/*
+ * The R40 user manual is self-conflicting on whether the prescaler is
+ * fixed or configurable. The clock diagram shows it as fixed, but there
+ * is also a configurable divider in the RTC block.
+ */
+static const struct sun6i_rtc_clk_data sun8i_r40_rtc_data = {
+ .rc_osc_rate = 16000000,
+ .fixed_prescaler = 512,
+};
+static void __init sun8i_r40_rtc_clk_init(struct device_node *node)
+{
+ sun6i_rtc_clk_init(node, &sun8i_r40_rtc_data);
+}
+CLK_OF_DECLARE_DRIVER(sun8i_r40_rtc_clk, "allwinner,sun8i-r40-rtc",
+ sun8i_r40_rtc_clk_init);
+
static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = {
.rc_osc_rate = 32000,
.has_out_clk = 1,
@@ -598,6 +648,33 @@ static const struct rtc_class_ops sun6i_rtc_ops = {
.alarm_irq_enable = sun6i_rtc_alarm_irq_enable
};
+#ifdef CONFIG_PM_SLEEP
+/* Enable IRQ wake on suspend, to wake up from RTC. */
+static int sun6i_rtc_suspend(struct device *dev)
+{
+ struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(chip->irq);
+
+ return 0;
+}
+
+/* Disable IRQ wake on resume. */
+static int sun6i_rtc_resume(struct device *dev)
+{
+ struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(chip->irq);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(sun6i_rtc_pm_ops,
+ sun6i_rtc_suspend, sun6i_rtc_resume);
+
static int sun6i_rtc_probe(struct platform_device *pdev)
{
struct sun6i_rtc_dev *chip = sun6i_rtc;
@@ -607,13 +684,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
return -ENODEV;
platform_set_drvdata(pdev, chip);
- chip->dev = &pdev->dev;
chip->irq = platform_get_irq(pdev, 0);
- if (chip->irq < 0) {
- dev_err(&pdev->dev, "No IRQ resource\n");
+ if (chip->irq < 0)
return chip->irq;
- }
ret = devm_request_irq(&pdev->dev, chip->irq, sun6i_rtc_alarmirq,
0, dev_name(&pdev->dev), chip);
@@ -650,6 +724,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
clk_prepare_enable(chip->losc);
+ device_init_wakeup(&pdev->dev, 1);
+
chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-sun6i",
&sun6i_rtc_ops, THIS_MODULE);
if (IS_ERR(chip->rtc)) {
@@ -675,6 +751,7 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
{ .compatible = "allwinner,sun8i-r40-rtc" },
{ .compatible = "allwinner,sun8i-v3-rtc" },
{ .compatible = "allwinner,sun50i-h5-rtc" },
+ { .compatible = "allwinner,sun50i-h6-rtc" },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
@@ -684,6 +761,7 @@ static struct platform_driver sun6i_rtc_driver = {
.driver = {
.name = "sun6i-rtc",
.of_match_table = sun6i_rtc_dt_ids,
+ .pm = &sun6i_rtc_pm_ops,
},
};
builtin_platform_driver(sun6i_rtc_driver);
diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c
index 6eeabb81106f..f5d7f44550ce 100644
--- a/drivers/rtc/rtc-sunxi.c
+++ b/drivers/rtc/rtc-sunxi.c
@@ -422,7 +422,6 @@ MODULE_DEVICE_TABLE(of, sunxi_rtc_dt_ids);
static int sunxi_rtc_probe(struct platform_device *pdev)
{
struct sunxi_rtc_dev *chip;
- struct resource *res;
int ret;
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
@@ -436,16 +435,13 @@ static int sunxi_rtc_probe(struct platform_device *pdev)
if (IS_ERR(chip->rtc))
return PTR_ERR(chip->rtc);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- chip->base = devm_ioremap_resource(&pdev->dev, res);
+ chip->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(chip->base))
return PTR_ERR(chip->base);
chip->irq = platform_get_irq(pdev, 0);
- if (chip->irq < 0) {
- dev_err(&pdev->dev, "No IRQ resource\n");
+ if (chip->irq < 0)
return chip->irq;
- }
ret = devm_request_irq(&pdev->dev, chip->irq, sunxi_rtc_alarmirq,
0, dev_name(&pdev->dev), chip);
if (ret) {
@@ -474,15 +470,7 @@ static int sunxi_rtc_probe(struct platform_device *pdev)
chip->rtc->ops = &sunxi_rtc_ops;
- ret = rtc_register_device(chip->rtc);
- if (ret) {
- dev_err(&pdev->dev, "unable to register device\n");
- return ret;
- }
-
- dev_info(&pdev->dev, "RTC enabled\n");
-
- return 0;
+ return rtc_register_device(chip->rtc);
}
static struct platform_driver sunxi_rtc_driver = {
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c
index 8fa1b3febf69..7fbb1741692f 100644
--- a/drivers/rtc/rtc-tegra.c
+++ b/drivers/rtc/rtc-tegra.c
@@ -103,7 +103,7 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct tegra_rtc_info *info = dev_get_drvdata(dev);
unsigned long flags;
- u32 sec, msec;
+ u32 sec;
/*
* RTC hardware copies seconds to shadow seconds when a read of
@@ -111,7 +111,7 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
*/
spin_lock_irqsave(&info->lock, flags);
- msec = readl(info->base + TEGRA_RTC_REG_MILLI_SECONDS);
+ readl(info->base + TEGRA_RTC_REG_MILLI_SECONDS);
sec = readl(info->base + TEGRA_RTC_REG_SHADOW_SECONDS);
spin_unlock_irqrestore(&info->lock, flags);
@@ -277,23 +277,19 @@ MODULE_DEVICE_TABLE(of, tegra_rtc_dt_match);
static int tegra_rtc_probe(struct platform_device *pdev)
{
struct tegra_rtc_info *info;
- struct resource *res;
int ret;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- info->base = devm_ioremap_resource(&pdev->dev, res);
+ info->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(info->base))
return PTR_ERR(info->base);
ret = platform_get_irq(pdev, 0);
- if (ret <= 0) {
- dev_err(&pdev->dev, "failed to get platform IRQ: %d\n", ret);
+ if (ret <= 0)
return ret;
- }
info->irq = ret;
@@ -334,10 +330,8 @@ static int tegra_rtc_probe(struct platform_device *pdev)
}
ret = rtc_register_device(info->rtc);
- if (ret) {
- dev_err(&pdev->dev, "failed to register device: %d\n", ret);
+ if (ret)
goto disable_clk;
- }
dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n");
diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c
index d6434e514a52..e39af2d67051 100644
--- a/drivers/rtc/rtc-tps6586x.c
+++ b/drivers/rtc/rtc-tps6586x.c
@@ -23,6 +23,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/mfd/tps6586x.h>
#include <linux/module.h>
@@ -259,7 +260,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
- dev_err(&pdev->dev, "RTC allocate device: ret %d\n", ret);
goto fail_rtc_register;
}
@@ -268,6 +268,8 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
rtc->rtc->start_secs = mktime64(2009, 1, 1, 0, 0, 0);
rtc->rtc->set_start_time = true;
+ irq_set_status_flags(rtc->irq, IRQ_NOAUTOEN);
+
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
tps6586x_rtc_irq,
IRQF_ONESHOT,
@@ -277,13 +279,10 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
rtc->irq, ret);
goto fail_rtc_register;
}
- disable_irq(rtc->irq);
ret = rtc_register_device(rtc->rtc);
- if (ret) {
- dev_err(&pdev->dev, "RTC device register: ret %d\n", ret);
+ if (ret)
goto fail_rtc_register;
- }
return 0;
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c
index 7078f6da1cbc..e3840386f430 100644
--- a/drivers/rtc/rtc-tps65910.c
+++ b/drivers/rtc/rtc-tps65910.c
@@ -361,6 +361,13 @@ static const struct rtc_class_ops tps65910_rtc_ops = {
.set_offset = tps65910_set_offset,
};
+static const struct rtc_class_ops tps65910_rtc_ops_noirq = {
+ .read_time = tps65910_rtc_read_time,
+ .set_time = tps65910_rtc_set_time,
+ .read_offset = tps65910_read_offset,
+ .set_offset = tps65910_set_offset,
+};
+
static int tps65910_rtc_probe(struct platform_device *pdev)
{
struct tps65910 *tps65910 = NULL;
@@ -414,24 +421,20 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
tps65910_rtc_interrupt, IRQF_TRIGGER_LOW,
dev_name(&pdev->dev), &pdev->dev);
- if (ret < 0) {
- dev_err(&pdev->dev, "IRQ is not free.\n");
- return ret;
- }
+ if (ret < 0)
+ irq = -1;
+
tps_rtc->irq = irq;
- device_set_wakeup_capable(&pdev->dev, 1);
+ if (irq != -1) {
+ device_set_wakeup_capable(&pdev->dev, 1);
+ tps_rtc->rtc->ops = &tps65910_rtc_ops;
+ } else
+ tps_rtc->rtc->ops = &tps65910_rtc_ops_noirq;
- tps_rtc->rtc->ops = &tps65910_rtc_ops;
tps_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
tps_rtc->rtc->range_max = RTC_TIMESTAMP_END_2099;
- ret = rtc_register_device(tps_rtc->rtc);
- if (ret) {
- dev_err(&pdev->dev, "RTC device register: err %d\n", ret);
- return ret;
- }
-
- return 0;
+ return rtc_register_device(tps_rtc->rtc);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c
index 5a29915a06ec..715b82981279 100644
--- a/drivers/rtc/rtc-tx4939.c
+++ b/drivers/rtc/rtc-tx4939.c
@@ -236,7 +236,6 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
struct tx4939rtc_plat_data *pdata;
- struct resource *res;
int irq, ret;
struct nvmem_config nvmem_cfg = {
.name = "tx4939_nvram",
@@ -253,8 +252,7 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, pdata);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pdata->rtcreg = devm_ioremap_resource(&pdev->dev, res);
+ pdata->rtcreg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->rtcreg))
return PTR_ERR(pdata->rtcreg);
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index 63ffba21397b..d2da92187d56 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -284,7 +284,6 @@ static int rtc_probe(struct platform_device *pdev)
struct v3020 *chip;
int retval = -EBUSY;
int i;
- int temp;
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
@@ -302,7 +301,7 @@ static int rtc_probe(struct platform_device *pdev)
/* Make sure the v3020 expects a communication cycle
* by reading 8 times */
for (i = 0; i < 8; i++)
- temp = chip->ops->read_bit(chip);
+ chip->ops->read_bit(chip);
/* Test chip by doing a write/read sequence
* to the chip ram */
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index c75230562c0d..c3671043ace7 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2003-2008 Yoichi Yuasa <yuasa@linux-mips.org>
*/
+#include <linux/compat.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/init.h>
@@ -66,6 +67,9 @@ static void __iomem *rtc2_base;
#define rtc2_read(offset) readw(rtc2_base + (offset))
#define rtc2_write(offset, value) writew((value), rtc2_base + (offset))
+/* 32-bit compat for ioctls that nobody else uses */
+#define RTC_EPOCH_READ32 _IOR('p', 0x0d, __u32)
+
static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */
static DEFINE_SPINLOCK(rtc_lock);
@@ -179,6 +183,10 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
switch (cmd) {
case RTC_EPOCH_READ:
return put_user(epoch, (unsigned long __user *)arg);
+#ifdef CONFIG_64BIT
+ case RTC_EPOCH_READ32:
+ return put_user(epoch, (unsigned int __user *)arg);
+#endif
case RTC_EPOCH_SET:
/* Doesn't support before 1900 */
if (arg < 1900)
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c
index f59d232810de..e2588625025f 100644
--- a/drivers/rtc/rtc-vt8500.c
+++ b/drivers/rtc/rtc-vt8500.c
@@ -122,12 +122,6 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev);
- if (tm->tm_year < 100) {
- dev_warn(dev, "Only years 2000-2199 are supported by the "
- "hardware!\n");
- return -EINVAL;
- }
-
writel((bin2bcd(tm->tm_year % 100) << DATE_YEAR_S)
| (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S)
| (bin2bcd(tm->tm_mday))
@@ -200,7 +194,6 @@ static const struct rtc_class_ops vt8500_rtc_ops = {
static int vt8500_rtc_probe(struct platform_device *pdev)
{
struct vt8500_rtc *vt8500_rtc;
- struct resource *res;
int ret;
vt8500_rtc = devm_kzalloc(&pdev->dev,
@@ -212,13 +205,10 @@ static int vt8500_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, vt8500_rtc);
vt8500_rtc->irq_alarm = platform_get_irq(pdev, 0);
- if (vt8500_rtc->irq_alarm < 0) {
- dev_err(&pdev->dev, "No alarm IRQ resource defined\n");
+ if (vt8500_rtc->irq_alarm < 0)
return vt8500_rtc->irq_alarm;
- }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- vt8500_rtc->regbase = devm_ioremap_resource(&pdev->dev, res);
+ vt8500_rtc->regbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(vt8500_rtc->regbase))
return PTR_ERR(vt8500_rtc->regbase);
@@ -226,27 +216,23 @@ static int vt8500_rtc_probe(struct platform_device *pdev)
writel(VT8500_RTC_CR_ENABLE,
vt8500_rtc->regbase + VT8500_RTC_CR);
- vt8500_rtc->rtc = devm_rtc_device_register(&pdev->dev, "vt8500-rtc",
- &vt8500_rtc_ops, THIS_MODULE);
- if (IS_ERR(vt8500_rtc->rtc)) {
- ret = PTR_ERR(vt8500_rtc->rtc);
- dev_err(&pdev->dev,
- "Failed to register RTC device -> %d\n", ret);
- goto err_return;
- }
+ vt8500_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(vt8500_rtc->rtc))
+ return PTR_ERR(vt8500_rtc->rtc);
+
+ vt8500_rtc->rtc->ops = &vt8500_rtc_ops;
+ vt8500_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ vt8500_rtc->rtc->range_max = RTC_TIMESTAMP_END_2199;
ret = devm_request_irq(&pdev->dev, vt8500_rtc->irq_alarm,
vt8500_rtc_irq, 0, "rtc alarm", vt8500_rtc);
if (ret < 0) {
dev_err(&pdev->dev, "can't get irq %i, err %d\n",
vt8500_rtc->irq_alarm, ret);
- goto err_return;
+ return ret;
}
- return 0;
-
-err_return:
- return ret;
+ return rtc_register_device(vt8500_rtc->rtc);
}
static int vt8500_rtc_remove(struct platform_device *pdev)
diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c
index 8ad4c4e6d557..ff46066a68a4 100644
--- a/drivers/rtc/rtc-wilco-ec.c
+++ b/drivers/rtc/rtc-wilco-ec.c
@@ -110,10 +110,12 @@ static int wilco_ec_rtc_read(struct device *dev, struct rtc_time *tm)
tm->tm_mday = rtc.day;
tm->tm_mon = rtc.month - 1;
tm->tm_year = rtc.year + (rtc.century * 100) - 1900;
- tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
+ /* Ignore other tm fields, man rtc says userspace shouldn't use them. */
- /* Don't compute day of week, we don't need it. */
- tm->tm_wday = -1;
+ if (rtc_valid_tm(tm)) {
+ dev_err(dev, "Time from RTC is invalid: %ptRr\n", tm);
+ return -EIO;
+ }
return 0;
}
diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c
index 9888383f0088..96db441f92b3 100644
--- a/drivers/rtc/rtc-xgene.c
+++ b/drivers/rtc/rtc-xgene.c
@@ -34,7 +34,6 @@
struct xgene_rtc_dev {
struct rtc_device *rtc;
- struct device *dev;
void __iomem *csr_base;
struct clk *clk;
unsigned int irq_wake;
@@ -137,7 +136,6 @@ static irqreturn_t xgene_rtc_interrupt(int irq, void *id)
static int xgene_rtc_probe(struct platform_device *pdev)
{
struct xgene_rtc_dev *pdata;
- struct resource *res;
int ret;
int irq;
@@ -145,10 +143,8 @@ static int xgene_rtc_probe(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
platform_set_drvdata(pdev, pdata);
- pdata->dev = &pdev->dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pdata->csr_base = devm_ioremap_resource(&pdev->dev, res);
+ pdata->csr_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->csr_base))
return PTR_ERR(pdata->csr_base);
@@ -157,10 +153,8 @@ static int xgene_rtc_probe(struct platform_device *pdev)
return PTR_ERR(pdata->rtc);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "No IRQ resource\n");
+ if (irq < 0)
return irq;
- }
ret = devm_request_irq(&pdev->dev, irq, xgene_rtc_interrupt, 0,
dev_name(&pdev->dev), pdata);
if (ret) {
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
index 00639594de0c..5786866c09e9 100644
--- a/drivers/rtc/rtc-zynqmp.c
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -44,7 +44,7 @@ struct xlnx_rtc_dev {
void __iomem *reg_base;
int alarm_irq;
int sec_irq;
- int calibval;
+ unsigned int calibval;
};
static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -94,7 +94,7 @@ static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
* RTC has updated the CURRENT_TIME with the time written into
* SET_TIME_WRITE register.
*/
- rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
+ read_time = readl(xrtcdev->reg_base + RTC_CUR_TM);
} else {
/*
* Time written in SET_TIME_WRITE has not yet updated into
@@ -104,8 +104,8 @@ static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
* reading.
*/
read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1;
- rtc_time64_to_tm(read_time, tm);
}
+ rtc_time64_to_tm(read_time, tm);
return 0;
}
@@ -195,7 +195,6 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
static int xlnx_rtc_probe(struct platform_device *pdev)
{
struct xlnx_rtc_dev *xrtcdev;
- struct resource *res;
int ret;
xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
@@ -211,17 +210,13 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
xrtcdev->rtc->ops = &xlnx_rtc_ops;
xrtcdev->rtc->range_max = U32_MAX;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ xrtcdev->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(xrtcdev->reg_base))
return PTR_ERR(xrtcdev->reg_base);
xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm");
- if (xrtcdev->alarm_irq < 0) {
- dev_err(&pdev->dev, "no irq resource\n");
+ if (xrtcdev->alarm_irq < 0)
return xrtcdev->alarm_irq;
- }
ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq,
xlnx_rtc_interrupt, 0,
dev_name(&pdev->dev), xrtcdev);
@@ -231,10 +226,8 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
}
xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec");
- if (xrtcdev->sec_irq < 0) {
- dev_err(&pdev->dev, "no irq resource\n");
+ if (xrtcdev->sec_irq < 0)
return xrtcdev->sec_irq;
- }
ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq,
xlnx_rtc_interrupt, 0,
dev_name(&pdev->dev), xrtcdev);
diff --git a/drivers/rtc/sysfs.c b/drivers/rtc/sysfs.c
index be3531e7f868..b7ca7d79fb28 100644
--- a/drivers/rtc/sysfs.c
+++ b/drivers/rtc/sysfs.c
@@ -103,8 +103,11 @@ static DEVICE_ATTR_RW(max_user_freq);
/**
* rtc_sysfs_show_hctosys - indicate if the given RTC set the system time
+ * @dev: The device that the attribute belongs to.
+ * @attr: The attribute being read.
+ * @buf: The result buffer.
*
- * Returns 1 if the system clock was set by this RTC at the last
+ * buf is "1" if the system clock was set by this RTC at the last
* boot or resume event.
*/
static ssize_t
OpenPOWER on IntegriCloud