aboutsummaryrefslogtreecommitdiff
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig93
-rw-r--r--drivers/rtc/Makefile7
-rw-r--r--drivers/rtc/class.c71
-rw-r--r--drivers/rtc/interface.c12
-rw-r--r--drivers/rtc/nvmem.c91
-rw-r--r--drivers/rtc/rtc-88pm80x.c2
-rw-r--r--drivers/rtc/rtc-88pm860x.c2
-rw-r--r--drivers/rtc/rtc-ab-b5ze-s3.c2
-rw-r--r--drivers/rtc/rtc-ab-eoz9.c2
-rw-r--r--drivers/rtc/rtc-ab3100.c254
-rw-r--r--drivers/rtc/rtc-ab8500.c2
-rw-r--r--drivers/rtc/rtc-abx80x.c41
-rw-r--r--drivers/rtc/rtc-ac100.c6
-rw-r--r--drivers/rtc/rtc-armada38x.c23
-rw-r--r--drivers/rtc/rtc-asm9260.c6
-rw-r--r--drivers/rtc/rtc-aspeed.c2
-rw-r--r--drivers/rtc/rtc-at91rm9200.c108
-rw-r--r--drivers/rtc/rtc-at91sam9.c2
-rw-r--r--drivers/rtc/rtc-au1xxx.c2
-rw-r--r--drivers/rtc/rtc-bd70528.c2
-rw-r--r--drivers/rtc/rtc-bq32k.c2
-rw-r--r--drivers/rtc/rtc-brcmstb-waketimer.c7
-rw-r--r--drivers/rtc/rtc-cadence.c2
-rw-r--r--drivers/rtc/rtc-cmos.c36
-rw-r--r--drivers/rtc/rtc-coh901331.c290
-rw-r--r--drivers/rtc/rtc-cpcap.c8
-rw-r--r--drivers/rtc/rtc-cros-ec.c2
-rw-r--r--drivers/rtc/rtc-da9052.c2
-rw-r--r--drivers/rtc/rtc-da9063.c4
-rw-r--r--drivers/rtc/rtc-davinci.c2
-rw-r--r--drivers/rtc/rtc-digicolor.c4
-rw-r--r--drivers/rtc/rtc-dm355evm.c2
-rw-r--r--drivers/rtc/rtc-ds1305.c10
-rw-r--r--drivers/rtc/rtc-ds1307.c164
-rw-r--r--drivers/rtc/rtc-ds1343.c5
-rw-r--r--drivers/rtc/rtc-ds1347.c2
-rw-r--r--drivers/rtc/rtc-ds1374.c2
-rw-r--r--drivers/rtc/rtc-ds1511.c6
-rw-r--r--drivers/rtc/rtc-ds1553.c6
-rw-r--r--drivers/rtc/rtc-ds1672.c4
-rw-r--r--drivers/rtc/rtc-ds1685.c19
-rw-r--r--drivers/rtc/rtc-ds1742.c6
-rw-r--r--drivers/rtc/rtc-ds2404.c2
-rw-r--r--drivers/rtc/rtc-ds3232.c9
-rw-r--r--drivers/rtc/rtc-ep93xx.c8
-rw-r--r--drivers/rtc/rtc-fsl-ftm-alarm.c6
-rw-r--r--drivers/rtc/rtc-ftrtc010.c2
-rw-r--r--drivers/rtc/rtc-goldfish.c2
-rw-r--r--drivers/rtc/rtc-hym8563.c12
-rw-r--r--drivers/rtc/rtc-imx-sc.c2
-rw-r--r--drivers/rtc/rtc-imxdi.c2
-rw-r--r--drivers/rtc/rtc-isl12026.c4
-rw-r--r--drivers/rtc/rtc-isl1208.c6
-rw-r--r--drivers/rtc/rtc-jz4740.c2
-rw-r--r--drivers/rtc/rtc-lpc32xx.c2
-rw-r--r--drivers/rtc/rtc-ls1x.c2
-rw-r--r--drivers/rtc/rtc-m41t80.c27
-rw-r--r--drivers/rtc/rtc-m48t59.c27
-rw-r--r--drivers/rtc/rtc-m48t86.c5
-rw-r--r--drivers/rtc/rtc-mc13xxx.c2
-rw-r--r--drivers/rtc/rtc-mc146818-lib.c77
-rw-r--r--drivers/rtc/rtc-mcp795.c5
-rw-r--r--drivers/rtc/rtc-meson-vrtc.c7
-rw-r--r--drivers/rtc/rtc-meson.c6
-rw-r--r--drivers/rtc/rtc-mpc5121.c2
-rw-r--r--drivers/rtc/rtc-mrst.c521
-rw-r--r--drivers/rtc/rtc-mt2712.c2
-rw-r--r--drivers/rtc/rtc-mt6397.c5
-rw-r--r--drivers/rtc/rtc-mv.c16
-rw-r--r--drivers/rtc/rtc-mxc.c30
-rw-r--r--drivers/rtc/rtc-mxc_v2.c9
-rw-r--r--drivers/rtc/rtc-omap.c13
-rw-r--r--drivers/rtc/rtc-opal.c27
-rw-r--r--drivers/rtc/rtc-pcap.c2
-rw-r--r--drivers/rtc/rtc-pcf2123.c7
-rw-r--r--drivers/rtc/rtc-pcf2127.c123
-rw-r--r--drivers/rtc/rtc-pcf85063.c53
-rw-r--r--drivers/rtc/rtc-pcf8523.c34
-rw-r--r--drivers/rtc/rtc-pcf85363.c14
-rw-r--r--drivers/rtc/rtc-pcf8563.c4
-rw-r--r--drivers/rtc/rtc-pic32.c2
-rw-r--r--drivers/rtc/rtc-pl030.c2
-rw-r--r--drivers/rtc/rtc-pl031.c16
-rw-r--r--drivers/rtc/rtc-pm8xxx.c20
-rw-r--r--drivers/rtc/rtc-ps3.c2
-rw-r--r--drivers/rtc/rtc-r7301.c5
-rw-r--r--drivers/rtc/rtc-r9701.c43
-rw-r--r--drivers/rtc/rtc-rc5t619.c2
-rw-r--r--drivers/rtc/rtc-rk808.c2
-rw-r--r--drivers/rtc/rtc-rp5c01.c5
-rw-r--r--drivers/rtc/rtc-rs5c313.c34
-rw-r--r--drivers/rtc/rtc-rs5c348.c2
-rw-r--r--drivers/rtc/rtc-rs5c372.c2
-rw-r--r--drivers/rtc/rtc-rv3028.c242
-rw-r--r--drivers/rtc/rtc-rv3029c2.c26
-rw-r--r--drivers/rtc/rtc-rv3032.c926
-rw-r--r--drivers/rtc/rtc-rv8803.c26
-rw-r--r--drivers/rtc/rtc-rx6110.c165
-rw-r--r--drivers/rtc/rtc-rx8010.c335
-rw-r--r--drivers/rtc/rtc-rx8025.c5
-rw-r--r--drivers/rtc/rtc-rx8581.c6
-rw-r--r--drivers/rtc/rtc-s35390a.c4
-rw-r--r--drivers/rtc/rtc-s3c.c256
-rw-r--r--drivers/rtc/rtc-s5m.c33
-rw-r--r--drivers/rtc/rtc-sa1100.c2
-rw-r--r--drivers/rtc/rtc-sc27xx.c42
-rw-r--r--drivers/rtc/rtc-sd3078.c4
-rw-r--r--drivers/rtc/rtc-sh.c2
-rw-r--r--drivers/rtc/rtc-sirfsoc.c446
-rw-r--r--drivers/rtc/rtc-snvs.c69
-rw-r--r--drivers/rtc/rtc-st-lpc.c4
-rw-r--r--drivers/rtc/rtc-starfire.c2
-rw-r--r--drivers/rtc/rtc-stk17ta8.c5
-rw-r--r--drivers/rtc/rtc-stm32.c4
-rw-r--r--drivers/rtc/rtc-stmp3xxx.c2
-rw-r--r--drivers/rtc/rtc-sun4v.c2
-rw-r--r--drivers/rtc/rtc-sun6i.c10
-rw-r--r--drivers/rtc/rtc-sunxi.c2
-rw-r--r--drivers/rtc/rtc-tegra.c8
-rw-r--r--drivers/rtc/rtc-test.c3
-rw-r--r--drivers/rtc/rtc-tps6586x.c2
-rw-r--r--drivers/rtc/rtc-tps65910.c21
-rw-r--r--drivers/rtc/rtc-tx4939.c304
-rw-r--r--drivers/rtc/rtc-vr41xx.c2
-rw-r--r--drivers/rtc/rtc-vt8500.c2
-rw-r--r--drivers/rtc/rtc-wilco-ec.c2
-rw-r--r--drivers/rtc/rtc-wm831x.c2
-rw-r--r--drivers/rtc/rtc-xgene.c2
-rw-r--r--drivers/rtc/rtc-zynqmp.c2
-rw-r--r--drivers/rtc/sysfs.c2
-rw-r--r--drivers/rtc/systohc.c61
131 files changed, 2168 insertions, 3396 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 48c536acd777..ce723dc54aa4 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -13,7 +13,7 @@ config RTC_MC146818_LIB
menuconfig RTC_CLASS
bool "Real Time Clock"
default n
- depends on !S390 && !UML
+ depends on !S390
select RTC_LIB
help
Generic RTC class support. If you say yes here, you will
@@ -669,6 +669,16 @@ config RTC_DRV_RV3028
This driver can also be built as a module. If so, the module
will be called rtc-rv3028.
+config RTC_DRV_RV3032
+ tristate "Micro Crystal RV3032"
+ select REGMAP_I2C
+ help
+ If you say yes here you get support for the Micro Crystal
+ RV3032.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-rv3032.
+
config RTC_DRV_RV8803
tristate "Micro Crystal RV8803, Epson RX8900"
help
@@ -682,6 +692,7 @@ config RTC_DRV_S5M
tristate "Samsung S2M/S5M series"
depends on MFD_SEC_CORE || COMPILE_TEST
select REGMAP_IRQ
+ select REGMAP_I2C
help
If you say yes here you will get support for the
RTC of Samsung S2MPS14 and S5M PMIC series.
@@ -807,15 +818,6 @@ config RTC_DRV_RX4581
This driver can also be built as a module. If so the module
will be called rtc-rx4581.
-config RTC_DRV_RX6110
- tristate "Epson RX-6110"
- select REGMAP_SPI
- help
- If you say yes here you will get support for the Epson RX-6610.
-
- This driver can also be built as a module. If so the module
- will be called rtc-rx6110.
-
config RTC_DRV_RS5C348
tristate "Ricoh RS5C348A/B"
help
@@ -926,6 +928,17 @@ config RTC_DRV_RV3029_HWMON
Say Y here if you want to expose temperature sensor data on
rtc-rv3029.
+config RTC_DRV_RX6110
+ tristate "Epson RX-6110"
+ depends on RTC_I2C_AND_SPI
+ select REGMAP_SPI if SPI_MASTER
+ select REGMAP_I2C if I2C
+ help
+ If you say yes here you will get support for the Epson RX-6110.
+
+ This driver can also be built as a module. If so the module
+ will be called rtc-rx6110.
+
comment "Platform RTC drivers"
# this 'CMOS' RTC driver is arch dependent because it requires
@@ -961,18 +974,6 @@ config RTC_DRV_ALPHA
Direct support for the real-time clock found on every Alpha
system, specifically MC146818 compatibles. If in doubt, say Y.
-config RTC_DRV_VRTC
- tristate "Virtual RTC for Intel MID platforms"
- depends on X86_INTEL_MID
- default y if X86_INTEL_MID
-
- help
- Say "yes" here to get direct support for the real time clock
- found on Moorestown platforms. The VRTC is a emulated RTC that
- derives its clock source from a real RTC in the PMIC. The MC146818
- style programming interface is mostly conserved, but any
- updates are done via IPC calls to the system controller FW.
-
config RTC_DRV_DS1216
tristate "Dallas DS1216"
depends on SNI_RM
@@ -1007,6 +1008,7 @@ config RTC_DRV_DS1553
config RTC_DRV_DS1685_FAMILY
tristate "Dallas/Maxim DS1685 Family"
+ depends on HAS_IOMEM
help
If you say yes here you get support for the Dallas/Maxim DS1685
family of real time chips. This family includes the DS1685/DS1687,
@@ -1140,6 +1142,7 @@ config RTC_DRV_STK17TA8
config RTC_DRV_M48T86
tristate "ST M48T86/Dallas DS12887"
+ depends on HAS_IOMEM
help
If you say Y here you will get support for the
ST M48T86 and Dallas DS12887 RTC chips.
@@ -1256,14 +1259,6 @@ config RTC_DRV_PCF50633
If you say yes here you get support for the RTC subsystem of the
NXP PCF50633 used in embedded systems.
-config RTC_DRV_AB3100
- tristate "ST-Ericsson AB3100 RTC"
- depends on AB3100_CORE
- default y if AB3100_CORE
- help
- Select this to enable the ST-Ericsson AB3100 Mixed Signal IC RTC
- support. This chip contains a battery- and capacitor-backed RTC.
-
config RTC_DRV_AB8500
tristate "ST-Ericsson AB8500 RTC"
depends on AB8500_CORE
@@ -1286,7 +1281,7 @@ config RTC_DRV_OPAL
config RTC_DRV_ZYNQMP
tristate "Xilinx Zynq Ultrascale+ MPSoC RTC"
- depends on OF
+ depends on OF && HAS_IOMEM
help
If you say yes here you get support for the RTC controller found on
Xilinx Zynq Ultrascale+ MPSoC.
@@ -1573,13 +1568,6 @@ config RTC_DRV_STARFIRE
If you say Y here you will get support for the RTC found on
Starfire systems.
-config RTC_DRV_TX4939
- tristate "TX4939 SoC"
- depends on SOC_TX4939 || COMPILE_TEST
- help
- Driver for the internal RTC (Realtime Clock) module found on
- Toshiba TX4939 SoC.
-
config RTC_DRV_MV
tristate "Marvell SoC RTC"
depends on ARCH_DOVE || ARCH_MVEBU || COMPILE_TEST
@@ -1594,6 +1582,7 @@ config RTC_DRV_MV
config RTC_DRV_ARMADA38X
tristate "Armada 38x Marvell SoC RTC"
depends on ARCH_MVEBU || COMPILE_TEST
+ depends on OF
help
If you say yes here you will get support for the in-chip RTC
that can be found in the Armada 38x Marvell's SoC device
@@ -1631,18 +1620,6 @@ config RTC_DRV_PS3
This driver can also be built as a module. If so, the module
will be called rtc-ps3.
-config RTC_DRV_COH901331
- tristate "ST-Ericsson COH 901 331 RTC"
- depends on ARCH_U300 || COMPILE_TEST
- help
- If you say Y here you will get access to ST-Ericsson
- COH 901 331 RTC clock found in some ST-Ericsson Mobile
- Platforms.
-
- This driver can also be built as a module. If so, the module
- will be called "rtc-coh901331".
-
-
config RTC_DRV_STMP
tristate "Freescale STMP3xxx/i.MX23/i.MX28 RTC"
depends on ARCH_MXS || COMPILE_TEST
@@ -1742,7 +1719,9 @@ config RTC_DRV_LOONGSON1
config RTC_DRV_MXC
tristate "Freescale MXC Real Time Clock"
- depends on ARCH_MXC
+ depends on ARCH_MXC || COMPILE_TEST
+ depends on HAS_IOMEM
+ depends on OF
help
If you say yes here you get support for the Freescale MXC
RTC module.
@@ -1752,7 +1731,9 @@ config RTC_DRV_MXC
config RTC_DRV_MXC_V2
tristate "Freescale MXC Real Time Clock for i.MX53"
- depends on ARCH_MXC
+ depends on ARCH_MXC || COMPILE_TEST
+ depends on HAS_IOMEM
+ depends on OF
help
If you say yes here you get support for the Freescale MXC
SRTC module in i.MX53 processor.
@@ -1781,13 +1762,6 @@ config RTC_DRV_IMX_SC
If you say yes here you get support for the NXP i.MX System
Controller RTC module.
-config RTC_DRV_SIRFSOC
- tristate "SiRFSOC RTC"
- depends on ARCH_SIRF
- help
- Say "yes" here to support the real time clock on SiRF SOC chips.
- This driver can also be built as a module called rtc-sirfsoc.
-
config RTC_DRV_ST_LPC
tristate "STMicroelectronics LPC RTC"
depends on ARCH_STI
@@ -1925,7 +1899,6 @@ config RTC_DRV_HID_SENSOR_TIME
config RTC_DRV_GOLDFISH
tristate "Goldfish Real Time Clock"
depends on OF && HAS_IOMEM
- depends on GOLDFISH || COMPILE_TEST
help
Say yes to enable RTC driver for the Goldfish based virtual platform.
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 880e08a409c3..4e930183c170 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -6,7 +6,6 @@
ccflags-$(CONFIG_RTC_DEBUG) := -DDEBUG
obj-$(CONFIG_RTC_LIB) += lib.o
-obj-$(CONFIG_RTC_SYSTOHC) += systohc.o
obj-$(CONFIG_RTC_CLASS) += rtc-core.o
obj-$(CONFIG_RTC_MC146818_LIB) += rtc-mc146818-lib.o
rtc-core-y := class.o interface.o
@@ -20,7 +19,6 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += sysfs.o
obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o
obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o
-obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o
obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o
obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o
obj-$(CONFIG_RTC_DRV_ABEOZ9) += rtc-ab-eoz9.o
@@ -39,7 +37,6 @@ obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o
obj-$(CONFIG_RTC_DRV_CADENCE) += rtc-cadence.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
-obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o
obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o
obj-$(CONFIG_RTC_DRV_CROS_EC) += rtc-cros-ec.o
obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o
@@ -141,6 +138,7 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
obj-$(CONFIG_RTC_DRV_RTD119X) += rtc-rtd119x.o
obj-$(CONFIG_RTC_DRV_RV3028) += rtc-rv3028.o
obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o
+obj-$(CONFIG_RTC_DRV_RV3032) += rtc-rv3032.o
obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o
obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o
obj-$(CONFIG_RTC_DRV_RX6110) += rtc-rx6110.o
@@ -154,7 +152,6 @@ obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
obj-$(CONFIG_RTC_DRV_SC27XX) += rtc-sc27xx.o
obj-$(CONFIG_RTC_DRV_SD3078) += rtc-sd3078.o
obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
-obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o
obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
@@ -171,10 +168,8 @@ obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o
obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o
obj-$(CONFIG_RTC_DRV_TPS80031) += rtc-tps80031.o
obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
-obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
-obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o
obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o
obj-$(CONFIG_RTC_DRV_WILCO_EC) += rtc-wilco-ec.o
obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 7c88d190c51f..f77bc089eb6b 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -28,6 +28,7 @@ static void rtc_device_release(struct device *dev)
struct rtc_device *rtc = to_rtc_device(dev);
ida_simple_remove(&rtc_ida, rtc->id);
+ mutex_destroy(&rtc->ops_lock);
kfree(rtc);
}
@@ -200,8 +201,13 @@ static struct rtc_device *rtc_allocate_device(void)
device_initialize(&rtc->dev);
- /* Drivers can revise this default after allocating the device. */
- rtc->set_offset_nsec = NSEC_PER_SEC / 2;
+ /*
+ * Drivers can revise this default after allocating the device.
+ * The default is what most RTCs do: Increment seconds exactly one
+ * second after the write happened. This adds a default transport
+ * time of 5ms which is at least halfways close to reality.
+ */
+ rtc->set_offset_nsec = NSEC_PER_SEC + 5 * NSEC_PER_MSEC;
rtc->irq_freq = 1;
rtc->max_user_freq = 64;
@@ -225,6 +231,8 @@ static struct rtc_device *rtc_allocate_device(void)
rtc->pie_timer.function = rtc_pie_update_irq;
rtc->pie_enabled = 0;
+ set_bit(RTC_FEATURE_ALARM, rtc->features);
+
return rtc;
}
@@ -316,13 +324,10 @@ static void rtc_device_get_offset(struct rtc_device *rtc)
rtc->offset_secs = 0;
}
-/**
- * rtc_device_unregister - removes the previously registered RTC class device
- *
- * @rtc: the RTC class device to destroy
- */
-static void rtc_device_unregister(struct rtc_device *rtc)
+static void devm_rtc_unregister_device(void *data)
{
+ struct rtc_device *rtc = data;
+
mutex_lock(&rtc->ops_lock);
/*
* Remove innards of this RTC, then disable it, before
@@ -332,60 +337,43 @@ static void rtc_device_unregister(struct rtc_device *rtc)
cdev_device_del(&rtc->char_dev, &rtc->dev);
rtc->ops = NULL;
mutex_unlock(&rtc->ops_lock);
- put_device(&rtc->dev);
}
-static void devm_rtc_release_device(struct device *dev, void *res)
+static void devm_rtc_release_device(void *res)
{
- struct rtc_device *rtc = *(struct rtc_device **)res;
-
- rtc_nvmem_unregister(rtc);
+ struct rtc_device *rtc = res;
- if (rtc->registered)
- rtc_device_unregister(rtc);
- else
- put_device(&rtc->dev);
+ put_device(&rtc->dev);
}
struct rtc_device *devm_rtc_allocate_device(struct device *dev)
{
- struct rtc_device **ptr, *rtc;
+ struct rtc_device *rtc;
int id, err;
id = rtc_device_get_id(dev);
if (id < 0)
return ERR_PTR(id);
- ptr = devres_alloc(devm_rtc_release_device, sizeof(*ptr), GFP_KERNEL);
- if (!ptr) {
- err = -ENOMEM;
- goto exit_ida;
- }
-
rtc = rtc_allocate_device();
if (!rtc) {
- err = -ENOMEM;
- goto exit_devres;
+ ida_simple_remove(&rtc_ida, id);
+ return ERR_PTR(-ENOMEM);
}
- *ptr = rtc;
- devres_add(dev, ptr);
-
rtc->id = id;
rtc->dev.parent = dev;
dev_set_name(&rtc->dev, "rtc%d", id);
- return rtc;
+ err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc);
+ if (err)
+ return ERR_PTR(err);
-exit_devres:
- devres_free(ptr);
-exit_ida:
- ida_simple_remove(&rtc_ida, id);
- return ERR_PTR(err);
+ return rtc;
}
EXPORT_SYMBOL_GPL(devm_rtc_allocate_device);
-int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
+int __devm_rtc_register_device(struct module *owner, struct rtc_device *rtc)
{
struct rtc_wkalrm alrm;
int err;
@@ -395,6 +383,9 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
return -EINVAL;
}
+ if (!rtc->ops->set_alarm)
+ clear_bit(RTC_FEATURE_ALARM, rtc->features);
+
rtc->owner = owner;
rtc_device_get_offset(rtc);
@@ -415,7 +406,6 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
rtc_proc_add_device(rtc);
- rtc->registered = true;
dev_info(rtc->dev.parent, "registered as %s\n",
dev_name(&rtc->dev));
@@ -424,9 +414,10 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
rtc_hctosys(rtc);
#endif
- return 0;
+ return devm_add_action_or_reset(rtc->dev.parent,
+ devm_rtc_unregister_device, rtc);
}
-EXPORT_SYMBOL_GPL(__rtc_register_device);
+EXPORT_SYMBOL_GPL(__devm_rtc_register_device);
/**
* devm_rtc_device_register - resource managed rtc_device_register()
@@ -456,7 +447,7 @@ struct rtc_device *devm_rtc_device_register(struct device *dev,
rtc->ops = ops;
- err = __rtc_register_device(owner, rtc);
+ err = __devm_rtc_register_device(owner, rtc);
if (err)
return ERR_PTR(err);
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 794a4f036b99..dcb34c73319e 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -186,7 +186,7 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc,
if (!rtc->ops) {
err = -ENODEV;
- } else if (!rtc->ops->read_alarm) {
+ } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->read_alarm) {
err = -EINVAL;
} else {
alarm->enabled = 0;
@@ -392,7 +392,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
return err;
if (!rtc->ops) {
err = -ENODEV;
- } else if (!rtc->ops->read_alarm) {
+ } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->read_alarm) {
err = -EINVAL;
} else {
memset(alarm, 0, sizeof(struct rtc_wkalrm));
@@ -436,7 +436,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
if (!rtc->ops)
err = -ENODEV;
- else if (!rtc->ops->set_alarm)
+ else if (!test_bit(RTC_FEATURE_ALARM, rtc->features))
err = -EINVAL;
else
err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
@@ -451,7 +451,7 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
if (!rtc->ops)
return -ENODEV;
- else if (!rtc->ops->set_alarm)
+ else if (!test_bit(RTC_FEATURE_ALARM, rtc->features))
return -EINVAL;
err = rtc_valid_tm(&alarm->time);
@@ -531,7 +531,7 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
/* nothing */;
else if (!rtc->ops)
err = -ENODEV;
- else if (!rtc->ops->alarm_irq_enable)
+ else if (!test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->alarm_irq_enable)
err = -EINVAL;
else
err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled);
@@ -843,7 +843,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
static void rtc_alarm_disable(struct rtc_device *rtc)
{
- if (!rtc->ops || !rtc->ops->alarm_irq_enable)
+ if (!rtc->ops || !test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->alarm_irq_enable)
return;
rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c
index 4312096c7738..07ede21cee34 100644
--- a/drivers/rtc/nvmem.c
+++ b/drivers/rtc/nvmem.c
@@ -9,99 +9,22 @@
#include <linux/types.h>
#include <linux/nvmem-consumer.h>
#include <linux/rtc.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-/*
- * Deprecated ABI compatibility, this should be removed at some point
- */
-
-static const char nvram_warning[] = "Deprecated ABI, please use nvmem";
-
-static ssize_t
-rtc_nvram_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- dev_warn_once(kobj_to_dev(kobj), nvram_warning);
-
- return nvmem_device_read(attr->private, off, count, buf);
-}
-
-static ssize_t
-rtc_nvram_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- dev_warn_once(kobj_to_dev(kobj), nvram_warning);
-
- return nvmem_device_write(attr->private, off, count, buf);
-}
-
-static int rtc_nvram_register(struct rtc_device *rtc,
- struct nvmem_device *nvmem, size_t size)
-{
- int err;
-
- rtc->nvram = kzalloc(sizeof(*rtc->nvram), GFP_KERNEL);
- if (!rtc->nvram)
- return -ENOMEM;
-
- rtc->nvram->attr.name = "nvram";
- rtc->nvram->attr.mode = 0644;
- rtc->nvram->private = nvmem;
-
- sysfs_bin_attr_init(rtc->nvram);
-
- rtc->nvram->read = rtc_nvram_read;
- rtc->nvram->write = rtc_nvram_write;
- rtc->nvram->size = size;
-
- err = sysfs_create_bin_file(&rtc->dev.parent->kobj,
- rtc->nvram);
- if (err) {
- kfree(rtc->nvram);
- rtc->nvram = NULL;
- }
-
- return err;
-}
-
-static void rtc_nvram_unregister(struct rtc_device *rtc)
-{
- sysfs_remove_bin_file(&rtc->dev.parent->kobj, rtc->nvram);
- kfree(rtc->nvram);
- rtc->nvram = NULL;
-}
-
-/*
- * New ABI, uses nvmem
- */
-int rtc_nvmem_register(struct rtc_device *rtc,
+int devm_rtc_nvmem_register(struct rtc_device *rtc,
struct nvmem_config *nvmem_config)
{
+ struct device *dev = rtc->dev.parent;
struct nvmem_device *nvmem;
if (!nvmem_config)
return -ENODEV;
- nvmem_config->dev = rtc->dev.parent;
+ nvmem_config->dev = dev;
nvmem_config->owner = rtc->owner;
- nvmem = devm_nvmem_register(rtc->dev.parent, nvmem_config);
+ nvmem = devm_nvmem_register(dev, nvmem_config);
if (IS_ERR(nvmem))
- return PTR_ERR(nvmem);
-
- /* Register the old ABI */
- if (rtc->nvram_old_abi)
- rtc_nvram_register(rtc, nvmem, nvmem_config->size);
+ dev_err(dev, "failed to register nvmem device for RTC\n");
- return 0;
-}
-EXPORT_SYMBOL_GPL(rtc_nvmem_register);
-
-void rtc_nvmem_unregister(struct rtc_device *rtc)
-{
- /* unregister the old ABI */
- if (rtc->nvram)
- rtc_nvram_unregister(rtc);
+ return PTR_ERR_OR_ZERO(nvmem);
}
+EXPORT_SYMBOL_GPL(devm_rtc_nvmem_register);
diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c
index 75779e8501a3..6a3f44cf6ebe 100644
--- a/drivers/rtc/rtc-88pm80x.c
+++ b/drivers/rtc/rtc-88pm80x.c
@@ -294,7 +294,7 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
info->rtc_dev->ops = &pm80x_rtc_ops;
info->rtc_dev->range_max = U32_MAX;
- ret = rtc_register_device(info->rtc_dev);
+ ret = devm_rtc_register_device(info->rtc_dev);
if (ret)
goto out_rtc;
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index c90457d001e9..2c809a1a445e 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -307,7 +307,7 @@ static int pm860x_rtc_probe(struct platform_device *pdev)
info->rtc_dev->ops = &pm860x_rtc_ops;
info->rtc_dev->range_max = U32_MAX;
- ret = rtc_register_device(info->rtc_dev);
+ ret = devm_rtc_register_device(info->rtc_dev);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c
index 2370ac0cdb5f..6e3e320dc727 100644
--- a/drivers/rtc/rtc-ab-b5ze-s3.c
+++ b/drivers/rtc/rtc-ab-b5ze-s3.c
@@ -892,7 +892,7 @@ static int abb5zes3_probe(struct i2c_client *client,
}
}
- ret = rtc_register_device(data->rtc);
+ ret = devm_rtc_register_device(data->rtc);
err:
if (ret && data->irq)
diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c
index d690985caa4c..b20d8f26dcdb 100644
--- a/drivers/rtc/rtc-ab-eoz9.c
+++ b/drivers/rtc/rtc-ab-eoz9.c
@@ -420,7 +420,7 @@ static int abeoz9_probe(struct i2c_client *client,
data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
data->rtc->range_max = RTC_TIMESTAMP_END_2099;
- ret = rtc_register_device(data->rtc);
+ ret = devm_rtc_register_device(data->rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c
deleted file mode 100644
index 2ed6def90975..000000000000
--- a/drivers/rtc/rtc-ab3100.c
+++ /dev/null
@@ -1,254 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * RTC clock driver for the AB3100 Analog Baseband Chip
- * Author: Linus Walleij <[email protected]>
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/rtc.h>
-#include <linux/mfd/abx500.h>
-
-/* Clock rate in Hz */
-#define AB3100_RTC_CLOCK_RATE 32768
-
-/*
- * The AB3100 RTC registers. These are the same for
- * AB3000 and AB3100.
- * Control register:
- * Bit 0: RTC Monitor cleared=0, active=1, if you set it
- * to 1 it remains active until RTC power is lost.
- * Bit 1: 32 kHz Oscillator, 0 = on, 1 = bypass
- * Bit 2: Alarm on, 0 = off, 1 = on
- * Bit 3: 32 kHz buffer disabling, 0 = enabled, 1 = disabled
- */
-#define AB3100_RTC 0x53
-/* default setting, buffer disabled, alarm on */
-#define RTC_SETTING 0x30
-/* Alarm when AL0-AL3 == TI0-TI3 */
-#define AB3100_AL0 0x56
-#define AB3100_AL1 0x57
-#define AB3100_AL2 0x58
-#define AB3100_AL3 0x59
-/* This 48-bit register that counts up at 32768 Hz */
-#define AB3100_TI0 0x5a
-#define AB3100_TI1 0x5b
-#define AB3100_TI2 0x5c
-#define AB3100_TI3 0x5d
-#define AB3100_TI4 0x5e
-#define AB3100_TI5 0x5f
-
-/*
- * RTC clock functions and device struct declaration
- */
-static int ab3100_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2,
- AB3100_TI3, AB3100_TI4, AB3100_TI5};
- unsigned char buf[6];
- u64 hw_counter = rtc_tm_to_time64(tm) * AB3100_RTC_CLOCK_RATE * 2;
- int err = 0;
- int i;
-
- buf[0] = (hw_counter) & 0xFF;
- buf[1] = (hw_counter >> 8) & 0xFF;
- buf[2] = (hw_counter >> 16) & 0xFF;
- buf[3] = (hw_counter >> 24) & 0xFF;
- buf[4] = (hw_counter >> 32) & 0xFF;
- buf[5] = (hw_counter >> 40) & 0xFF;
-
- for (i = 0; i < 6; i++) {
- err = abx500_set_register_interruptible(dev, 0,
- regs[i], buf[i]);
- if (err)
- return err;
- }
-
- /* Set the flag to mark that the clock is now set */
- return abx500_mask_and_set_register_interruptible(dev, 0,
- AB3100_RTC,
- 0x01, 0x01);
-
-}
-
-static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- time64_t time;
- u8 rtcval;
- int err;
-
- err = abx500_get_register_interruptible(dev, 0,
- AB3100_RTC, &rtcval);
- if (err)
- return err;
-
- if (!(rtcval & 0x01)) {
- dev_info(dev, "clock not set (lost power)");
- return -EINVAL;
- } else {
- u64 hw_counter;
- u8 buf[6];
-
- /* Read out time registers */
- err = abx500_get_register_page_interruptible(dev, 0,
- AB3100_TI0,
- buf, 6);
- if (err != 0)
- return err;
-
- hw_counter = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) |
- ((u64) buf[3] << 24) | ((u64) buf[2] << 16) |
- ((u64) buf[1] << 8) | (u64) buf[0];
- time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
- }
-
- rtc_time64_to_tm(time, tm);
-
- return 0;
-}
-
-static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
- time64_t time;
- u64 hw_counter;
- u8 buf[6];
- u8 rtcval;
- int err;
-
- /* Figure out if alarm is enabled or not */
- err = abx500_get_register_interruptible(dev, 0,
- AB3100_RTC, &rtcval);
- if (err)
- return err;
- if (rtcval & 0x04)
- alarm->enabled = 1;
- else
- alarm->enabled = 0;
- /* No idea how this could be represented */
- alarm->pending = 0;
- /* Read out alarm registers, only 4 bytes */
- err = abx500_get_register_page_interruptible(dev, 0,
- AB3100_AL0, buf, 4);
- if (err)
- return err;
- hw_counter = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) |
- ((u64) buf[1] << 24) | ((u64) buf[0] << 16);
- time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
-
- rtc_time64_to_tm(time, &alarm->time);
-
- return rtc_valid_tm(&alarm->time);
-}
-
-static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
- u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3};
- unsigned char buf[4];
- time64_t secs;
- u64 hw_counter;
- int err;
- int i;
-
- secs = rtc_tm_to_time64(&alarm->time);
- hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2;
- buf[0] = (hw_counter >> 16) & 0xFF;
- buf[1] = (hw_counter >> 24) & 0xFF;
- buf[2] = (hw_counter >> 32) & 0xFF;
- buf[3] = (hw_counter >> 40) & 0xFF;
-
- /* Set the alarm */
- for (i = 0; i < 4; i++) {
- err = abx500_set_register_interruptible(dev, 0,
- regs[i], buf[i]);
- if (err)
- return err;
- }
- /* Then enable the alarm */
- return abx500_mask_and_set_register_interruptible(dev, 0,
- AB3100_RTC, (1 << 2),
- alarm->enabled << 2);
-}
-
-static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled)
-{
- /*
- * It's not possible to enable/disable the alarm IRQ for this RTC.
- * It does not actually trigger any IRQ: instead its only function is
- * to power up the system, if it wasn't on. This will manifest as
- * a "power up cause" in the AB3100 power driver (battery charging etc)
- * and need to be handled there instead.
- */
- if (enabled)
- return abx500_mask_and_set_register_interruptible(dev, 0,
- AB3100_RTC, (1 << 2),
- 1 << 2);
- else
- return abx500_mask_and_set_register_interruptible(dev, 0,
- AB3100_RTC, (1 << 2),
- 0);
-}
-
-static const struct rtc_class_ops ab3100_rtc_ops = {
- .read_time = ab3100_rtc_read_time,
- .set_time = ab3100_rtc_set_time,
- .read_alarm = ab3100_rtc_read_alarm,
- .set_alarm = ab3100_rtc_set_alarm,
- .alarm_irq_enable = ab3100_rtc_irq_enable,
-};
-
-static int __init ab3100_rtc_probe(struct platform_device *pdev)
-{
- int err;
- u8 regval;
- struct rtc_device *rtc;
-
- /* The first RTC register needs special treatment */
- err = abx500_get_register_interruptible(&pdev->dev, 0,
- AB3100_RTC, &regval);
- if (err) {
- dev_err(&pdev->dev, "unable to read RTC register\n");
- return -ENODEV;
- }
-
- if ((regval & 0xFE) != RTC_SETTING) {
- dev_warn(&pdev->dev, "not default value in RTC reg 0x%x\n",
- regval);
- }
-
- if ((regval & 1) == 0) {
- /*
- * Set bit to detect power loss.
- * This bit remains until RTC power is lost.
- */
- regval = 1 | RTC_SETTING;
- err = abx500_set_register_interruptible(&pdev->dev, 0,
- AB3100_RTC, regval);
- /* Ignore any error on this write */
- }
-
- rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(rtc))
- return PTR_ERR(rtc);
-
- rtc->ops = &ab3100_rtc_ops;
- /* 48bit counter at (AB3100_RTC_CLOCK_RATE * 2) */
- rtc->range_max = U32_MAX;
-
- platform_set_drvdata(pdev, rtc);
-
- return rtc_register_device(rtc);
-}
-
-static struct platform_driver ab3100_rtc_driver = {
- .driver = {
- .name = "ab3100-rtc",
- },
-};
-
-module_platform_driver_probe(ab3100_rtc_driver, ab3100_rtc_probe);
-
-MODULE_AUTHOR("Linus Walleij <[email protected]>");
-MODULE_DESCRIPTION("AB3100 RTC Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index 3d60f3283f11..b40048871295 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -404,7 +404,7 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
if (err)
return err;
- return rtc_register_device(rtc);
+ return devm_rtc_register_device(rtc);
}
static int ab8500_rtc_remove(struct platform_device *pdev)
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c
index 803725b3a02c..9b0138d07232 100644
--- a/drivers/rtc/rtc-abx80x.c
+++ b/drivers/rtc/rtc-abx80x.c
@@ -117,6 +117,16 @@ struct abx80x_priv {
struct watchdog_device wdog;
};
+static int abx80x_write_config_key(struct i2c_client *client, u8 key)
+{
+ if (i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, key) < 0) {
+ dev_err(&client->dev, "Unable to write configuration key\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
static int abx80x_is_rc_mode(struct i2c_client *client)
{
int flags = 0;
@@ -140,12 +150,8 @@ static int abx80x_enable_trickle_charger(struct i2c_client *client,
* Write the configuration key register to enable access to the Trickle
* register
*/
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY,
- ABX8XX_CFG_KEY_MISC);
- if (err < 0) {
- dev_err(&client->dev, "Unable to write configuration key\n");
+ if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_MISC) < 0)
return -EIO;
- }
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_TRICKLE,
ABX8XX_TRICKLE_CHARGE_ENABLE |
@@ -358,12 +364,8 @@ static int abx80x_rtc_set_autocalibration(struct device *dev,
}
/* Unlock write access to Oscillator Control Register */
- retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY,
- ABX8XX_CFG_KEY_OSC);
- if (retval < 0) {
- dev_err(dev, "Failed to write CONFIG_KEY register\n");
- return retval;
- }
+ if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_OSC) < 0)
+ return -EIO;
retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
@@ -450,12 +452,8 @@ static ssize_t oscillator_store(struct device *dev,
flags |= (ABX8XX_OSC_OSEL);
/* Unlock write access on Oscillator Control register */
- retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY,
- ABX8XX_CFG_KEY_OSC);
- if (retval < 0) {
- dev_err(dev, "Failed to write CONFIG_KEY register\n");
- return retval;
- }
+ if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_OSC) < 0)
+ return -EIO;
retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
if (retval < 0) {
@@ -762,13 +760,8 @@ static int abx80x_probe(struct i2c_client *client,
* Write the configuration key register to enable access to
* the config2 register
*/
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY,
- ABX8XX_CFG_KEY_MISC);
- if (err < 0) {
- dev_err(&client->dev,
- "Unable to write configuration key\n");
+ if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_MISC) < 0)
return -EIO;
- }
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OUT_CTRL,
data | ABX8XX_OUT_CTRL_EXDS);
@@ -851,7 +844,7 @@ static int abx80x_probe(struct i2c_client *client,
return err;
}
- return rtc_register_device(priv->rtc);
+ return devm_rtc_register_device(priv->rtc);
}
static const struct i2c_device_id abx80x_id[] = {
diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c
index 29223931aba7..66783cb5e711 100644
--- a/drivers/rtc/rtc-ac100.c
+++ b/drivers/rtc/rtc-ac100.c
@@ -528,7 +528,7 @@ static irqreturn_t ac100_rtc_irq(int irq, void *data)
unsigned int val = 0;
int ret;
- mutex_lock(&chip->rtc->ops_lock);
+ rtc_lock(chip->rtc);
/* read status */
ret = regmap_read(regmap, AC100_ALM_INT_STA, &val);
@@ -551,7 +551,7 @@ static irqreturn_t ac100_rtc_irq(int irq, void *data)
}
out:
- mutex_unlock(&chip->rtc->ops_lock);
+ rtc_unlock(chip->rtc);
return IRQ_HANDLED;
}
@@ -610,7 +610,7 @@ static int ac100_rtc_probe(struct platform_device *pdev)
if (ret)
return ret;
- return rtc_register_device(chip->rtc);
+ return devm_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 94d7c22fc4f3..cc542e6b1d5b 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -458,14 +458,6 @@ static const struct rtc_class_ops armada38x_rtc_ops = {
.set_offset = armada38x_rtc_set_offset,
};
-static const struct rtc_class_ops armada38x_rtc_ops_noirq = {
- .read_time = armada38x_rtc_read_time,
- .set_time = armada38x_rtc_set_time,
- .read_alarm = armada38x_rtc_read_alarm,
- .read_offset = armada38x_rtc_read_offset,
- .set_offset = armada38x_rtc_set_offset,
-};
-
static const struct armada38x_rtc_data armada38x_data = {
.update_mbus_timing = rtc_update_38x_mbus_timing_params,
.read_rtc_reg = read_rtc_register_38x_wa,
@@ -540,23 +532,18 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, rtc);
- if (rtc->irq != -1) {
+ if (rtc->irq != -1)
device_init_wakeup(&pdev->dev, 1);
- rtc->rtc_dev->ops = &armada38x_rtc_ops;
- } else {
- /*
- * If there is no interrupt available then we can't
- * use the alarm
- */
- rtc->rtc_dev->ops = &armada38x_rtc_ops_noirq;
- }
+ else
+ clear_bit(RTC_FEATURE_ALARM, rtc->rtc_dev->features);
/* Update RTC-MBUS bridge timing parameters */
rtc->data->update_mbus_timing(rtc);
+ rtc->rtc_dev->ops = &armada38x_rtc_ops;
rtc->rtc_dev->range_max = U32_MAX;
- return rtc_register_device(rtc->rtc_dev);
+ return devm_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 3ab81cdec00b..de795e489f71 100644
--- a/drivers/rtc/rtc-asm9260.c
+++ b/drivers/rtc/rtc-asm9260.c
@@ -116,15 +116,15 @@ static irqreturn_t asm9260_rtc_irq(int irq, void *dev_id)
u32 isr;
unsigned long events = 0;
- mutex_lock(&priv->rtc->ops_lock);
+ rtc_lock(priv->rtc);
isr = ioread32(priv->iobase + HW_CIIR);
if (!isr) {
- mutex_unlock(&priv->rtc->ops_lock);
+ rtc_unlock(priv->rtc);
return IRQ_NONE;
}
iowrite32(0, priv->iobase + HW_CIIR);
- mutex_unlock(&priv->rtc->ops_lock);
+ rtc_unlock(priv->rtc);
events |= RTC_AF | RTC_IRQF;
diff --git a/drivers/rtc/rtc-aspeed.c b/drivers/rtc/rtc-aspeed.c
index eacdd0637cce..a93352ed3aec 100644
--- a/drivers/rtc/rtc-aspeed.c
+++ b/drivers/rtc/rtc-aspeed.c
@@ -104,7 +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 */
- return rtc_register_device(rtc->rtc_dev);
+ return devm_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 5e811e04cb21..fe396d27ebb7 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -36,6 +36,10 @@
#define AT91_RTC_UPDCAL BIT(1) /* Update Request Calendar Register */
#define AT91_RTC_MR 0x04 /* Mode Register */
+#define AT91_RTC_HRMOD BIT(0) /* 12/24 hour mode */
+#define AT91_RTC_NEGPPM BIT(4) /* Negative PPM correction */
+#define AT91_RTC_CORRECTION GENMASK(14, 8) /* Slow clock correction */
+#define AT91_RTC_HIGHPPM BIT(15) /* High PPM correction */
#define AT91_RTC_TIMR 0x08 /* Time Register */
#define AT91_RTC_SEC GENMASK(6, 0) /* Current Second */
@@ -77,6 +81,9 @@
#define AT91_RTC_NVTIMALR BIT(2) /* Non valid Time Alarm */
#define AT91_RTC_NVCALALR BIT(3) /* Non valid Calendar Alarm */
+#define AT91_RTC_CORR_DIVIDEND 3906000
+#define AT91_RTC_CORR_LOW_RATIO 20
+
#define at91_rtc_read(field) \
readl_relaxed(at91_rtc_regs + field)
#define at91_rtc_write(field, val) \
@@ -84,6 +91,7 @@
struct at91_rtc_config {
bool use_shadow_imr;
+ bool has_correction;
};
static const struct at91_rtc_config *at91_rtc_config;
@@ -293,6 +301,75 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}
+static int at91_rtc_readoffset(struct device *dev, long *offset)
+{
+ u32 mr = at91_rtc_read(AT91_RTC_MR);
+ long val = FIELD_GET(AT91_RTC_CORRECTION, mr);
+
+ if (!val) {
+ *offset = 0;
+ return 0;
+ }
+
+ val++;
+
+ if (!(mr & AT91_RTC_NEGPPM))
+ val = -val;
+
+ if (!(mr & AT91_RTC_HIGHPPM))
+ val *= AT91_RTC_CORR_LOW_RATIO;
+
+ *offset = DIV_ROUND_CLOSEST(AT91_RTC_CORR_DIVIDEND, val);
+
+ return 0;
+}
+
+static int at91_rtc_setoffset(struct device *dev, long offset)
+{
+ long corr;
+ u32 mr;
+
+ if (offset > AT91_RTC_CORR_DIVIDEND / 2)
+ return -ERANGE;
+ if (offset < -AT91_RTC_CORR_DIVIDEND / 2)
+ return -ERANGE;
+
+ mr = at91_rtc_read(AT91_RTC_MR);
+ mr &= ~(AT91_RTC_NEGPPM | AT91_RTC_CORRECTION | AT91_RTC_HIGHPPM);
+
+ if (offset > 0)
+ mr |= AT91_RTC_NEGPPM;
+ else
+ offset = -offset;
+
+ /* offset less than 764 ppb, disable correction*/
+ if (offset < 764) {
+ at91_rtc_write(AT91_RTC_MR, mr & ~AT91_RTC_NEGPPM);
+
+ return 0;
+ }
+
+ /*
+ * 29208 ppb is the perfect cutoff between low range and high range
+ * low range values are never better than high range value after that.
+ */
+ if (offset < 29208) {
+ corr = DIV_ROUND_CLOSEST(AT91_RTC_CORR_DIVIDEND, offset * AT91_RTC_CORR_LOW_RATIO);
+ } else {
+ corr = DIV_ROUND_CLOSEST(AT91_RTC_CORR_DIVIDEND, offset);
+ mr |= AT91_RTC_HIGHPPM;
+ }
+
+ if (corr > 128)
+ corr = 128;
+
+ mr |= FIELD_PREP(AT91_RTC_CORRECTION, corr - 1);
+
+ at91_rtc_write(AT91_RTC_MR, mr);
+
+ return 0;
+}
+
/*
* IRQ handler for the RTC
*/
@@ -343,6 +420,10 @@ static const struct at91_rtc_config at91sam9x5_config = {
.use_shadow_imr = true,
};
+static const struct at91_rtc_config sama5d4_config = {
+ .has_correction = true,
+};
+
static const struct of_device_id at91_rtc_dt_ids[] = {
{
.compatible = "atmel,at91rm9200-rtc",
@@ -352,10 +433,13 @@ static const struct of_device_id at91_rtc_dt_ids[] = {
.data = &at91sam9x5_config,
}, {
.compatible = "atmel,sama5d4-rtc",
- .data = &at91rm9200_config,
+ .data = &sama5d4_config,
}, {
.compatible = "atmel,sama5d2-rtc",
- .data = &at91rm9200_config,
+ .data = &sama5d4_config,
+ }, {
+ .compatible = "microchip,sam9x60-rtc",
+ .data = &sama5d4_config,
}, {
/* sentinel */
}
@@ -370,6 +454,16 @@ static const struct rtc_class_ops at91_rtc_ops = {
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
};
+static const struct rtc_class_ops sama5d4_rtc_ops = {
+ .read_time = at91_rtc_readtime,
+ .set_time = at91_rtc_settime,
+ .read_alarm = at91_rtc_readalarm,
+ .set_alarm = at91_rtc_setalarm,
+ .alarm_irq_enable = at91_rtc_alarm_irq_enable,
+ .set_offset = at91_rtc_setoffset,
+ .read_offset = at91_rtc_readoffset,
+};
+
/*
* Initialize and install RTC driver
*/
@@ -416,7 +510,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
}
at91_rtc_write(AT91_RTC_CR, 0);
- at91_rtc_write(AT91_RTC_MR, 0); /* 24 hour mode */
+ at91_rtc_write(AT91_RTC_MR, at91_rtc_read(AT91_RTC_MR) & ~AT91_RTC_HRMOD);
/* Disable all interrupts */
at91_rtc_write_idr(AT91_RTC_ACKUPD | AT91_RTC_ALARM |
@@ -437,10 +531,14 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
if (!device_can_wakeup(&pdev->dev))
device_init_wakeup(&pdev->dev, 1);
- rtc->ops = &at91_rtc_ops;
+ if (at91_rtc_config->has_correction)
+ rtc->ops = &sama5d4_rtc_ops;
+ else
+ rtc->ops = &at91_rtc_ops;
+
rtc->range_min = RTC_TIMESTAMP_BEGIN_1900;
rtc->range_max = RTC_TIMESTAMP_END_2099;
- ret = rtc_register_device(rtc);
+ ret = devm_rtc_register_device(rtc);
if (ret)
goto err_clk;
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index e39e89867d29..2216be429ab7 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -431,7 +431,7 @@ static int at91_rtc_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "%s: SET TIME!\n",
dev_name(&rtc->rtcdev->dev));
- return rtc_register_device(rtc->rtcdev);
+ return devm_rtc_register_device(rtc->rtcdev);
err_clk:
clk_disable_unprepare(rtc->sclk);
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c
index 791bebcb6f47..e6428b27b5d4 100644
--- a/drivers/rtc/rtc-au1xxx.c
+++ b/drivers/rtc/rtc-au1xxx.c
@@ -104,7 +104,7 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtcdev);
- return rtc_register_device(rtcdev);
+ return devm_rtc_register_device(rtcdev);
}
static struct platform_driver au1xrtc_driver = {
diff --git a/drivers/rtc/rtc-bd70528.c b/drivers/rtc/rtc-bd70528.c
index 4492b770422c..17cb67f5bf6e 100644
--- a/drivers/rtc/rtc-bd70528.c
+++ b/drivers/rtc/rtc-bd70528.c
@@ -604,7 +604,7 @@ static int bd70528_probe(struct platform_device *pdev)
}
}
- return rtc_register_device(rtc);
+ return devm_rtc_register_device(rtc);
}
static const struct platform_device_id bd718x7_rtc_id[] = {
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c
index 933e4237237d..2235c968842d 100644
--- a/drivers/rtc/rtc-bq32k.c
+++ b/drivers/rtc/rtc-bq32k.c
@@ -311,7 +311,7 @@ static const struct i2c_device_id bq32k_id[] = {
};
MODULE_DEVICE_TABLE(i2c, bq32k_id);
-static const struct of_device_id bq32k_of_match[] = {
+static const __maybe_unused struct of_device_id bq32k_of_match[] = {
{ .compatible = "ti,bq32000" },
{ }
};
diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c
index 4fee57c51280..c74130e8f496 100644
--- a/drivers/rtc/rtc-brcmstb-waketimer.c
+++ b/drivers/rtc/rtc-brcmstb-waketimer.c
@@ -252,7 +252,7 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
timer->rtc->ops = &brcmstb_waketmr_ops;
timer->rtc->range_max = U32_MAX;
- ret = rtc_register_device(timer->rtc);
+ ret = devm_rtc_register_device(timer->rtc);
if (ret)
goto err_notifier;
@@ -264,8 +264,7 @@ err_notifier:
unregister_reboot_notifier(&timer->reboot_notifier);
err_clk:
- if (timer->clk)
- clk_disable_unprepare(timer->clk);
+ clk_disable_unprepare(timer->clk);
return ret;
}
@@ -307,7 +306,7 @@ static int brcmstb_waketmr_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(brcmstb_waketmr_pm_ops,
brcmstb_waketmr_suspend, brcmstb_waketmr_resume);
-static const struct of_device_id brcmstb_waketmr_of_match[] = {
+static const __maybe_unused struct of_device_id brcmstb_waketmr_of_match[] = {
{ .compatible = "brcm,brcmstb-waketimer" },
{ /* sentinel */ },
};
diff --git a/drivers/rtc/rtc-cadence.c b/drivers/rtc/rtc-cadence.c
index 595d5d252850..1edf7f16d73a 100644
--- a/drivers/rtc/rtc-cadence.c
+++ b/drivers/rtc/rtc-cadence.c
@@ -336,7 +336,7 @@ static int cdns_rtc_probe(struct platform_device *pdev)
writel(0, crtc->regs + CDNS_RTC_HMR);
writel(CDNS_RTC_KRTCR_KRTC, crtc->regs + CDNS_RTC_KRTCR);
- ret = rtc_register_device(crtc->rtc_dev);
+ ret = devm_rtc_register_device(crtc->rtc_dev);
if (ret)
goto err_disable_wakeup;
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index bcc96ab7793f..670fd8a2970e 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -574,12 +574,6 @@ static const struct rtc_class_ops cmos_rtc_ops = {
.alarm_irq_enable = cmos_alarm_irq_enable,
};
-static const struct rtc_class_ops cmos_rtc_ops_no_alarm = {
- .read_time = cmos_read_time,
- .set_time = cmos_set_time,
- .proc = cmos_procfs,
-};
-
/*----------------------------------------------------------------*/
/*
@@ -649,11 +643,10 @@ static struct cmos_rtc cmos_rtc;
static irqreturn_t cmos_interrupt(int irq, void *p)
{
- unsigned long flags;
u8 irqstat;
u8 rtc_control;
- spin_lock_irqsave(&rtc_lock, flags);
+ spin_lock(&rtc_lock);
/* When the HPET interrupt handler calls us, the interrupt
* status is passed as arg1 instead of the irq number. But
@@ -687,7 +680,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
hpet_mask_rtc_irq_bit(RTC_AIE);
CMOS_READ(RTC_INTR_FLAGS);
}
- spin_unlock_irqrestore(&rtc_lock, flags);
+ spin_unlock(&rtc_lock);
if (is_intr(irqstat)) {
rtc_update_irq(p, 1, irqstat);
@@ -805,6 +798,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
spin_lock_irq(&rtc_lock);
+ /* Ensure that the RTC is accessible. Bit 6 must be 0! */
+ if ((CMOS_READ(RTC_VALID) & 0x40) != 0) {
+ spin_unlock_irq(&rtc_lock);
+ dev_warn(dev, "not accessible\n");
+ retval = -ENXIO;
+ goto cleanup1;
+ }
+
if (!(flags & CMOS_RTC_FLAGS_NOFREQ)) {
/* force periodic irq to CMOS reset default of 1024Hz;
*
@@ -857,21 +858,22 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
goto cleanup1;
}
-
- cmos_rtc.rtc->ops = &cmos_rtc_ops;
} else {
- cmos_rtc.rtc->ops = &cmos_rtc_ops_no_alarm;
+ clear_bit(RTC_FEATURE_ALARM, cmos_rtc.rtc->features);
}
- cmos_rtc.rtc->nvram_old_abi = true;
- retval = rtc_register_device(cmos_rtc.rtc);
+ cmos_rtc.rtc->ops = &cmos_rtc_ops;
+
+ retval = devm_rtc_register_device(cmos_rtc.rtc);
if (retval)
goto cleanup2;
+ /* Set the sync offset for the periodic 11min update correct */
+ cmos_rtc.rtc->set_offset_nsec = NSEC_PER_SEC / 2;
+
/* export at least the first block of NVRAM */
nvmem_cfg.size = address_space - NVRAM_OFFSET;
- if (rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg))
- dev_err(dev, "nvmem registration failed\n");
+ devm_rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg);
dev_info(dev, "%s%s, %d bytes nvram%s\n",
!is_valid_irq(rtc_irq) ? "no alarms" :
@@ -1006,6 +1008,7 @@ static int cmos_suspend(struct device *dev)
enable_irq_wake(cmos->irq);
}
+ memset(&cmos->saved_wkalrm, 0, sizeof(struct rtc_wkalrm));
cmos_read_alarm(dev, &cmos->saved_wkalrm);
dev_dbg(dev, "suspend%s, ctrl %02x\n",
@@ -1054,6 +1057,7 @@ static void cmos_check_wkalrm(struct device *dev)
return;
}
+ memset(&current_alarm, 0, sizeof(struct rtc_wkalrm));
cmos_read_alarm(dev, &current_alarm);
t_current_expires = rtc_tm_to_time64(&current_alarm.time);
t_saved_expires = rtc_tm_to_time64(&cmos->saved_wkalrm.time);
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
deleted file mode 100644
index da59917c9ee8..000000000000
--- a/drivers/rtc/rtc-coh901331.c
+++ /dev/null
@@ -1,290 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * Real Time Clock interface for ST-Ericsson AB COH 901 331 RTC.
- * Author: Linus Walleij <[email protected]>
- * Based on rtc-pl031.c by Deepak Saxena <[email protected]>
- * Copyright 2006 (c) MontaVista Software, Inc.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/rtc.h>
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-/*
- * Registers in the COH 901 331
- */
-/* Alarm value 32bit (R/W) */
-#define COH901331_ALARM 0x00U
-/* Used to set current time 32bit (R/W) */
-#define COH901331_SET_TIME 0x04U
-/* Indication if current time is valid 32bit (R/-) */
-#define COH901331_VALID 0x08U
-/* Read the current time 32bit (R/-) */
-#define COH901331_CUR_TIME 0x0cU
-/* Event register for the "alarm" interrupt */
-#define COH901331_IRQ_EVENT 0x10U
-/* Mask register for the "alarm" interrupt */
-#define COH901331_IRQ_MASK 0x14U
-/* Force register for the "alarm" interrupt */
-#define COH901331_IRQ_FORCE 0x18U
-
-/*
- * Reference to RTC block clock
- * Notice that the frequent clk_enable()/clk_disable() on this
- * clock is mainly to be able to turn on/off other clocks in the
- * hierarchy as needed, the RTC clock is always on anyway.
- */
-struct coh901331_port {
- struct rtc_device *rtc;
- struct clk *clk;
- void __iomem *virtbase;
- int irq;
-#ifdef CONFIG_PM_SLEEP
- u32 irqmaskstore;
-#endif
-};
-
-static irqreturn_t coh901331_interrupt(int irq, void *data)
-{
- struct coh901331_port *rtap = data;
-
- clk_enable(rtap->clk);
- /* Ack IRQ */
- writel(1, rtap->virtbase + COH901331_IRQ_EVENT);
- /*
- * Disable the interrupt. This is necessary because
- * the RTC lives on a lower-clocked line and will
- * not release the IRQ line until after a few (slower)
- * clock cycles. The interrupt will be re-enabled when
- * a new alarm is set anyway.
- */
- writel(0, rtap->virtbase + COH901331_IRQ_MASK);
- clk_disable(rtap->clk);
-
- /* Set alarm flag */
- rtc_update_irq(rtap->rtc, 1, RTC_AF);
-
- return IRQ_HANDLED;
-}
-
-static int coh901331_read_time(struct device *dev, struct rtc_time *tm)
-{
- struct coh901331_port *rtap = dev_get_drvdata(dev);
-
- clk_enable(rtap->clk);
- /* Check if the time is valid */
- if (!readl(rtap->virtbase + COH901331_VALID)) {
- clk_disable(rtap->clk);
- return -EINVAL;
- }
-
- rtc_time64_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm);
- clk_disable(rtap->clk);
- return 0;
-}
-
-static int coh901331_set_time(struct device *dev, struct rtc_time *tm)
-{
- struct coh901331_port *rtap = dev_get_drvdata(dev);
-
- clk_enable(rtap->clk);
- writel(rtc_tm_to_time64(tm), rtap->virtbase + COH901331_SET_TIME);
- clk_disable(rtap->clk);
-
- return 0;
-}
-
-static int coh901331_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
- struct coh901331_port *rtap = dev_get_drvdata(dev);
-
- clk_enable(rtap->clk);
- rtc_time64_to_tm(readl(rtap->virtbase + COH901331_ALARM), &alarm->time);
- alarm->pending = readl(rtap->virtbase + COH901331_IRQ_EVENT) & 1U;
- alarm->enabled = readl(rtap->virtbase + COH901331_IRQ_MASK) & 1U;
- clk_disable(rtap->clk);
-
- return 0;
-}
-
-static int coh901331_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
- struct coh901331_port *rtap = dev_get_drvdata(dev);
- unsigned long time = rtc_tm_to_time64(&alarm->time);
-
- clk_enable(rtap->clk);
- writel(time, rtap->virtbase + COH901331_ALARM);
- writel(alarm->enabled, rtap->virtbase + COH901331_IRQ_MASK);
- clk_disable(rtap->clk);
-
- return 0;
-}
-
-static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled)
-{
- struct coh901331_port *rtap = dev_get_drvdata(dev);
-
- clk_enable(rtap->clk);
- if (enabled)
- writel(1, rtap->virtbase + COH901331_IRQ_MASK);
- else
- writel(0, rtap->virtbase + COH901331_IRQ_MASK);
- clk_disable(rtap->clk);
-
- return 0;
-}
-
-static const struct rtc_class_ops coh901331_ops = {
- .read_time = coh901331_read_time,
- .set_time = coh901331_set_time,
- .read_alarm = coh901331_read_alarm,
- .set_alarm = coh901331_set_alarm,
- .alarm_irq_enable = coh901331_alarm_irq_enable,
-};
-
-static int __exit coh901331_remove(struct platform_device *pdev)
-{
- struct coh901331_port *rtap = platform_get_drvdata(pdev);
-
- if (rtap)
- clk_unprepare(rtap->clk);
-
- return 0;
-}
-
-
-static int __init coh901331_probe(struct platform_device *pdev)
-{
- int ret;
- struct coh901331_port *rtap;
-
- rtap = devm_kzalloc(&pdev->dev,
- sizeof(struct coh901331_port), GFP_KERNEL);
- if (!rtap)
- return -ENOMEM;
-
- rtap->virtbase = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(rtap->virtbase))
- return PTR_ERR(rtap->virtbase);
-
- rtap->irq = platform_get_irq(pdev, 0);
- if (devm_request_irq(&pdev->dev, rtap->irq, coh901331_interrupt, 0,
- "RTC COH 901 331 Alarm", rtap))
- return -EIO;
-
- rtap->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(rtap->clk)) {
- ret = PTR_ERR(rtap->clk);
- dev_err(&pdev->dev, "could not get clock\n");
- return ret;
- }
-
- rtap->rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(rtap->rtc))
- return PTR_ERR(rtap->rtc);
-
- rtap->rtc->ops = &coh901331_ops;
- rtap->rtc->range_max = U32_MAX;
-
- /* We enable/disable the clock only to assure it works */
- ret = clk_prepare_enable(rtap->clk);
- if (ret) {
- dev_err(&pdev->dev, "could not enable clock\n");
- return ret;
- }
- clk_disable(rtap->clk);
-
- platform_set_drvdata(pdev, rtap);
-
- ret = rtc_register_device(rtap->rtc);
- if (ret)
- goto out_no_rtc;
-
- return 0;
-
- out_no_rtc:
- clk_unprepare(rtap->clk);
- return ret;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int coh901331_suspend(struct device *dev)
-{
- struct coh901331_port *rtap = dev_get_drvdata(dev);
-
- /*
- * If this RTC alarm will be used for waking the system up,
- * don't disable it of course. Else we just disable the alarm
- * and await suspension.
- */
- if (device_may_wakeup(dev)) {
- enable_irq_wake(rtap->irq);
- } else {
- clk_enable(rtap->clk);
- rtap->irqmaskstore = readl(rtap->virtbase + COH901331_IRQ_MASK);
- writel(0, rtap->virtbase + COH901331_IRQ_MASK);
- clk_disable(rtap->clk);
- }
- clk_unprepare(rtap->clk);
- return 0;
-}
-
-static int coh901331_resume(struct device *dev)
-{
- int ret;
- struct coh901331_port *rtap = dev_get_drvdata(dev);
-
- ret = clk_prepare(rtap->clk);
- if (ret)
- return ret;
-
- if (device_may_wakeup(dev)) {
- disable_irq_wake(rtap->irq);
- } else {
- clk_enable(rtap->clk);
- writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK);
- clk_disable(rtap->clk);
- }
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(coh901331_pm_ops, coh901331_suspend, coh901331_resume);
-
-static void coh901331_shutdown(struct platform_device *pdev)
-{
- struct coh901331_port *rtap = platform_get_drvdata(pdev);
-
- clk_enable(rtap->clk);
- writel(0, rtap->virtbase + COH901331_IRQ_MASK);
- clk_disable_unprepare(rtap->clk);
-}
-
-static const struct of_device_id coh901331_dt_match[] = {
- { .compatible = "stericsson,coh901331" },
- {},
-};
-MODULE_DEVICE_TABLE(of, coh901331_dt_match);
-
-static struct platform_driver coh901331_driver = {
- .driver = {
- .name = "rtc-coh901331",
- .pm = &coh901331_pm_ops,
- .of_match_table = coh901331_dt_match,
- },
- .remove = __exit_p(coh901331_remove),
- .shutdown = coh901331_shutdown,
-};
-
-module_platform_driver_probe(coh901331_driver, coh901331_probe);
-
-MODULE_AUTHOR("Linus Walleij <[email protected]>");
-MODULE_DESCRIPTION("ST-Ericsson AB COH 901 331 RTC Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c
index 800667d73a6f..afc8fcba8f88 100644
--- a/drivers/rtc/rtc-cpcap.c
+++ b/drivers/rtc/rtc-cpcap.c
@@ -269,7 +269,8 @@ static int cpcap_rtc_probe(struct platform_device *pdev)
rtc->alarm_irq = platform_get_irq(pdev, 0);
err = devm_request_threaded_irq(dev, rtc->alarm_irq, NULL,
- cpcap_rtc_alarm_irq, IRQF_TRIGGER_NONE,
+ cpcap_rtc_alarm_irq,
+ IRQF_TRIGGER_NONE | IRQF_ONESHOT,
"rtc_alarm", rtc);
if (err) {
dev_err(dev, "Could not request alarm irq: %d\n", err);
@@ -285,7 +286,8 @@ static int cpcap_rtc_probe(struct platform_device *pdev)
*/
rtc->update_irq = platform_get_irq(pdev, 1);
err = devm_request_threaded_irq(dev, rtc->update_irq, NULL,
- cpcap_rtc_update_irq, IRQF_TRIGGER_NONE,
+ cpcap_rtc_update_irq,
+ IRQF_TRIGGER_NONE | IRQF_ONESHOT,
"rtc_1hz", rtc);
if (err) {
dev_err(dev, "Could not request update irq: %d\n", err);
@@ -299,7 +301,7 @@ static int cpcap_rtc_probe(struct platform_device *pdev)
/* ignore error and continue without wakeup support */
}
- return rtc_register_device(rtc->rtc_dev);
+ return devm_rtc_register_device(rtc->rtc_dev);
}
static const struct of_device_id cpcap_rtc_of_match[] = {
diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c
index f7343c289cab..70626793ca69 100644
--- a/drivers/rtc/rtc-cros-ec.c
+++ b/drivers/rtc/rtc-cros-ec.c
@@ -350,7 +350,7 @@ static int cros_ec_rtc_probe(struct platform_device *pdev)
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);
+ ret = devm_rtc_register_device(cros_ec_rtc->rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c
index 58de10da37b1..9ca99bd35702 100644
--- a/drivers/rtc/rtc-da9052.c
+++ b/drivers/rtc/rtc-da9052.c
@@ -304,7 +304,7 @@ static int da9052_rtc_probe(struct platform_device *pdev)
rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rtc->rtc->range_max = RTC_TIMESTAMP_END_2063;
- ret = rtc_register_device(rtc->rtc);
+ ret = devm_rtc_register_device(rtc->rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c
index 046b1d4c3dae..d4b72a9fa2ba 100644
--- a/drivers/rtc/rtc-da9063.c
+++ b/drivers/rtc/rtc-da9063.c
@@ -243,7 +243,7 @@ static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm)
al_secs = rtc_tm_to_time64(&rtc->alarm_time);
/* handle the rtc synchronisation delay */
- if (rtc->rtc_sync == true && al_secs - tm_secs == 1)
+ if (rtc->rtc_sync && al_secs - tm_secs == 1)
memcpy(tm, &rtc->alarm_time, sizeof(struct rtc_time));
else
rtc->rtc_sync = false;
@@ -494,7 +494,7 @@ static int da9063_rtc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n",
irq_alarm, ret);
- return rtc_register_device(rtc->rtc_dev);
+ return devm_rtc_register_device(rtc->rtc_dev);
}
static struct platform_driver da9063_rtc_driver = {
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c
index 73f87a17cdf3..6bef0f2353da 100644
--- a/drivers/rtc/rtc-davinci.c
+++ b/drivers/rtc/rtc-davinci.c
@@ -484,7 +484,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 0);
- return rtc_register_device(davinci_rtc->rtc);
+ return devm_rtc_register_device(davinci_rtc->rtc);
}
static int __exit davinci_rtc_remove(struct platform_device *pdev)
diff --git a/drivers/rtc/rtc-digicolor.c b/drivers/rtc/rtc-digicolor.c
index 200d85b01e8b..218a6de19247 100644
--- a/drivers/rtc/rtc-digicolor.c
+++ b/drivers/rtc/rtc-digicolor.c
@@ -202,10 +202,10 @@ static int __init dc_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev->ops = &dc_rtc_ops;
rtc->rtc_dev->range_max = U32_MAX;
- return rtc_register_device(rtc->rtc_dev);
+ return devm_rtc_register_device(rtc->rtc_dev);
}
-static const struct of_device_id dc_dt_ids[] = {
+static const __maybe_unused struct of_device_id dc_dt_ids[] = {
{ .compatible = "cnxt,cx92755-rtc" },
{ /* sentinel */ }
};
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c
index cd947a20843b..94fb16ac3e0f 100644
--- a/drivers/rtc/rtc-dm355evm.c
+++ b/drivers/rtc/rtc-dm355evm.c
@@ -132,7 +132,7 @@ static int dm355evm_rtc_probe(struct platform_device *pdev)
rtc->ops = &dm355evm_rtc_ops;
rtc->range_max = U32_MAX;
- return rtc_register_device(rtc);
+ return devm_rtc_register_device(rtc);
}
/*
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
index a3d790889eea..9ef107b99b65 100644
--- a/drivers/rtc/rtc-ds1305.c
+++ b/drivers/rtc/rtc-ds1305.c
@@ -435,13 +435,12 @@ static const struct rtc_class_ops ds1305_ops = {
static void ds1305_work(struct work_struct *work)
{
struct ds1305 *ds1305 = container_of(work, struct ds1305, work);
- struct mutex *lock = &ds1305->rtc->ops_lock;
struct spi_device *spi = ds1305->spi;
u8 buf[3];
int status;
/* lock to protect ds1305->ctrl */
- mutex_lock(lock);
+ rtc_lock(ds1305->rtc);
/* Disable the IRQ, and clear its status ... for now, we "know"
* that if more than one alarm is active, they're in sync.
@@ -459,7 +458,7 @@ static void ds1305_work(struct work_struct *work)
if (status < 0)
dev_dbg(&spi->dev, "clear irq --> %d\n", status);
- mutex_unlock(lock);
+ rtc_unlock(ds1305->rtc);
if (!test_bit(FLAG_EXITING, &ds1305->flags))
enable_irq(spi->irq);
@@ -694,12 +693,11 @@ static int ds1305_probe(struct spi_device *spi)
ds1305->rtc->range_max = RTC_TIMESTAMP_END_2099;
ds1305_nvmem_cfg.priv = ds1305;
- ds1305->rtc->nvram_old_abi = true;
- status = rtc_register_device(ds1305->rtc);
+ status = devm_rtc_register_device(ds1305->rtc);
if (status)
return status;
- rtc_nvmem_register(ds1305->rtc, &ds1305_nvmem_cfg);
+ devm_rtc_nvmem_register(ds1305->rtc, &ds1305_nvmem_cfg);
/* Maybe set up alarm IRQ; be ready to handle it triggering right
* away. NOTE that we don't share this. The signal is active low,
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 54c85cdd019d..cd8e438bc9c4 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -8,12 +8,12 @@
* Copyright (C) 2012 Bertrand Achard (nvram access fixes)
*/
-#include <linux/acpi.h>
#include <linux/bcd.h>
#include <linux/i2c.h>
#include <linux/init.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/property.h>
#include <linux/rtc/ds1307.h>
#include <linux/rtc.h>
#include <linux/slab.h>
@@ -31,6 +31,7 @@
* That's a natural job for a factory or repair bench.
*/
enum ds_type {
+ unknown_ds_type, /* always first and 0 */
ds_1307,
ds_1308,
ds_1337,
@@ -122,6 +123,9 @@ enum ds_type {
#define RX8130_REG_FLAG_AF BIT(3)
#define RX8130_REG_CONTROL0 0x1e
#define RX8130_REG_CONTROL0_AIE BIT(3)
+#define RX8130_REG_CONTROL1 0x1f
+#define RX8130_REG_CONTROL1_INIEN BIT(4)
+#define RX8130_REG_CONTROL1_CHGEN BIT(5)
#define MCP794XX_REG_CONTROL 0x07
# define MCP794XX_BIT_ALM0_EN 0x10
@@ -153,6 +157,7 @@ enum ds_type {
#define DS1388_REG_CONTROL 0x0c
# define DS1388_BIT_RST BIT(0)
# define DS1388_BIT_WDE BIT(1)
+# define DS1388_BIT_nEOSC BIT(7)
/* negative offset step is -2.034ppm */
#define M41TXX_NEG_OFFSET_STEP_PPB 2034
@@ -190,6 +195,15 @@ struct chip_desc {
u16 trickle_charger_reg;
u8 (*do_trickle_setup)(struct ds1307 *, u32,
bool);
+ /* Does the RTC require trickle-resistor-ohms to select the value of
+ * the resistor between Vcc and Vbackup?
+ */
+ bool requires_trickle_resistor;
+ /* Some RTC's batteries and supercaps were charged by default, others
+ * allow charging but were not configured previously to do so.
+ * Remember this behavior to stay backwards compatible.
+ */
+ bool charge_default;
};
static const struct chip_desc chips[last_ds_type];
@@ -352,6 +366,10 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
regmap_update_bits(ds1307->regmap, DS1340_REG_FLAG,
DS1340_BIT_OSF, 0);
break;
+ case ds_1388:
+ regmap_update_bits(ds1307->regmap, DS1388_REG_FLAG,
+ DS1388_BIT_OSF, 0);
+ break;
case mcp794xx:
/*
* these bits were cleared when preparing the date/time
@@ -507,6 +525,8 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, u32 ohms, bool diode)
u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE :
DS1307_TRICKLE_CHARGER_NO_DIODE;
+ setup |= DS13XX_TRICKLE_CHARGER_MAGIC;
+
switch (ohms) {
case 250:
setup |= DS1307_TRICKLE_CHARGER_250_OHM;
@@ -525,14 +545,23 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, u32 ohms, bool diode)
return setup;
}
+static u8 do_trickle_setup_rx8130(struct ds1307 *ds1307, u32 ohms, bool diode)
+{
+ /* make sure that the backup battery is enabled */
+ u8 setup = RX8130_REG_CONTROL1_INIEN;
+ if (diode)
+ setup |= RX8130_REG_CONTROL1_CHGEN;
+
+ return setup;
+}
+
static irqreturn_t rx8130_irq(int irq, void *dev_id)
{
struct ds1307 *ds1307 = dev_id;
- struct mutex *lock = &ds1307->rtc->ops_lock;
u8 ctl[3];
int ret;
- mutex_lock(lock);
+ rtc_lock(ds1307->rtc);
/* Read control registers. */
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
@@ -552,7 +581,7 @@ static irqreturn_t rx8130_irq(int irq, void *dev_id)
rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF);
out:
- mutex_unlock(lock);
+ rtc_unlock(ds1307->rtc);
return IRQ_HANDLED;
}
@@ -979,6 +1008,8 @@ static const struct chip_desc chips[last_ds_type] = {
.bbsqi_bit = DS1339_BIT_BBSQI,
.trickle_charger_reg = 0x10,
.do_trickle_setup = &do_trickle_setup_ds1339,
+ .requires_trickle_resistor = true,
+ .charge_default = true,
},
[ds_1340] = {
.century_reg = DS1307_REG_HOUR,
@@ -986,6 +1017,8 @@ static const struct chip_desc chips[last_ds_type] = {
.century_bit = DS1340_BIT_CENTURY,
.do_trickle_setup = &do_trickle_setup_ds1339,
.trickle_charger_reg = 0x08,
+ .requires_trickle_resistor = true,
+ .charge_default = true,
},
[ds_1341] = {
.century_reg = DS1307_REG_MONTH,
@@ -1009,6 +1042,8 @@ static const struct chip_desc chips[last_ds_type] = {
.offset = 0x10,
.irq_handler = rx8130_irq,
.rtc_ops = &rx8130_rtc_ops,
+ .trickle_charger_reg = RX8130_REG_CONTROL1,
+ .do_trickle_setup = &do_trickle_setup_rx8130,
},
[m41t0] = {
.rtc_ops = &m41txx_rtc_ops,
@@ -1055,7 +1090,6 @@ static const struct i2c_device_id ds1307_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ds1307_id);
-#ifdef CONFIG_OF
static const struct of_device_id ds1307_of_match[] = {
{
.compatible = "dallas,ds1307",
@@ -1132,32 +1166,6 @@ static const struct of_device_id ds1307_of_match[] = {
{ }
};
MODULE_DEVICE_TABLE(of, ds1307_of_match);
-#endif
-
-#ifdef CONFIG_ACPI
-static const struct acpi_device_id ds1307_acpi_ids[] = {
- { .id = "DS1307", .driver_data = ds_1307 },
- { .id = "DS1308", .driver_data = ds_1308 },
- { .id = "DS1337", .driver_data = ds_1337 },
- { .id = "DS1338", .driver_data = ds_1338 },
- { .id = "DS1339", .driver_data = ds_1339 },
- { .id = "DS1388", .driver_data = ds_1388 },
- { .id = "DS1340", .driver_data = ds_1340 },
- { .id = "DS1341", .driver_data = ds_1341 },
- { .id = "DS3231", .driver_data = ds_3231 },
- { .id = "M41T0", .driver_data = m41t0 },
- { .id = "M41T00", .driver_data = m41t00 },
- { .id = "M41T11", .driver_data = m41t11 },
- { .id = "MCP7940X", .driver_data = mcp794xx },
- { .id = "MCP7941X", .driver_data = mcp794xx },
- { .id = "PT7C4338", .driver_data = ds_1307 },
- { .id = "RX8025", .driver_data = rx_8025 },
- { .id = "ISL12057", .driver_data = ds_1337 },
- { .id = "RX8130", .driver_data = rx_8130 },
- { }
-};
-MODULE_DEVICE_TABLE(acpi, ds1307_acpi_ids);
-#endif
/*
* The ds1337 and ds1339 both have two alarms, but we only use the first
@@ -1293,18 +1301,37 @@ static int ds1307_nvram_write(void *priv, unsigned int offset, void *val,
static u8 ds1307_trickle_init(struct ds1307 *ds1307,
const struct chip_desc *chip)
{
- u32 ohms;
- bool diode = true;
+ u32 ohms, chargeable;
+ bool diode = chip->charge_default;
if (!chip->do_trickle_setup)
return 0;
if (device_property_read_u32(ds1307->dev, "trickle-resistor-ohms",
- &ohms))
+ &ohms) && chip->requires_trickle_resistor)
return 0;
- if (device_property_read_bool(ds1307->dev, "trickle-diode-disable"))
+ /* aux-voltage-chargeable takes precedence over the deprecated
+ * trickle-diode-disable
+ */
+ if (!device_property_read_u32(ds1307->dev, "aux-voltage-chargeable",
+ &chargeable)) {
+ switch (chargeable) {
+ case 0:
+ diode = false;
+ break;
+ case 1:
+ diode = true;
+ break;
+ default:
+ dev_warn(ds1307->dev,
+ "unsupported aux-voltage-chargeable value\n");
+ break;
+ }
+ } else if (device_property_read_bool(ds1307->dev,
+ "trickle-diode-disable")) {
diode = false;
+ }
return chip->do_trickle_setup(ds1307, ohms, diode);
}
@@ -1572,13 +1599,16 @@ static const struct clk_ops ds3231_clk_32khz_ops = {
.recalc_rate = ds3231_clk_32khz_recalc_rate,
};
+static const char *ds3231_clks_names[] = {
+ [DS3231_CLK_SQW] = "ds3231_clk_sqw",
+ [DS3231_CLK_32KHZ] = "ds3231_clk_32khz",
+};
+
static struct clk_init_data ds3231_clks_init[] = {
[DS3231_CLK_SQW] = {
- .name = "ds3231_clk_sqw",
.ops = &ds3231_clk_sqw_ops,
},
[DS3231_CLK_32KHZ] = {
- .name = "ds3231_clk_32khz",
.ops = &ds3231_clk_32khz_ops,
},
};
@@ -1599,6 +1629,11 @@ static int ds3231_clks_register(struct ds1307 *ds1307)
if (!onecell->clks)
return -ENOMEM;
+ /* optional override of the clockname */
+ device_property_read_string_array(ds1307->dev, "clock-output-names",
+ ds3231_clks_names,
+ ARRAY_SIZE(ds3231_clks_names));
+
for (i = 0; i < ARRAY_SIZE(ds3231_clks_init); i++) {
struct clk_init_data init = ds3231_clks_init[i];
@@ -1609,9 +1644,7 @@ static int ds3231_clks_register(struct ds1307 *ds1307)
if (i == DS3231_CLK_SQW && test_bit(HAS_ALARM, &ds1307->flags))
continue;
- /* optional override of the clockname */
- of_property_read_string_index(node, "clock-output-names", i,
- &init.name);
+ init.name = ds3231_clks_names[i];
ds1307->clks[i].init = &init;
onecell->clks[i] = devm_clk_register(ds1307->dev,
@@ -1620,10 +1653,8 @@ static int ds3231_clks_register(struct ds1307 *ds1307)
return PTR_ERR(onecell->clks[i]);
}
- if (!node)
- return 0;
-
- of_clk_add_provider(node, of_clk_src_onecell_get, onecell);
+ if (node)
+ of_clk_add_provider(node, of_clk_src_onecell_get, onecell);
return 0;
}
@@ -1707,6 +1738,7 @@ static int ds1307_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ds1307 *ds1307;
+ const void *match;
int err = -ENODEV;
int tmp;
const struct chip_desc *chip;
@@ -1732,22 +1764,15 @@ static int ds1307_probe(struct i2c_client *client,
i2c_set_clientdata(client, ds1307);
- if (client->dev.of_node) {
- ds1307->type = (enum ds_type)
- of_device_get_match_data(&client->dev);
+ match = device_get_match_data(&client->dev);
+ if (match) {
+ ds1307->type = (enum ds_type)match;
chip = &chips[ds1307->type];
} else if (id) {
chip = &chips[id->driver_data];
ds1307->type = id->driver_data;
} else {
- const struct acpi_device_id *acpi_id;
-
- acpi_id = acpi_match_device(ACPI_PTR(ds1307_acpi_ids),
- ds1307->dev);
- if (!acpi_id)
- return -ENODEV;
- chip = &chips[acpi_id->driver_data];
- ds1307->type = acpi_id->driver_data;
+ return -ENODEV;
}
want_irq = client->irq > 0 && chip->alarm;
@@ -1758,7 +1783,6 @@ static int ds1307_probe(struct i2c_client *client,
trickle_charger_setup = pdata->trickle_charger_setup;
if (trickle_charger_setup && chip->trickle_charger_reg) {
- trickle_charger_setup |= DS13XX_TRICKLE_CHARGER_MAGIC;
dev_dbg(ds1307->dev,
"writing trickle charger info 0x%x to 0x%x\n",
trickle_charger_setup, chip->trickle_charger_reg);
@@ -1766,7 +1790,6 @@ static int ds1307_probe(struct i2c_client *client,
trickle_charger_setup);
}
-#ifdef CONFIG_OF
/*
* For devices with no IRQ directly connected to the SoC, the RTC chip
* can be forced as a wakeup source by stating that explicitly in
@@ -1775,10 +1798,8 @@ static int ds1307_probe(struct i2c_client *client,
* This will guarantee the 'wakealarm' sysfs entry is available on the device,
* if supported by the RTC.
*/
- if (chip->alarm && of_property_read_bool(client->dev.of_node,
- "wakeup-source"))
+ if (chip->alarm && device_property_read_bool(&client->dev, "wakeup-source"))
ds1307_can_wakeup_device = true;
-#endif
switch (ds1307->type) {
case ds_1337:
@@ -1881,6 +1902,19 @@ static int ds1307_probe(struct i2c_client *client,
DS1307_REG_HOUR << 4 | 0x08, hour);
}
break;
+ case ds_1388:
+ err = regmap_read(ds1307->regmap, DS1388_REG_CONTROL, &tmp);
+ if (err) {
+ dev_dbg(ds1307->dev, "read error %d\n", err);
+ goto exit;
+ }
+
+ /* oscillator off? turn it on, so clock can tick. */
+ if (tmp & DS1388_BIT_nEOSC) {
+ tmp &= ~DS1388_BIT_nEOSC;
+ regmap_write(ds1307->regmap, DS1388_REG_CONTROL, tmp);
+ }
+ break;
default:
break;
}
@@ -1966,7 +2000,7 @@ static int ds1307_probe(struct i2c_client *client,
if (err)
return err;
- err = rtc_register_device(ds1307->rtc);
+ err = devm_rtc_register_device(ds1307->rtc);
if (err)
return err;
@@ -1981,8 +2015,7 @@ static int ds1307_probe(struct i2c_client *client,
.priv = ds1307,
};
- ds1307->rtc->nvram_old_abi = true;
- rtc_nvmem_register(ds1307->rtc, &nvmem_cfg);
+ devm_rtc_nvmem_register(ds1307->rtc, &nvmem_cfg);
}
ds1307_hwmon_register(ds1307);
@@ -1998,8 +2031,7 @@ exit:
static struct i2c_driver ds1307_driver = {
.driver = {
.name = "rtc-ds1307",
- .of_match_table = of_match_ptr(ds1307_of_match),
- .acpi_match_table = ACPI_PTR(ds1307_acpi_ids),
+ .of_match_table = ds1307_of_match,
},
.probe = ds1307_probe,
.id_table = ds1307_id,
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index ba143423875b..f14ed6c96437 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -399,7 +399,6 @@ static int ds1343_probe(struct spi_device *spi)
if (IS_ERR(priv->rtc))
return PTR_ERR(priv->rtc);
- 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;
@@ -409,12 +408,12 @@ static int ds1343_probe(struct spi_device *spi)
dev_err(&spi->dev,
"unable to create sysfs entries for rtc ds1343\n");
- res = rtc_register_device(priv->rtc);
+ res = devm_rtc_register_device(priv->rtc);
if (res)
return res;
nvmem_cfg.priv = priv;
- rtc_nvmem_register(priv->rtc, &nvmem_cfg);
+ devm_rtc_nvmem_register(priv->rtc, &nvmem_cfg);
priv->irq = spi->irq;
diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c
index 7025cf3fb9f8..157bf5209ac4 100644
--- a/drivers/rtc/rtc-ds1347.c
+++ b/drivers/rtc/rtc-ds1347.c
@@ -166,7 +166,7 @@ static int ds1347_probe(struct spi_device *spi)
rtc->range_min = RTC_TIMESTAMP_BEGIN_0000;
rtc->range_max = RTC_TIMESTAMP_END_9999;
- return rtc_register_device(rtc);
+ return devm_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 177d870bda0d..fab79921a712 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -508,7 +508,7 @@ static int ds1374_probe(struct i2c_client *client,
ds1374->rtc->ops = &ds1374_rtc_ops;
ds1374->rtc->range_max = U32_MAX;
- ret = rtc_register_device(ds1374->rtc);
+ ret = devm_rtc_register_device(ds1374->rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index a63872c4c76d..bda884333082 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -466,13 +466,11 @@ static int ds1511_rtc_probe(struct platform_device *pdev)
pdata->rtc->ops = &ds1511_rtc_ops;
- pdata->rtc->nvram_old_abi = true;
-
- ret = rtc_register_device(pdata->rtc);
+ ret = devm_rtc_register_device(pdata->rtc);
if (ret)
return ret;
- rtc_nvmem_register(pdata->rtc, &ds1511_nvmem_cfg);
+ devm_rtc_nvmem_register(pdata->rtc, &ds1511_nvmem_cfg);
/*
* if the platform has an interrupt in mind for this device,
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index cdf5e05b9489..dbff5b621ef5 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -294,9 +294,8 @@ static int ds1553_rtc_probe(struct platform_device *pdev)
return PTR_ERR(pdata->rtc);
pdata->rtc->ops = &ds1553_rtc_ops;
- pdata->rtc->nvram_old_abi = true;
- ret = rtc_register_device(pdata->rtc);
+ ret = devm_rtc_register_device(pdata->rtc);
if (ret)
return ret;
@@ -310,8 +309,7 @@ static int ds1553_rtc_probe(struct platform_device *pdev)
}
}
- if (rtc_nvmem_register(pdata->rtc, &nvmem_cfg))
- dev_err(&pdev->dev, "unable to register nvmem\n");
+ devm_rtc_nvmem_register(pdata->rtc, &nvmem_cfg);
return 0;
}
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index 9da84df9f152..4cd8efbef6cf 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -124,7 +124,7 @@ static int ds1672_probe(struct i2c_client *client,
rtc->ops = &ds1672_rtc_ops;
rtc->range_max = U32_MAX;
- err = rtc_register_device(rtc);
+ err = devm_rtc_register_device(rtc);
if (err)
return err;
@@ -139,7 +139,7 @@ static const struct i2c_device_id ds1672_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ds1672_id);
-static const struct of_device_id ds1672_of_match[] = {
+static const __maybe_unused struct of_device_id ds1672_of_match[] = {
{ .compatible = "dallas,ds1672" },
{ }
};
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c
index 56c670af2e50..75db7ab654a5 100644
--- a/drivers/rtc/rtc-ds1685.c
+++ b/drivers/rtc/rtc-ds1685.c
@@ -193,12 +193,12 @@ ds1685_rtc_begin_data_access(struct ds1685_priv *rtc)
rtc->write(rtc, RTC_CTRL_B,
(rtc->read(rtc, RTC_CTRL_B) | RTC_CTRL_B_SET));
+ /* Switch to Bank 1 */
+ ds1685_rtc_switch_to_bank1(rtc);
+
/* Read Ext Ctrl 4A and check the INCR bit to avoid a lockout. */
while (rtc->read(rtc, RTC_EXT_CTRL_4A) & RTC_CTRL_4A_INCR)
cpu_relax();
-
- /* Switch to Bank 1 */
- ds1685_rtc_switch_to_bank1(rtc);
}
/**
@@ -213,7 +213,7 @@ static inline void
ds1685_rtc_end_data_access(struct ds1685_priv *rtc)
{
/* Switch back to Bank 0 */
- ds1685_rtc_switch_to_bank1(rtc);
+ ds1685_rtc_switch_to_bank0(rtc);
/* Clear the SET bit in Ctrl B */
rtc->write(rtc, RTC_CTRL_B,
@@ -658,7 +658,6 @@ ds1685_rtc_irq_handler(int irq, void *dev_id)
{
struct platform_device *pdev = dev_id;
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
- struct mutex *rtc_mutex;
u8 ctrlb, ctrlc;
unsigned long events = 0;
u8 num_irqs = 0;
@@ -667,8 +666,7 @@ ds1685_rtc_irq_handler(int irq, void *dev_id)
if (unlikely(!rtc))
return IRQ_HANDLED;
- rtc_mutex = &rtc->dev->ops_lock;
- mutex_lock(rtc_mutex);
+ rtc_lock(rtc->dev);
/* Ctrlb holds the interrupt-enable bits and ctrlc the flag bits. */
ctrlb = rtc->read(rtc, RTC_CTRL_B);
@@ -713,7 +711,7 @@ ds1685_rtc_irq_handler(int irq, void *dev_id)
}
}
rtc_update_irq(rtc->dev, num_irqs, events);
- mutex_unlock(rtc_mutex);
+ rtc_unlock(rtc->dev);
return events ? IRQ_HANDLED : IRQ_NONE;
}
@@ -1316,13 +1314,12 @@ ds1685_rtc_probe(struct platform_device *pdev)
if (ret)
return ret;
- rtc_dev->nvram_old_abi = true;
nvmem_cfg.priv = rtc;
- ret = rtc_nvmem_register(rtc_dev, &nvmem_cfg);
+ ret = devm_rtc_nvmem_register(rtc_dev, &nvmem_cfg);
if (ret)
return ret;
- return rtc_register_device(rtc_dev);
+ return devm_rtc_register_device(rtc_dev);
}
/**
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 2b949f0dbaa9..13d45c697da6 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -190,14 +190,12 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
return PTR_ERR(rtc);
rtc->ops = &ds1742_rtc_ops;
- rtc->nvram_old_abi = true;
- ret = rtc_register_device(rtc);
+ ret = devm_rtc_register_device(rtc);
if (ret)
return ret;
- if (rtc_nvmem_register(rtc, &nvmem_cfg))
- dev_err(&pdev->dev, "Unable to register nvmem\n");
+ devm_rtc_nvmem_register(rtc, &nvmem_cfg);
return 0;
}
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c
index 9df0c44512b8..0480f592307e 100644
--- a/drivers/rtc/rtc-ds2404.c
+++ b/drivers/rtc/rtc-ds2404.c
@@ -234,7 +234,7 @@ static int rtc_probe(struct platform_device *pdev)
chip->rtc->ops = &ds2404_rtc_ops;
chip->rtc->range_max = U32_MAX;
- retval = rtc_register_device(chip->rtc);
+ retval = devm_rtc_register_device(chip->rtc);
if (retval)
return retval;
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 69c37ab64352..168bc27f1f5a 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -406,11 +406,10 @@ static irqreturn_t ds3232_irq(int irq, void *dev_id)
{
struct device *dev = dev_id;
struct ds3232 *ds3232 = dev_get_drvdata(dev);
- struct mutex *lock = &ds3232->rtc->ops_lock;
int ret;
int stat, control;
- mutex_lock(lock);
+ rtc_lock(ds3232->rtc);
ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
if (ret)
@@ -448,7 +447,7 @@ static irqreturn_t ds3232_irq(int irq, void *dev_id)
}
unlock:
- mutex_unlock(lock);
+ rtc_unlock(ds3232->rtc);
return IRQ_HANDLED;
}
@@ -518,7 +517,7 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
if (IS_ERR(ds3232->rtc))
return PTR_ERR(ds3232->rtc);
- ret = rtc_nvmem_register(ds3232->rtc, &nvmem_cfg);
+ ret = devm_rtc_nvmem_register(ds3232->rtc, &nvmem_cfg);
if(ret)
return ret;
@@ -593,7 +592,7 @@ static const struct i2c_device_id ds3232_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ds3232_id);
-static const struct of_device_id ds3232_of_match[] = {
+static const __maybe_unused struct of_device_id ds3232_of_match[] = {
{ .compatible = "dallas,ds3232" },
{ }
};
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index 8ec9ea1ca72e..acae7f16808f 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -33,7 +33,7 @@ struct ep93xx_rtc {
static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
unsigned short *delete)
{
- struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev);
+ struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev);
unsigned long comp;
comp = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_SWCOMP);
@@ -51,7 +51,7 @@ static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
- struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev);
+ struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev);
unsigned long time;
time = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA);
@@ -62,7 +62,7 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
- struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev);
+ struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev);
unsigned long secs = rtc_tm_to_time64(tm);
writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD);
@@ -145,7 +145,7 @@ static int ep93xx_rtc_probe(struct platform_device *pdev)
if (err)
return err;
- return rtc_register_device(ep93xx_rtc->rtc);
+ return devm_rtc_register_device(ep93xx_rtc->rtc);
}
static struct platform_driver ep93xx_rtc_driver = {
diff --git a/drivers/rtc/rtc-fsl-ftm-alarm.c b/drivers/rtc/rtc-fsl-ftm-alarm.c
index 68f0a1801a2e..57cc09d0a806 100644
--- a/drivers/rtc/rtc-fsl-ftm-alarm.c
+++ b/drivers/rtc/rtc-fsl-ftm-alarm.c
@@ -3,7 +3,7 @@
* Freescale FlexTimer Module (FTM) alarm device driver.
*
* Copyright 2014 Freescale Semiconductor, Inc.
- * Copyright 2019 NXP
+ * Copyright 2019-2020 NXP
*
*/
@@ -290,7 +290,7 @@ static int ftm_rtc_probe(struct platform_device *pdev)
if (ret)
dev_err(&pdev->dev, "failed to enable irq wake\n");
- ret = rtc_register_device(rtc->rtc_dev);
+ ret = devm_rtc_register_device(rtc->rtc_dev);
if (ret) {
dev_err(&pdev->dev, "can't register rtc device\n");
return ret;
@@ -312,7 +312,7 @@ static const struct of_device_id ftm_rtc_match[] = {
};
static const struct acpi_device_id ftm_imx_acpi_ids[] = {
- {"NXP0011",},
+ {"NXP0014",},
{ }
};
MODULE_DEVICE_TABLE(acpi, ftm_imx_acpi_ids);
diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c
index 0919f7dc94a3..ad3add5db4c8 100644
--- a/drivers/rtc/rtc-ftrtc010.c
+++ b/drivers/rtc/rtc-ftrtc010.c
@@ -176,7 +176,7 @@ static int ftrtc010_rtc_probe(struct platform_device *pdev)
if (unlikely(ret))
return ret;
- return rtc_register_device(rtc->rtc_dev);
+ return devm_rtc_register_device(rtc->rtc_dev);
}
static int ftrtc010_rtc_remove(struct platform_device *pdev)
diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c
index 6349d2cd3680..7ab95d052644 100644
--- a/drivers/rtc/rtc-goldfish.c
+++ b/drivers/rtc/rtc-goldfish.c
@@ -194,7 +194,7 @@ static int goldfish_rtc_probe(struct platform_device *pdev)
if (err)
return err;
- return rtc_register_device(rtcdrv->rtc);
+ return devm_rtc_register_device(rtcdrv->rtc);
}
static const struct of_device_id goldfish_rtc_of_match[] = {
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c
index 0fb79c4afb46..0751cae27285 100644
--- a/drivers/rtc/rtc-hym8563.c
+++ b/drivers/rtc/rtc-hym8563.c
@@ -428,10 +428,9 @@ static irqreturn_t hym8563_irq(int irq, void *dev_id)
{
struct hym8563 *hym8563 = (struct hym8563 *)dev_id;
struct i2c_client *client = hym8563->client;
- struct mutex *lock = &hym8563->rtc->ops_lock;
int data, ret;
- mutex_lock(lock);
+ rtc_lock(hym8563->rtc);
/* Clear the alarm flag */
@@ -451,7 +450,7 @@ static irqreturn_t hym8563_irq(int irq, void *dev_id)
}
out:
- mutex_unlock(lock);
+ rtc_unlock(hym8563->rtc);
return IRQ_HANDLED;
}
@@ -527,8 +526,6 @@ static int hym8563_probe(struct i2c_client *client,
hym8563->client = client;
i2c_set_clientdata(client, hym8563);
- device_set_wakeup_capable(&client->dev, true);
-
ret = hym8563_init_device(client);
if (ret) {
dev_err(&client->dev, "could not init device, %d\n", ret);
@@ -547,6 +544,11 @@ static int hym8563_probe(struct i2c_client *client,
}
}
+ if (client->irq > 0 ||
+ device_property_read_bool(&client->dev, "wakeup-source")) {
+ device_init_wakeup(&client->dev, true);
+ }
+
/* check state of calendar information */
ret = i2c_smbus_read_byte_data(client, HYM8563_SEC);
if (ret < 0)
diff --git a/drivers/rtc/rtc-imx-sc.c b/drivers/rtc/rtc-imx-sc.c
index a5f59e6f862e..cc9fbab49999 100644
--- a/drivers/rtc/rtc-imx-sc.c
+++ b/drivers/rtc/rtc-imx-sc.c
@@ -166,7 +166,7 @@ static int imx_sc_rtc_probe(struct platform_device *pdev)
imx_sc_rtc->range_min = 0;
imx_sc_rtc->range_max = U32_MAX;
- ret = rtc_register_device(imx_sc_rtc);
+ ret = devm_rtc_register_device(imx_sc_rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c
index 8d141d8a5490..c2692da74e09 100644
--- a/drivers/rtc/rtc-imxdi.c
+++ b/drivers/rtc/rtc-imxdi.c
@@ -814,7 +814,7 @@ static int __init dryice_rtc_probe(struct platform_device *pdev)
imxdi->rtc->ops = &dryice_rtc_ops;
imxdi->rtc->range_max = U32_MAX;
- rc = rtc_register_device(imxdi->rtc);
+ rc = devm_rtc_register_device(imxdi->rtc);
if (rc)
goto err;
diff --git a/drivers/rtc/rtc-isl12026.c b/drivers/rtc/rtc-isl12026.c
index 5b6b17fb6d62..1fc6627d854d 100644
--- a/drivers/rtc/rtc-isl12026.c
+++ b/drivers/rtc/rtc-isl12026.c
@@ -465,11 +465,11 @@ static int isl12026_probe_new(struct i2c_client *client)
priv->rtc->ops = &isl12026_rtc_ops;
nvm_cfg.priv = priv;
- ret = rtc_nvmem_register(priv->rtc, &nvm_cfg);
+ ret = devm_rtc_nvmem_register(priv->rtc, &nvm_cfg);
if (ret)
return ret;
- return rtc_register_device(priv->rtc);
+ return devm_rtc_register_device(priv->rtc);
}
static int isl12026_remove(struct i2c_client *client)
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index ebb691fa48a6..182dfa605515 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -99,7 +99,7 @@ static const struct i2c_device_id isl1208_id[] = {
};
MODULE_DEVICE_TABLE(i2c, isl1208_id);
-static const struct of_device_id isl1208_of_match[] = {
+static const __maybe_unused struct of_device_id isl1208_of_match[] = {
{ .compatible = "isil,isl1208", .data = &isl1208_configs[TYPE_ISL1208] },
{ .compatible = "isil,isl1209", .data = &isl1208_configs[TYPE_ISL1209] },
{ .compatible = "isil,isl1218", .data = &isl1208_configs[TYPE_ISL1218] },
@@ -890,11 +890,11 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (rc)
return rc;
- rc = rtc_nvmem_register(isl1208->rtc, &isl1208->nvmem_config);
+ rc = devm_rtc_nvmem_register(isl1208->rtc, &isl1208->nvmem_config);
if (rc)
return rc;
- return rtc_register_device(isl1208->rtc);
+ return devm_rtc_register_device(isl1208->rtc);
}
static struct i2c_driver isl1208_driver = {
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c
index 9607e6b6e0b3..6e51df72fd65 100644
--- a/drivers/rtc/rtc-jz4740.c
+++ b/drivers/rtc/rtc-jz4740.c
@@ -375,7 +375,7 @@ static int jz4740_rtc_probe(struct platform_device *pdev)
/* Each 1 Hz pulse should happen after (rate) ticks */
jz4740_rtc_reg_write(rtc, JZ_REG_RTC_REGULATOR, rate - 1);
- ret = rtc_register_device(rtc->rtc);
+ ret = devm_rtc_register_device(rtc->rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c
index 15d8abda81fe..76ad7031a13d 100644
--- a/drivers/rtc/rtc-lpc32xx.c
+++ b/drivers/rtc/rtc-lpc32xx.c
@@ -239,7 +239,7 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev)
rtc->rtc->ops = &lpc32xx_rtc_ops;
rtc->rtc->range_max = U32_MAX;
- err = rtc_register_device(rtc->rtc);
+ err = devm_rtc_register_device(rtc->rtc);
if (err)
return err;
diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c
index 8bd34056fea0..5af26dc5c2a3 100644
--- a/drivers/rtc/rtc-ls1x.c
+++ b/drivers/rtc/rtc-ls1x.c
@@ -176,7 +176,7 @@ static int ls1x_rtc_probe(struct platform_device *pdev)
rtcdev->range_min = RTC_TIMESTAMP_BEGIN_1900;
rtcdev->range_max = RTC_TIMESTAMP_END_2099;
- return rtc_register_device(rtcdev);
+ return devm_rtc_register_device(rtcdev);
}
static struct platform_driver ls1x_rtc_driver = {
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 8a89bc52b0d4..cce5b5284658 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -85,7 +85,7 @@ static const struct i2c_device_id m41t80_id[] = {
};
MODULE_DEVICE_TABLE(i2c, m41t80_id);
-static const struct of_device_id m41t80_of_match[] = {
+static const __maybe_unused struct of_device_id m41t80_of_match[] = {
{
.compatible = "st,m41t62",
.data = (void *)(M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT)
@@ -158,21 +158,20 @@ static irqreturn_t m41t80_handle_irq(int irq, void *dev_id)
{
struct i2c_client *client = dev_id;
struct m41t80_data *m41t80 = i2c_get_clientdata(client);
- struct mutex *lock = &m41t80->rtc->ops_lock;
unsigned long events = 0;
int flags, flags_afe;
- mutex_lock(lock);
+ rtc_lock(m41t80->rtc);
flags_afe = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
if (flags_afe < 0) {
- mutex_unlock(lock);
+ rtc_unlock(m41t80->rtc);
return IRQ_NONE;
}
flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
if (flags <= 0) {
- mutex_unlock(lock);
+ rtc_unlock(m41t80->rtc);
return IRQ_NONE;
}
@@ -189,7 +188,7 @@ static irqreturn_t m41t80_handle_irq(int irq, void *dev_id)
flags_afe);
}
- mutex_unlock(lock);
+ rtc_unlock(m41t80->rtc);
return IRQ_HANDLED;
}
@@ -397,10 +396,13 @@ static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return 0;
}
-static struct rtc_class_ops m41t80_rtc_ops = {
+static const struct rtc_class_ops m41t80_rtc_ops = {
.read_time = m41t80_rtc_read_time,
.set_time = m41t80_rtc_set_time,
.proc = m41t80_rtc_proc,
+ .read_alarm = m41t80_read_alarm,
+ .set_alarm = m41t80_set_alarm,
+ .alarm_irq_enable = m41t80_alarm_irq_enable,
};
#ifdef CONFIG_PM_SLEEP
@@ -913,13 +915,10 @@ static int m41t80_probe(struct i2c_client *client,
wakeup_source = false;
}
}
- if (client->irq > 0 || wakeup_source) {
- m41t80_rtc_ops.read_alarm = m41t80_read_alarm;
- m41t80_rtc_ops.set_alarm = m41t80_set_alarm;
- m41t80_rtc_ops.alarm_irq_enable = m41t80_alarm_irq_enable;
- /* Enable the wakealarm */
+ if (client->irq > 0 || wakeup_source)
device_init_wakeup(&client->dev, true);
- }
+ else
+ clear_bit(RTC_FEATURE_ALARM, m41t80_data->rtc->features);
m41t80_data->rtc->ops = &m41t80_rtc_ops;
m41t80_data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
@@ -977,7 +976,7 @@ static int m41t80_probe(struct i2c_client *client,
m41t80_sqw_register_clk(m41t80_data);
#endif
- rc = rtc_register_device(m41t80_data->rtc);
+ rc = devm_rtc_register_device(m41t80_data->rtc);
if (rc)
return rc;
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index 67e218758a8b..1d2e99a70fce 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -313,11 +313,6 @@ static const struct rtc_class_ops m48t59_rtc_ops = {
.alarm_irq_enable = m48t59_rtc_alarm_irq_enable,
};
-static const struct rtc_class_ops m48t02_rtc_ops = {
- .read_time = m48t59_rtc_read_time,
- .set_time = m48t59_rtc_set_time,
-};
-
static int m48t59_nvram_read(void *priv, unsigned int offset, void *val,
size_t size)
{
@@ -366,7 +361,6 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
struct m48t59_private *m48t59 = NULL;
struct resource *res;
int ret = -ENOMEM;
- const struct rtc_class_ops *ops;
struct nvmem_config nvmem_cfg = {
.name = "m48t59-",
.word_size = 1,
@@ -438,17 +432,21 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
if (ret)
return ret;
}
+
+ m48t59->rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(m48t59->rtc))
+ return PTR_ERR(m48t59->rtc);
+
switch (pdata->type) {
case M48T59RTC_TYPE_M48T59:
- ops = &m48t59_rtc_ops;
pdata->offset = 0x1ff0;
break;
case M48T59RTC_TYPE_M48T02:
- ops = &m48t02_rtc_ops;
+ clear_bit(RTC_FEATURE_ALARM, m48t59->rtc->features);
pdata->offset = 0x7f0;
break;
case M48T59RTC_TYPE_M48T08:
- ops = &m48t02_rtc_ops;
+ clear_bit(RTC_FEATURE_ALARM, m48t59->rtc->features);
pdata->offset = 0x1ff0;
break;
default:
@@ -459,19 +457,14 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
spin_lock_init(&m48t59->lock);
platform_set_drvdata(pdev, m48t59);
- m48t59->rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(m48t59->rtc))
- return PTR_ERR(m48t59->rtc);
-
- m48t59->rtc->nvram_old_abi = true;
- m48t59->rtc->ops = ops;
+ m48t59->rtc->ops = &m48t59_rtc_ops;
nvmem_cfg.size = pdata->offset;
- ret = rtc_nvmem_register(m48t59->rtc, &nvmem_cfg);
+ ret = devm_rtc_nvmem_register(m48t59->rtc, &nvmem_cfg);
if (ret)
return ret;
- ret = rtc_register_device(m48t59->rtc);
+ ret = devm_rtc_register_device(m48t59->rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index 75a0e73071d8..481c9525b1dd 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -254,13 +254,12 @@ static int m48t86_rtc_probe(struct platform_device *pdev)
return PTR_ERR(info->rtc);
info->rtc->ops = &m48t86_rtc_ops;
- info->rtc->nvram_old_abi = true;
- err = rtc_register_device(info->rtc);
+ err = devm_rtc_register_device(info->rtc);
if (err)
return err;
- rtc_nvmem_register(info->rtc, &m48t86_nvmem_cfg);
+ devm_rtc_nvmem_register(info->rtc, &m48t86_nvmem_cfg);
/* read battery status */
reg = m48t86_readb(&pdev->dev, M48T86_D);
diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c
index d6802e6191cb..d4234e78497e 100644
--- a/drivers/rtc/rtc-mc13xxx.c
+++ b/drivers/rtc/rtc-mc13xxx.c
@@ -307,7 +307,7 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev)
mc13xxx_unlock(mc13xxx);
- ret = rtc_register_device(priv->rtc);
+ ret = devm_rtc_register_device(priv->rtc);
if (ret) {
mc13xxx_lock(mc13xxx);
goto err_irq_request;
diff --git a/drivers/rtc/rtc-mc146818-lib.c b/drivers/rtc/rtc-mc146818-lib.c
index 2ecd8752b088..dcfaf09946ee 100644
--- a/drivers/rtc/rtc-mc146818-lib.c
+++ b/drivers/rtc/rtc-mc146818-lib.c
@@ -8,41 +8,48 @@
#include <linux/acpi.h>
#endif
-/*
- * Returns true if a clock update is in progress
- */
-static inline unsigned char mc146818_is_updating(void)
-{
- unsigned char uip;
- unsigned long flags;
-
- spin_lock_irqsave(&rtc_lock, flags);
- uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
- spin_unlock_irqrestore(&rtc_lock, flags);
- return uip;
-}
-
unsigned int mc146818_get_time(struct rtc_time *time)
{
unsigned char ctrl;
unsigned long flags;
unsigned char century = 0;
+ bool retry;
#ifdef CONFIG_MACH_DECSTATION
unsigned int real_year;
#endif
+again:
+ spin_lock_irqsave(&rtc_lock, flags);
+ /* Ensure that the RTC is accessible. Bit 6 must be 0! */
+ if (WARN_ON_ONCE((CMOS_READ(RTC_VALID) & 0x40) != 0)) {
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ memset(time, 0xff, sizeof(*time));
+ return 0;
+ }
+
/*
- * read RTC once any update in progress is done. The update
- * can take just over 2ms. We wait 20ms. There is no need to
- * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
- * If you need to know *exactly* when a second has started, enable
- * periodic update complete interrupts, (via ioctl) and then
- * immediately read /dev/rtc which will block until you get the IRQ.
- * Once the read clears, read the RTC time (again via ioctl). Easy.
+ * Check whether there is an update in progress during which the
+ * readout is unspecified. The maximum update time is ~2ms. Poll
+ * every msec for completion.
+ *
+ * Store the second value before checking UIP so a long lasting NMI
+ * which happens to hit after the UIP check cannot make an update
+ * cycle invisible.
*/
- if (mc146818_is_updating())
- mdelay(20);
+ time->tm_sec = CMOS_READ(RTC_SECONDS);
+
+ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ mdelay(1);
+ goto again;
+ }
+
+ /* Revalidate the above readout */
+ if (time->tm_sec != CMOS_READ(RTC_SECONDS)) {
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ goto again;
+ }
/*
* Only the values that we read from the RTC are set. We leave
@@ -50,8 +57,6 @@ unsigned int mc146818_get_time(struct rtc_time *time)
* RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
* by the RTC when initially set to a non-zero value.
*/
- spin_lock_irqsave(&rtc_lock, flags);
- time->tm_sec = CMOS_READ(RTC_SECONDS);
time->tm_min = CMOS_READ(RTC_MINUTES);
time->tm_hour = CMOS_READ(RTC_HOURS);
time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
@@ -66,8 +71,24 @@ unsigned int mc146818_get_time(struct rtc_time *time)
century = CMOS_READ(acpi_gbl_FADT.century);
#endif
ctrl = CMOS_READ(RTC_CONTROL);
+ /*
+ * Check for the UIP bit again. If it is set now then
+ * the above values may contain garbage.
+ */
+ retry = CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP;
+ /*
+ * A NMI might have interrupted the above sequence so check whether
+ * the seconds value has changed which indicates that the NMI took
+ * longer than the UIP bit was set. Unlikely, but possible and
+ * there is also virt...
+ */
+ retry |= time->tm_sec != CMOS_READ(RTC_SECONDS);
+
spin_unlock_irqrestore(&rtc_lock, flags);
+ if (retry)
+ goto again;
+
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
{
time->tm_sec = bcd2bin(time->tm_sec);
@@ -121,7 +142,6 @@ int mc146818_set_time(struct rtc_time *time)
if (yrs > 255) /* They are unsigned */
return -EINVAL;
- spin_lock_irqsave(&rtc_lock, flags);
#ifdef CONFIG_MACH_DECSTATION
real_yrs = yrs;
leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) ||
@@ -150,10 +170,8 @@ int mc146818_set_time(struct rtc_time *time)
/* These limits and adjustments are independent of
* whether the chip is in binary mode or not.
*/
- if (yrs > 169) {
- spin_unlock_irqrestore(&rtc_lock, flags);
+ if (yrs > 169)
return -EINVAL;
- }
if (yrs >= 100)
yrs -= 100;
@@ -169,6 +187,7 @@ int mc146818_set_time(struct rtc_time *time)
century = bin2bcd(century);
}
+ spin_lock_irqsave(&rtc_lock, flags);
save_control = CMOS_READ(RTC_CONTROL);
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
diff --git a/drivers/rtc/rtc-mcp795.c b/drivers/rtc/rtc-mcp795.c
index 21cbf7f892e8..bad7792b6ca5 100644
--- a/drivers/rtc/rtc-mcp795.c
+++ b/drivers/rtc/rtc-mcp795.c
@@ -350,10 +350,9 @@ static irqreturn_t mcp795_irq(int irq, void *data)
{
struct spi_device *spi = data;
struct rtc_device *rtc = spi_get_drvdata(spi);
- struct mutex *lock = &rtc->ops_lock;
int ret;
- mutex_lock(lock);
+ rtc_lock(rtc);
/* Disable alarm.
* There is no need to clear ALM0IF (Alarm 0 Interrupt Flag) bit,
@@ -365,7 +364,7 @@ static irqreturn_t mcp795_irq(int irq, void *data)
"Failed to disable alarm in IRQ (ret=%d)\n", ret);
rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
- mutex_unlock(lock);
+ rtc_unlock(rtc);
return IRQ_HANDLED;
}
diff --git a/drivers/rtc/rtc-meson-vrtc.c b/drivers/rtc/rtc-meson-vrtc.c
index 89e5ba0dae69..1463c8621561 100644
--- a/drivers/rtc/rtc-meson-vrtc.c
+++ b/drivers/rtc/rtc-meson-vrtc.c
@@ -65,7 +65,6 @@ static const struct rtc_class_ops meson_vrtc_ops = {
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)
@@ -84,11 +83,7 @@ static int meson_vrtc_probe(struct platform_device *pdev)
return PTR_ERR(vrtc->rtc);
vrtc->rtc->ops = &meson_vrtc_ops;
- ret = rtc_register_device(vrtc->rtc);
- if (ret)
- return ret;
-
- return 0;
+ return devm_rtc_register_device(vrtc->rtc);
}
static int __maybe_unused meson_vrtc_suspend(struct device *dev)
diff --git a/drivers/rtc/rtc-meson.c b/drivers/rtc/rtc-meson.c
index 47ebcf834cc2..44bdc8b4a90d 100644
--- a/drivers/rtc/rtc-meson.c
+++ b/drivers/rtc/rtc-meson.c
@@ -365,11 +365,11 @@ static int meson_rtc_probe(struct platform_device *pdev)
}
meson_rtc_nvmem_config.priv = rtc;
- ret = rtc_nvmem_register(rtc->rtc, &meson_rtc_nvmem_config);
+ ret = devm_rtc_nvmem_register(rtc->rtc, &meson_rtc_nvmem_config);
if (ret)
goto out_disable_vdd;
- ret = rtc_register_device(rtc->rtc);
+ ret = devm_rtc_register_device(rtc->rtc);
if (ret)
goto out_disable_vdd;
@@ -380,7 +380,7 @@ out_disable_vdd:
return ret;
}
-static const struct of_device_id meson_rtc_dt_match[] = {
+static const __maybe_unused struct of_device_id meson_rtc_dt_match[] = {
{ .compatible = "amlogic,meson6-rtc", },
{ .compatible = "amlogic,meson8-rtc", },
{ .compatible = "amlogic,meson8b-rtc", },
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
index 5c2ce71aa044..bb2ea9bc56f2 100644
--- a/drivers/rtc/rtc-mpc5121.c
+++ b/drivers/rtc/rtc-mpc5121.c
@@ -371,7 +371,7 @@ static int mpc5121_rtc_probe(struct platform_device *op)
rtc->rtc->range_max = U32_MAX;
}
- err = rtc_register_device(rtc->rtc);
+ err = devm_rtc_register_device(rtc->rtc);
if (err)
goto out_dispose2;
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
deleted file mode 100644
index 17bf5394e1e5..000000000000
--- a/drivers/rtc/rtc-mrst.c
+++ /dev/null
@@ -1,521 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * rtc-mrst.c: Driver for Moorestown virtual RTC
- *
- * (C) Copyright 2009 Intel Corporation
- * Author: Jacob Pan ([email protected])
- * Feng Tang ([email protected])
- *
- * Note:
- * VRTC is emulated by system controller firmware, the real HW
- * RTC is located in the PMIC device. SCU FW shadows PMIC RTC
- * in a memory mapped IO space that is visible to the host IA
- * processor.
- *
- * This driver is based upon drivers/rtc/rtc-cmos.c
- */
-
-/*
- * Note:
- * * vRTC only supports binary mode and 24H mode
- * * vRTC only support PIE and AIE, no UIE, and its PIE only happens
- * at 23:59:59pm everyday, no support for adjustable frequency
- * * Alarm function is also limited to hr/min/sec.
- */
-
-#include <linux/mod_devicetable.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/kernel.h>
-#include <linux/mc146818rtc.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/sfi.h>
-
-#include <asm/intel_scu_ipc.h>
-#include <asm/intel-mid.h>
-#include <asm/intel_mid_vrtc.h>
-
-struct mrst_rtc {
- struct rtc_device *rtc;
- struct device *dev;
- int irq;
-
- u8 enabled_wake;
- u8 suspend_ctrl;
-};
-
-static const char driver_name[] = "rtc_mrst";
-
-#define RTC_IRQMASK (RTC_PF | RTC_AF)
-
-static inline int is_intr(u8 rtc_intr)
-{
- if (!(rtc_intr & RTC_IRQF))
- return 0;
- return rtc_intr & RTC_IRQMASK;
-}
-
-static inline unsigned char vrtc_is_updating(void)
-{
- unsigned char uip;
- unsigned long flags;
-
- spin_lock_irqsave(&rtc_lock, flags);
- uip = (vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP);
- spin_unlock_irqrestore(&rtc_lock, flags);
- return uip;
-}
-
-/*
- * rtc_time's year contains the increment over 1900, but vRTC's YEAR
- * register can't be programmed to value larger than 0x64, so vRTC
- * driver chose to use 1972 (1970 is UNIX time start point) as the base,
- * and does the translation at read/write time.
- *
- * Why not just use 1970 as the offset? it's because using 1972 will
- * make it consistent in leap year setting for both vrtc and low-level
- * physical rtc devices. Then why not use 1960 as the offset? If we use
- * 1960, for a device's first use, its YEAR register is 0 and the system
- * year will be parsed as 1960 which is not a valid UNIX time and will
- * cause many applications to fail mysteriously.
- */
-static int mrst_read_time(struct device *dev, struct rtc_time *time)
-{
- unsigned long flags;
-
- if (vrtc_is_updating())
- msleep(20);
-
- spin_lock_irqsave(&rtc_lock, flags);
- time->tm_sec = vrtc_cmos_read(RTC_SECONDS);
- time->tm_min = vrtc_cmos_read(RTC_MINUTES);
- time->tm_hour = vrtc_cmos_read(RTC_HOURS);
- time->tm_mday = vrtc_cmos_read(RTC_DAY_OF_MONTH);
- time->tm_mon = vrtc_cmos_read(RTC_MONTH);
- time->tm_year = vrtc_cmos_read(RTC_YEAR);
- spin_unlock_irqrestore(&rtc_lock, flags);
-
- /* Adjust for the 1972/1900 */
- time->tm_year += 72;
- time->tm_mon--;
- return 0;
-}
-
-static int mrst_set_time(struct device *dev, struct rtc_time *time)
-{
- int ret;
- unsigned long flags;
- unsigned char mon, day, hrs, min, sec;
- unsigned int yrs;
-
- yrs = time->tm_year;
- mon = time->tm_mon + 1; /* tm_mon starts at zero */
- day = time->tm_mday;
- hrs = time->tm_hour;
- min = time->tm_min;
- sec = time->tm_sec;
-
- if (yrs < 72 || yrs > 172)
- return -EINVAL;
- yrs -= 72;
-
- spin_lock_irqsave(&rtc_lock, flags);
-
- vrtc_cmos_write(yrs, RTC_YEAR);
- vrtc_cmos_write(mon, RTC_MONTH);
- vrtc_cmos_write(day, RTC_DAY_OF_MONTH);
- vrtc_cmos_write(hrs, RTC_HOURS);
- vrtc_cmos_write(min, RTC_MINUTES);
- vrtc_cmos_write(sec, RTC_SECONDS);
-
- spin_unlock_irqrestore(&rtc_lock, flags);
-
- ret = intel_scu_ipc_simple_command(IPCMSG_VRTC, IPC_CMD_VRTC_SETTIME);
- return ret;
-}
-
-static int mrst_read_alarm(struct device *dev, struct rtc_wkalrm *t)
-{
- struct mrst_rtc *mrst = dev_get_drvdata(dev);
- unsigned char rtc_control;
-
- if (mrst->irq <= 0)
- return -EIO;
-
- /* vRTC only supports binary mode */
- spin_lock_irq(&rtc_lock);
- t->time.tm_sec = vrtc_cmos_read(RTC_SECONDS_ALARM);
- t->time.tm_min = vrtc_cmos_read(RTC_MINUTES_ALARM);
- t->time.tm_hour = vrtc_cmos_read(RTC_HOURS_ALARM);
-
- rtc_control = vrtc_cmos_read(RTC_CONTROL);
- spin_unlock_irq(&rtc_lock);
-
- t->enabled = !!(rtc_control & RTC_AIE);
- t->pending = 0;
-
- return 0;
-}
-
-static void mrst_checkintr(struct mrst_rtc *mrst, unsigned char rtc_control)
-{
- unsigned char rtc_intr;
-
- /*
- * NOTE after changing RTC_xIE bits we always read INTR_FLAGS;
- * allegedly some older rtcs need that to handle irqs properly
- */
- rtc_intr = vrtc_cmos_read(RTC_INTR_FLAGS);
- rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
- if (is_intr(rtc_intr))
- rtc_update_irq(mrst->rtc, 1, rtc_intr);
-}
-
-static void mrst_irq_enable(struct mrst_rtc *mrst, unsigned char mask)
-{
- unsigned char rtc_control;
-
- /*
- * Flush any pending IRQ status, notably for update irqs,
- * before we enable new IRQs
- */
- rtc_control = vrtc_cmos_read(RTC_CONTROL);
- mrst_checkintr(mrst, rtc_control);
-
- rtc_control |= mask;
- vrtc_cmos_write(rtc_control, RTC_CONTROL);
-
- mrst_checkintr(mrst, rtc_control);
-}
-
-static void mrst_irq_disable(struct mrst_rtc *mrst, unsigned char mask)
-{
- unsigned char rtc_control;
-
- rtc_control = vrtc_cmos_read(RTC_CONTROL);
- rtc_control &= ~mask;
- vrtc_cmos_write(rtc_control, RTC_CONTROL);
- mrst_checkintr(mrst, rtc_control);
-}
-
-static int mrst_set_alarm(struct device *dev, struct rtc_wkalrm *t)
-{
- struct mrst_rtc *mrst = dev_get_drvdata(dev);
- unsigned char hrs, min, sec;
- int ret = 0;
-
- if (!mrst->irq)
- return -EIO;
-
- hrs = t->time.tm_hour;
- min = t->time.tm_min;
- sec = t->time.tm_sec;
-
- spin_lock_irq(&rtc_lock);
- /* Next rtc irq must not be from previous alarm setting */
- mrst_irq_disable(mrst, RTC_AIE);
-
- /* Update alarm */
- vrtc_cmos_write(hrs, RTC_HOURS_ALARM);
- vrtc_cmos_write(min, RTC_MINUTES_ALARM);
- vrtc_cmos_write(sec, RTC_SECONDS_ALARM);
-
- spin_unlock_irq(&rtc_lock);
-
- ret = intel_scu_ipc_simple_command(IPCMSG_VRTC, IPC_CMD_VRTC_SETALARM);
- if (ret)
- return ret;
-
- spin_lock_irq(&rtc_lock);
- if (t->enabled)
- mrst_irq_enable(mrst, RTC_AIE);
-
- spin_unlock_irq(&rtc_lock);
-
- return 0;
-}
-
-/* Currently, the vRTC doesn't support UIE ON/OFF */
-static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
-{
- struct mrst_rtc *mrst = dev_get_drvdata(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&rtc_lock, flags);
- if (enabled)
- mrst_irq_enable(mrst, RTC_AIE);
- else
- mrst_irq_disable(mrst, RTC_AIE);
- spin_unlock_irqrestore(&rtc_lock, flags);
- return 0;
-}
-
-
-#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
-
-static int mrst_procfs(struct device *dev, struct seq_file *seq)
-{
- unsigned char rtc_control;
-
- spin_lock_irq(&rtc_lock);
- rtc_control = vrtc_cmos_read(RTC_CONTROL);
- spin_unlock_irq(&rtc_lock);
-
- seq_printf(seq,
- "periodic_IRQ\t: %s\n"
- "alarm\t\t: %s\n"
- "BCD\t\t: no\n"
- "periodic_freq\t: daily (not adjustable)\n",
- (rtc_control & RTC_PIE) ? "on" : "off",
- (rtc_control & RTC_AIE) ? "on" : "off");
-
- return 0;
-}
-
-#else
-#define mrst_procfs NULL
-#endif
-
-static const struct rtc_class_ops mrst_rtc_ops = {
- .read_time = mrst_read_time,
- .set_time = mrst_set_time,
- .read_alarm = mrst_read_alarm,
- .set_alarm = mrst_set_alarm,
- .proc = mrst_procfs,
- .alarm_irq_enable = mrst_rtc_alarm_irq_enable,
-};
-
-static struct mrst_rtc mrst_rtc;
-
-/*
- * When vRTC IRQ is captured by SCU FW, FW will clear the AIE bit in
- * Reg B, so no need for this driver to clear it
- */
-static irqreturn_t mrst_rtc_irq(int irq, void *p)
-{
- u8 irqstat;
-
- spin_lock(&rtc_lock);
- /* This read will clear all IRQ flags inside Reg C */
- irqstat = vrtc_cmos_read(RTC_INTR_FLAGS);
- spin_unlock(&rtc_lock);
-
- irqstat &= RTC_IRQMASK | RTC_IRQF;
- if (is_intr(irqstat)) {
- rtc_update_irq(p, 1, irqstat);
- return IRQ_HANDLED;
- }
- return IRQ_NONE;
-}
-
-static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem,
- int rtc_irq)
-{
- int retval = 0;
- unsigned char rtc_control;
-
- /* There can be only one ... */
- if (mrst_rtc.dev)
- return -EBUSY;
-
- if (!iomem)
- return -ENODEV;
-
- iomem = devm_request_mem_region(dev, iomem->start, resource_size(iomem),
- driver_name);
- if (!iomem) {
- dev_dbg(dev, "i/o mem already in use.\n");
- return -EBUSY;
- }
-
- mrst_rtc.irq = rtc_irq;
- mrst_rtc.dev = dev;
- dev_set_drvdata(dev, &mrst_rtc);
-
- mrst_rtc.rtc = devm_rtc_allocate_device(dev);
- if (IS_ERR(mrst_rtc.rtc))
- return PTR_ERR(mrst_rtc.rtc);
-
- mrst_rtc.rtc->ops = &mrst_rtc_ops;
-
- rename_region(iomem, dev_name(&mrst_rtc.rtc->dev));
-
- spin_lock_irq(&rtc_lock);
- mrst_irq_disable(&mrst_rtc, RTC_PIE | RTC_AIE);
- rtc_control = vrtc_cmos_read(RTC_CONTROL);
- spin_unlock_irq(&rtc_lock);
-
- if (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))
- dev_dbg(dev, "TODO: support more than 24-hr BCD mode\n");
-
- if (rtc_irq) {
- retval = devm_request_irq(dev, rtc_irq, mrst_rtc_irq,
- 0, dev_name(&mrst_rtc.rtc->dev),
- mrst_rtc.rtc);
- if (retval < 0) {
- dev_dbg(dev, "IRQ %d is already in use, err %d\n",
- rtc_irq, retval);
- goto cleanup0;
- }
- }
-
- retval = rtc_register_device(mrst_rtc.rtc);
- if (retval)
- goto cleanup0;
-
- dev_dbg(dev, "initialised\n");
- return 0;
-
-cleanup0:
- mrst_rtc.dev = NULL;
- dev_err(dev, "rtc-mrst: unable to initialise\n");
- return retval;
-}
-
-static void rtc_mrst_do_shutdown(void)
-{
- spin_lock_irq(&rtc_lock);
- mrst_irq_disable(&mrst_rtc, RTC_IRQMASK);
- spin_unlock_irq(&rtc_lock);
-}
-
-static void rtc_mrst_do_remove(struct device *dev)
-{
- struct mrst_rtc *mrst = dev_get_drvdata(dev);
-
- rtc_mrst_do_shutdown();
-
- mrst->rtc = NULL;
- mrst->dev = NULL;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int mrst_suspend(struct device *dev)
-{
- struct mrst_rtc *mrst = dev_get_drvdata(dev);
- unsigned char tmp;
-
- /* Only the alarm might be a wakeup event source */
- spin_lock_irq(&rtc_lock);
- mrst->suspend_ctrl = tmp = vrtc_cmos_read(RTC_CONTROL);
- if (tmp & (RTC_PIE | RTC_AIE)) {
- unsigned char mask;
-
- if (device_may_wakeup(dev))
- mask = RTC_IRQMASK & ~RTC_AIE;
- else
- mask = RTC_IRQMASK;
- tmp &= ~mask;
- vrtc_cmos_write(tmp, RTC_CONTROL);
-
- mrst_checkintr(mrst, tmp);
- }
- spin_unlock_irq(&rtc_lock);
-
- if (tmp & RTC_AIE) {
- mrst->enabled_wake = 1;
- enable_irq_wake(mrst->irq);
- }
-
- dev_dbg(&mrst_rtc.rtc->dev, "suspend%s, ctrl %02x\n",
- (tmp & RTC_AIE) ? ", alarm may wake" : "",
- tmp);
-
- return 0;
-}
-
-/*
- * We want RTC alarms to wake us from the deep power saving state
- */
-static inline int mrst_poweroff(struct device *dev)
-{
- return mrst_suspend(dev);
-}
-
-static int mrst_resume(struct device *dev)
-{
- struct mrst_rtc *mrst = dev_get_drvdata(dev);
- unsigned char tmp = mrst->suspend_ctrl;
-
- /* Re-enable any irqs previously active */
- if (tmp & RTC_IRQMASK) {
- unsigned char mask;
-
- if (mrst->enabled_wake) {
- disable_irq_wake(mrst->irq);
- mrst->enabled_wake = 0;
- }
-
- spin_lock_irq(&rtc_lock);
- do {
- vrtc_cmos_write(tmp, RTC_CONTROL);
-
- mask = vrtc_cmos_read(RTC_INTR_FLAGS);
- mask &= (tmp & RTC_IRQMASK) | RTC_IRQF;
- if (!is_intr(mask))
- break;
-
- rtc_update_irq(mrst->rtc, 1, mask);
- tmp &= ~RTC_AIE;
- } while (mask & RTC_AIE);
- spin_unlock_irq(&rtc_lock);
- }
-
- dev_dbg(&mrst_rtc.rtc->dev, "resume, ctrl %02x\n", tmp);
-
- return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(mrst_pm_ops, mrst_suspend, mrst_resume);
-#define MRST_PM_OPS (&mrst_pm_ops)
-
-#else
-#define MRST_PM_OPS NULL
-
-static inline int mrst_poweroff(struct device *dev)
-{
- return -ENOSYS;
-}
-
-#endif
-
-static int vrtc_mrst_platform_probe(struct platform_device *pdev)
-{
- return vrtc_mrst_do_probe(&pdev->dev,
- platform_get_resource(pdev, IORESOURCE_MEM, 0),
- platform_get_irq(pdev, 0));
-}
-
-static int vrtc_mrst_platform_remove(struct platform_device *pdev)
-{
- rtc_mrst_do_remove(&pdev->dev);
- return 0;
-}
-
-static void vrtc_mrst_platform_shutdown(struct platform_device *pdev)
-{
- if (system_state == SYSTEM_POWER_OFF && !mrst_poweroff(&pdev->dev))
- return;
-
- rtc_mrst_do_shutdown();
-}
-
-MODULE_ALIAS("platform:vrtc_mrst");
-
-static struct platform_driver vrtc_mrst_platform_driver = {
- .probe = vrtc_mrst_platform_probe,
- .remove = vrtc_mrst_platform_remove,
- .shutdown = vrtc_mrst_platform_shutdown,
- .driver = {
- .name = driver_name,
- .pm = MRST_PM_OPS,
- }
-};
-
-module_platform_driver(vrtc_mrst_platform_driver);
-
-MODULE_AUTHOR("Jacob Pan; Feng Tang");
-MODULE_DESCRIPTION("Driver for Moorestown virtual RTC");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-mt2712.c b/drivers/rtc/rtc-mt2712.c
index d5f691c8a035..cd92a9788351 100644
--- a/drivers/rtc/rtc-mt2712.c
+++ b/drivers/rtc/rtc-mt2712.c
@@ -352,7 +352,7 @@ static int mt2712_rtc_probe(struct platform_device *pdev)
mt2712_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
mt2712_rtc->rtc->range_max = MT2712_RTC_TIMESTAMP_END_2127;
- return rtc_register_device(mt2712_rtc->rtc);
+ return devm_rtc_register_device(mt2712_rtc->rtc);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
index f8b1353777ba..6655035e5164 100644
--- a/drivers/rtc/rtc-mt6397.c
+++ b/drivers/rtc/rtc-mt6397.c
@@ -31,7 +31,8 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
MTK_RTC_POLL_DELAY_US,
MTK_RTC_POLL_TIMEOUT);
if (ret < 0)
- dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret);
+ dev_err(rtc->rtc_dev->dev.parent,
+ "failed to write WRTGR: %d\n", ret);
return ret;
}
@@ -300,7 +301,7 @@ static int mtk_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev->ops = &mtk_rtc_ops;
- return rtc_register_device(rtc->rtc_dev);
+ return devm_rtc_register_device(rtc->rtc_dev);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index d5f190e578e4..6c526e2ec56d 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -200,11 +200,6 @@ static irqreturn_t mv_rtc_interrupt(int irq, void *data)
static const struct rtc_class_ops mv_rtc_ops = {
.read_time = mv_rtc_read_time,
.set_time = mv_rtc_set_time,
-};
-
-static const struct rtc_class_ops mv_rtc_alarm_ops = {
- .read_time = mv_rtc_read_time,
- .set_time = mv_rtc_set_time,
.read_alarm = mv_rtc_read_alarm,
.set_alarm = mv_rtc_set_alarm,
.alarm_irq_enable = mv_rtc_alarm_irq_enable,
@@ -268,17 +263,16 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
}
}
- if (pdata->irq >= 0) {
+ if (pdata->irq >= 0)
device_init_wakeup(&pdev->dev, 1);
- pdata->rtc->ops = &mv_rtc_alarm_ops;
- } else {
- pdata->rtc->ops = &mv_rtc_ops;
- }
+ else
+ clear_bit(RTC_FEATURE_ALARM, pdata->rtc->features);
+ pdata->rtc->ops = &mv_rtc_ops;
pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
pdata->rtc->range_max = RTC_TIMESTAMP_END_2099;
- ret = rtc_register_device(pdata->rtc);
+ ret = devm_rtc_register_device(pdata->rtc);
if (!ret)
return 0;
out:
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index a8cfbde048f4..db57dda7ab97 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -70,27 +70,12 @@ struct rtc_plat_data {
enum imx_rtc_type devtype;
};
-static const struct platform_device_id imx_rtc_devtype[] = {
- {
- .name = "imx1-rtc",
- .driver_data = IMX1_RTC,
- }, {
- .name = "imx21-rtc",
- .driver_data = IMX21_RTC,
- }, {
- /* sentinel */
- }
-};
-MODULE_DEVICE_TABLE(platform, imx_rtc_devtype);
-
-#ifdef CONFIG_OF
static const struct of_device_id imx_rtc_dt_ids[] = {
{ .compatible = "fsl,imx1-rtc", .data = (const void *)IMX1_RTC },
{ .compatible = "fsl,imx21-rtc", .data = (const void *)IMX21_RTC },
{}
};
MODULE_DEVICE_TABLE(of, imx_rtc_dt_ids);
-#endif
static inline int is_imx1_rtc(struct rtc_plat_data *data)
{
@@ -204,11 +189,10 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
struct platform_device *pdev = dev_id;
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr;
- unsigned long flags;
u32 status;
u32 events = 0;
- spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
+ spin_lock(&pdata->rtc->irq_lock);
status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR);
/* clear interrupt sources */
writew(status, ioaddr + RTC_RTCISR);
@@ -224,7 +208,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
events |= (RTC_PF | RTC_IRQF);
rtc_update_irq(pdata->rtc, 1, events);
- spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags);
+ spin_unlock(&pdata->rtc->irq_lock);
return IRQ_HANDLED;
}
@@ -322,17 +306,12 @@ static int mxc_rtc_probe(struct platform_device *pdev)
u32 reg;
unsigned long rate;
int ret;
- const struct of_device_id *of_id;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
- of_id = of_match_device(imx_rtc_dt_ids, &pdev->dev);
- if (of_id)
- pdata->devtype = (enum imx_rtc_type)of_id->data;
- else
- pdata->devtype = pdev->id_entry->driver_data;
+ pdata->devtype = (enum imx_rtc_type)of_device_get_match_data(&pdev->dev);
pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->ioaddr))
@@ -428,7 +407,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to enable irq wake\n");
}
- ret = rtc_register_device(rtc);
+ ret = devm_rtc_register_device(rtc);
return ret;
}
@@ -438,7 +417,6 @@ static struct platform_driver mxc_rtc_driver = {
.name = "mxc_rtc",
.of_match_table = of_match_ptr(imx_rtc_dt_ids),
},
- .id_table = imx_rtc_devtype,
.probe = mxc_rtc_probe,
};
diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c
index 91534560fe2a..a577a74aaf75 100644
--- a/drivers/rtc/rtc-mxc_v2.c
+++ b/drivers/rtc/rtc-mxc_v2.c
@@ -74,13 +74,12 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
struct device *dev = dev_id;
struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
- unsigned long flags;
u32 lp_status;
u32 lp_cr;
- spin_lock_irqsave(&pdata->lock, flags);
+ spin_lock(&pdata->lock);
if (clk_enable(pdata->clk)) {
- spin_unlock_irqrestore(&pdata->lock, flags);
+ spin_unlock(&pdata->lock);
return IRQ_NONE;
}
@@ -104,7 +103,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
mxc_rtc_sync_lp_locked(dev, ioaddr);
clk_disable(pdata->clk);
- spin_unlock_irqrestore(&pdata->lock, flags);
+ spin_unlock(&pdata->lock);
return IRQ_HANDLED;
}
@@ -354,7 +353,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
return ret;
}
- ret = rtc_register_device(pdata->rtc);
+ ret = devm_rtc_register_device(pdata->rtc);
if (ret < 0)
clk_unprepare(pdata->clk);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index c20fc7937dfa..dc7db2477f88 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -879,18 +879,18 @@ static int omap_rtc_probe(struct platform_device *pdev)
/* Support ext_wakeup pinconf */
rtc_pinctrl_desc.name = dev_name(&pdev->dev);
- rtc->pctldev = pinctrl_register(&rtc_pinctrl_desc, &pdev->dev, rtc);
+ rtc->pctldev = devm_pinctrl_register(&pdev->dev, &rtc_pinctrl_desc, rtc);
if (IS_ERR(rtc->pctldev)) {
dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
ret = PTR_ERR(rtc->pctldev);
goto err;
}
- ret = rtc_register_device(rtc->rtc);
+ ret = devm_rtc_register_device(rtc->rtc);
if (ret)
- goto err_deregister_pinctrl;
+ goto err;
- rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config);
+ devm_rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config);
if (rtc->is_pmic_controller) {
if (!pm_power_off) {
@@ -901,8 +901,6 @@ static int omap_rtc_probe(struct platform_device *pdev)
return 0;
-err_deregister_pinctrl:
- pinctrl_unregister(rtc->pctldev);
err:
clk_disable_unprepare(rtc->clk);
device_init_wakeup(&pdev->dev, false);
@@ -945,9 +943,6 @@ static int omap_rtc_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- /* Remove ext_wakeup pinconf */
- pinctrl_unregister(rtc->pctldev);
-
return 0;
}
diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c
index 7b9f8bcf86fe..f8f49a969c23 100644
--- a/drivers/rtc/rtc-opal.c
+++ b/drivers/rtc/rtc-opal.c
@@ -224,32 +224,35 @@ static int opal_tpo_alarm_irq_enable(struct device *dev, unsigned int enabled)
return enabled ? 0 : opal_set_tpo_time(dev, &alarm);
}
-static struct rtc_class_ops opal_rtc_ops = {
+static const struct rtc_class_ops opal_rtc_ops = {
.read_time = opal_get_rtc_time,
.set_time = opal_set_rtc_time,
+ .read_alarm = opal_get_tpo_time,
+ .set_alarm = opal_set_tpo_time,
+ .alarm_irq_enable = opal_tpo_alarm_irq_enable,
};
static int opal_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
+ rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
if (pdev->dev.of_node &&
(of_property_read_bool(pdev->dev.of_node, "wakeup-source") ||
- of_property_read_bool(pdev->dev.of_node, "has-tpo")/* legacy */)) {
+ of_property_read_bool(pdev->dev.of_node, "has-tpo")/* legacy */))
device_set_wakeup_capable(&pdev->dev, true);
- opal_rtc_ops.read_alarm = opal_get_tpo_time;
- opal_rtc_ops.set_alarm = opal_set_tpo_time;
- opal_rtc_ops.alarm_irq_enable = opal_tpo_alarm_irq_enable;
- }
-
- rtc = devm_rtc_device_register(&pdev->dev, DRVNAME, &opal_rtc_ops,
- THIS_MODULE);
- if (IS_ERR(rtc))
- return PTR_ERR(rtc);
+ else
+ clear_bit(RTC_FEATURE_ALARM, rtc->features);
+ rtc->ops = &opal_rtc_ops;
+ rtc->range_min = RTC_TIMESTAMP_BEGIN_0000;
+ rtc->range_max = RTC_TIMESTAMP_END_9999;
rtc->uie_unsupported = 1;
- return 0;
+ return devm_rtc_register_device(rtc);
}
static const struct of_device_id opal_rtc_match[] = {
diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c
index 178bfb1dea21..8c7a98a5452c 100644
--- a/drivers/rtc/rtc-pcap.c
+++ b/drivers/rtc/rtc-pcap.c
@@ -163,7 +163,7 @@ static int __init pcap_rtc_probe(struct platform_device *pdev)
if (err)
return err;
- return rtc_register_device(pcap_rtc->rtc);
+ return devm_rtc_register_device(pcap_rtc->rtc);
}
static int __exit pcap_rtc_remove(struct platform_device *pdev)
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
index c3691fa4210e..0f58cac81d8c 100644
--- a/drivers/rtc/rtc-pcf2123.c
+++ b/drivers/rtc/rtc-pcf2123.c
@@ -307,11 +307,10 @@ static int pcf2123_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
static irqreturn_t pcf2123_rtc_irq(int irq, void *dev)
{
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);
+ rtc_lock(pcf2123->rtc);
regmap_read(pcf2123->map, PCF2123_REG_CTRL2, &val);
/* Alarm? */
@@ -324,7 +323,7 @@ static irqreturn_t pcf2123_rtc_irq(int irq, void *dev)
rtc_update_irq(pcf2123->rtc, 1, RTC_IRQF | RTC_AF);
}
- mutex_unlock(lock);
+ rtc_unlock(pcf2123->rtc);
return ret;
}
@@ -434,7 +433,7 @@ static int pcf2123_probe(struct spi_device *spi)
rtc->range_max = RTC_TIMESTAMP_END_2099;
rtc->set_start_time = true;
- ret = rtc_register_device(rtc);
+ ret = devm_rtc_register_device(rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c
index ed6316992cbb..d13c20a2adf7 100644
--- a/drivers/rtc/rtc-pcf2127.c
+++ b/drivers/rtc/rtc-pcf2127.c
@@ -26,6 +26,7 @@
/* Control register 1 */
#define PCF2127_REG_CTRL1 0x00
+#define PCF2127_BIT_CTRL1_POR_OVRD BIT(3)
#define PCF2127_BIT_CTRL1_TSF1 BIT(4)
/* Control register 2 */
#define PCF2127_REG_CTRL2 0x01
@@ -57,6 +58,9 @@
#define PCF2127_REG_ALARM_DM 0x0D
#define PCF2127_REG_ALARM_DW 0x0E
#define PCF2127_BIT_ALARM_AE BIT(7)
+/* CLKOUT control register */
+#define PCF2127_REG_CLKOUT 0x0f
+#define PCF2127_BIT_CLKOUT_OTPR BIT(5)
/* Watchdog registers */
#define PCF2127_REG_WD_CTL 0x10
#define PCF2127_BIT_WD_CTL_TF0 BIT(0)
@@ -225,12 +229,6 @@ static int pcf2127_rtc_ioctl(struct device *dev,
}
}
-static const struct rtc_class_ops pcf2127_rtc_ops = {
- .ioctl = pcf2127_rtc_ioctl,
- .read_time = pcf2127_rtc_read_time,
- .set_time = pcf2127_rtc_set_time,
-};
-
static int pcf2127_nvmem_read(void *priv, unsigned int offset,
void *val, size_t bytes)
{
@@ -243,10 +241,8 @@ static int pcf2127_nvmem_read(void *priv, unsigned int offset,
if (ret)
return ret;
- ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_RD_CMD,
- val, bytes);
-
- return ret ?: bytes;
+ return regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_RD_CMD,
+ val, bytes);
}
static int pcf2127_nvmem_write(void *priv, unsigned int offset,
@@ -261,10 +257,8 @@ static int pcf2127_nvmem_write(void *priv, unsigned int offset,
if (ret)
return ret;
- ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD,
- val, bytes);
-
- return ret ?: bytes;
+ return regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD,
+ val, bytes);
}
/* watchdog driver */
@@ -335,6 +329,37 @@ static const struct watchdog_ops pcf2127_watchdog_ops = {
.set_timeout = pcf2127_wdt_set_timeout,
};
+static int pcf2127_watchdog_init(struct device *dev, struct pcf2127 *pcf2127)
+{
+ u32 wdd_timeout;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_WATCHDOG) ||
+ !device_property_read_bool(dev, "reset-source"))
+ return 0;
+
+ 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;
+ pcf2127->wdd.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
+
+ watchdog_set_drvdata(&pcf2127->wdd, pcf2127);
+
+ /* 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);
+
+ return devm_watchdog_register_device(dev, &pcf2127->wdd);
+}
+
/* Alarm */
static int pcf2127_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
@@ -432,7 +457,7 @@ static irqreturn_t pcf2127_rtc_irq(int irq, void *dev)
return IRQ_HANDLED;
}
-static const struct rtc_class_ops pcf2127_rtc_alrm_ops = {
+static const struct rtc_class_ops pcf2127_rtc_ops = {
.ioctl = pcf2127_rtc_ioctl,
.read_time = pcf2127_rtc_read_time,
.set_time = pcf2127_rtc_set_time,
@@ -533,11 +558,11 @@ static const struct attribute_group pcf2127_attr_group = {
};
static int pcf2127_probe(struct device *dev, struct regmap *regmap,
- int alarm_irq, const char *name, bool has_nvmem)
+ int alarm_irq, const char *name, bool is_pcf2127)
{
struct pcf2127 *pcf2127;
- u32 wdd_timeout;
int ret = 0;
+ unsigned int val;
dev_dbg(dev, "%s\n", __func__);
@@ -558,8 +583,9 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
pcf2127->rtc->range_max = RTC_TIMESTAMP_END_2099;
pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */
pcf2127->rtc->uie_unsupported = 1;
+ clear_bit(RTC_FEATURE_ALARM, pcf2127->rtc->features);
- if (alarm_irq >= 0) {
+ if (alarm_irq > 0) {
ret = devm_request_threaded_irq(dev, alarm_irq, NULL,
pcf2127_rtc_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
@@ -570,23 +596,12 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
}
}
- if (alarm_irq >= 0 || device_property_read_bool(dev, "wakeup-source")) {
+ if (alarm_irq > 0 || device_property_read_bool(dev, "wakeup-source")) {
device_init_wakeup(dev, true);
- pcf2127->rtc->ops = &pcf2127_rtc_alrm_ops;
+ set_bit(RTC_FEATURE_ALARM, pcf2127->rtc->features);
}
- 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;
- pcf2127->wdd.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
-
- watchdog_set_drvdata(&pcf2127->wdd, pcf2127);
-
- if (has_nvmem) {
+ if (is_pcf2127) {
struct nvmem_config nvmem_cfg = {
.priv = pcf2127,
.reg_read = pcf2127_nvmem_read,
@@ -594,13 +609,37 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
.size = 512,
};
- ret = rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg);
+ ret = devm_rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg);
+ }
+
+ /*
+ * The "Power-On Reset Override" facility prevents the RTC to do a reset
+ * after power on. For normal operation the PORO must be disabled.
+ */
+ regmap_clear_bits(pcf2127->regmap, PCF2127_REG_CTRL1,
+ PCF2127_BIT_CTRL1_POR_OVRD);
+
+ ret = regmap_read(pcf2127->regmap, PCF2127_REG_CLKOUT, &val);
+ if (ret < 0)
+ return ret;
+
+ if (!(val & PCF2127_BIT_CLKOUT_OTPR)) {
+ ret = regmap_set_bits(pcf2127->regmap, PCF2127_REG_CLKOUT,
+ PCF2127_BIT_CLKOUT_OTPR);
+ if (ret < 0)
+ return ret;
+
+ msleep(100);
}
/*
* 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.
+ * For pca2129, pcf2129, only bit[7] is for Symbol WD_CD
+ * of register watchdg_tim_ctl. The bit[6] is labeled
+ * as T. Bits labeled as T must always be written with
+ * logic 0.
*/
ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_WD_CTL,
PCF2127_BIT_WD_CTL_CD1 |
@@ -608,26 +647,14 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
PCF2127_BIT_WD_CTL_TF1 |
PCF2127_BIT_WD_CTL_TF0,
PCF2127_BIT_WD_CTL_CD1 |
- PCF2127_BIT_WD_CTL_CD0 |
+ (is_pcf2127 ? PCF2127_BIT_WD_CTL_CD0 : 0) |
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 */
+ pcf2127_watchdog_init(dev, pcf2127);
/*
* Disable battery low/switch-over timestamp and interrupts.
@@ -680,7 +707,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
return ret;
}
- return rtc_register_device(pcf2127->rtc);
+ return devm_rtc_register_device(pcf2127->rtc);
}
#ifdef CONFIG_OF
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index f8b99cb72959..aef6c1ee8bb0 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -311,14 +311,6 @@ static const struct rtc_class_ops pcf85063_rtc_ops = {
.set_time = pcf85063_rtc_set_time,
.read_offset = pcf85063_read_offset,
.set_offset = pcf85063_set_offset,
- .ioctl = pcf85063_ioctl,
-};
-
-static const struct rtc_class_ops pcf85063_rtc_ops_alarm = {
- .read_time = pcf85063_rtc_read_time,
- .set_time = pcf85063_rtc_set_time,
- .read_offset = pcf85063_read_offset,
- .set_offset = pcf85063_set_offset,
.read_alarm = pcf85063_rtc_read_alarm,
.set_alarm = pcf85063_rtc_set_alarm,
.alarm_irq_enable = pcf85063_rtc_alarm_irq_enable,
@@ -509,15 +501,6 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
}
#endif
-static const struct pcf85063_config pcf85063a_config = {
- .regmap = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 0x11,
- },
- .has_alarms = 1,
-};
-
static const struct pcf85063_config pcf85063tp_config = {
.regmap = {
.reg_bits = 8,
@@ -526,16 +509,6 @@ static const struct pcf85063_config pcf85063tp_config = {
},
};
-static const struct pcf85063_config rv8263_config = {
- .regmap = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 0x11,
- },
- .has_alarms = 1,
- .force_cap_7000 = 1,
-};
-
static int pcf85063_probe(struct i2c_client *client)
{
struct pcf85063 *pcf85063;
@@ -587,6 +560,7 @@ static int pcf85063_probe(struct i2c_client *client)
pcf85063->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
pcf85063->rtc->range_max = RTC_TIMESTAMP_END_2099;
pcf85063->rtc->uie_unsupported = 1;
+ clear_bit(RTC_FEATURE_ALARM, pcf85063->rtc->features);
if (config->has_alarms && client->irq > 0) {
err = devm_request_threaded_irq(&client->dev, client->irq,
@@ -597,7 +571,7 @@ static int pcf85063_probe(struct i2c_client *client)
dev_warn(&pcf85063->rtc->dev,
"unable to request IRQ, alarms disabled\n");
} else {
- pcf85063->rtc->ops = &pcf85063_rtc_ops_alarm;
+ set_bit(RTC_FEATURE_ALARM, pcf85063->rtc->features);
device_init_wakeup(&client->dev, true);
err = dev_pm_set_wake_irq(&client->dev, client->irq);
if (err)
@@ -607,17 +581,36 @@ static int pcf85063_probe(struct i2c_client *client)
}
nvmem_cfg.priv = pcf85063->regmap;
- rtc_nvmem_register(pcf85063->rtc, &nvmem_cfg);
+ devm_rtc_nvmem_register(pcf85063->rtc, &nvmem_cfg);
#ifdef CONFIG_COMMON_CLK
/* register clk in common clk framework */
pcf85063_clkout_register_clk(pcf85063);
#endif
- return rtc_register_device(pcf85063->rtc);
+ return devm_rtc_register_device(pcf85063->rtc);
}
#ifdef CONFIG_OF
+static const struct pcf85063_config pcf85063a_config = {
+ .regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0x11,
+ },
+ .has_alarms = 1,
+};
+
+static const struct pcf85063_config rv8263_config = {
+ .regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0x11,
+ },
+ .has_alarms = 1,
+ .force_cap_7000 = 1,
+};
+
static const struct of_device_id pcf85063_of_match[] = {
{ .compatible = "nxp,pcf85063", .data = &pcf85063tp_config },
{ .compatible = "nxp,pcf85063tp", .data = &pcf85063tp_config },
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c
index 57d351dfe272..5e1e7b2a8c9a 100644
--- a/drivers/rtc/rtc-pcf8523.c
+++ b/drivers/rtc/rtc-pcf8523.c
@@ -12,18 +12,18 @@
#define DRIVER_NAME "rtc-pcf8523"
#define REG_CONTROL1 0x00
-#define REG_CONTROL1_CAP_SEL (1 << 7)
-#define REG_CONTROL1_STOP (1 << 5)
+#define REG_CONTROL1_CAP_SEL BIT(7)
+#define REG_CONTROL1_STOP BIT(5)
#define REG_CONTROL3 0x02
-#define REG_CONTROL3_PM_BLD (1 << 7) /* battery low detection disabled */
-#define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */
-#define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */
+#define REG_CONTROL3_PM_BLD BIT(7) /* battery low detection disabled */
+#define REG_CONTROL3_PM_VDD BIT(6) /* switch-over disabled */
+#define REG_CONTROL3_PM_DSM BIT(5) /* direct switching mode */
#define REG_CONTROL3_PM_MASK 0xe0
-#define REG_CONTROL3_BLF (1 << 2) /* battery low bit, read-only */
+#define REG_CONTROL3_BLF BIT(2) /* battery low bit, read-only */
#define REG_SECONDS 0x03
-#define REG_SECONDS_OS (1 << 7)
+#define REG_SECONDS_OS BIT(7)
#define REG_MINUTES 0x04
#define REG_HOURS 0x05
@@ -226,17 +226,6 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
u8 regs[8];
int err;
- /*
- * The hardware can only store values between 0 and 99 in it's YEAR
- * register (with 99 overflowing to 0 on increment).
- * After 2100-02-28 we could start interpreting the year to be in the
- * interval [2100, 2199], but there is no path to switch in a smooth way
- * because the chip handles YEAR=0x00 (and the out-of-spec
- * YEAR=0xa0) as a leap year, but 2100 isn't.
- */
- if (tm->tm_year < 100 || tm->tm_year >= 200)
- return -EINVAL;
-
err = pcf8523_stop_rtc(client);
if (err < 0)
return err;
@@ -356,12 +345,15 @@ static int pcf8523_probe(struct i2c_client *client,
if (err < 0)
return err;
- rtc = devm_rtc_device_register(&client->dev, DRIVER_NAME,
- &pcf8523_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- return 0;
+ rtc->ops = &pcf8523_rtc_ops;
+ rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rtc->range_max = RTC_TIMESTAMP_END_2099;
+
+ return devm_rtc_register_device(rtc);
}
static const struct i2c_device_id pcf8523_id[] = {
diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c
index 3450d615974d..bb3e9ba75f6c 100644
--- a/drivers/rtc/rtc-pcf85363.c
+++ b/drivers/rtc/rtc-pcf85363.c
@@ -285,11 +285,6 @@ static irqreturn_t pcf85363_rtc_handle_irq(int irq, void *dev_id)
static const struct rtc_class_ops rtc_ops = {
.read_time = pcf85363_rtc_read_time,
.set_time = pcf85363_rtc_set_time,
-};
-
-static const struct rtc_class_ops rtc_ops_alarm = {
- .read_time = pcf85363_rtc_read_time,
- .set_time = pcf85363_rtc_set_time,
.read_alarm = pcf85363_rtc_read_alarm,
.set_alarm = pcf85363_rtc_set_alarm,
.alarm_irq_enable = pcf85363_rtc_alarm_irq_enable,
@@ -403,6 +398,7 @@ static int pcf85363_probe(struct i2c_client *client,
pcf85363->rtc->ops = &rtc_ops;
pcf85363->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
pcf85363->rtc->range_max = RTC_TIMESTAMP_END_2099;
+ clear_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features);
if (client->irq > 0) {
regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);
@@ -415,20 +411,20 @@ static int pcf85363_probe(struct i2c_client *client,
if (ret)
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
else
- pcf85363->rtc->ops = &rtc_ops_alarm;
+ set_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features);
}
- ret = rtc_register_device(pcf85363->rtc);
+ ret = devm_rtc_register_device(pcf85363->rtc);
for (i = 0; i < config->num_nvram; i++) {
nvmem_cfg[i].priv = pcf85363;
- rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg[i]);
+ devm_rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg[i]);
}
return ret;
}
-static const struct of_device_id dev_ids[] = {
+static const __maybe_unused struct of_device_id dev_ids[] = {
{ .compatible = "nxp,pcf85263", .data = &pcf_85263_config },
{ .compatible = "nxp,pcf85363", .data = &pcf_85363_config },
{ /* sentinel */ }
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 2dc30eafa639..18f12f36eb2b 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -582,7 +582,7 @@ static int pcf8563_probe(struct i2c_client *client,
}
}
- err = rtc_register_device(pcf8563->rtc);
+ err = devm_rtc_register_device(pcf8563->rtc);
if (err)
return err;
@@ -597,6 +597,7 @@ static int pcf8563_probe(struct i2c_client *client,
static const struct i2c_device_id pcf8563_id[] = {
{ "pcf8563", 0 },
{ "rtc8564", 0 },
+ { "pca8565", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pcf8563_id);
@@ -606,6 +607,7 @@ static const struct of_device_id pcf8563_of_match[] = {
{ .compatible = "nxp,pcf8563" },
{ .compatible = "epson,rtc8564" },
{ .compatible = "microcrystal,rv8564" },
+ { .compatible = "nxp,pca8565" },
{}
};
MODULE_DEVICE_TABLE(of, pcf8563_of_match);
diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c
index 2b6946744654..7fb9145c43bd 100644
--- a/drivers/rtc/rtc-pic32.c
+++ b/drivers/rtc/rtc-pic32.c
@@ -338,7 +338,7 @@ static int pic32_rtc_probe(struct platform_device *pdev)
pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
pdata->rtc->range_max = RTC_TIMESTAMP_END_2099;
- ret = rtc_register_device(pdata->rtc);
+ ret = devm_rtc_register_device(pdata->rtc);
if (ret)
goto err_nortc;
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c
index ebe03eba8f5f..5a880516f3e8 100644
--- a/drivers/rtc/rtc-pl030.c
+++ b/drivers/rtc/rtc-pl030.c
@@ -121,7 +121,7 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
if (ret)
goto err_irq;
- ret = rtc_register_device(rtc->rtc);
+ ret = devm_rtc_register_device(rtc->rtc);
if (ret)
goto err_reg;
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index c6b89273feba..7c3967df4f9a 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -352,23 +352,21 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
}
}
- if (!adev->irq[0]) {
- /* When there's no interrupt, no point in exposing the alarm */
- ops->read_alarm = NULL;
- ops->set_alarm = NULL;
- ops->alarm_irq_enable = NULL;
- }
+ if (!adev->irq[0])
+ clear_bit(RTC_FEATURE_ALARM, ldata->rtc->features);
device_init_wakeup(&adev->dev, true);
ldata->rtc = devm_rtc_allocate_device(&adev->dev);
- if (IS_ERR(ldata->rtc))
- return PTR_ERR(ldata->rtc);
+ if (IS_ERR(ldata->rtc)) {
+ ret = PTR_ERR(ldata->rtc);
+ goto out;
+ }
ldata->rtc->ops = ops;
ldata->rtc->range_min = vendor->range_min;
ldata->rtc->range_max = vendor->range_max;
- ret = rtc_register_device(ldata->rtc);
+ ret = devm_rtc_register_device(ldata->rtc);
if (ret)
goto out;
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index b45ee2cb2c04..eb206597a8fa 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -20,6 +20,7 @@
/* RTC_CTRL register bit fields */
#define PM8xxx_RTC_ENABLE BIT(7)
#define PM8xxx_RTC_ALARM_CLEAR BIT(0)
+#define PM8xxx_RTC_ALARM_ENABLE BIT(7)
#define NUM_8_BIT_RTC_REGS 0x4
@@ -265,6 +266,7 @@ rtc_rw_fail:
static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
int rc;
+ unsigned int ctrl_reg;
u8 value[NUM_8_BIT_RTC_REGS];
unsigned long secs;
struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
@@ -282,6 +284,13 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
rtc_time64_to_tm(secs, &alarm->time);
+ rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
+ if (rc) {
+ dev_err(dev, "Read from RTC alarm control register failed\n");
+ return rc;
+ }
+ alarm->enabled = !!(ctrl_reg & PM8xxx_RTC_ALARM_ENABLE);
+
dev_dbg(dev, "Alarm set for - h:m:s=%ptRt, y-m-d=%ptRdr\n",
&alarm->time, &alarm->time);
@@ -343,16 +352,15 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id)
const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
unsigned int ctrl_reg;
int rc;
- unsigned long irq_flags;
rtc_update_irq(rtc_dd->rtc, 1, RTC_IRQF | RTC_AF);
- spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
+ spin_lock(&rtc_dd->ctrl_reg_lock);
/* Clear the alarm enable bit */
rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
if (rc) {
- spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
+ spin_unlock(&rtc_dd->ctrl_reg_lock);
goto rtc_alarm_handled;
}
@@ -360,13 +368,13 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id)
rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg);
if (rc) {
- spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
+ spin_unlock(&rtc_dd->ctrl_reg_lock);
dev_err(rtc_dd->rtc_dev,
"Write to alarm control register failed\n");
goto rtc_alarm_handled;
}
- spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
+ spin_unlock(&rtc_dd->ctrl_reg_lock);
/* Clear RTC alarm register */
rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl2, &ctrl_reg);
@@ -508,7 +516,7 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
return rc;
}
- return rtc_register_device(rtc_dd->rtc);
+ return devm_rtc_register_device(rtc_dd->rtc);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c
index f0336d691e6c..6b098734c715 100644
--- a/drivers/rtc/rtc-ps3.c
+++ b/drivers/rtc/rtc-ps3.c
@@ -56,7 +56,7 @@ static int __init ps3_rtc_probe(struct platform_device *dev)
platform_set_drvdata(dev, rtc);
- return rtc_register_device(rtc);
+ return devm_rtc_register_device(rtc);
}
static struct platform_driver ps3_rtc_driver = {
diff --git a/drivers/rtc/rtc-r7301.c b/drivers/rtc/rtc-r7301.c
index aaf1b95e3990..5dbaeb7af648 100644
--- a/drivers/rtc/rtc-r7301.c
+++ b/drivers/rtc/rtc-r7301.c
@@ -320,11 +320,10 @@ static irqreturn_t rtc7301_irq_handler(int irq, void *dev_id)
{
struct rtc_device *rtc = dev_id;
struct rtc7301_priv *priv = dev_get_drvdata(rtc->dev.parent);
- unsigned long flags;
irqreturn_t ret = IRQ_NONE;
u8 alrm_ctrl;
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
rtc7301_select_bank(priv, 1);
@@ -335,7 +334,7 @@ static irqreturn_t rtc7301_irq_handler(int irq, void *dev_id)
rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
}
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
return ret;
}
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c
index 84f0d25259ae..60a3c3d7499b 100644
--- a/drivers/rtc/rtc-r9701.c
+++ b/drivers/rtc/rtc-r9701.c
@@ -75,8 +75,6 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt)
if (ret)
return ret;
- memset(dt, 0, sizeof(*dt));
-
dt->tm_sec = bcd2bin(buf[0]); /* RSECCNT */
dt->tm_min = bcd2bin(buf[1]); /* RMINCNT */
dt->tm_hour = bcd2bin(buf[2]); /* RHRCNT */
@@ -85,20 +83,12 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt)
dt->tm_mon = bcd2bin(buf[4]) - 1; /* RMONCNT */
dt->tm_year = bcd2bin(buf[5]) + 100; /* RYRCNT */
- /* the rtc device may contain illegal values on power up
- * according to the data sheet. make sure they are valid.
- */
-
return 0;
}
static int r9701_set_datetime(struct device *dev, struct rtc_time *dt)
{
- int ret, year;
-
- year = dt->tm_year + 1900;
- if (year >= 2100 || year < 2000)
- return -EINVAL;
+ int ret;
ret = write_reg(dev, RHRCNT, bin2bcd(dt->tm_hour));
ret = ret ? ret : write_reg(dev, RMINCNT, bin2bcd(dt->tm_min));
@@ -106,7 +96,6 @@ static int r9701_set_datetime(struct device *dev, struct rtc_time *dt)
ret = ret ? ret : write_reg(dev, RDAYCNT, bin2bcd(dt->tm_mday));
ret = ret ? ret : write_reg(dev, RMONCNT, bin2bcd(dt->tm_mon + 1));
ret = ret ? ret : write_reg(dev, RYRCNT, bin2bcd(dt->tm_year - 100));
- ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday);
return ret;
}
@@ -119,7 +108,6 @@ static const struct rtc_class_ops r9701_rtc_ops = {
static int r9701_probe(struct spi_device *spi)
{
struct rtc_device *rtc;
- struct rtc_time dt;
unsigned char tmp;
int res;
@@ -130,35 +118,16 @@ static int r9701_probe(struct spi_device *spi)
return -ENODEV;
}
- /*
- * The device seems to be present. Now check if the registers
- * contain invalid values. If so, try to write a default date:
- * 2000/1/1 00:00:00
- */
- if (r9701_get_datetime(&spi->dev, &dt)) {
- dev_info(&spi->dev, "trying to repair invalid date/time\n");
- dt.tm_sec = 0;
- dt.tm_min = 0;
- dt.tm_hour = 0;
- dt.tm_mday = 1;
- dt.tm_mon = 0;
- dt.tm_year = 100;
-
- if (r9701_set_datetime(&spi->dev, &dt) ||
- r9701_get_datetime(&spi->dev, &dt)) {
- dev_err(&spi->dev, "cannot repair RTC register\n");
- return -ENODEV;
- }
- }
-
- rtc = devm_rtc_device_register(&spi->dev, "r9701",
- &r9701_rtc_ops, THIS_MODULE);
+ rtc = devm_rtc_allocate_device(&spi->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
spi_set_drvdata(spi, rtc);
+ rtc->ops = &r9701_rtc_ops;
+ rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rtc->range_max = RTC_TIMESTAMP_END_2099;
- return 0;
+ return devm_rtc_register_device(rtc);
}
static struct spi_driver r9701_driver = {
diff --git a/drivers/rtc/rtc-rc5t619.c b/drivers/rtc/rtc-rc5t619.c
index dd1a20977478..e73102a39f1b 100644
--- a/drivers/rtc/rtc-rc5t619.c
+++ b/drivers/rtc/rtc-rc5t619.c
@@ -426,7 +426,7 @@ static int rc5t619_rtc_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "rc5t619 interrupt is disabled\n");
}
- return rtc_register_device(rtc->rtc);
+ return devm_rtc_register_device(rtc->rtc);
}
static struct platform_driver rc5t619_rtc_driver = {
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index c0334c602e88..e920da8c08da 100644
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -447,7 +447,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
return ret;
}
- return rtc_register_device(rk808_rtc->rtc);
+ return devm_rtc_register_device(rk808_rtc->rtc);
}
static struct platform_driver rk808_rtc_driver = {
diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c
index 8776eadbdd3a..44afa6d996e7 100644
--- a/drivers/rtc/rtc-rp5c01.c
+++ b/drivers/rtc/rtc-rp5c01.c
@@ -251,16 +251,15 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev)
return PTR_ERR(rtc);
rtc->ops = &rp5c01_rtc_ops;
- rtc->nvram_old_abi = true;
priv->rtc = rtc;
nvmem_cfg.priv = priv;
- error = rtc_nvmem_register(rtc, &nvmem_cfg);
+ error = devm_rtc_nvmem_register(rtc, &nvmem_cfg);
if (error)
return error;
- return rtc_register_device(rtc);
+ return devm_rtc_register_device(rtc);
}
static struct platform_driver rp5c01_rtc_driver = {
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c
index 89f38e3e917d..e98f85f34206 100644
--- a/drivers/rtc/rtc-rs5c313.c
+++ b/drivers/rtc/rtc-rs5c313.c
@@ -366,15 +366,15 @@ static const struct rtc_class_ops rs5c313_rtc_ops = {
static int rs5c313_rtc_probe(struct platform_device *pdev)
{
- struct rtc_device *rtc = devm_rtc_device_register(&pdev->dev, "rs5c313",
- &rs5c313_rtc_ops, THIS_MODULE);
+ struct rtc_device *rtc;
- if (IS_ERR(rtc))
- return PTR_ERR(rtc);
+ rs5c313_init_port();
+ rs5c313_check_xstp_bit();
- platform_set_drvdata(pdev, rtc);
+ rtc = devm_rtc_device_register(&pdev->dev, "rs5c313", &rs5c313_rtc_ops,
+ THIS_MODULE);
- return 0;
+ return PTR_ERR_OR_ZERO(rtc);
}
static struct platform_driver rs5c313_rtc_platform_driver = {
@@ -384,27 +384,7 @@ static struct platform_driver rs5c313_rtc_platform_driver = {
.probe = rs5c313_rtc_probe,
};
-static int __init rs5c313_rtc_init(void)
-{
- int err;
-
- err = platform_driver_register(&rs5c313_rtc_platform_driver);
- if (err)
- return err;
-
- rs5c313_init_port();
- rs5c313_check_xstp_bit();
-
- return 0;
-}
-
-static void __exit rs5c313_rtc_exit(void)
-{
- platform_driver_unregister(&rs5c313_rtc_platform_driver);
-}
-
-module_init(rs5c313_rtc_init);
-module_exit(rs5c313_rtc_exit);
+module_platform_driver(rs5c313_rtc_platform_driver);
MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <[email protected]>");
MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver");
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c
index 47c13678449e..fec633f80789 100644
--- a/drivers/rtc/rtc-rs5c348.c
+++ b/drivers/rtc/rtc-rs5c348.c
@@ -197,7 +197,7 @@ static int rs5c348_probe(struct spi_device *spi)
rtc->ops = &rs5c348_rtc_ops;
- return rtc_register_device(rtc);
+ return devm_rtc_register_device(rtc);
}
static struct spi_driver rs5c348_driver = {
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 3bd6eaa0dcf6..80980414890c 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -83,7 +83,7 @@ static const struct i2c_device_id rs5c372_id[] = {
};
MODULE_DEVICE_TABLE(i2c, rs5c372_id);
-static const struct of_device_id rs5c372_of_match[] = {
+static const __maybe_unused struct of_device_id rs5c372_of_match[] = {
{
.compatible = "ricoh,r2025sd",
.data = (void *)rtc_r2025sd
diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c
index ec84db0b3d7a..0c48d980d06a 100644
--- a/drivers/rtc/rtc-rv3028.c
+++ b/drivers/rtc/rtc-rv3028.c
@@ -71,6 +71,7 @@
#define RV3028_EVT_CTRL_TSR BIT(2)
+#define RV3028_EEPROM_CMD_UPDATE 0x11
#define RV3028_EEPROM_CMD_WRITE 0x21
#define RV3028_EEPROM_CMD_READ 0x22
@@ -95,7 +96,7 @@ struct rv3028_data {
#endif
};
-static u16 rv3028_trickle_resistors[] = {1000, 3000, 6000, 11000};
+static u16 rv3028_trickle_resistors[] = {3000, 5000, 9000, 15000};
static ssize_t timestamp0_store(struct device *dev,
struct device_attribute *attr,
@@ -171,6 +172,88 @@ static const struct attribute_group rv3028_attr_group = {
.attrs = rv3028_attrs,
};
+static int rv3028_exit_eerd(struct rv3028_data *rv3028, u32 eerd)
+{
+ if (eerd)
+ return 0;
+
+ return regmap_update_bits(rv3028->regmap, RV3028_CTRL1, RV3028_CTRL1_EERD, 0);
+}
+
+static int rv3028_enter_eerd(struct rv3028_data *rv3028, u32 *eerd)
+{
+ u32 ctrl1, status;
+ int ret;
+
+ ret = regmap_read(rv3028->regmap, RV3028_CTRL1, &ctrl1);
+ if (ret)
+ return ret;
+
+ *eerd = ctrl1 & RV3028_CTRL1_EERD;
+ if (*eerd)
+ return 0;
+
+ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1,
+ RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
+ if (ret)
+ return ret;
+
+ ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
+ !(status & RV3028_STATUS_EEBUSY),
+ RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
+ if (ret) {
+ rv3028_exit_eerd(rv3028, *eerd);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rv3028_update_eeprom(struct rv3028_data *rv3028, u32 eerd)
+{
+ u32 status;
+ int ret;
+
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
+ if (ret)
+ goto exit_eerd;
+
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, RV3028_EEPROM_CMD_UPDATE);
+ if (ret)
+ goto exit_eerd;
+
+ usleep_range(63000, RV3028_EEBUSY_TIMEOUT);
+
+ ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
+ !(status & RV3028_STATUS_EEBUSY),
+ RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
+
+exit_eerd:
+ rv3028_exit_eerd(rv3028, eerd);
+
+ return ret;
+}
+
+static int rv3028_update_cfg(struct rv3028_data *rv3028, unsigned int reg,
+ unsigned int mask, unsigned int val)
+{
+ u32 eerd;
+ int ret;
+
+ ret = rv3028_enter_eerd(rv3028, &eerd);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(rv3028->regmap, reg, mask, val);
+ if (ret) {
+ rv3028_exit_eerd(rv3028, eerd);
+ return ret;
+ }
+
+ return rv3028_update_eeprom(rv3028, eerd);
+}
+
static irqreturn_t rv3028_handle_irq(int irq, void *dev_id)
{
struct rv3028_data *rv3028 = dev_id;
@@ -182,8 +265,7 @@ static irqreturn_t rv3028_handle_irq(int irq, void *dev_id)
return IRQ_NONE;
}
- if (status & RV3028_STATUS_PORF)
- dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n");
+ status &= ~RV3028_STATUS_PORF;
if (status & RV3028_STATUS_TF) {
status |= RV3028_STATUS_TF;
@@ -228,10 +310,8 @@ static int rv3028_get_time(struct device *dev, struct rtc_time *tm)
if (ret < 0)
return ret;
- if (status & RV3028_STATUS_PORF) {
- dev_warn(dev, "Voltage low, data is invalid.\n");
+ if (status & RV3028_STATUS_PORF)
return -EINVAL;
- }
ret = regmap_bulk_read(rv3028->regmap, RV3028_SEC, date, sizeof(date));
if (ret)
@@ -404,17 +484,32 @@ static int rv3028_read_offset(struct device *dev, long *offset)
static int rv3028_set_offset(struct device *dev, long offset)
{
struct rv3028_data *rv3028 = dev_get_drvdata(dev);
+ u32 eerd;
int ret;
offset = clamp(offset, -244141L, 243187L) * 1000;
offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT);
+ ret = rv3028_enter_eerd(rv3028, &eerd);
+ if (ret)
+ return ret;
+
ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1);
if (ret < 0)
- return ret;
+ goto exit_eerd;
+
+ ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7),
+ offset << 7);
+ if (ret < 0)
+ goto exit_eerd;
+
+ return rv3028_update_eeprom(rv3028, eerd);
+
+exit_eerd:
+ rv3028_exit_eerd(rv3028, eerd);
+
+ return ret;
- return regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7),
- offset << 7);
}
static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
@@ -451,49 +546,36 @@ static int rv3028_nvram_read(void *priv, unsigned int offset, void *val,
static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val,
size_t bytes)
{
- u32 status, ctrl1;
- int i, ret, err;
+ struct rv3028_data *rv3028 = priv;
+ u32 status, eerd;
+ int i, ret;
u8 *buf = val;
- ret = regmap_read(priv, RV3028_CTRL1, &ctrl1);
+ ret = rv3028_enter_eerd(rv3028, &eerd);
if (ret)
return ret;
- if (!(ctrl1 & RV3028_CTRL1_EERD)) {
- ret = regmap_update_bits(priv, RV3028_CTRL1,
- RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
- if (ret)
- return ret;
-
- ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
- !(status & RV3028_STATUS_EEBUSY),
- RV3028_EEBUSY_POLL,
- RV3028_EEBUSY_TIMEOUT);
- if (ret)
- goto restore_eerd;
- }
-
for (i = 0; i < bytes; i++) {
- ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_DATA, buf[i]);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_DATA, buf[i]);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_CMD,
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD,
RV3028_EEPROM_CMD_WRITE);
if (ret)
goto restore_eerd;
usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
- ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
+ ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL,
RV3028_EEBUSY_TIMEOUT);
@@ -502,13 +584,7 @@ static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val,
}
restore_eerd:
- if (!(ctrl1 & RV3028_CTRL1_EERD))
- {
- err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
- 0);
- if (err && !ret)
- ret = err;
- }
+ rv3028_exit_eerd(rv3028, eerd);
return ret;
}
@@ -516,63 +592,44 @@ restore_eerd:
static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{
- u32 status, ctrl1, data;
- int i, ret, err;
+ struct rv3028_data *rv3028 = priv;
+ u32 status, eerd, data;
+ int i, ret;
u8 *buf = val;
- ret = regmap_read(priv, RV3028_CTRL1, &ctrl1);
+ ret = rv3028_enter_eerd(rv3028, &eerd);
if (ret)
return ret;
- if (!(ctrl1 & RV3028_CTRL1_EERD)) {
- ret = regmap_update_bits(priv, RV3028_CTRL1,
- RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
- if (ret)
- return ret;
-
- ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
- !(status & RV3028_STATUS_EEBUSY),
- RV3028_EEBUSY_POLL,
- RV3028_EEBUSY_TIMEOUT);
- if (ret)
- goto restore_eerd;
- }
-
for (i = 0; i < bytes; i++) {
- ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_CMD,
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD,
RV3028_EEPROM_CMD_READ);
if (ret)
goto restore_eerd;
- ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
+ ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL,
RV3028_EEBUSY_TIMEOUT);
if (ret)
goto restore_eerd;
- ret = regmap_read(priv, RV3028_EEPROM_DATA, &data);
+ ret = regmap_read(rv3028->regmap, RV3028_EEPROM_DATA, &data);
if (ret)
goto restore_eerd;
buf[i] = data;
}
restore_eerd:
- if (!(ctrl1 & RV3028_CTRL1_EERD))
- {
- err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
- 0);
- if (err && !ret)
- ret = err;
- }
+ rv3028_exit_eerd(rv3028, eerd);
return ret;
}
@@ -619,24 +676,23 @@ static int rv3028_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
int i, ret;
+ u32 enabled;
struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);
+ ret = regmap_read(rv3028->regmap, RV3028_CLKOUT, &enabled);
+ if (ret < 0)
+ return ret;
+
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;
+ enabled &= RV3028_CLKOUT_CLKOE;
- return regmap_write(rv3028->regmap, RV3028_CLKOUT,
- RV3028_CLKOUT_CLKSY | RV3028_CLKOUT_CLKOE);
- }
- }
+ for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
+ if (clkout_rates[i] == rate)
+ return rv3028_update_cfg(rv3028, RV3028_CLKOUT, 0xff,
+ RV3028_CLKOUT_CLKSY | enabled | i);
return -EINVAL;
}
@@ -711,9 +767,12 @@ static int rv3028_clkout_register_clk(struct rv3028_data *rv3028,
}
#endif
-static struct rtc_class_ops rv3028_rtc_ops = {
+static const struct rtc_class_ops rv3028_rtc_ops = {
.read_time = rv3028_get_time,
.set_time = rv3028_set_time,
+ .read_alarm = rv3028_get_alarm,
+ .set_alarm = rv3028_set_alarm,
+ .alarm_irq_enable = rv3028_alarm_irq_enable,
.read_offset = rv3028_read_offset,
.set_offset = rv3028_set_offset,
.ioctl = rv3028_ioctl,
@@ -764,9 +823,6 @@ static int rv3028_probe(struct i2c_client *client)
if (ret < 0)
return ret;
- if (status & RV3028_STATUS_PORF)
- dev_warn(&client->dev, "Voltage low, data loss detected.\n");
-
if (status & RV3028_STATUS_AF)
dev_warn(&client->dev, "An alarm may have been missed.\n");
@@ -782,12 +838,10 @@ static int rv3028_probe(struct i2c_client *client)
if (ret) {
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
client->irq = 0;
- } else {
- rv3028_rtc_ops.read_alarm = rv3028_get_alarm;
- rv3028_rtc_ops.set_alarm = rv3028_set_alarm;
- rv3028_rtc_ops.alarm_irq_enable = rv3028_alarm_irq_enable;
}
}
+ if (!client->irq)
+ clear_bit(RTC_FEATURE_ALARM, rv3028->rtc->features);
ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1,
RV3028_CTRL1_WADA, RV3028_CTRL1_WADA);
@@ -811,10 +865,8 @@ static int rv3028_probe(struct i2c_client *client)
break;
if (i < ARRAY_SIZE(rv3028_trickle_resistors)) {
- ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP,
- RV3028_BACKUP_TCE |
- RV3028_BACKUP_TCR_MASK,
- RV3028_BACKUP_TCE | i);
+ ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE |
+ RV3028_BACKUP_TCR_MASK, RV3028_BACKUP_TCE | i);
if (ret)
return ret;
} else {
@@ -829,14 +881,14 @@ static int rv3028_probe(struct i2c_client *client)
rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099;
rv3028->rtc->ops = &rv3028_rtc_ops;
- ret = rtc_register_device(rv3028->rtc);
+ ret = devm_rtc_register_device(rv3028->rtc);
if (ret)
return ret;
nvmem_cfg.priv = rv3028->regmap;
- rtc_nvmem_register(rv3028->rtc, &nvmem_cfg);
- eeprom_cfg.priv = rv3028->regmap;
- rtc_nvmem_register(rv3028->rtc, &eeprom_cfg);
+ devm_rtc_nvmem_register(rv3028->rtc, &nvmem_cfg);
+ eeprom_cfg.priv = rv3028;
+ devm_rtc_nvmem_register(rv3028->rtc, &eeprom_cfg);
rv3028->rtc->max_user_freq = 1;
@@ -846,7 +898,7 @@ static int rv3028_probe(struct i2c_client *client)
return 0;
}
-static const struct of_device_id rv3028_of_match[] = {
+static const __maybe_unused struct of_device_id rv3028_of_match[] = {
{ .compatible = "microcrystal,rv3028", },
{ }
};
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 62718231731b..8cb84c9595fc 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -265,24 +265,23 @@ 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;
int ret;
- mutex_lock(lock);
+ rtc_lock(rv3029->rtc);
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);
+ rtc_unlock(rv3029->rtc);
return IRQ_NONE;
}
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);
+ rtc_unlock(rv3029->rtc);
return IRQ_NONE;
}
@@ -297,7 +296,7 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
regmap_write(rv3029->regmap, RV3029_IRQ_FLAGS, flags);
regmap_write(rv3029->regmap, RV3029_IRQ_CTRL, controls);
}
- mutex_unlock(lock);
+ rtc_unlock(rv3029->rtc);
return IRQ_HANDLED;
}
@@ -694,10 +693,13 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
#endif /* CONFIG_RTC_DRV_RV3029_HWMON */
-static struct rtc_class_ops rv3029_rtc_ops = {
+static const struct rtc_class_ops rv3029_rtc_ops = {
.read_time = rv3029_read_time,
.set_time = rv3029_set_time,
.ioctl = rv3029_ioctl,
+ .read_alarm = rv3029_read_alarm,
+ .set_alarm = rv3029_set_alarm,
+ .alarm_irq_enable = rv3029_alarm_irq_enable,
};
static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
@@ -739,23 +741,21 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
if (rc) {
dev_warn(dev, "unable to request IRQ, alarms disabled\n");
rv3029->irq = 0;
- } else {
- rv3029_rtc_ops.read_alarm = rv3029_read_alarm;
- rv3029_rtc_ops.set_alarm = rv3029_set_alarm;
- rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable;
}
}
+ if (!rv3029->irq)
+ clear_bit(RTC_FEATURE_ALARM, rv3029->rtc->features);
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);
+ rc = devm_rtc_register_device(rv3029->rtc);
if (rc)
return rc;
nvmem_cfg.priv = rv3029->regmap;
- rtc_nvmem_register(rv3029->rtc, &nvmem_cfg);
+ devm_rtc_nvmem_register(rv3029->rtc, &nvmem_cfg);
return 0;
}
@@ -808,7 +808,7 @@ static const struct i2c_device_id rv3029_id[] = {
};
MODULE_DEVICE_TABLE(i2c, rv3029_id);
-static const struct of_device_id rv3029_of_match[] = {
+static const __maybe_unused struct of_device_id rv3029_of_match[] = {
{ .compatible = "microcrystal,rv3029" },
{ }
};
diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c
new file mode 100644
index 000000000000..d63102d5cb1e
--- /dev/null
+++ b/drivers/rtc/rtc-rv3032.c
@@ -0,0 +1,926 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RTC driver for the Micro Crystal RV3032
+ *
+ * Copyright (C) 2020 Micro Crystal SA
+ *
+ * Alexandre Belloni <[email protected]>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/bcd.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/hwmon.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/rtc.h>
+
+#define RV3032_SEC 0x01
+#define RV3032_MIN 0x02
+#define RV3032_HOUR 0x03
+#define RV3032_WDAY 0x04
+#define RV3032_DAY 0x05
+#define RV3032_MONTH 0x06
+#define RV3032_YEAR 0x07
+#define RV3032_ALARM_MIN 0x08
+#define RV3032_ALARM_HOUR 0x09
+#define RV3032_ALARM_DAY 0x0A
+#define RV3032_STATUS 0x0D
+#define RV3032_TLSB 0x0E
+#define RV3032_TMSB 0x0F
+#define RV3032_CTRL1 0x10
+#define RV3032_CTRL2 0x11
+#define RV3032_CTRL3 0x12
+#define RV3032_TS_CTRL 0x13
+#define RV3032_CLK_IRQ 0x14
+#define RV3032_EEPROM_ADDR 0x3D
+#define RV3032_EEPROM_DATA 0x3E
+#define RV3032_EEPROM_CMD 0x3F
+#define RV3032_RAM1 0x40
+#define RV3032_PMU 0xC0
+#define RV3032_OFFSET 0xC1
+#define RV3032_CLKOUT1 0xC2
+#define RV3032_CLKOUT2 0xC3
+#define RV3032_TREF0 0xC4
+#define RV3032_TREF1 0xC5
+
+#define RV3032_STATUS_VLF BIT(0)
+#define RV3032_STATUS_PORF BIT(1)
+#define RV3032_STATUS_EVF BIT(2)
+#define RV3032_STATUS_AF BIT(3)
+#define RV3032_STATUS_TF BIT(4)
+#define RV3032_STATUS_UF BIT(5)
+#define RV3032_STATUS_TLF BIT(6)
+#define RV3032_STATUS_THF BIT(7)
+
+#define RV3032_TLSB_CLKF BIT(1)
+#define RV3032_TLSB_EEBUSY BIT(2)
+#define RV3032_TLSB_TEMP GENMASK(7, 4)
+
+#define RV3032_CLKOUT2_HFD_MSK GENMASK(4, 0)
+#define RV3032_CLKOUT2_FD_MSK GENMASK(6, 5)
+#define RV3032_CLKOUT2_OS BIT(7)
+
+#define RV3032_CTRL1_EERD BIT(3)
+#define RV3032_CTRL1_WADA BIT(5)
+
+#define RV3032_CTRL2_STOP BIT(0)
+#define RV3032_CTRL2_EIE BIT(2)
+#define RV3032_CTRL2_AIE BIT(3)
+#define RV3032_CTRL2_TIE BIT(4)
+#define RV3032_CTRL2_UIE BIT(5)
+#define RV3032_CTRL2_CLKIE BIT(6)
+#define RV3032_CTRL2_TSE BIT(7)
+
+#define RV3032_PMU_TCM GENMASK(1, 0)
+#define RV3032_PMU_TCR GENMASK(3, 2)
+#define RV3032_PMU_BSM GENMASK(5, 4)
+#define RV3032_PMU_NCLKE BIT(6)
+
+#define RV3032_PMU_BSM_DSM 1
+#define RV3032_PMU_BSM_LSM 2
+
+#define RV3032_OFFSET_MSK GENMASK(5, 0)
+
+#define RV3032_EVT_CTRL_TSR BIT(2)
+
+#define RV3032_EEPROM_CMD_UPDATE 0x11
+#define RV3032_EEPROM_CMD_WRITE 0x21
+#define RV3032_EEPROM_CMD_READ 0x22
+
+#define RV3032_EEPROM_USER 0xCB
+
+#define RV3032_EEBUSY_POLL 10000
+#define RV3032_EEBUSY_TIMEOUT 100000
+
+#define OFFSET_STEP_PPT 238419
+
+struct rv3032_data {
+ struct regmap *regmap;
+ struct rtc_device *rtc;
+#ifdef CONFIG_COMMON_CLK
+ struct clk_hw clkout_hw;
+#endif
+};
+
+static u16 rv3032_trickle_resistors[] = {1000, 2000, 7000, 11000};
+static u16 rv3032_trickle_voltages[] = {0, 1750, 3000, 4400};
+
+static int rv3032_exit_eerd(struct rv3032_data *rv3032, u32 eerd)
+{
+ if (eerd)
+ return 0;
+
+ return regmap_update_bits(rv3032->regmap, RV3032_CTRL1, RV3032_CTRL1_EERD, 0);
+}
+
+static int rv3032_enter_eerd(struct rv3032_data *rv3032, u32 *eerd)
+{
+ u32 ctrl1, status;
+ int ret;
+
+ ret = regmap_read(rv3032->regmap, RV3032_CTRL1, &ctrl1);
+ if (ret)
+ return ret;
+
+ *eerd = ctrl1 & RV3032_CTRL1_EERD;
+ if (*eerd)
+ return 0;
+
+ ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1,
+ RV3032_CTRL1_EERD, RV3032_CTRL1_EERD);
+ if (ret)
+ return ret;
+
+ ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
+ !(status & RV3032_TLSB_EEBUSY),
+ RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
+ if (ret) {
+ rv3032_exit_eerd(rv3032, *eerd);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rv3032_update_cfg(struct rv3032_data *rv3032, unsigned int reg,
+ unsigned int mask, unsigned int val)
+{
+ u32 status, eerd;
+ int ret;
+
+ ret = rv3032_enter_eerd(rv3032, &eerd);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(rv3032->regmap, reg, mask, val);
+ if (ret)
+ goto exit_eerd;
+
+ ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, RV3032_EEPROM_CMD_UPDATE);
+ if (ret)
+ goto exit_eerd;
+
+ usleep_range(46000, RV3032_EEBUSY_TIMEOUT);
+
+ ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
+ !(status & RV3032_TLSB_EEBUSY),
+ RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
+
+exit_eerd:
+ rv3032_exit_eerd(rv3032, eerd);
+
+ return ret;
+}
+
+static irqreturn_t rv3032_handle_irq(int irq, void *dev_id)
+{
+ struct rv3032_data *rv3032 = dev_id;
+ unsigned long events = 0;
+ u32 status = 0, ctrl = 0;
+
+ if (regmap_read(rv3032->regmap, RV3032_STATUS, &status) < 0 ||
+ status == 0) {
+ return IRQ_NONE;
+ }
+
+ if (status & RV3032_STATUS_TF) {
+ status |= RV3032_STATUS_TF;
+ ctrl |= RV3032_CTRL2_TIE;
+ events |= RTC_PF;
+ }
+
+ if (status & RV3032_STATUS_AF) {
+ status |= RV3032_STATUS_AF;
+ ctrl |= RV3032_CTRL2_AIE;
+ events |= RTC_AF;
+ }
+
+ if (status & RV3032_STATUS_UF) {
+ status |= RV3032_STATUS_UF;
+ ctrl |= RV3032_CTRL2_UIE;
+ events |= RTC_UF;
+ }
+
+ if (events) {
+ rtc_update_irq(rv3032->rtc, 1, events);
+ regmap_update_bits(rv3032->regmap, RV3032_STATUS, status, 0);
+ regmap_update_bits(rv3032->regmap, RV3032_CTRL2, ctrl, 0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int rv3032_get_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+ u8 date[7];
+ int ret, status;
+
+ ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status);
+ if (ret < 0)
+ return ret;
+
+ if (status & (RV3032_STATUS_PORF | RV3032_STATUS_VLF))
+ return -EINVAL;
+
+ ret = regmap_bulk_read(rv3032->regmap, RV3032_SEC, date, sizeof(date));
+ if (ret)
+ return ret;
+
+ tm->tm_sec = bcd2bin(date[0] & 0x7f);
+ tm->tm_min = bcd2bin(date[1] & 0x7f);
+ tm->tm_hour = bcd2bin(date[2] & 0x3f);
+ tm->tm_wday = date[3] & 0x7;
+ tm->tm_mday = bcd2bin(date[4] & 0x3f);
+ tm->tm_mon = bcd2bin(date[5] & 0x1f) - 1;
+ tm->tm_year = bcd2bin(date[6]) + 100;
+
+ return 0;
+}
+
+static int rv3032_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+ u8 date[7];
+ int ret;
+
+ date[0] = bin2bcd(tm->tm_sec);
+ date[1] = bin2bcd(tm->tm_min);
+ date[2] = bin2bcd(tm->tm_hour);
+ date[3] = tm->tm_wday;
+ date[4] = bin2bcd(tm->tm_mday);
+ date[5] = bin2bcd(tm->tm_mon + 1);
+ date[6] = bin2bcd(tm->tm_year - 100);
+
+ ret = regmap_bulk_write(rv3032->regmap, RV3032_SEC, date,
+ sizeof(date));
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS,
+ RV3032_STATUS_PORF | RV3032_STATUS_VLF, 0);
+
+ return ret;
+}
+
+static int rv3032_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+ u8 alarmvals[3];
+ int status, ctrl, ret;
+
+ ret = regmap_bulk_read(rv3032->regmap, RV3032_ALARM_MIN, alarmvals,
+ sizeof(alarmvals));
+ if (ret)
+ return ret;
+
+ ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status);
+ if (ret < 0)
+ return ret;
+
+ ret = regmap_read(rv3032->regmap, RV3032_CTRL2, &ctrl);
+ if (ret < 0)
+ return ret;
+
+ alrm->time.tm_sec = 0;
+ alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f);
+ alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f);
+ alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f);
+
+ alrm->enabled = !!(ctrl & RV3032_CTRL2_AIE);
+ alrm->pending = (status & RV3032_STATUS_AF) && alrm->enabled;
+
+ return 0;
+}
+
+static int rv3032_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+ u8 alarmvals[3];
+ u8 ctrl = 0;
+ int ret;
+
+ /* The alarm has no seconds, round up to nearest minute */
+ if (alrm->time.tm_sec) {
+ time64_t alarm_time = rtc_tm_to_time64(&alrm->time);
+
+ alarm_time += 60 - alrm->time.tm_sec;
+ rtc_time64_to_tm(alarm_time, &alrm->time);
+ }
+
+ ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2,
+ RV3032_CTRL2_AIE | RV3032_CTRL2_UIE, 0);
+ if (ret)
+ return ret;
+
+ alarmvals[0] = bin2bcd(alrm->time.tm_min);
+ alarmvals[1] = bin2bcd(alrm->time.tm_hour);
+ alarmvals[2] = bin2bcd(alrm->time.tm_mday);
+
+ ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS,
+ RV3032_STATUS_AF, 0);
+ if (ret)
+ return ret;
+
+ ret = regmap_bulk_write(rv3032->regmap, RV3032_ALARM_MIN, alarmvals,
+ sizeof(alarmvals));
+ if (ret)
+ return ret;
+
+ if (alrm->enabled) {
+ if (rv3032->rtc->uie_rtctimer.enabled)
+ ctrl |= RV3032_CTRL2_UIE;
+ if (rv3032->rtc->aie_timer.enabled)
+ ctrl |= RV3032_CTRL2_AIE;
+ }
+
+ ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2,
+ RV3032_CTRL2_UIE | RV3032_CTRL2_AIE, ctrl);
+
+ return ret;
+}
+
+static int rv3032_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+ int ctrl = 0, ret;
+
+ if (enabled) {
+ if (rv3032->rtc->uie_rtctimer.enabled)
+ ctrl |= RV3032_CTRL2_UIE;
+ if (rv3032->rtc->aie_timer.enabled)
+ ctrl |= RV3032_CTRL2_AIE;
+ }
+
+ ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS,
+ RV3032_STATUS_AF | RV3032_STATUS_UF, 0);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2,
+ RV3032_CTRL2_UIE | RV3032_CTRL2_AIE, ctrl);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int rv3032_read_offset(struct device *dev, long *offset)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+ int ret, value, steps;
+
+ ret = regmap_read(rv3032->regmap, RV3032_OFFSET, &value);
+ if (ret < 0)
+ return ret;
+
+ steps = sign_extend32(FIELD_GET(RV3032_OFFSET_MSK, value), 5);
+
+ *offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000);
+
+ return 0;
+}
+
+static int rv3032_set_offset(struct device *dev, long offset)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+
+ offset = clamp(offset, -7629L, 7391L) * 1000;
+ offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT);
+
+ return rv3032_update_cfg(rv3032, RV3032_OFFSET, RV3032_OFFSET_MSK,
+ FIELD_PREP(RV3032_OFFSET_MSK, offset));
+}
+
+static int rv3032_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+ int status, val = 0, ret = 0;
+
+ switch (cmd) {
+ case RTC_VL_READ:
+ ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status);
+ if (ret < 0)
+ return ret;
+
+ if (status & (RV3032_STATUS_PORF | RV3032_STATUS_VLF))
+ val = RTC_VL_DATA_INVALID;
+ return put_user(val, (unsigned int __user *)arg);
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static int rv3032_nvram_write(void *priv, unsigned int offset, void *val, size_t bytes)
+{
+ return regmap_bulk_write(priv, RV3032_RAM1 + offset, val, bytes);
+}
+
+static int rv3032_nvram_read(void *priv, unsigned int offset, void *val, size_t bytes)
+{
+ return regmap_bulk_read(priv, RV3032_RAM1 + offset, val, bytes);
+}
+
+static int rv3032_eeprom_write(void *priv, unsigned int offset, void *val, size_t bytes)
+{
+ struct rv3032_data *rv3032 = priv;
+ u32 status, eerd;
+ int i, ret;
+ u8 *buf = val;
+
+ ret = rv3032_enter_eerd(rv3032, &eerd);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < bytes; i++) {
+ ret = regmap_write(rv3032->regmap, RV3032_EEPROM_ADDR,
+ RV3032_EEPROM_USER + offset + i);
+ if (ret)
+ goto exit_eerd;
+
+ ret = regmap_write(rv3032->regmap, RV3032_EEPROM_DATA, buf[i]);
+ if (ret)
+ goto exit_eerd;
+
+ ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD,
+ RV3032_EEPROM_CMD_WRITE);
+ if (ret)
+ goto exit_eerd;
+
+ usleep_range(RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
+
+ ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
+ !(status & RV3032_TLSB_EEBUSY),
+ RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
+ if (ret)
+ goto exit_eerd;
+ }
+
+exit_eerd:
+ rv3032_exit_eerd(rv3032, eerd);
+
+ return ret;
+}
+
+static int rv3032_eeprom_read(void *priv, unsigned int offset, void *val, size_t bytes)
+{
+ struct rv3032_data *rv3032 = priv;
+ u32 status, eerd, data;
+ int i, ret;
+ u8 *buf = val;
+
+ ret = rv3032_enter_eerd(rv3032, &eerd);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < bytes; i++) {
+ ret = regmap_write(rv3032->regmap, RV3032_EEPROM_ADDR,
+ RV3032_EEPROM_USER + offset + i);
+ if (ret)
+ goto exit_eerd;
+
+ ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD,
+ RV3032_EEPROM_CMD_READ);
+ if (ret)
+ goto exit_eerd;
+
+ ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
+ !(status & RV3032_TLSB_EEBUSY),
+ RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
+ if (ret)
+ goto exit_eerd;
+
+ ret = regmap_read(rv3032->regmap, RV3032_EEPROM_DATA, &data);
+ if (ret)
+ goto exit_eerd;
+ buf[i] = data;
+ }
+
+exit_eerd:
+ rv3032_exit_eerd(rv3032, eerd);
+
+ return ret;
+}
+
+static int rv3032_trickle_charger_setup(struct device *dev, struct rv3032_data *rv3032)
+{
+ u32 val, ohms, voltage;
+ int i;
+
+ val = FIELD_PREP(RV3032_PMU_TCM, 1) | FIELD_PREP(RV3032_PMU_BSM, RV3032_PMU_BSM_DSM);
+ if (!device_property_read_u32(dev, "trickle-voltage-millivolt", &voltage)) {
+ for (i = 0; i < ARRAY_SIZE(rv3032_trickle_voltages); i++)
+ if (voltage == rv3032_trickle_voltages[i])
+ break;
+ if (i < ARRAY_SIZE(rv3032_trickle_voltages))
+ val = FIELD_PREP(RV3032_PMU_TCM, i) |
+ FIELD_PREP(RV3032_PMU_BSM, RV3032_PMU_BSM_LSM);
+ }
+
+ if (device_property_read_u32(dev, "trickle-resistor-ohms", &ohms))
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(rv3032_trickle_resistors); i++)
+ if (ohms == rv3032_trickle_resistors[i])
+ break;
+
+ if (i >= ARRAY_SIZE(rv3032_trickle_resistors)) {
+ dev_warn(dev, "invalid trickle resistor value\n");
+
+ return 0;
+ }
+
+ return rv3032_update_cfg(rv3032, RV3032_PMU,
+ RV3032_PMU_TCR | RV3032_PMU_TCM | RV3032_PMU_BSM,
+ val | FIELD_PREP(RV3032_PMU_TCR, i));
+}
+
+#ifdef CONFIG_COMMON_CLK
+#define clkout_hw_to_rv3032(hw) container_of(hw, struct rv3032_data, clkout_hw)
+
+static int clkout_xtal_rates[] = {
+ 32768,
+ 1024,
+ 64,
+ 1,
+};
+
+#define RV3032_HFD_STEP 8192
+
+static unsigned long rv3032_clkout_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ int clkout, ret;
+ struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);
+
+ ret = regmap_read(rv3032->regmap, RV3032_CLKOUT2, &clkout);
+ if (ret < 0)
+ return 0;
+
+ if (clkout & RV3032_CLKOUT2_OS) {
+ unsigned long rate = FIELD_GET(RV3032_CLKOUT2_HFD_MSK, clkout) << 8;
+
+ ret = regmap_read(rv3032->regmap, RV3032_CLKOUT1, &clkout);
+ if (ret < 0)
+ return 0;
+
+ rate += clkout + 1;
+
+ return rate * RV3032_HFD_STEP;
+ }
+
+ return clkout_xtal_rates[FIELD_GET(RV3032_CLKOUT2_FD_MSK, clkout)];
+}
+
+static long rv3032_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ int i, hfd;
+
+ if (rate < RV3032_HFD_STEP)
+ for (i = 0; i < ARRAY_SIZE(clkout_xtal_rates); i++)
+ if (clkout_xtal_rates[i] <= rate)
+ return clkout_xtal_rates[i];
+
+ hfd = DIV_ROUND_CLOSEST(rate, RV3032_HFD_STEP);
+
+ return RV3032_HFD_STEP * clamp(hfd, 0, 8192);
+}
+
+static int rv3032_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);
+ u32 status, eerd;
+ int i, hfd, ret;
+
+ for (i = 0; i < ARRAY_SIZE(clkout_xtal_rates); i++) {
+ if (clkout_xtal_rates[i] == rate) {
+ return rv3032_update_cfg(rv3032, RV3032_CLKOUT2, 0xff,
+ FIELD_PREP(RV3032_CLKOUT2_FD_MSK, i));
+ }
+ }
+
+ hfd = DIV_ROUND_CLOSEST(rate, RV3032_HFD_STEP);
+ hfd = clamp(hfd, 1, 8192) - 1;
+
+ ret = rv3032_enter_eerd(rv3032, &eerd);
+ if (ret)
+ goto exit_eerd;
+
+ ret = regmap_write(rv3032->regmap, RV3032_CLKOUT1, hfd & 0xff);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(rv3032->regmap, RV3032_CLKOUT2, RV3032_CLKOUT2_OS |
+ FIELD_PREP(RV3032_CLKOUT2_HFD_MSK, hfd >> 8));
+ if (ret)
+ goto exit_eerd;
+
+ ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, RV3032_EEPROM_CMD_UPDATE);
+ if (ret)
+ goto exit_eerd;
+
+ usleep_range(46000, RV3032_EEBUSY_TIMEOUT);
+
+ ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status,
+ !(status & RV3032_TLSB_EEBUSY),
+ RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT);
+
+exit_eerd:
+ rv3032_exit_eerd(rv3032, eerd);
+
+ return ret;
+}
+
+static int rv3032_clkout_prepare(struct clk_hw *hw)
+{
+ struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);
+
+ return rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_NCLKE, 0);
+}
+
+static void rv3032_clkout_unprepare(struct clk_hw *hw)
+{
+ struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);
+
+ rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_NCLKE, RV3032_PMU_NCLKE);
+}
+
+static int rv3032_clkout_is_prepared(struct clk_hw *hw)
+{
+ int val, ret;
+ struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw);
+
+ ret = regmap_read(rv3032->regmap, RV3032_PMU, &val);
+ if (ret < 0)
+ return ret;
+
+ return !(val & RV3032_PMU_NCLKE);
+}
+
+static const struct clk_ops rv3032_clkout_ops = {
+ .prepare = rv3032_clkout_prepare,
+ .unprepare = rv3032_clkout_unprepare,
+ .is_prepared = rv3032_clkout_is_prepared,
+ .recalc_rate = rv3032_clkout_recalc_rate,
+ .round_rate = rv3032_clkout_round_rate,
+ .set_rate = rv3032_clkout_set_rate,
+};
+
+static int rv3032_clkout_register_clk(struct rv3032_data *rv3032,
+ 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(rv3032->regmap, RV3032_TLSB, RV3032_TLSB_CLKF, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, RV3032_CTRL2_CLKIE, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = regmap_write(rv3032->regmap, RV3032_CLK_IRQ, 0);
+ if (ret < 0)
+ return ret;
+
+ init.name = "rv3032-clkout";
+ init.ops = &rv3032_clkout_ops;
+ init.flags = 0;
+ init.parent_names = NULL;
+ init.num_parents = 0;
+ rv3032->clkout_hw.init = &init;
+
+ of_property_read_string(node, "clock-output-names", &init.name);
+
+ clk = devm_clk_register(&client->dev, &rv3032->clkout_hw);
+ if (!IS_ERR(clk))
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+
+ return 0;
+}
+#endif
+
+static int rv3032_hwmon_read_temp(struct device *dev, long *mC)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+ u8 buf[2];
+ int temp, prev = 0;
+ int ret;
+
+ ret = regmap_bulk_read(rv3032->regmap, RV3032_TLSB, buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ temp = sign_extend32(buf[1], 7) << 4;
+ temp |= FIELD_GET(RV3032_TLSB_TEMP, buf[0]);
+
+ /* No blocking or shadowing on RV3032_TLSB and RV3032_TMSB */
+ do {
+ prev = temp;
+
+ ret = regmap_bulk_read(rv3032->regmap, RV3032_TLSB, buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ temp = sign_extend32(buf[1], 7) << 4;
+ temp |= FIELD_GET(RV3032_TLSB_TEMP, buf[0]);
+ } while (temp != prev);
+
+ *mC = (temp * 1000) / 16;
+
+ return 0;
+}
+
+static umode_t rv3032_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ if (type != hwmon_temp)
+ return 0;
+
+ switch (attr) {
+ case hwmon_temp_input:
+ return 0444;
+ default:
+ return 0;
+ }
+}
+
+static int rv3032_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *temp)
+{
+ int err;
+
+ switch (attr) {
+ case hwmon_temp_input:
+ err = rv3032_hwmon_read_temp(dev, temp);
+ break;
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ return err;
+}
+
+static const struct hwmon_channel_info *rv3032_hwmon_info[] = {
+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST),
+ NULL
+};
+
+static const struct hwmon_ops rv3032_hwmon_hwmon_ops = {
+ .is_visible = rv3032_hwmon_is_visible,
+ .read = rv3032_hwmon_read,
+};
+
+static const struct hwmon_chip_info rv3032_hwmon_chip_info = {
+ .ops = &rv3032_hwmon_hwmon_ops,
+ .info = rv3032_hwmon_info,
+};
+
+static void rv3032_hwmon_register(struct device *dev)
+{
+ struct rv3032_data *rv3032 = dev_get_drvdata(dev);
+
+ if (!IS_REACHABLE(CONFIG_HWMON))
+ return;
+
+ devm_hwmon_device_register_with_info(dev, "rv3032", rv3032, &rv3032_hwmon_chip_info, NULL);
+}
+
+static const struct rtc_class_ops rv3032_rtc_ops = {
+ .read_time = rv3032_get_time,
+ .set_time = rv3032_set_time,
+ .read_offset = rv3032_read_offset,
+ .set_offset = rv3032_set_offset,
+ .ioctl = rv3032_ioctl,
+ .read_alarm = rv3032_get_alarm,
+ .set_alarm = rv3032_set_alarm,
+ .alarm_irq_enable = rv3032_alarm_irq_enable,
+};
+
+static const struct regmap_config regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0xCA,
+};
+
+static int rv3032_probe(struct i2c_client *client)
+{
+ struct rv3032_data *rv3032;
+ int ret, status;
+ struct nvmem_config nvmem_cfg = {
+ .name = "rv3032_nvram",
+ .word_size = 1,
+ .stride = 1,
+ .size = 16,
+ .type = NVMEM_TYPE_BATTERY_BACKED,
+ .reg_read = rv3032_nvram_read,
+ .reg_write = rv3032_nvram_write,
+ };
+ struct nvmem_config eeprom_cfg = {
+ .name = "rv3032_eeprom",
+ .word_size = 1,
+ .stride = 1,
+ .size = 32,
+ .type = NVMEM_TYPE_EEPROM,
+ .reg_read = rv3032_eeprom_read,
+ .reg_write = rv3032_eeprom_write,
+ };
+
+ rv3032 = devm_kzalloc(&client->dev, sizeof(struct rv3032_data),
+ GFP_KERNEL);
+ if (!rv3032)
+ return -ENOMEM;
+
+ rv3032->regmap = devm_regmap_init_i2c(client, &regmap_config);
+ if (IS_ERR(rv3032->regmap))
+ return PTR_ERR(rv3032->regmap);
+
+ i2c_set_clientdata(client, rv3032);
+
+ ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status);
+ if (ret < 0)
+ return ret;
+
+ rv3032->rtc = devm_rtc_allocate_device(&client->dev);
+ if (IS_ERR(rv3032->rtc))
+ return PTR_ERR(rv3032->rtc);
+
+ if (client->irq > 0) {
+ ret = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, rv3032_handle_irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "rv3032", rv3032);
+ if (ret) {
+ dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
+ client->irq = 0;
+ }
+ }
+ if (!client->irq)
+ clear_bit(RTC_FEATURE_ALARM, rv3032->rtc->features);
+
+ ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1,
+ RV3032_CTRL1_WADA, RV3032_CTRL1_WADA);
+ if (ret)
+ return ret;
+
+ rv3032_trickle_charger_setup(&client->dev, rv3032);
+
+ rv3032->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rv3032->rtc->range_max = RTC_TIMESTAMP_END_2099;
+ rv3032->rtc->ops = &rv3032_rtc_ops;
+ ret = devm_rtc_register_device(rv3032->rtc);
+ if (ret)
+ return ret;
+
+ nvmem_cfg.priv = rv3032->regmap;
+ devm_rtc_nvmem_register(rv3032->rtc, &nvmem_cfg);
+ eeprom_cfg.priv = rv3032;
+ devm_rtc_nvmem_register(rv3032->rtc, &eeprom_cfg);
+
+ rv3032->rtc->max_user_freq = 1;
+
+#ifdef CONFIG_COMMON_CLK
+ rv3032_clkout_register_clk(rv3032, client);
+#endif
+
+ rv3032_hwmon_register(&client->dev);
+
+ return 0;
+}
+
+static const __maybe_unused struct of_device_id rv3032_of_match[] = {
+ { .compatible = "microcrystal,rv3032", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, rv3032_of_match);
+
+static struct i2c_driver rv3032_driver = {
+ .driver = {
+ .name = "rtc-rv3032",
+ .of_match_table = of_match_ptr(rv3032_of_match),
+ },
+ .probe_new = rv3032_probe,
+};
+module_i2c_driver(rv3032_driver);
+
+MODULE_AUTHOR("Alexandre Belloni <[email protected]>");
+MODULE_DESCRIPTION("Micro Crystal RV3032 RTC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
index 93c3a6b627bd..72adef5a5ebe 100644
--- a/drivers/rtc/rtc-rv8803.c
+++ b/drivers/rtc/rtc-rv8803.c
@@ -454,13 +454,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
static int rv8803_nvram_write(void *priv, unsigned int offset, void *val,
size_t bytes)
{
- int ret;
-
- ret = rv8803_write_reg(priv, RV8803_RAM, *(u8 *)val);
- if (ret)
- return ret;
-
- return 0;
+ return rv8803_write_reg(priv, RV8803_RAM, *(u8 *)val);
}
static int rv8803_nvram_read(void *priv, unsigned int offset,
@@ -477,10 +471,13 @@ static int rv8803_nvram_read(void *priv, unsigned int offset,
return 0;
}
-static struct rtc_class_ops rv8803_rtc_ops = {
+static const struct rtc_class_ops rv8803_rtc_ops = {
.read_time = rv8803_get_time,
.set_time = rv8803_set_time,
.ioctl = rv8803_ioctl,
+ .read_alarm = rv8803_get_alarm,
+ .set_alarm = rv8803_set_alarm,
+ .alarm_irq_enable = rv8803_alarm_irq_enable,
};
static int rx8900_trickle_charger_init(struct rv8803_data *rv8803)
@@ -573,12 +570,10 @@ static int rv8803_probe(struct i2c_client *client,
if (err) {
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
client->irq = 0;
- } else {
- rv8803_rtc_ops.read_alarm = rv8803_get_alarm;
- rv8803_rtc_ops.set_alarm = rv8803_set_alarm;
- rv8803_rtc_ops.alarm_irq_enable = rv8803_alarm_irq_enable;
}
}
+ if (!client->irq)
+ clear_bit(RTC_FEATURE_ALARM, rv8803->rtc->features);
err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA);
if (err)
@@ -591,14 +586,13 @@ static int rv8803_probe(struct i2c_client *client,
}
rv8803->rtc->ops = &rv8803_rtc_ops;
- rv8803->rtc->nvram_old_abi = true;
rv8803->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rv8803->rtc->range_max = RTC_TIMESTAMP_END_2099;
- err = rtc_register_device(rv8803->rtc);
+ err = devm_rtc_register_device(rv8803->rtc);
if (err)
return err;
- rtc_nvmem_register(rv8803->rtc, &nvmem_cfg);
+ devm_rtc_nvmem_register(rv8803->rtc, &nvmem_cfg);
rv8803->rtc->max_user_freq = 1;
@@ -613,7 +607,7 @@ static const struct i2c_device_id rv8803_id[] = {
};
MODULE_DEVICE_TABLE(i2c, rv8803_id);
-static const struct of_device_id rv8803_of_match[] = {
+static const __maybe_unused struct of_device_id rv8803_of_match[] = {
{
.compatible = "microcrystal,rv8803",
.data = (void *)rv_8803
diff --git a/drivers/rtc/rtc-rx6110.c b/drivers/rtc/rtc-rx6110.c
index 3a9eb7043f01..79161d4c6ce4 100644
--- a/drivers/rtc/rtc-rx6110.c
+++ b/drivers/rtc/rtc-rx6110.c
@@ -16,6 +16,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
+#include <linux/i2c.h>
/* RX-6110 Register definitions */
#define RX6110_REG_SEC 0x10
@@ -310,6 +311,27 @@ static const struct rtc_class_ops rx6110_rtc_ops = {
.set_time = rx6110_set_time,
};
+static int rx6110_probe(struct rx6110_data *rx6110, struct device *dev)
+{
+ int err;
+
+ rx6110->rtc = devm_rtc_device_register(dev,
+ RX6110_DRIVER_NAME,
+ &rx6110_rtc_ops, THIS_MODULE);
+
+ if (IS_ERR(rx6110->rtc))
+ return PTR_ERR(rx6110->rtc);
+
+ err = rx6110_init(rx6110);
+ if (err)
+ return err;
+
+ rx6110->rtc->max_user_freq = 1;
+
+ return 0;
+}
+
+#if IS_ENABLED(CONFIG_SPI_MASTER)
static struct regmap_config regmap_spi_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -318,13 +340,12 @@ static struct regmap_config regmap_spi_config = {
};
/**
- * rx6110_probe - initialize rtc driver
+ * rx6110_spi_probe - initialize rtc driver
* @spi: pointer to spi device
*/
-static int rx6110_probe(struct spi_device *spi)
+static int rx6110_spi_probe(struct spi_device *spi)
{
struct rx6110_data *rx6110;
- int err;
if ((spi->bits_per_word && spi->bits_per_word != 8) ||
(spi->max_speed_hz > 2000000) ||
@@ -346,27 +367,14 @@ static int rx6110_probe(struct spi_device *spi)
spi_set_drvdata(spi, rx6110);
- rx6110->rtc = devm_rtc_device_register(&spi->dev,
- RX6110_DRIVER_NAME,
- &rx6110_rtc_ops, THIS_MODULE);
-
- if (IS_ERR(rx6110->rtc))
- return PTR_ERR(rx6110->rtc);
-
- err = rx6110_init(rx6110);
- if (err)
- return err;
-
- rx6110->rtc->max_user_freq = 1;
-
- return 0;
+ return rx6110_probe(rx6110, &spi->dev);
}
-static const struct spi_device_id rx6110_id[] = {
+static const struct spi_device_id rx6110_spi_id[] = {
{ "rx6110", 0 },
{ }
};
-MODULE_DEVICE_TABLE(spi, rx6110_id);
+MODULE_DEVICE_TABLE(spi, rx6110_spi_id);
static const struct of_device_id rx6110_spi_of_match[] = {
{ .compatible = "epson,rx6110" },
@@ -374,16 +382,127 @@ static const struct of_device_id rx6110_spi_of_match[] = {
};
MODULE_DEVICE_TABLE(of, rx6110_spi_of_match);
-static struct spi_driver rx6110_driver = {
+static struct spi_driver rx6110_spi_driver = {
.driver = {
.name = RX6110_DRIVER_NAME,
.of_match_table = of_match_ptr(rx6110_spi_of_match),
},
- .probe = rx6110_probe,
- .id_table = rx6110_id,
+ .probe = rx6110_spi_probe,
+ .id_table = rx6110_spi_id,
+};
+
+static int rx6110_spi_register(void)
+{
+ return spi_register_driver(&rx6110_spi_driver);
+}
+
+static void rx6110_spi_unregister(void)
+{
+ spi_unregister_driver(&rx6110_spi_driver);
+}
+#else
+static int rx6110_spi_register(void)
+{
+ return 0;
+}
+
+static void rx6110_spi_unregister(void)
+{
+}
+#endif /* CONFIG_SPI_MASTER */
+
+#if IS_ENABLED(CONFIG_I2C)
+static struct regmap_config regmap_i2c_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = RX6110_REG_IRQ,
+ .read_flag_mask = 0x80,
};
-module_spi_driver(rx6110_driver);
+static int rx6110_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct rx6110_data *rx6110;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
+ | I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ dev_err(&adapter->dev,
+ "doesn't support required functionality\n");
+ return -EIO;
+ }
+
+ rx6110 = devm_kzalloc(&client->dev, sizeof(*rx6110), GFP_KERNEL);
+ if (!rx6110)
+ return -ENOMEM;
+
+ rx6110->regmap = devm_regmap_init_i2c(client, &regmap_i2c_config);
+ if (IS_ERR(rx6110->regmap)) {
+ dev_err(&client->dev, "regmap init failed for rtc rx6110\n");
+ return PTR_ERR(rx6110->regmap);
+ }
+
+ i2c_set_clientdata(client, rx6110);
+
+ return rx6110_probe(rx6110, &client->dev);
+}
+
+static const struct i2c_device_id rx6110_i2c_id[] = {
+ { "rx6110", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, rx6110_i2c_id);
+
+static struct i2c_driver rx6110_i2c_driver = {
+ .driver = {
+ .name = RX6110_DRIVER_NAME,
+ },
+ .probe = rx6110_i2c_probe,
+ .id_table = rx6110_i2c_id,
+};
+
+static int rx6110_i2c_register(void)
+{
+ return i2c_add_driver(&rx6110_i2c_driver);
+}
+
+static void rx6110_i2c_unregister(void)
+{
+ i2c_del_driver(&rx6110_i2c_driver);
+}
+#else
+static int rx6110_i2c_register(void)
+{
+ return 0;
+}
+
+static void rx6110_i2c_unregister(void)
+{
+}
+#endif /* CONFIG_I2C */
+
+static int __init rx6110_module_init(void)
+{
+ int ret;
+
+ ret = rx6110_spi_register();
+ if (ret)
+ return ret;
+
+ ret = rx6110_i2c_register();
+ if (ret)
+ rx6110_spi_unregister();
+
+ return ret;
+}
+module_init(rx6110_module_init);
+
+static void __exit rx6110_module_exit(void)
+{
+ rx6110_spi_unregister();
+ rx6110_i2c_unregister();
+}
+module_exit(rx6110_module_exit);
MODULE_AUTHOR("Val Krutov <[email protected]>");
MODULE_DESCRIPTION("RX-6110 SA RTC driver");
diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c
index fe010151ec8f..d09056570739 100644
--- a/drivers/rtc/rtc-rx8010.c
+++ b/drivers/rtc/rtc-rx8010.c
@@ -11,42 +11,43 @@
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/regmap.h>
#include <linux/rtc.h>
-#define RX8010_SEC 0x10
-#define RX8010_MIN 0x11
-#define RX8010_HOUR 0x12
-#define RX8010_WDAY 0x13
-#define RX8010_MDAY 0x14
-#define RX8010_MONTH 0x15
-#define RX8010_YEAR 0x16
-#define RX8010_RESV17 0x17
-#define RX8010_ALMIN 0x18
-#define RX8010_ALHOUR 0x19
-#define RX8010_ALWDAY 0x1A
-#define RX8010_TCOUNT0 0x1B
-#define RX8010_TCOUNT1 0x1C
-#define RX8010_EXT 0x1D
-#define RX8010_FLAG 0x1E
-#define RX8010_CTRL 0x1F
+#define RX8010_SEC 0x10
+#define RX8010_MIN 0x11
+#define RX8010_HOUR 0x12
+#define RX8010_WDAY 0x13
+#define RX8010_MDAY 0x14
+#define RX8010_MONTH 0x15
+#define RX8010_YEAR 0x16
+#define RX8010_RESV17 0x17
+#define RX8010_ALMIN 0x18
+#define RX8010_ALHOUR 0x19
+#define RX8010_ALWDAY 0x1A
+#define RX8010_TCOUNT0 0x1B
+#define RX8010_TCOUNT1 0x1C
+#define RX8010_EXT 0x1D
+#define RX8010_FLAG 0x1E
+#define RX8010_CTRL 0x1F
/* 0x20 to 0x2F are user registers */
-#define RX8010_RESV30 0x30
-#define RX8010_RESV31 0x31
-#define RX8010_IRQ 0x32
+#define RX8010_RESV30 0x30
+#define RX8010_RESV31 0x31
+#define RX8010_IRQ 0x32
-#define RX8010_EXT_WADA BIT(3)
+#define RX8010_EXT_WADA BIT(3)
-#define RX8010_FLAG_VLF BIT(1)
-#define RX8010_FLAG_AF BIT(3)
-#define RX8010_FLAG_TF BIT(4)
-#define RX8010_FLAG_UF BIT(5)
+#define RX8010_FLAG_VLF BIT(1)
+#define RX8010_FLAG_AF BIT(3)
+#define RX8010_FLAG_TF BIT(4)
+#define RX8010_FLAG_UF BIT(5)
-#define RX8010_CTRL_AIE BIT(3)
-#define RX8010_CTRL_UIE BIT(5)
-#define RX8010_CTRL_STOP BIT(6)
-#define RX8010_CTRL_TEST BIT(7)
+#define RX8010_CTRL_AIE BIT(3)
+#define RX8010_CTRL_UIE BIT(5)
+#define RX8010_CTRL_STOP BIT(6)
+#define RX8010_CTRL_TEST BIT(7)
-#define RX8010_ALARM_AE BIT(7)
+#define RX8010_ALARM_AE BIT(7)
static const struct i2c_device_id rx8010_id[] = {
{ "rx8010", 0 },
@@ -54,14 +55,14 @@ static const struct i2c_device_id rx8010_id[] = {
};
MODULE_DEVICE_TABLE(i2c, rx8010_id);
-static const struct of_device_id rx8010_of_match[] = {
+static const __maybe_unused struct of_device_id rx8010_of_match[] = {
{ .compatible = "epson,rx8010" },
{ }
};
MODULE_DEVICE_TABLE(of, rx8010_of_match);
struct rx8010_data {
- struct i2c_client *client;
+ struct regmap *regs;
struct rtc_device *rtc;
u8 ctrlreg;
};
@@ -70,14 +71,13 @@ static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id)
{
struct i2c_client *client = dev_id;
struct rx8010_data *rx8010 = i2c_get_clientdata(client);
- int flagreg;
+ int flagreg, err;
- mutex_lock(&rx8010->rtc->ops_lock);
+ rtc_lock(rx8010->rtc);
- flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG);
-
- if (flagreg <= 0) {
- mutex_unlock(&rx8010->rtc->ops_lock);
+ err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
+ if (err) {
+ rtc_unlock(rx8010->rtc);
return IRQ_NONE;
}
@@ -99,32 +99,29 @@ static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id)
rtc_update_irq(rx8010->rtc, 1, RTC_UF | RTC_IRQF);
}
- i2c_smbus_write_byte_data(client, RX8010_FLAG, flagreg);
-
- mutex_unlock(&rx8010->rtc->ops_lock);
- return IRQ_HANDLED;
+ err = regmap_write(rx8010->regs, RX8010_FLAG, flagreg);
+ rtc_unlock(rx8010->rtc);
+ return err ? IRQ_NONE : IRQ_HANDLED;
}
static int rx8010_get_time(struct device *dev, struct rtc_time *dt)
{
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
- u8 date[7];
- int flagreg;
- int err;
+ u8 date[RX8010_YEAR - RX8010_SEC + 1];
+ int flagreg, err;
- flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
+ err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
+ if (err)
+ return err;
if (flagreg & RX8010_FLAG_VLF) {
dev_warn(dev, "Frequency stop detected\n");
return -EINVAL;
}
- err = i2c_smbus_read_i2c_block_data(rx8010->client, RX8010_SEC,
- 7, date);
- if (err != 7)
- return err < 0 ? err : -EIO;
+ err = regmap_bulk_read(rx8010->regs, RX8010_SEC, date, sizeof(date));
+ if (err)
+ return err;
dt->tm_sec = bcd2bin(date[RX8010_SEC - RX8010_SEC] & 0x7f);
dt->tm_min = bcd2bin(date[RX8010_MIN - RX8010_SEC] & 0x7f);
@@ -140,22 +137,13 @@ static int rx8010_get_time(struct device *dev, struct rtc_time *dt)
static int rx8010_set_time(struct device *dev, struct rtc_time *dt)
{
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
- u8 date[7];
- int ctrl, flagreg;
- int ret;
-
- if ((dt->tm_year < 100) || (dt->tm_year > 199))
- return -EINVAL;
+ u8 date[RX8010_YEAR - RX8010_SEC + 1];
+ int err;
/* set STOP bit before changing clock/calendar */
- ctrl = i2c_smbus_read_byte_data(rx8010->client, RX8010_CTRL);
- if (ctrl < 0)
- return ctrl;
- rx8010->ctrlreg = ctrl | RX8010_CTRL_STOP;
- ret = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (ret < 0)
- return ret;
+ err = regmap_set_bits(rx8010->regs, RX8010_CTRL, RX8010_CTRL_STOP);
+ if (err)
+ return err;
date[RX8010_SEC - RX8010_SEC] = bin2bcd(dt->tm_sec);
date[RX8010_MIN - RX8010_SEC] = bin2bcd(dt->tm_min);
@@ -165,66 +153,54 @@ static int rx8010_set_time(struct device *dev, struct rtc_time *dt)
date[RX8010_YEAR - RX8010_SEC] = bin2bcd(dt->tm_year - 100);
date[RX8010_WDAY - RX8010_SEC] = bin2bcd(1 << dt->tm_wday);
- ret = i2c_smbus_write_i2c_block_data(rx8010->client,
- RX8010_SEC, 7, date);
- if (ret < 0)
- return ret;
+ err = regmap_bulk_write(rx8010->regs, RX8010_SEC, date, sizeof(date));
+ if (err)
+ return err;
/* clear STOP bit after changing clock/calendar */
- ctrl = i2c_smbus_read_byte_data(rx8010->client, RX8010_CTRL);
- if (ctrl < 0)
- return ctrl;
- rx8010->ctrlreg = ctrl & ~RX8010_CTRL_STOP;
- ret = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (ret < 0)
- return ret;
-
- flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG);
- if (flagreg < 0) {
- return flagreg;
- }
+ err = regmap_clear_bits(rx8010->regs, RX8010_CTRL, RX8010_CTRL_STOP);
+ if (err)
+ return err;
- if (flagreg & RX8010_FLAG_VLF)
- ret = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG,
- flagreg & ~RX8010_FLAG_VLF);
+ err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_VLF);
+ if (err)
+ return err;
return 0;
}
-static int rx8010_init_client(struct i2c_client *client)
+static int rx8010_init(struct device *dev)
{
- struct rx8010_data *rx8010 = i2c_get_clientdata(client);
+ struct rx8010_data *rx8010 = dev_get_drvdata(dev);
u8 ctrl[2];
- int need_clear = 0, err = 0;
+ int need_clear = 0, err;
/* Initialize reserved registers as specified in datasheet */
- err = i2c_smbus_write_byte_data(client, RX8010_RESV17, 0xD8);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_RESV17, 0xD8);
+ if (err)
return err;
- err = i2c_smbus_write_byte_data(client, RX8010_RESV30, 0x00);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_RESV30, 0x00);
+ if (err)
return err;
- err = i2c_smbus_write_byte_data(client, RX8010_RESV31, 0x08);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_RESV31, 0x08);
+ if (err)
return err;
- err = i2c_smbus_write_byte_data(client, RX8010_IRQ, 0x00);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_IRQ, 0x00);
+ if (err)
return err;
- err = i2c_smbus_read_i2c_block_data(rx8010->client, RX8010_FLAG,
- 2, ctrl);
- if (err != 2)
- return err < 0 ? err : -EIO;
+ err = regmap_bulk_read(rx8010->regs, RX8010_FLAG, ctrl, 2);
+ if (err)
+ return err;
if (ctrl[0] & RX8010_FLAG_VLF)
- dev_warn(&client->dev, "Frequency stop was detected\n");
+ dev_warn(dev, "Frequency stop was detected\n");
if (ctrl[0] & RX8010_FLAG_AF) {
- dev_warn(&client->dev, "Alarm was detected\n");
+ dev_warn(dev, "Alarm was detected\n");
need_clear = 1;
}
@@ -236,8 +212,8 @@ static int rx8010_init_client(struct i2c_client *client)
if (need_clear) {
ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
- err = i2c_smbus_write_byte_data(client, RX8010_FLAG, ctrl[0]);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_FLAG, ctrl[0]);
+ if (err)
return err;
}
@@ -249,18 +225,16 @@ static int rx8010_init_client(struct i2c_client *client)
static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
- struct i2c_client *client = rx8010->client;
u8 alarmvals[3];
- int flagreg;
- int err;
+ int flagreg, err;
- err = i2c_smbus_read_i2c_block_data(client, RX8010_ALMIN, 3, alarmvals);
- if (err != 3)
- return err < 0 ? err : -EIO;
+ err = regmap_bulk_read(rx8010->regs, RX8010_ALMIN, alarmvals, 3);
+ if (err)
+ return err;
- flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
+ err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
+ if (err)
+ return err;
t->time.tm_sec = 0;
t->time.tm_min = bcd2bin(alarmvals[0] & 0x7f);
@@ -277,55 +251,38 @@ static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t)
static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
- struct i2c_client *client = to_i2c_client(dev);
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
u8 alarmvals[3];
- int extreg, flagreg;
int err;
- flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG);
- if (flagreg < 0) {
- return flagreg;
- }
-
if (rx8010->ctrlreg & (RX8010_CTRL_AIE | RX8010_CTRL_UIE)) {
rx8010->ctrlreg &= ~(RX8010_CTRL_AIE | RX8010_CTRL_UIE);
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (err < 0) {
+ err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
+ if (err)
return err;
- }
}
- flagreg &= ~RX8010_FLAG_AF;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG, flagreg);
- if (err < 0)
+ err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_AF);
+ if (err)
return err;
alarmvals[0] = bin2bcd(t->time.tm_min);
alarmvals[1] = bin2bcd(t->time.tm_hour);
alarmvals[2] = bin2bcd(t->time.tm_mday);
- err = i2c_smbus_write_i2c_block_data(rx8010->client, RX8010_ALMIN,
- 2, alarmvals);
- if (err < 0)
+ err = regmap_bulk_write(rx8010->regs, RX8010_ALMIN, alarmvals, 2);
+ if (err)
return err;
- extreg = i2c_smbus_read_byte_data(client, RX8010_EXT);
- if (extreg < 0)
- return extreg;
-
- extreg |= RX8010_EXT_WADA;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_EXT, extreg);
- if (err < 0)
+ err = regmap_clear_bits(rx8010->regs, RX8010_EXT, RX8010_EXT_WADA);
+ if (err)
return err;
if (alarmvals[2] == 0)
alarmvals[2] |= RX8010_ALARM_AE;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_ALWDAY,
- alarmvals[2]);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_ALWDAY, alarmvals[2]);
+ if (err)
return err;
if (t->enabled) {
@@ -335,9 +292,8 @@ static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t)
rx8010->ctrlreg |=
(RX8010_CTRL_AIE | RX8010_CTRL_UIE);
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
+ if (err)
return err;
}
@@ -347,11 +303,9 @@ static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t)
static int rx8010_alarm_irq_enable(struct device *dev,
unsigned int enabled)
{
- struct i2c_client *client = to_i2c_client(dev);
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
- int flagreg;
- u8 ctrl;
int err;
+ u8 ctrl;
ctrl = rx8010->ctrlreg;
@@ -367,20 +321,14 @@ static int rx8010_alarm_irq_enable(struct device *dev,
ctrl &= ~RX8010_CTRL_AIE;
}
- flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
-
- flagreg &= ~RX8010_FLAG_AF;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG, flagreg);
- if (err < 0)
+ err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_AF);
+ if (err)
return err;
if (ctrl != rx8010->ctrlreg) {
rx8010->ctrlreg = ctrl;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
+ if (err)
return err;
}
@@ -390,14 +338,13 @@ static int rx8010_alarm_irq_enable(struct device *dev,
static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
- int tmp;
- int flagreg;
+ int tmp, flagreg, err;
switch (cmd) {
case RTC_VL_READ:
- flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
+ err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
+ if (err)
+ return err;
tmp = flagreg & RX8010_FLAG_VLF ? RTC_VL_DATA_INVALID : 0;
return put_user(tmp, (unsigned int __user *)arg);
@@ -407,65 +354,65 @@ static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
}
}
-static struct rtc_class_ops rx8010_rtc_ops = {
+static const struct rtc_class_ops rx8010_rtc_ops = {
.read_time = rx8010_get_time,
.set_time = rx8010_set_time,
.ioctl = rx8010_ioctl,
+ .read_alarm = rx8010_read_alarm,
+ .set_alarm = rx8010_set_alarm,
+ .alarm_irq_enable = rx8010_alarm_irq_enable,
};
-static int rx8010_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static const struct regmap_config rx8010_regmap_config = {
+ .name = "rx8010-rtc",
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int rx8010_probe(struct i2c_client *client)
{
- struct i2c_adapter *adapter = client->adapter;
+ struct device *dev = &client->dev;
struct rx8010_data *rx8010;
int err = 0;
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
- | I2C_FUNC_SMBUS_I2C_BLOCK)) {
- dev_err(&adapter->dev, "doesn't support required functionality\n");
- return -EIO;
- }
-
- rx8010 = devm_kzalloc(&client->dev, sizeof(struct rx8010_data),
- GFP_KERNEL);
+ rx8010 = devm_kzalloc(dev, sizeof(*rx8010), GFP_KERNEL);
if (!rx8010)
return -ENOMEM;
- rx8010->client = client;
i2c_set_clientdata(client, rx8010);
- err = rx8010_init_client(client);
+ rx8010->regs = devm_regmap_init_i2c(client, &rx8010_regmap_config);
+ if (IS_ERR(rx8010->regs))
+ return PTR_ERR(rx8010->regs);
+
+ err = rx8010_init(dev);
if (err)
return err;
+ rx8010->rtc = devm_rtc_allocate_device(dev);
+ if (IS_ERR(rx8010->rtc))
+ return PTR_ERR(rx8010->rtc);
+
if (client->irq > 0) {
- dev_info(&client->dev, "IRQ %d supplied\n", client->irq);
- err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+ dev_info(dev, "IRQ %d supplied\n", client->irq);
+ err = devm_request_threaded_irq(dev, client->irq, NULL,
rx8010_irq_1_handler,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"rx8010", client);
-
if (err) {
- dev_err(&client->dev, "unable to request IRQ\n");
- client->irq = 0;
- } else {
- rx8010_rtc_ops.read_alarm = rx8010_read_alarm;
- rx8010_rtc_ops.set_alarm = rx8010_set_alarm;
- rx8010_rtc_ops.alarm_irq_enable = rx8010_alarm_irq_enable;
+ dev_err(dev, "unable to request IRQ\n");
+ return err;
}
+ } else {
+ clear_bit(RTC_FEATURE_ALARM, rx8010->rtc->features);
}
- rx8010->rtc = devm_rtc_device_register(&client->dev, client->name,
- &rx8010_rtc_ops, THIS_MODULE);
-
- if (IS_ERR(rx8010->rtc)) {
- dev_err(&client->dev, "unable to register the class device\n");
- return PTR_ERR(rx8010->rtc);
- }
-
+ rx8010->rtc->ops = &rx8010_rtc_ops;
rx8010->rtc->max_user_freq = 1;
+ rx8010->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rx8010->rtc->range_max = RTC_TIMESTAMP_END_2099;
- return 0;
+ return devm_rtc_register_device(rx8010->rtc);
}
static struct i2c_driver rx8010_driver = {
@@ -473,7 +420,7 @@ static struct i2c_driver rx8010_driver = {
.name = "rtc-rx8010",
.of_match_table = of_match_ptr(rx8010_of_match),
},
- .probe = rx8010_probe,
+ .probe_new = rx8010_probe,
.id_table = rx8010_id,
};
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index a24f85893f90..c914091819ba 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -142,10 +142,9 @@ static irqreturn_t rx8025_handle_irq(int irq, void *dev_id)
{
struct i2c_client *client = dev_id;
struct rx8025_data *rx8025 = i2c_get_clientdata(client);
- struct mutex *lock = &rx8025->rtc->ops_lock;
int status;
- mutex_lock(lock);
+ rtc_lock(rx8025->rtc);
status = rx8025_read_reg(client, RX8025_REG_CTRL2);
if (status < 0)
goto out;
@@ -170,7 +169,7 @@ static irqreturn_t rx8025_handle_irq(int irq, void *dev_id)
}
out:
- mutex_unlock(lock);
+ rtc_unlock(rx8025->rtc);
return IRQ_HANDLED;
}
diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c
index 490f70f57636..aed4898a0ff4 100644
--- a/drivers/rtc/rtc-rx8581.c
+++ b/drivers/rtc/rtc-rx8581.c
@@ -298,11 +298,11 @@ static int rx8581_probe(struct i2c_client *client,
rx8581->rtc->start_secs = 0;
rx8581->rtc->set_start_time = true;
- ret = rtc_register_device(rx8581->rtc);
+ ret = devm_rtc_register_device(rx8581->rtc);
for (i = 0; i < config->num_nvram; i++) {
nvmem_cfg[i].priv = rx8581;
- rtc_nvmem_register(rx8581->rtc, &nvmem_cfg[i]);
+ devm_rtc_nvmem_register(rx8581->rtc, &nvmem_cfg[i]);
}
return ret;
@@ -314,7 +314,7 @@ static const struct i2c_device_id rx8581_id[] = {
};
MODULE_DEVICE_TABLE(i2c, rx8581_id);
-static const struct of_device_id rx8581_of_match[] = {
+static const __maybe_unused struct of_device_id rx8581_of_match[] = {
{ .compatible = "epson,rx8571", .data = &rx8571_config },
{ .compatible = "epson,rx8581", .data = &rx8581_config },
{ /* sentinel */ }
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index 03672a246356..b5bdeda7d767 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -55,7 +55,7 @@ static const struct i2c_device_id s35390a_id[] = {
};
MODULE_DEVICE_TABLE(i2c, s35390a_id);
-static const struct of_device_id s35390a_of_match[] = {
+static const __maybe_unused struct of_device_id s35390a_of_match[] = {
{ .compatible = "s35390a" },
{ .compatible = "sii,s35390a" },
{ }
@@ -497,7 +497,7 @@ static int s35390a_probe(struct i2c_client *client,
if (status1 & S35390A_FLAG_INT2)
rtc_update_irq(s35390a->rtc, 1, RTC_AF);
- return rtc_register_device(s35390a->rtc);
+ return devm_rtc_register_device(s35390a->rtc);
}
static struct i2c_driver s35390a_driver = {
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index e1b50e682fc4..e57d3ca70a78 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -42,26 +42,15 @@ struct s3c_rtc {
const struct s3c_rtc_data *data;
int irq_alarm;
- int irq_tick;
-
- spinlock_t pie_lock;
spinlock_t alarm_lock;
- int ticnt_save;
- int ticnt_en_save;
bool wake_en;
};
struct s3c_rtc_data {
- int max_user_freq;
bool needs_src_clk;
void (*irq_handler) (struct s3c_rtc *info, int mask);
- void (*set_freq) (struct s3c_rtc *info, int freq);
- void (*enable_tick) (struct s3c_rtc *info, struct seq_file *seq);
- void (*select_tick_clk) (struct s3c_rtc *info);
- void (*save_tick_cnt) (struct s3c_rtc *info);
- void (*restore_tick_cnt) (struct s3c_rtc *info);
void (*enable) (struct s3c_rtc *info);
void (*disable) (struct s3c_rtc *info);
};
@@ -91,17 +80,7 @@ static void s3c_rtc_disable_clk(struct s3c_rtc *info)
clk_disable(info->rtc_clk);
}
-/* IRQ Handlers */
-static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
-{
- struct s3c_rtc *info = (struct s3c_rtc *)id;
-
- if (info->data->irq_handler)
- info->data->irq_handler(info, S3C2410_INTP_TIC);
-
- return IRQ_HANDLED;
-}
-
+/* IRQ Handler */
static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
{
struct s3c_rtc *info = (struct s3c_rtc *)id;
@@ -148,28 +127,6 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)
return ret;
}
-/* Set RTC frequency */
-static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq)
-{
- int ret;
-
- if (!is_power_of_2(freq))
- return -EINVAL;
-
- ret = s3c_rtc_enable_clk(info);
- if (ret)
- return ret;
- spin_lock_irq(&info->pie_lock);
-
- if (info->data->set_freq)
- info->data->set_freq(info, freq);
-
- spin_unlock_irq(&info->pie_lock);
- s3c_rtc_disable_clk(info);
-
- return 0;
-}
-
/* Time read/write */
static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
{
@@ -348,29 +305,11 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
return 0;
}
-static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)
-{
- struct s3c_rtc *info = dev_get_drvdata(dev);
- int ret;
-
- ret = s3c_rtc_enable_clk(info);
- if (ret)
- return ret;
-
- if (info->data->enable_tick)
- info->data->enable_tick(info, seq);
-
- s3c_rtc_disable_clk(info);
-
- return 0;
-}
-
static const struct rtc_class_ops s3c_rtcops = {
.read_time = s3c_rtc_gettime,
.set_time = s3c_rtc_settime,
.read_alarm = s3c_rtc_getalarm,
.set_alarm = s3c_rtc_setalarm,
- .proc = s3c_rtc_proc,
.alarm_irq_enable = s3c_rtc_setaie,
};
@@ -443,25 +382,18 @@ static int s3c_rtc_remove(struct platform_device *pdev)
static int s3c_rtc_probe(struct platform_device *pdev)
{
struct s3c_rtc *info = NULL;
- struct rtc_time rtc_tm;
int ret;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
- /* find the IRQs */
- info->irq_tick = platform_get_irq(pdev, 1);
- if (info->irq_tick < 0)
- return info->irq_tick;
-
info->dev = &pdev->dev;
info->data = of_device_get_match_data(&pdev->dev);
if (!info->data) {
dev_err(&pdev->dev, "failed getting s3c_rtc_data\n");
return -EINVAL;
}
- spin_lock_init(&info->pie_lock);
spin_lock_init(&info->alarm_lock);
platform_set_drvdata(pdev, info);
@@ -470,8 +402,7 @@ static int s3c_rtc_probe(struct platform_device *pdev)
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);
+ dev_dbg(&pdev->dev, "s3c2410_rtc: alarm irq %d\n", info->irq_alarm);
/* get the memory region */
info->base = devm_platform_ioremap_resource(pdev, 0);
@@ -494,13 +425,8 @@ static int s3c_rtc_probe(struct platform_device *pdev)
if (info->data->needs_src_clk) {
info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src");
if (IS_ERR(info->rtc_src_clk)) {
- ret = PTR_ERR(info->rtc_src_clk);
- if (ret != -EPROBE_DEFER)
- dev_err(&pdev->dev,
- "failed to find rtc source clock\n");
- else
- dev_dbg(&pdev->dev,
- "probe deferred due to missing rtc src clk\n");
+ ret = dev_err_probe(&pdev->dev, PTR_ERR(info->rtc_src_clk),
+ "failed to find rtc source clock\n");
goto err_src_clk;
}
ret = clk_prepare_enable(info->rtc_src_clk);
@@ -508,6 +434,10 @@ static int s3c_rtc_probe(struct platform_device *pdev)
goto err_src_clk;
}
+ /* disable RTC enable bits potentially set by the bootloader */
+ if (info->data->disable)
+ info->data->disable(info);
+
/* check to see if everything is setup correctly */
if (info->data->enable)
info->data->enable(info);
@@ -517,20 +447,6 @@ static int s3c_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
- /* Check RTC Time */
- if (s3c_rtc_gettime(&pdev->dev, &rtc_tm)) {
- rtc_tm.tm_year = 100;
- rtc_tm.tm_mon = 0;
- rtc_tm.tm_mday = 1;
- rtc_tm.tm_hour = 0;
- rtc_tm.tm_min = 0;
- rtc_tm.tm_sec = 0;
-
- s3c_rtc_settime(&pdev->dev, &rtc_tm);
-
- dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
- }
-
/* register RTC and exit */
info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops,
THIS_MODULE);
@@ -547,18 +463,6 @@ static int s3c_rtc_probe(struct platform_device *pdev)
goto err_nortc;
}
- ret = devm_request_irq(&pdev->dev, info->irq_tick, s3c_rtc_tickirq,
- 0, "s3c2410-rtc tick", info);
- if (ret) {
- dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_tick, ret);
- goto err_nortc;
- }
-
- if (info->data->select_tick_clk)
- info->data->select_tick_clk(info);
-
- s3c_rtc_setfreq(info, 1);
-
s3c_rtc_disable_clk(info);
return 0;
@@ -586,10 +490,6 @@ static int s3c_rtc_suspend(struct device *dev)
if (ret)
return ret;
- /* save TICNT for anyone using periodic interrupts */
- if (info->data->save_tick_cnt)
- info->data->save_tick_cnt(info);
-
if (info->data->disable)
info->data->disable(info);
@@ -610,9 +510,6 @@ static int s3c_rtc_resume(struct device *dev)
if (info->data->enable)
info->data->enable(info);
- if (info->data->restore_tick_cnt)
- info->data->restore_tick_cnt(info);
-
s3c_rtc_disable_clk(info);
if (device_may_wakeup(dev) && info->wake_en) {
@@ -636,167 +533,32 @@ static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask)
writeb(mask, info->base + S3C2410_INTP);
}
-static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq)
-{
- unsigned int tmp = 0;
- int val;
-
- tmp = readb(info->base + S3C2410_TICNT);
- tmp &= S3C2410_TICNT_ENABLE;
-
- val = (info->rtc->max_user_freq / freq) - 1;
- tmp |= val;
-
- writel(tmp, info->base + S3C2410_TICNT);
-}
-
-static void s3c2416_rtc_setfreq(struct s3c_rtc *info, int freq)
-{
- unsigned int tmp = 0;
- int val;
-
- tmp = readb(info->base + S3C2410_TICNT);
- tmp &= S3C2410_TICNT_ENABLE;
-
- val = (info->rtc->max_user_freq / freq) - 1;
-
- tmp |= S3C2443_TICNT_PART(val);
- writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1);
-
- writel(S3C2416_TICNT2_PART(val), info->base + S3C2416_TICNT2);
-
- writel(tmp, info->base + S3C2410_TICNT);
-}
-
-static void s3c2443_rtc_setfreq(struct s3c_rtc *info, int freq)
-{
- unsigned int tmp = 0;
- int val;
-
- tmp = readb(info->base + S3C2410_TICNT);
- tmp &= S3C2410_TICNT_ENABLE;
-
- val = (info->rtc->max_user_freq / freq) - 1;
-
- tmp |= S3C2443_TICNT_PART(val);
- writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1);
-
- writel(tmp, info->base + S3C2410_TICNT);
-}
-
-static void s3c6410_rtc_setfreq(struct s3c_rtc *info, int freq)
-{
- int val;
-
- val = (info->rtc->max_user_freq / freq) - 1;
- writel(val, info->base + S3C2410_TICNT);
-}
-
-static void s3c24xx_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq)
-{
- unsigned int ticnt;
-
- ticnt = readb(info->base + S3C2410_TICNT);
- ticnt &= S3C2410_TICNT_ENABLE;
-
- seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no");
-}
-
-static void s3c2416_rtc_select_tick_clk(struct s3c_rtc *info)
-{
- unsigned int con;
-
- con = readw(info->base + S3C2410_RTCCON);
- con |= S3C2443_RTCCON_TICSEL;
- writew(con, info->base + S3C2410_RTCCON);
-}
-
-static void s3c6410_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq)
-{
- unsigned int ticnt;
-
- ticnt = readw(info->base + S3C2410_RTCCON);
- ticnt &= S3C64XX_RTCCON_TICEN;
-
- seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no");
-}
-
-static void s3c24xx_rtc_save_tick_cnt(struct s3c_rtc *info)
-{
- info->ticnt_save = readb(info->base + S3C2410_TICNT);
-}
-
-static void s3c24xx_rtc_restore_tick_cnt(struct s3c_rtc *info)
-{
- writeb(info->ticnt_save, info->base + S3C2410_TICNT);
-}
-
-static void s3c6410_rtc_save_tick_cnt(struct s3c_rtc *info)
-{
- info->ticnt_en_save = readw(info->base + S3C2410_RTCCON);
- info->ticnt_en_save &= S3C64XX_RTCCON_TICEN;
- info->ticnt_save = readl(info->base + S3C2410_TICNT);
-}
-
-static void s3c6410_rtc_restore_tick_cnt(struct s3c_rtc *info)
-{
- unsigned int con;
-
- writel(info->ticnt_save, info->base + S3C2410_TICNT);
- if (info->ticnt_en_save) {
- con = readw(info->base + S3C2410_RTCCON);
- writew(con | info->ticnt_en_save, info->base + S3C2410_RTCCON);
- }
-}
-
static struct s3c_rtc_data const s3c2410_rtc_data = {
- .max_user_freq = 128,
.irq_handler = s3c24xx_rtc_irq,
- .set_freq = s3c2410_rtc_setfreq,
- .enable_tick = s3c24xx_rtc_enable_tick,
- .save_tick_cnt = s3c24xx_rtc_save_tick_cnt,
- .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt,
.enable = s3c24xx_rtc_enable,
.disable = s3c24xx_rtc_disable,
};
static struct s3c_rtc_data const s3c2416_rtc_data = {
- .max_user_freq = 32768,
.irq_handler = s3c24xx_rtc_irq,
- .set_freq = s3c2416_rtc_setfreq,
- .enable_tick = s3c24xx_rtc_enable_tick,
- .select_tick_clk = s3c2416_rtc_select_tick_clk,
- .save_tick_cnt = s3c24xx_rtc_save_tick_cnt,
- .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt,
.enable = s3c24xx_rtc_enable,
.disable = s3c24xx_rtc_disable,
};
static struct s3c_rtc_data const s3c2443_rtc_data = {
- .max_user_freq = 32768,
.irq_handler = s3c24xx_rtc_irq,
- .set_freq = s3c2443_rtc_setfreq,
- .enable_tick = s3c24xx_rtc_enable_tick,
- .select_tick_clk = s3c2416_rtc_select_tick_clk,
- .save_tick_cnt = s3c24xx_rtc_save_tick_cnt,
- .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt,
.enable = s3c24xx_rtc_enable,
.disable = s3c24xx_rtc_disable,
};
static struct s3c_rtc_data const s3c6410_rtc_data = {
- .max_user_freq = 32768,
.needs_src_clk = true,
.irq_handler = s3c6410_rtc_irq,
- .set_freq = s3c6410_rtc_setfreq,
- .enable_tick = s3c6410_rtc_enable_tick,
- .save_tick_cnt = s3c6410_rtc_save_tick_cnt,
- .restore_tick_cnt = s3c6410_rtc_restore_tick_cnt,
.enable = s3c24xx_rtc_enable,
.disable = s3c6410_rtc_disable,
};
-static const struct of_device_id s3c_rtc_dt_match[] = {
+static const __maybe_unused struct of_device_id s3c_rtc_dt_match[] = {
{
.compatible = "samsung,s3c2410-rtc",
.data = &s3c2410_rtc_data,
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
index eb9dde4095a9..80b66f16db89 100644
--- a/drivers/rtc/rtc-s5m.c
+++ b/drivers/rtc/rtc-s5m.c
@@ -760,7 +760,8 @@ static int s5m_rtc_probe(struct platform_device *pdev)
return -ENODEV;
}
- info->i2c = i2c_new_dummy_device(s5m87xx->i2c->adapter, RTC_I2C_ADDR);
+ info->i2c = devm_i2c_new_dummy_device(&pdev->dev, s5m87xx->i2c->adapter,
+ RTC_I2C_ADDR);
if (IS_ERR(info->i2c)) {
dev_err(&pdev->dev, "Failed to allocate I2C for RTC\n");
return PTR_ERR(info->i2c);
@@ -771,7 +772,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)
ret = PTR_ERR(info->regmap);
dev_err(&pdev->dev, "Failed to allocate RTC register map: %d\n",
ret);
- goto err;
+ return ret;
}
info->dev = &pdev->dev;
@@ -781,26 +782,25 @@ static int s5m_rtc_probe(struct platform_device *pdev)
if (s5m87xx->irq_data) {
info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq);
if (info->irq <= 0) {
- ret = -EINVAL;
dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n",
alarm_irq);
- goto err;
+ return -EINVAL;
}
}
platform_set_drvdata(pdev, info);
ret = s5m8767_rtc_init_reg(info);
+ if (ret)
+ return ret;
device_init_wakeup(&pdev->dev, 1);
info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc",
&s5m_rtc_ops, THIS_MODULE);
- if (IS_ERR(info->rtc_dev)) {
- ret = PTR_ERR(info->rtc_dev);
- goto err;
- }
+ if (IS_ERR(info->rtc_dev))
+ return PTR_ERR(info->rtc_dev);
if (!info->irq) {
dev_info(&pdev->dev, "Alarm IRQ not available\n");
@@ -813,24 +813,10 @@ static int s5m_rtc_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
info->irq, ret);
- goto err;
+ return ret;
}
return 0;
-
-err:
- i2c_unregister_device(info->i2c);
-
- return ret;
-}
-
-static int s5m_rtc_remove(struct platform_device *pdev)
-{
- struct s5m_rtc_info *info = platform_get_drvdata(pdev);
-
- i2c_unregister_device(info->i2c);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -874,7 +860,6 @@ static struct platform_driver s5m_rtc_driver = {
.pm = &s5m_rtc_pm_ops,
},
.probe = s5m_rtc_probe,
- .remove = s5m_rtc_remove,
.id_table = s5m_rtc_id,
};
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 9ccc97cf5e09..1250887e4382 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -205,7 +205,7 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info)
info->rtc->max_user_freq = RTC_FREQ;
info->rtc->range_max = U32_MAX;
- ret = rtc_register_device(info->rtc);
+ ret = devm_rtc_register_device(info->rtc);
if (ret) {
clk_disable_unprepare(info->clk);
return ret;
diff --git a/drivers/rtc/rtc-sc27xx.c b/drivers/rtc/rtc-sc27xx.c
index 36810dd40cd3..187aa955b79c 100644
--- a/drivers/rtc/rtc-sc27xx.c
+++ b/drivers/rtc/rtc-sc27xx.c
@@ -299,33 +299,6 @@ static int sprd_rtc_set_secs(struct sprd_rtc *rtc, enum sprd_rtc_reg_types type,
sts_mask);
}
-static int sprd_rtc_read_aux_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct sprd_rtc *rtc = dev_get_drvdata(dev);
- time64_t secs;
- u32 val;
- int ret;
-
- ret = sprd_rtc_get_secs(rtc, SPRD_RTC_AUX_ALARM, &secs);
- if (ret)
- return ret;
-
- rtc_time64_to_tm(secs, &alrm->time);
-
- ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_INT_EN, &val);
- if (ret)
- return ret;
-
- alrm->enabled = !!(val & SPRD_RTC_AUXALM_EN);
-
- ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_INT_RAW_STS, &val);
- if (ret)
- return ret;
-
- alrm->pending = !!(val & SPRD_RTC_AUXALM_EN);
- return 0;
-}
-
static int sprd_rtc_set_aux_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct sprd_rtc *rtc = dev_get_drvdata(dev);
@@ -415,16 +388,9 @@ static int sprd_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
u32 val;
/*
- * Before RTC device is registered, it will check to see if there is an
- * alarm already set in RTC hardware, and we always read the normal
- * alarm at this time.
- *
- * Or if aie_timer is enabled, we should get the normal alarm time.
- * Otherwise we should get auxiliary alarm time.
+ * The RTC core checks to see if there is an alarm already set in RTC
+ * hardware, and we always read the normal alarm at this time.
*/
- if (rtc->rtc && rtc->rtc->registered && rtc->rtc->aie_timer.enabled == 0)
- return sprd_rtc_read_aux_alarm(dev, alrm);
-
ret = sprd_rtc_get_secs(rtc, SPRD_RTC_ALARM, &secs);
if (ret)
return ret;
@@ -563,7 +529,7 @@ static int sprd_rtc_check_power_down(struct sprd_rtc *rtc)
* means the RTC has been powered down, so the RTC time values are
* invalid.
*/
- rtc->valid = val == SPRD_RTC_POWER_RESET_VALUE ? false : true;
+ rtc->valid = val != SPRD_RTC_POWER_RESET_VALUE;
return 0;
}
@@ -652,7 +618,7 @@ static int sprd_rtc_probe(struct platform_device *pdev)
rtc->rtc->ops = &sprd_rtc_ops;
rtc->rtc->range_min = 0;
rtc->rtc->range_max = 5662310399LL;
- ret = rtc_register_device(rtc->rtc);
+ ret = devm_rtc_register_device(rtc->rtc);
if (ret) {
device_init_wakeup(&pdev->dev, 0);
return ret;
diff --git a/drivers/rtc/rtc-sd3078.c b/drivers/rtc/rtc-sd3078.c
index a7aa943c1183..24e8528e23ec 100644
--- a/drivers/rtc/rtc-sd3078.c
+++ b/drivers/rtc/rtc-sd3078.c
@@ -192,7 +192,7 @@ static int sd3078_probe(struct i2c_client *client,
sd3078->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
sd3078->rtc->range_max = RTC_TIMESTAMP_END_2099;
- ret = rtc_register_device(sd3078->rtc);
+ ret = devm_rtc_register_device(sd3078->rtc);
if (ret)
return ret;
@@ -207,7 +207,7 @@ static const struct i2c_device_id sd3078_id[] = {
};
MODULE_DEVICE_TABLE(i2c, sd3078_id);
-static const struct of_device_id rtc_dt_match[] = {
+static const __maybe_unused struct of_device_id rtc_dt_match[] = {
{ .compatible = "whwave,sd3078" },
{},
};
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 9167b48014a1..cd146b574143 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -607,7 +607,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev->range_max = mktime64(2098, 12, 31, 23, 59, 59);
}
- ret = rtc_register_device(rtc->rtc_dev);
+ ret = devm_rtc_register_device(rtc->rtc_dev);
if (ret)
goto err_unmap;
diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c
deleted file mode 100644
index abf19435dbad..000000000000
--- a/drivers/rtc/rtc-sirfsoc.c
+++ /dev/null
@@ -1,446 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * SiRFSoC Real Time Clock interface for Linux
- *
- * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company.
- */
-
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/rtc.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/regmap.h>
-#include <linux/rtc/sirfsoc_rtciobrg.h>
-
-
-#define RTC_CN 0x00
-#define RTC_ALARM0 0x04
-#define RTC_ALARM1 0x18
-#define RTC_STATUS 0x08
-#define RTC_SW_VALUE 0x40
-#define SIRFSOC_RTC_AL1E (1<<6)
-#define SIRFSOC_RTC_AL1 (1<<4)
-#define SIRFSOC_RTC_HZE (1<<3)
-#define SIRFSOC_RTC_AL0E (1<<2)
-#define SIRFSOC_RTC_HZ (1<<1)
-#define SIRFSOC_RTC_AL0 (1<<0)
-#define RTC_DIV 0x0c
-#define RTC_DEEP_CTRL 0x14
-#define RTC_CLOCK_SWITCH 0x1c
-#define SIRFSOC_RTC_CLK 0x03 /* others are reserved */
-
-/* Refer to RTC DIV switch */
-#define RTC_HZ 16
-
-/* This macro is also defined in arch/arm/plat-sirfsoc/cpu.c */
-#define RTC_SHIFT 4
-
-#define INTR_SYSRTC_CN 0x48
-
-struct sirfsoc_rtc_drv {
- struct rtc_device *rtc;
- u32 rtc_base;
- u32 irq;
- unsigned irq_wake;
- /* Overflow for every 8 years extra time */
- u32 overflow_rtc;
- spinlock_t lock;
- struct regmap *regmap;
-#ifdef CONFIG_PM
- u32 saved_counter;
- u32 saved_overflow_rtc;
-#endif
-};
-
-static u32 sirfsoc_rtc_readl(struct sirfsoc_rtc_drv *rtcdrv, u32 offset)
-{
- u32 val;
-
- regmap_read(rtcdrv->regmap, rtcdrv->rtc_base + offset, &val);
- return val;
-}
-
-static void sirfsoc_rtc_writel(struct sirfsoc_rtc_drv *rtcdrv,
- u32 offset, u32 val)
-{
- regmap_write(rtcdrv->regmap, rtcdrv->rtc_base + offset, val);
-}
-
-static int sirfsoc_rtc_read_alarm(struct device *dev,
- struct rtc_wkalrm *alrm)
-{
- unsigned long rtc_alarm, rtc_count;
- struct sirfsoc_rtc_drv *rtcdrv;
-
- rtcdrv = dev_get_drvdata(dev);
-
- spin_lock_irq(&rtcdrv->lock);
-
- rtc_count = sirfsoc_rtc_readl(rtcdrv, RTC_CN);
-
- rtc_alarm = sirfsoc_rtc_readl(rtcdrv, RTC_ALARM0);
- memset(alrm, 0, sizeof(struct rtc_wkalrm));
-
- /*
- * assume alarm interval not beyond one round counter overflow_rtc:
- * 0->0xffffffff
- */
- /* if alarm is in next overflow cycle */
- if (rtc_count > rtc_alarm)
- rtc_time64_to_tm((rtcdrv->overflow_rtc + 1)
- << (BITS_PER_LONG - RTC_SHIFT)
- | rtc_alarm >> RTC_SHIFT, &alrm->time);
- else
- rtc_time64_to_tm(rtcdrv->overflow_rtc
- << (BITS_PER_LONG - RTC_SHIFT)
- | rtc_alarm >> RTC_SHIFT, &alrm->time);
- if (sirfsoc_rtc_readl(rtcdrv, RTC_STATUS) & SIRFSOC_RTC_AL0E)
- alrm->enabled = 1;
-
- spin_unlock_irq(&rtcdrv->lock);
-
- return 0;
-}
-
-static int sirfsoc_rtc_set_alarm(struct device *dev,
- struct rtc_wkalrm *alrm)
-{
- unsigned long rtc_status_reg, rtc_alarm;
- struct sirfsoc_rtc_drv *rtcdrv;
- rtcdrv = dev_get_drvdata(dev);
-
- if (alrm->enabled) {
- rtc_alarm = rtc_tm_to_time64(&alrm->time);
-
- spin_lock_irq(&rtcdrv->lock);
-
- rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
- if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
- /*
- * An ongoing alarm in progress - ingore it and not
- * to return EBUSY
- */
- dev_info(dev, "An old alarm was set, will be replaced by a new one\n");
- }
-
- sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, rtc_alarm << RTC_SHIFT);
- rtc_status_reg &= ~0x07; /* mask out the lower status bits */
- /*
- * This bit RTC_AL sets it as a wake-up source for Sleep Mode
- * Writing 1 into this bit will clear it
- */
- rtc_status_reg |= SIRFSOC_RTC_AL0;
- /* enable the RTC alarm interrupt */
- rtc_status_reg |= SIRFSOC_RTC_AL0E;
- sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);
-
- spin_unlock_irq(&rtcdrv->lock);
- } else {
- /*
- * if this function was called with enabled=0
- * then it could mean that the application is
- * trying to cancel an ongoing alarm
- */
- spin_lock_irq(&rtcdrv->lock);
-
- rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
- if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
- /* clear the RTC status register's alarm bit */
- rtc_status_reg &= ~0x07;
- /* write 1 into SIRFSOC_RTC_AL0 to force a clear */
- rtc_status_reg |= (SIRFSOC_RTC_AL0);
- /* Clear the Alarm enable bit */
- rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
-
- sirfsoc_rtc_writel(rtcdrv, RTC_STATUS,
- rtc_status_reg);
- }
-
- spin_unlock_irq(&rtcdrv->lock);
- }
-
- return 0;
-}
-
-static int sirfsoc_rtc_read_time(struct device *dev,
- struct rtc_time *tm)
-{
- unsigned long tmp_rtc = 0;
- struct sirfsoc_rtc_drv *rtcdrv;
- rtcdrv = dev_get_drvdata(dev);
- /*
- * This patch is taken from WinCE - Need to validate this for
- * correctness. To work around sirfsoc RTC counter double sync logic
- * fail, read several times to make sure get stable value.
- */
- do {
- tmp_rtc = sirfsoc_rtc_readl(rtcdrv, RTC_CN);
- cpu_relax();
- } while (tmp_rtc != sirfsoc_rtc_readl(rtcdrv, RTC_CN));
-
- rtc_time64_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT)
- | tmp_rtc >> RTC_SHIFT, tm);
- return 0;
-}
-
-static int sirfsoc_rtc_set_time(struct device *dev,
- struct rtc_time *tm)
-{
- unsigned long rtc_time;
- struct sirfsoc_rtc_drv *rtcdrv;
- rtcdrv = dev_get_drvdata(dev);
-
- rtc_time = rtc_tm_to_time64(tm);
-
- rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT);
-
- sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc);
- sirfsoc_rtc_writel(rtcdrv, RTC_CN, rtc_time << RTC_SHIFT);
-
- return 0;
-}
-
-static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
- unsigned int enabled)
-{
- unsigned long rtc_status_reg = 0x0;
- struct sirfsoc_rtc_drv *rtcdrv;
-
- rtcdrv = dev_get_drvdata(dev);
-
- spin_lock_irq(&rtcdrv->lock);
-
- rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
- if (enabled)
- rtc_status_reg |= SIRFSOC_RTC_AL0E;
- else
- rtc_status_reg &= ~SIRFSOC_RTC_AL0E;
-
- sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);
-
- spin_unlock_irq(&rtcdrv->lock);
-
- return 0;
-
-}
-
-static const struct rtc_class_ops sirfsoc_rtc_ops = {
- .read_time = sirfsoc_rtc_read_time,
- .set_time = sirfsoc_rtc_set_time,
- .read_alarm = sirfsoc_rtc_read_alarm,
- .set_alarm = sirfsoc_rtc_set_alarm,
- .alarm_irq_enable = sirfsoc_rtc_alarm_irq_enable
-};
-
-static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
-{
- struct sirfsoc_rtc_drv *rtcdrv = pdata;
- unsigned long rtc_status_reg = 0x0;
- unsigned long events = 0x0;
-
- spin_lock(&rtcdrv->lock);
-
- rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
- /* this bit will be set ONLY if an alarm was active
- * and it expired NOW
- * So this is being used as an ASSERT
- */
- if (rtc_status_reg & SIRFSOC_RTC_AL0) {
- /*
- * clear the RTC status register's alarm bit
- * mask out the lower status bits
- */
- rtc_status_reg &= ~0x07;
- /* write 1 into SIRFSOC_RTC_AL0 to ACK the alarm interrupt */
- rtc_status_reg |= (SIRFSOC_RTC_AL0);
- /* Clear the Alarm enable bit */
- rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
- }
-
- sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);
-
- spin_unlock(&rtcdrv->lock);
-
- /* this should wake up any apps polling/waiting on the read
- * after setting the alarm
- */
- events |= RTC_IRQF | RTC_AF;
- rtc_update_irq(rtcdrv->rtc, 1, events);
-
- return IRQ_HANDLED;
-}
-
-static const struct of_device_id sirfsoc_rtc_of_match[] = {
- { .compatible = "sirf,prima2-sysrtc"},
- {},
-};
-
-static const struct regmap_config sysrtc_regmap_config = {
- .reg_bits = 32,
- .val_bits = 32,
- .fast_io = true,
-};
-
-MODULE_DEVICE_TABLE(of, sirfsoc_rtc_of_match);
-
-static int sirfsoc_rtc_probe(struct platform_device *pdev)
-{
- int err;
- unsigned long rtc_div;
- struct sirfsoc_rtc_drv *rtcdrv;
- struct device_node *np = pdev->dev.of_node;
-
- rtcdrv = devm_kzalloc(&pdev->dev,
- sizeof(struct sirfsoc_rtc_drv), GFP_KERNEL);
- if (rtcdrv == NULL)
- return -ENOMEM;
-
- spin_lock_init(&rtcdrv->lock);
-
- err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
- if (err) {
- dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");
- return err;
- }
-
- platform_set_drvdata(pdev, rtcdrv);
-
- /* Register rtc alarm as a wakeup source */
- device_init_wakeup(&pdev->dev, 1);
-
- rtcdrv->regmap = devm_regmap_init_iobg(&pdev->dev,
- &sysrtc_regmap_config);
- if (IS_ERR(rtcdrv->regmap)) {
- err = PTR_ERR(rtcdrv->regmap);
- dev_err(&pdev->dev, "Failed to allocate register map: %d\n",
- err);
- return err;
- }
-
- /*
- * Set SYS_RTC counter in RTC_HZ HZ Units
- * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
- * If 16HZ, therefore RTC_DIV = 1023;
- */
- rtc_div = ((32768 / RTC_HZ) / 2) - 1;
- sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div);
-
- /* 0x3 -> RTC_CLK */
- sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK);
-
- /* reset SYS RTC ALARM0 */
- sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0);
-
- /* reset SYS RTC ALARM1 */
- sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0);
-
- /* Restore RTC Overflow From Register After Command Reboot */
- rtcdrv->overflow_rtc =
- sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE);
-
- rtcdrv->rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(rtcdrv->rtc))
- return PTR_ERR(rtcdrv->rtc);
-
- rtcdrv->rtc->ops = &sirfsoc_rtc_ops;
- rtcdrv->rtc->range_max = (1ULL << 60) - 1;
-
- rtcdrv->irq = platform_get_irq(pdev, 0);
- err = devm_request_irq(&pdev->dev, rtcdrv->irq, sirfsoc_rtc_irq_handler,
- IRQF_SHARED, pdev->name, rtcdrv);
- if (err) {
- dev_err(&pdev->dev, "Unable to register for the SiRF SOC RTC IRQ\n");
- return err;
- }
-
- return rtc_register_device(rtcdrv->rtc);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int sirfsoc_rtc_suspend(struct device *dev)
-{
- struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev);
- rtcdrv->overflow_rtc =
- sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE);
-
- rtcdrv->saved_counter =
- sirfsoc_rtc_readl(rtcdrv, RTC_CN);
- rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc;
- if (device_may_wakeup(dev) && !enable_irq_wake(rtcdrv->irq))
- rtcdrv->irq_wake = 1;
-
- return 0;
-}
-
-static int sirfsoc_rtc_resume(struct device *dev)
-{
- u32 tmp;
- struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev);
-
- /*
- * if resume from snapshot and the rtc power is lost,
- * restroe the rtc settings
- */
- if (SIRFSOC_RTC_CLK != sirfsoc_rtc_readl(rtcdrv, RTC_CLOCK_SWITCH)) {
- u32 rtc_div;
- /* 0x3 -> RTC_CLK */
- sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK);
- /*
- * Set SYS_RTC counter in RTC_HZ HZ Units
- * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
- * If 16HZ, therefore RTC_DIV = 1023;
- */
- rtc_div = ((32768 / RTC_HZ) / 2) - 1;
-
- sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div);
-
- /* reset SYS RTC ALARM0 */
- sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0);
-
- /* reset SYS RTC ALARM1 */
- sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0);
- }
- rtcdrv->overflow_rtc = rtcdrv->saved_overflow_rtc;
-
- /*
- * if current counter is small than previous,
- * it means overflow in sleep
- */
- tmp = sirfsoc_rtc_readl(rtcdrv, RTC_CN);
- if (tmp <= rtcdrv->saved_counter)
- rtcdrv->overflow_rtc++;
- /*
- *PWRC Value Be Changed When Suspend, Restore Overflow
- * In Memory To Register
- */
- sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc);
-
- if (device_may_wakeup(dev) && rtcdrv->irq_wake) {
- disable_irq_wake(rtcdrv->irq);
- rtcdrv->irq_wake = 0;
- }
-
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(sirfsoc_rtc_pm_ops,
- sirfsoc_rtc_suspend, sirfsoc_rtc_resume);
-
-static struct platform_driver sirfsoc_rtc_driver = {
- .driver = {
- .name = "sirfsoc-rtc",
- .pm = &sirfsoc_rtc_pm_ops,
- .of_match_table = sirfsoc_rtc_of_match,
- },
- .probe = sirfsoc_rtc_probe,
-};
-module_platform_driver(sirfsoc_rtc_driver);
-
-MODULE_DESCRIPTION("SiRF SoC rtc driver");
-MODULE_AUTHOR("Xianglong Du <[email protected]>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:sirfsoc-rtc");
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
index 0263d996b8a8..bd929b0e7d7d 100644
--- a/drivers/rtc/rtc-snvs.c
+++ b/drivers/rtc/rtc-snvs.c
@@ -151,17 +151,14 @@ static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
unsigned long time;
int ret;
- if (data->clk) {
- ret = clk_enable(data->clk);
- if (ret)
- return ret;
- }
+ ret = clk_enable(data->clk);
+ if (ret)
+ return ret;
time = rtc_read_lp_counter(data);
rtc_time64_to_tm(time, tm);
- if (data->clk)
- clk_disable(data->clk);
+ clk_disable(data->clk);
return 0;
}
@@ -172,11 +169,9 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
unsigned long time = rtc_tm_to_time64(tm);
int ret;
- if (data->clk) {
- ret = clk_enable(data->clk);
- if (ret)
- return ret;
- }
+ ret = clk_enable(data->clk);
+ if (ret)
+ return ret;
/* Disable RTC first */
ret = snvs_rtc_enable(data, false);
@@ -190,8 +185,7 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* Enable RTC again */
ret = snvs_rtc_enable(data, true);
- if (data->clk)
- clk_disable(data->clk);
+ clk_disable(data->clk);
return ret;
}
@@ -202,11 +196,9 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
u32 lptar, lpsr;
int ret;
- if (data->clk) {
- ret = clk_enable(data->clk);
- if (ret)
- return ret;
- }
+ ret = clk_enable(data->clk);
+ if (ret)
+ return ret;
regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar);
rtc_time64_to_tm(lptar, &alrm->time);
@@ -214,8 +206,7 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
- if (data->clk)
- clk_disable(data->clk);
+ clk_disable(data->clk);
return 0;
}
@@ -225,11 +216,9 @@ static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
struct snvs_rtc_data *data = dev_get_drvdata(dev);
int ret;
- if (data->clk) {
- ret = clk_enable(data->clk);
- if (ret)
- return ret;
- }
+ ret = clk_enable(data->clk);
+ if (ret)
+ return ret;
regmap_update_bits(data->regmap, data->offset + SNVS_LPCR,
(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN),
@@ -237,8 +226,7 @@ static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
ret = rtc_write_sync_lp(data);
- if (data->clk)
- clk_disable(data->clk);
+ clk_disable(data->clk);
return ret;
}
@@ -249,11 +237,9 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
unsigned long time = rtc_tm_to_time64(&alrm->time);
int ret;
- if (data->clk) {
- ret = clk_enable(data->clk);
- if (ret)
- return ret;
- }
+ ret = clk_enable(data->clk);
+ if (ret)
+ return ret;
regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0);
ret = rtc_write_sync_lp(data);
@@ -264,8 +250,7 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
/* Clear alarm interrupt status bit */
regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA);
- if (data->clk)
- clk_disable(data->clk);
+ clk_disable(data->clk);
return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
}
@@ -285,8 +270,7 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
u32 lpsr;
u32 events = 0;
- if (data->clk)
- clk_enable(data->clk);
+ clk_enable(data->clk);
regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
@@ -302,8 +286,7 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
/* clear interrupt status */
regmap_write(data->regmap, data->offset + SNVS_LPSR, lpsr);
- if (data->clk)
- clk_disable(data->clk);
+ clk_disable(data->clk);
return events ? IRQ_HANDLED : IRQ_NONE;
}
@@ -316,8 +299,7 @@ static const struct regmap_config snvs_rtc_config = {
static void snvs_rtc_action(void *data)
{
- if (data)
- clk_disable_unprepare(data);
+ clk_disable_unprepare(data);
}
static int snvs_rtc_probe(struct platform_device *pdev)
@@ -405,15 +387,14 @@ static int snvs_rtc_probe(struct platform_device *pdev)
data->rtc->ops = &snvs_rtc_ops;
data->rtc->range_max = U32_MAX;
- return rtc_register_device(data->rtc);
+ return devm_rtc_register_device(data->rtc);
}
static int __maybe_unused snvs_rtc_suspend_noirq(struct device *dev)
{
struct snvs_rtc_data *data = dev_get_drvdata(dev);
- if (data->clk)
- clk_disable(data->clk);
+ clk_disable(data->clk);
return 0;
}
diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index 51041dc08af4..bdb20f63254e 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -173,7 +173,7 @@ static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
return 0;
}
-static struct rtc_class_ops st_rtc_ops = {
+static const struct rtc_class_ops st_rtc_ops = {
.read_time = st_rtc_read_time,
.set_time = st_rtc_set_time,
.read_alarm = st_rtc_read_alarm,
@@ -250,7 +250,7 @@ static int st_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev->range_max = U64_MAX;
do_div(rtc->rtc_dev->range_max, rtc->clkrate);
- ret = rtc_register_device(rtc->rtc_dev);
+ ret = devm_rtc_register_device(rtc->rtc_dev);
if (ret) {
clk_disable_unprepare(rtc->clk);
return ret;
diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c
index 37a26279e107..fbd1ed41cbf1 100644
--- a/drivers/rtc/rtc-starfire.c
+++ b/drivers/rtc/rtc-starfire.c
@@ -48,7 +48,7 @@ static int __init starfire_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc);
- return rtc_register_device(rtc);
+ return devm_rtc_register_device(rtc);
}
static struct platform_driver starfire_rtc_driver = {
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index 01a45044f468..7cb6be1b7815 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -311,14 +311,13 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev)
return PTR_ERR(pdata->rtc);
pdata->rtc->ops = &stk17ta8_rtc_ops;
- pdata->rtc->nvram_old_abi = true;
nvmem_cfg.priv = pdata;
- ret = rtc_nvmem_register(pdata->rtc, &nvmem_cfg);
+ ret = devm_rtc_nvmem_register(pdata->rtc, &nvmem_cfg);
if (ret)
return ret;
- return rtc_register_device(pdata->rtc);
+ return devm_rtc_register_device(pdata->rtc);
}
/* work with hotplug and coldplug */
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index d774aa18f57a..75a8924ba12b 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -209,7 +209,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
const struct stm32_rtc_events *evts = &rtc->data->events;
unsigned int status, cr;
- mutex_lock(&rtc->rtc_dev->ops_lock);
+ rtc_lock(rtc->rtc_dev);
status = readl_relaxed(rtc->base + regs->sr);
cr = readl_relaxed(rtc->base + regs->cr);
@@ -226,7 +226,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
stm32_rtc_clear_event_flags(rtc, evts->alra);
}
- mutex_unlock(&rtc->rtc_dev->ops_lock);
+ rtc_unlock(rtc->rtc_dev);
return IRQ_HANDLED;
}
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c
index 0a969af80af7..40c0f7ed36e0 100644
--- a/drivers/rtc/rtc-stmp3xxx.c
+++ b/drivers/rtc/rtc-stmp3xxx.c
@@ -366,7 +366,7 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev)
rtc_data->rtc->ops = &stmp3xxx_rtc_ops;
rtc_data->rtc->range_max = U32_MAX;
- err = rtc_register_device(rtc_data->rtc);
+ err = devm_rtc_register_device(rtc_data->rtc);
if (err)
return err;
diff --git a/drivers/rtc/rtc-sun4v.c b/drivers/rtc/rtc-sun4v.c
index 036463dfa103..a86e27de8c06 100644
--- a/drivers/rtc/rtc-sun4v.c
+++ b/drivers/rtc/rtc-sun4v.c
@@ -86,7 +86,7 @@ static int __init sun4v_rtc_probe(struct platform_device *pdev)
rtc->range_max = U64_MAX;
platform_set_drvdata(pdev, rtc);
- return rtc_register_device(rtc);
+ return devm_rtc_register_device(rtc);
}
static struct platform_driver sun4v_rtc_driver = {
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index e2b8b150bcb4..adec1b14a8de 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -272,7 +272,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
300000000);
if (IS_ERR(rtc->int_osc)) {
pr_crit("Couldn't register the internal oscillator\n");
- return;
+ goto err;
}
parents[0] = clk_hw_get_name(rtc->int_osc);
@@ -290,7 +290,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
rtc->losc = clk_register(NULL, &rtc->hw);
if (IS_ERR(rtc->losc)) {
pr_crit("Couldn't register the LOSC clock\n");
- return;
+ goto err_register;
}
of_property_read_string_index(node, "clock-output-names", 1,
@@ -301,7 +301,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
&rtc->lock);
if (IS_ERR(rtc->ext_losc)) {
pr_crit("Couldn't register the LOSC external gate\n");
- return;
+ goto err_register;
}
clk_data->num = 2;
@@ -314,6 +314,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
return;
+err_register:
+ clk_hw_unregister_fixed_rate(rtc->int_osc);
err:
kfree(clk_data);
}
@@ -724,7 +726,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
chip->rtc->ops = &sun6i_rtc_ops;
chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */
- ret = rtc_register_device(chip->rtc);
+ ret = devm_rtc_register_device(chip->rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c
index f5d7f44550ce..5d019e3a835a 100644
--- a/drivers/rtc/rtc-sunxi.c
+++ b/drivers/rtc/rtc-sunxi.c
@@ -470,7 +470,7 @@ static int sunxi_rtc_probe(struct platform_device *pdev)
chip->rtc->ops = &sunxi_rtc_ops;
- return rtc_register_device(chip->rtc);
+ return devm_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 7fbb1741692f..85f7ad5d5390 100644
--- a/drivers/rtc/rtc-tegra.c
+++ b/drivers/rtc/rtc-tegra.c
@@ -232,7 +232,7 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data)
{
struct device *dev = data;
struct tegra_rtc_info *info = dev_get_drvdata(dev);
- unsigned long events = 0, flags;
+ unsigned long events = 0;
u32 status;
status = readl(info->base + TEGRA_RTC_REG_INTR_STATUS);
@@ -240,10 +240,10 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data)
/* clear the interrupt masks and status on any IRQ */
tegra_rtc_wait_while_busy(dev);
- spin_lock_irqsave(&info->lock, flags);
+ spin_lock(&info->lock);
writel(0, info->base + TEGRA_RTC_REG_INTR_MASK);
writel(status, info->base + TEGRA_RTC_REG_INTR_STATUS);
- spin_unlock_irqrestore(&info->lock, flags);
+ spin_unlock(&info->lock);
}
/* check if alarm */
@@ -329,7 +329,7 @@ static int tegra_rtc_probe(struct platform_device *pdev)
goto disable_clk;
}
- ret = rtc_register_device(info->rtc);
+ ret = devm_rtc_register_device(info->rtc);
if (ret)
goto disable_clk;
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index 74b3a0603b73..7e0d8fb26465 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -50,7 +50,6 @@ static int test_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (expires > U32_MAX)
expires = U32_MAX;
- pr_err("ABE: %s +%d %s\n", __FILE__, __LINE__, __func__);
rtd->alarm.expires = expires;
if (alrm->enabled)
@@ -139,7 +138,7 @@ static int test_probe(struct platform_device *plat_dev)
timer_setup(&rtd->alarm, test_rtc_alarm_handler, 0);
rtd->alarm.expires = 0;
- return rtc_register_device(rtd->rtc);
+ return devm_rtc_register_device(rtd->rtc);
}
static struct platform_driver test_driver = {
diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c
index e39af2d67051..a980337c3065 100644
--- a/drivers/rtc/rtc-tps6586x.c
+++ b/drivers/rtc/rtc-tps6586x.c
@@ -280,7 +280,7 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
goto fail_rtc_register;
}
- ret = rtc_register_device(rtc->rtc);
+ ret = devm_rtc_register_device(rtc->rtc);
if (ret)
goto fail_rtc_register;
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c
index e3840386f430..288abb1abdb8 100644
--- a/drivers/rtc/rtc-tps65910.c
+++ b/drivers/rtc/rtc-tps65910.c
@@ -361,13 +361,6 @@ 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;
@@ -426,15 +419,19 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
tps_rtc->irq = irq;
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;
+ if (device_property_present(tps65910->dev, "wakeup-source"))
+ device_init_wakeup(&pdev->dev, 1);
+ else
+ device_set_wakeup_capable(&pdev->dev, 1);
+ } else {
+ clear_bit(RTC_FEATURE_ALARM, tps_rtc->rtc->features);
+ }
+ 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;
- return rtc_register_device(tps_rtc->rtc);
+ return devm_rtc_register_device(tps_rtc->rtc);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c
deleted file mode 100644
index 715b82981279..000000000000
--- a/drivers/rtc/rtc-tx4939.c
+++ /dev/null
@@ -1,304 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * TX4939 internal RTC driver
- * Based on RBTX49xx patch from CELF patch archive.
- *
- * (C) Copyright TOSHIBA CORPORATION 2005-2007
- */
-#include <linux/rtc.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/gfp.h>
-
-#define TX4939_RTCCTL_ALME 0x00000080
-#define TX4939_RTCCTL_ALMD 0x00000040
-#define TX4939_RTCCTL_BUSY 0x00000020
-
-#define TX4939_RTCCTL_COMMAND 0x00000007
-#define TX4939_RTCCTL_COMMAND_NOP 0x00000000
-#define TX4939_RTCCTL_COMMAND_GETTIME 0x00000001
-#define TX4939_RTCCTL_COMMAND_SETTIME 0x00000002
-#define TX4939_RTCCTL_COMMAND_GETALARM 0x00000003
-#define TX4939_RTCCTL_COMMAND_SETALARM 0x00000004
-
-#define TX4939_RTCTBC_PM 0x00000080
-#define TX4939_RTCTBC_COMP 0x0000007f
-
-#define TX4939_RTC_REG_RAMSIZE 0x00000100
-#define TX4939_RTC_REG_RWBSIZE 0x00000006
-
-struct tx4939_rtc_reg {
- __u32 ctl;
- __u32 adr;
- __u32 dat;
- __u32 tbc;
-};
-
-struct tx4939rtc_plat_data {
- struct rtc_device *rtc;
- struct tx4939_rtc_reg __iomem *rtcreg;
- spinlock_t lock;
-};
-
-static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd)
-{
- int i = 0;
-
- __raw_writel(cmd, &rtcreg->ctl);
- /* This might take 30us (next 32.768KHz clock) */
- while (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_BUSY) {
- /* timeout on approx. 100us (@ GBUS200MHz) */
- if (i++ > 200 * 100)
- return -EBUSY;
- cpu_relax();
- }
- return 0;
-}
-
-static int tx4939_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
- struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
- unsigned long secs = rtc_tm_to_time64(tm);
- int i, ret;
- unsigned char buf[6];
-
- buf[0] = 0;
- buf[1] = 0;
- buf[2] = secs;
- buf[3] = secs >> 8;
- buf[4] = secs >> 16;
- buf[5] = secs >> 24;
- spin_lock_irq(&pdata->lock);
- __raw_writel(0, &rtcreg->adr);
- for (i = 0; i < 6; i++)
- __raw_writel(buf[i], &rtcreg->dat);
- ret = tx4939_rtc_cmd(rtcreg,
- TX4939_RTCCTL_COMMAND_SETTIME |
- (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
- spin_unlock_irq(&pdata->lock);
- return ret;
-}
-
-static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
- struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
- int i, ret;
- unsigned long sec;
- unsigned char buf[6];
-
- spin_lock_irq(&pdata->lock);
- ret = tx4939_rtc_cmd(rtcreg,
- TX4939_RTCCTL_COMMAND_GETTIME |
- (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
- if (ret) {
- spin_unlock_irq(&pdata->lock);
- return ret;
- }
- __raw_writel(2, &rtcreg->adr);
- for (i = 2; i < 6; i++)
- buf[i] = __raw_readl(&rtcreg->dat);
- spin_unlock_irq(&pdata->lock);
- sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
- (buf[3] << 8) | buf[2];
- rtc_time64_to_tm(sec, tm);
- return 0;
-}
-
-static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
- struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
- int i, ret;
- unsigned long sec;
- unsigned char buf[6];
-
- sec = rtc_tm_to_time64(&alrm->time);
- buf[0] = 0;
- buf[1] = 0;
- buf[2] = sec;
- buf[3] = sec >> 8;
- buf[4] = sec >> 16;
- buf[5] = sec >> 24;
- spin_lock_irq(&pdata->lock);
- __raw_writel(0, &rtcreg->adr);
- for (i = 0; i < 6; i++)
- __raw_writel(buf[i], &rtcreg->dat);
- ret = tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_SETALARM |
- (alrm->enabled ? TX4939_RTCCTL_ALME : 0));
- spin_unlock_irq(&pdata->lock);
- return ret;
-}
-
-static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
- struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
- int i, ret;
- unsigned long sec;
- unsigned char buf[6];
- u32 ctl;
-
- spin_lock_irq(&pdata->lock);
- ret = tx4939_rtc_cmd(rtcreg,
- TX4939_RTCCTL_COMMAND_GETALARM |
- (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
- if (ret) {
- spin_unlock_irq(&pdata->lock);
- return ret;
- }
- __raw_writel(2, &rtcreg->adr);
- for (i = 2; i < 6; i++)
- buf[i] = __raw_readl(&rtcreg->dat);
- ctl = __raw_readl(&rtcreg->ctl);
- alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0;
- alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0;
- spin_unlock_irq(&pdata->lock);
- sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
- (buf[3] << 8) | buf[2];
- rtc_time64_to_tm(sec, &alrm->time);
- return rtc_valid_tm(&alrm->time);
-}
-
-static int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
-{
- struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
-
- spin_lock_irq(&pdata->lock);
- tx4939_rtc_cmd(pdata->rtcreg,
- TX4939_RTCCTL_COMMAND_NOP |
- (enabled ? TX4939_RTCCTL_ALME : 0));
- spin_unlock_irq(&pdata->lock);
- return 0;
-}
-
-static irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id)
-{
- struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev_id);
- struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
- unsigned long events = RTC_IRQF;
-
- spin_lock(&pdata->lock);
- if (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALMD) {
- events |= RTC_AF;
- tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP);
- }
- spin_unlock(&pdata->lock);
- rtc_update_irq(pdata->rtc, 1, events);
-
- return IRQ_HANDLED;
-}
-
-static const struct rtc_class_ops tx4939_rtc_ops = {
- .read_time = tx4939_rtc_read_time,
- .read_alarm = tx4939_rtc_read_alarm,
- .set_alarm = tx4939_rtc_set_alarm,
- .set_time = tx4939_rtc_set_time,
- .alarm_irq_enable = tx4939_rtc_alarm_irq_enable,
-};
-
-static int tx4939_nvram_read(void *priv, unsigned int pos, void *val,
- size_t bytes)
-{
- struct tx4939rtc_plat_data *pdata = priv;
- struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
- u8 *buf = val;
-
- spin_lock_irq(&pdata->lock);
- for (; bytes; bytes--) {
- __raw_writel(pos++, &rtcreg->adr);
- *buf++ = __raw_readl(&rtcreg->dat);
- }
- spin_unlock_irq(&pdata->lock);
- return 0;
-}
-
-static int tx4939_nvram_write(void *priv, unsigned int pos, void *val,
- size_t bytes)
-{
- struct tx4939rtc_plat_data *pdata = priv;
- struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
- u8 *buf = val;
-
- spin_lock_irq(&pdata->lock);
- for (; bytes; bytes--) {
- __raw_writel(pos++, &rtcreg->adr);
- __raw_writel(*buf++, &rtcreg->dat);
- }
- spin_unlock_irq(&pdata->lock);
- return 0;
-}
-
-static int __init tx4939_rtc_probe(struct platform_device *pdev)
-{
- struct rtc_device *rtc;
- struct tx4939rtc_plat_data *pdata;
- int irq, ret;
- struct nvmem_config nvmem_cfg = {
- .name = "tx4939_nvram",
- .size = TX4939_RTC_REG_RAMSIZE,
- .reg_read = tx4939_nvram_read,
- .reg_write = tx4939_nvram_write,
- };
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return -ENODEV;
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
- platform_set_drvdata(pdev, pdata);
-
- pdata->rtcreg = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(pdata->rtcreg))
- return PTR_ERR(pdata->rtcreg);
-
- spin_lock_init(&pdata->lock);
- tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
- if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt,
- 0, pdev->name, &pdev->dev) < 0)
- return -EBUSY;
- rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(rtc))
- return PTR_ERR(rtc);
-
- rtc->ops = &tx4939_rtc_ops;
- rtc->nvram_old_abi = true;
- rtc->range_max = U32_MAX;
-
- pdata->rtc = rtc;
-
- nvmem_cfg.priv = pdata;
- ret = rtc_nvmem_register(rtc, &nvmem_cfg);
- if (ret)
- return ret;
-
- return rtc_register_device(rtc);
-}
-
-static int __exit tx4939_rtc_remove(struct platform_device *pdev)
-{
- struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
- spin_lock_irq(&pdata->lock);
- tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
- spin_unlock_irq(&pdata->lock);
- return 0;
-}
-
-static struct platform_driver tx4939_rtc_driver = {
- .remove = __exit_p(tx4939_rtc_remove),
- .driver = {
- .name = "tx4939rtc",
- },
-};
-
-module_platform_driver_probe(tx4939_rtc_driver, tx4939_rtc_probe);
-
-MODULE_AUTHOR("Atsushi Nemoto <[email protected]>");
-MODULE_DESCRIPTION("TX4939 internal RTC driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tx4939rtc");
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index c3671043ace7..5a9f9ad86d32 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -335,7 +335,7 @@ static int rtc_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Real Time Clock of NEC VR4100 series\n");
- retval = rtc_register_device(rtc);
+ retval = devm_rtc_register_device(rtc);
if (retval)
goto err_iounmap_all;
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c
index e2588625025f..197b649cd629 100644
--- a/drivers/rtc/rtc-vt8500.c
+++ b/drivers/rtc/rtc-vt8500.c
@@ -232,7 +232,7 @@ static int vt8500_rtc_probe(struct platform_device *pdev)
return ret;
}
- return rtc_register_device(vt8500_rtc->rtc);
+ return devm_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 ff46066a68a4..2a205a646452 100644
--- a/drivers/rtc/rtc-wilco-ec.c
+++ b/drivers/rtc/rtc-wilco-ec.c
@@ -176,7 +176,7 @@ static int wilco_ec_rtc_probe(struct platform_device *pdev)
rtc->range_max = RTC_TIMESTAMP_END_2099;
rtc->owner = THIS_MODULE;
- return rtc_register_device(rtc);
+ return devm_rtc_register_device(rtc);
}
static struct platform_driver wilco_ec_rtc_driver = {
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c
index ccef887d2690..640833e21057 100644
--- a/drivers/rtc/rtc-wm831x.c
+++ b/drivers/rtc/rtc-wm831x.c
@@ -429,7 +429,7 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
wm831x_rtc->rtc->ops = &wm831x_rtc_ops;
wm831x_rtc->rtc->range_max = U32_MAX;
- ret = rtc_register_device(wm831x_rtc->rtc);
+ ret = devm_rtc_register_device(wm831x_rtc->rtc);
if (ret)
return ret;
diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c
index 96db441f92b3..cf68a9b1c9eb 100644
--- a/drivers/rtc/rtc-xgene.c
+++ b/drivers/rtc/rtc-xgene.c
@@ -185,7 +185,7 @@ static int xgene_rtc_probe(struct platform_device *pdev)
pdata->rtc->ops = &xgene_rtc_ops;
pdata->rtc->range_max = U32_MAX;
- ret = rtc_register_device(pdata->rtc);
+ ret = devm_rtc_register_device(pdata->rtc);
if (ret) {
clk_disable_unprepare(pdata->clk);
return ret;
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
index 4b1077e2f826..f440bb52be92 100644
--- a/drivers/rtc/rtc-zynqmp.c
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -264,7 +264,7 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
- return rtc_register_device(xrtcdev->rtc);
+ return devm_rtc_register_device(xrtcdev->rtc);
}
static int xlnx_rtc_remove(struct platform_device *pdev)
diff --git a/drivers/rtc/sysfs.c b/drivers/rtc/sysfs.c
index 950fac0d41ff..8a957d31a1a4 100644
--- a/drivers/rtc/sysfs.c
+++ b/drivers/rtc/sysfs.c
@@ -317,8 +317,6 @@ int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
size_t old_cnt = 0, add_cnt = 0, new_cnt;
const struct attribute_group **groups, **old;
- if (rtc->registered)
- return -EINVAL;
if (!grps)
return -EINVAL;
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
deleted file mode 100644
index 8b70f0520e13..000000000000
--- a/drivers/rtc/systohc.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/rtc.h>
-#include <linux/time.h>
-
-/**
- * rtc_set_ntp_time - Save NTP synchronized time to the RTC
- * @now: Current time of day
- * @target_nsec: pointer for desired now->tv_nsec value
- *
- * Replacement for the NTP platform function update_persistent_clock64
- * that stores time for later retrieval by rtc_hctosys.
- *
- * Returns 0 on successful RTC update, -ENODEV if a RTC update is not
- * possible at all, and various other -errno for specific temporary failure
- * cases.
- *
- * -EPROTO is returned if now.tv_nsec is not close enough to *target_nsec.
- *
- * If temporary failure is indicated the caller should try again 'soon'
- */
-int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec)
-{
- struct rtc_device *rtc;
- struct rtc_time tm;
- struct timespec64 to_set;
- int err = -ENODEV;
- bool ok;
-
- rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE);
- if (!rtc)
- goto out_err;
-
- if (!rtc->ops || !rtc->ops->set_time)
- goto out_close;
-
- /* Compute the value of tv_nsec we require the caller to supply in
- * now.tv_nsec. This is the value such that (now +
- * set_offset_nsec).tv_nsec == 0.
- */
- set_normalized_timespec64(&to_set, 0, -rtc->set_offset_nsec);
- *target_nsec = to_set.tv_nsec;
-
- /* The ntp code must call this with the correct value in tv_nsec, if
- * it does not we update target_nsec and return EPROTO to make the ntp
- * code try again later.
- */
- ok = rtc_tv_nsec_ok(rtc->set_offset_nsec, &to_set, &now);
- if (!ok) {
- err = -EPROTO;
- goto out_close;
- }
-
- rtc_time64_to_tm(to_set.tv_sec, &tm);
-
- err = rtc_set_time(rtc, &tm);
-
-out_close:
- rtc_class_close(rtc);
-out_err:
- return err;
-}