summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-01-01 13:24:31 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-01-01 13:24:31 -0800
commit28e8c4bc8eb483c22d977e147a0b98fc63efadf7 (patch)
tree8006dd759601c70d4dd1fc644ed817e9597cec55
parentc9bef4a651769927445900564781a9c99fdf6258 (diff)
parent36e14f5fdfdf7cec8887b7ff69cd9bb5051ecf62 (diff)
Merge tag 'rtc-4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni: "Subsystem: - new %ptR printk format - rename core files - allow registration of multiple nvmem devices New driver: - i.MX system controller RTC Driver updates: - abx80x: handle voltage ioctls, correct binding doc - m41t80: correct month in alarm reads - pcf85363: add pcf85263 support - pcf8523: properly handle battery low flag - s3c: limit alarm to one year in the future as ALMYEAR is broken - sun6i: rework clock output binding" * tag 'rtc-4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (54 commits) rtc: rename core files rtc: nvmem: fix possible use after free rtc: add i.MX system controller RTC support dt-bindings: fsl: scu: add rtc binding rtc: pcf2123: Add Microcrystal rv2123 rtc: class: reimplement devm_rtc_device_register rtc: enforce rtc_timer_init private_data type rtc: abx80x: Implement RTC_VL_READ,CLR ioctls rtc: pcf85363: Add support for NXP pcf85263 rtc dt-bindings: rtc: pcf85363: Document pcf85263 real-time clock rtc: pcf8523: don't return invalid date when battery is low dt-bindings: rtc: use a generic node name for ds1307 PM: Switch to use %ptR m68k/mac: Switch to use %ptR Input: hp_sdc_rtc - Switch to use %ptR rtc: tegra: Switch to use %ptR rtc: s5m: Switch to use %ptR rtc: s3c: Switch to use %ptR rtc: rx8025: Switch to use %ptR rtc: rx6110: Switch to use %ptR ...
-rw-r--r--Documentation/core-api/printk-formats.rst18
-rw-r--r--Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt10
-rw-r--r--Documentation/devicetree/bindings/rtc/abracon,abx80x.txt2
-rw-r--r--Documentation/devicetree/bindings/rtc/nxp,rtc-2123.txt1
-rw-r--r--Documentation/devicetree/bindings/rtc/pcf85363.txt4
-rw-r--r--Documentation/devicetree/bindings/rtc/rtc-ds1307.txt2
-rw-r--r--Documentation/devicetree/bindings/rtc/sun6i-rtc.txt33
-rw-r--r--arch/m68k/mac/misc.c8
-rw-r--r--drivers/base/power/trace.c4
-rw-r--r--drivers/char/rtc.c7
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c8
-rw-r--r--drivers/rtc/Kconfig7
-rw-r--r--drivers/rtc/Makefile9
-rw-r--r--drivers/rtc/class.c187
-rw-r--r--drivers/rtc/dev.c (renamed from drivers/rtc/rtc-dev.c)0
-rw-r--r--drivers/rtc/hctosys.c8
-rw-r--r--drivers/rtc/interface.c27
-rw-r--r--drivers/rtc/lib.c (renamed from drivers/rtc/rtc-lib.c)0
-rw-r--r--drivers/rtc/nvmem.c38
-rw-r--r--drivers/rtc/proc.c (renamed from drivers/rtc/rtc-proc.c)36
-rw-r--r--drivers/rtc/rtc-abx80x.c38
-rw-r--r--drivers/rtc/rtc-at91rm9200.c15
-rw-r--r--drivers/rtc/rtc-at91sam9.c16
-rw-r--r--drivers/rtc/rtc-ep93xx.c2
-rw-r--r--drivers/rtc/rtc-imx-sc.c91
-rw-r--r--drivers/rtc/rtc-isl1208.c37
-rw-r--r--drivers/rtc/rtc-m41t80.c21
-rw-r--r--drivers/rtc/rtc-m48t59.c8
-rw-r--r--drivers/rtc/rtc-max6916.c2
-rw-r--r--drivers/rtc/rtc-max77686.c2
-rw-r--r--drivers/rtc/rtc-max8997.c2
-rw-r--r--drivers/rtc/rtc-mcp795.c18
-rw-r--r--drivers/rtc/rtc-omap.c4
-rw-r--r--drivers/rtc/rtc-pcf2123.c1
-rw-r--r--drivers/rtc/rtc-pcf50633.c8
-rw-r--r--drivers/rtc/rtc-pcf8523.c32
-rw-r--r--drivers/rtc/rtc-pcf85363.c94
-rw-r--r--drivers/rtc/rtc-pic32.c18
-rw-r--r--drivers/rtc/rtc-pm8xxx.c16
-rw-r--r--drivers/rtc/rtc-puv3.c18
-rw-r--r--drivers/rtc/rtc-rk808.c22
-rw-r--r--drivers/rtc/rtc-rx6110.c12
-rw-r--r--drivers/rtc/rtc-rx8025.c19
-rw-r--r--drivers/rtc/rtc-s3c.c26
-rw-r--r--drivers/rtc/rtc-s5m.c27
-rw-r--r--drivers/rtc/rtc-sh.c7
-rw-r--r--drivers/rtc/rtc-sun6i.c121
-rw-r--r--drivers/rtc/rtc-tegra.c30
-rw-r--r--drivers/rtc/sysfs.c (renamed from drivers/rtc/rtc-sysfs.c)16
-rw-r--r--include/linux/rtc.h17
-rw-r--r--lib/test_printf.c61
-rw-r--r--lib/vsprintf.c100
52 files changed, 744 insertions, 566 deletions
diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
index ff48b55040ef..a7fae4538946 100644
--- a/Documentation/core-api/printk-formats.rst
+++ b/Documentation/core-api/printk-formats.rst
@@ -412,6 +412,24 @@ Examples::
Passed by reference.
+Time and date (struct rtc_time)
+-------------------------------
+
+::
+
+ %ptR YYYY-mm-ddTHH:MM:SS
+ %ptRd YYYY-mm-dd
+ %ptRt HH:MM:SS
+ %ptR[dt][r]
+
+For printing date and time as represented by struct rtc_time structure in
+human readable format.
+
+By default year will be incremented by 1900 and month by 1. Use %ptRr (raw)
+to suppress this behaviour.
+
+Passed by reference.
+
struct clk
----------
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
index 0af618b6a448..27784b6edfed 100644
--- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
@@ -109,6 +109,12 @@ Required properties for Pinctrl sub nodes:
[2] Documentation/devicetree/bindings/power/power_domain.txt
[3] Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
+RTC bindings based on SCU Message Protocol
+------------------------------------------------------------
+
+Required properties:
+- compatible: should be "fsl,imx8qxp-sc-rtc";
+
Example (imx8qxp):
-------------
lsio_mu1: mailbox@5d1c0000 {
@@ -151,6 +157,10 @@ firmware {
compatible = "fsl,imx8qxp-scu-pd";
#power-domain-cells = <1>;
};
+
+ rtc: rtc {
+ compatible = "fsl,imx8qxp-sc-rtc";
+ };
};
};
diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
index be789685a1c2..18b892d010d8 100644
--- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
+++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
@@ -27,4 +27,4 @@ and valid to enable charging:
- "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
- "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
- resistor, the other values are in ohm.
+ resistor, the other values are in kOhm.
diff --git a/Documentation/devicetree/bindings/rtc/nxp,rtc-2123.txt b/Documentation/devicetree/bindings/rtc/nxp,rtc-2123.txt
index 811124a36d16..1994f601800a 100644
--- a/Documentation/devicetree/bindings/rtc/nxp,rtc-2123.txt
+++ b/Documentation/devicetree/bindings/rtc/nxp,rtc-2123.txt
@@ -2,6 +2,7 @@ NXP PCF2123 SPI Real Time Clock
Required properties:
- compatible: should be: "nxp,rtc-pcf2123"
+ or "microcrystal,rv2123"
- reg: should be the SPI slave chipselect address
Optional properties:
diff --git a/Documentation/devicetree/bindings/rtc/pcf85363.txt b/Documentation/devicetree/bindings/rtc/pcf85363.txt
index 76fdabc59742..94adc1cf93d9 100644
--- a/Documentation/devicetree/bindings/rtc/pcf85363.txt
+++ b/Documentation/devicetree/bindings/rtc/pcf85363.txt
@@ -1,8 +1,8 @@
-NXP PCF85363 Real Time Clock
+NXP PCF85263/PCF85363 Real Time Clock
============================
Required properties:
-- compatible: Should contain "nxp,pcf85363".
+- compatible: Should contain "nxp,pcf85263" or "nxp,pcf85363".
- reg: I2C address for chip.
Optional properties:
diff --git a/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt b/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt
index eebfbe04207a..eaee19b60960 100644
--- a/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt
+++ b/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt
@@ -35,7 +35,7 @@ Optional properties:
Should be given if internal trickle charger diode should be disabled
Example:
- rtc1: ds1339@68 {
+ ds1339: rtc@68 {
compatible = "dallas,ds1339";
reg = <0x68>;
interrupt-parent = <&gpio4>;
diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
index 12c083c1140a..6b732c41392b 100644
--- a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
@@ -3,25 +3,44 @@
RTC controller for the Allwinner A31
Required properties:
-- compatible : Should be "allwinner,sun6i-a31-rtc"
+- compatible : Should be one of the following combinations:
+ - "allwinner,sun6i-a31-rtc"
+ - "allwinner,sun8i-a23-rtc"
+ - "allwinner,sun8i-h3-rtc"
+ - "allwinner,sun8i-r40-rtc", "allwinner,sun8i-h3-rtc"
+ - "allwinner,sun8i-v3-rtc"
+ - "allwinner,sun50i-a64-rtc", "allwinner,sun8i-h3-rtc"
+ - "allwinner,sun50i-h5-rtc"
+
+ Where there are two or more compatible strings, this
+ denotes the hardware covered by the most specific one
+ is backward-compatible with the latter ones, and the
+ implementation for the latter ones can be used, albeit
+ with reduced functionality.
+
- reg : physical base address of the controller and length of
memory mapped region.
- interrupts : IRQ lines for the RTC alarm 0 and alarm 1, in that order.
Required properties for new device trees
- clocks : phandle to the 32kHz external oscillator
-- clock-output-names : names of the LOSC and its external output clocks created
-- #clock-cells : must be equals to 1. The RTC provides two clocks: the
- LOSC and its external output, with index 0 and 1
- respectively.
+- clock-output-names : names of up to three clock outputs. See below.
+- #clock-cells : must be equal to 1.
+
+The RTC provides the following clocks at the given indices:
+- 0: LOSC
+- 1: LOSC external output, known as X32KFOUT in the datasheet.
+ This clock is not available on the A31 and is deprecated for old
+ device trees still using the "allwinner,sun6i-a31-rtc" compatible.
+- 2: InternalOSC, or internal RC oscillator (A64/H3/H5 only)
Example:
rtc: rtc@1f00000 {
compatible = "allwinner,sun6i-a31-rtc";
- reg = <0x01f00000 0x54>;
+ reg = <0x01f00000 0x400>;
interrupts = <0 40 4>, <0 41 4>;
- clock-output-names = "osc32k", "osc32k-out";
+ clock-output-names = "osc32k";
clocks = <&ext_osc32k>;
#clock-cells = <1>;
};
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index ebb3b6d169ea..71c4735a31ee 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -605,13 +605,9 @@ int mac_hwclk(int op, struct rtc_time *t)
unmktime(now, 0,
&t->tm_year, &t->tm_mon, &t->tm_mday,
&t->tm_hour, &t->tm_min, &t->tm_sec);
- pr_debug("%s: read %04d-%02d-%-2d %02d:%02d:%02d\n",
- __func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
- t->tm_hour, t->tm_min, t->tm_sec);
+ pr_debug("%s: read %ptR\n", __func__, t);
} else { /* write */
- pr_debug("%s: tried to write %04d-%02d-%-2d %02d:%02d:%02d\n",
- __func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
- t->tm_hour, t->tm_min, t->tm_sec);
+ pr_debug("%s: tried to write %ptR\n", __func__, t);
switch (macintosh_config->adb_type) {
case MAC_ADB_IOP:
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c
index 1cda505d6a85..b11f47a1e819 100644
--- a/drivers/base/power/trace.c
+++ b/drivers/base/power/trace.c
@@ -118,9 +118,7 @@ static unsigned int read_magic_time(void)
unsigned int val;
mc146818_get_time(&time);
- pr_info("RTC time: %2d:%02d:%02d, date: %02d/%02d/%02d\n",
- time.tm_hour, time.tm_min, time.tm_sec,
- time.tm_mon + 1, time.tm_mday, time.tm_year % 100);
+ pr_info("RTC time: %ptRt, date: %ptRd\n", &time, &time);
val = time.tm_year; /* 100 years */
if (val > 100)
val -= 100;
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 62b7c721c732..c862d0b6b118 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -1125,11 +1125,10 @@ static int rtc_proc_show(struct seq_file *seq, void *v)
* time or for Universal Standard Time (GMT). Probably local though.
*/
seq_printf(seq,
- "rtc_time\t: %02d:%02d:%02d\n"
- "rtc_date\t: %04d-%02d-%02d\n"
+ "rtc_time\t: %ptRt\n"
+ "rtc_date\t: %ptRd\n"
"rtc_epoch\t: %04lu\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
+ &tm, &tm, epoch);
get_rtc_alm_time(&tm);
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index 47eb8ca729fe..abca895a6156 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -441,12 +441,10 @@ static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v)
seq_puts(m, "BBRTC\t\t: READ FAILED!\n");
} else {
seq_printf(m,
- "rtc_time\t: %02d:%02d:%02d\n"
- "rtc_date\t: %04d-%02d-%02d\n"
+ "rtc_time\t: %ptRt\n"
+ "rtc_date\t: %ptRd\n"
"rtc_epoch\t: %04lu\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- tm.tm_year + 1900, tm.tm_mon + 1,
- tm.tm_mday, epoch);
+ &tm, &tm, epoch);
}
if (hp_sdc_rtc_read_rt(&tv)) {
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index a819ef07b7ec..225b0b8516f3 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1677,6 +1677,13 @@ config RTC_DRV_SNVS
This driver can also be built as a module, if so, the module
will be called "rtc-snvs".
+config RTC_DRV_IMX_SC
+ depends on IMX_SCU
+ tristate "NXP i.MX System Controller RTC support"
+ help
+ 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
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 290c1730fb0a..df022d820bee 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -5,7 +5,7 @@
ccflags-$(CONFIG_RTC_DEBUG) := -DDEBUG
-obj-$(CONFIG_RTC_LIB) += rtc-lib.o
+obj-$(CONFIG_RTC_LIB) += lib.o
obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
obj-$(CONFIG_RTC_SYSTOHC) += systohc.o
obj-$(CONFIG_RTC_CLASS) += rtc-core.o
@@ -17,9 +17,9 @@ rtc-core-y += rtc-efi-platform.o
endif
rtc-core-$(CONFIG_RTC_NVMEM) += nvmem.o
-rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
-rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
-rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
+rtc-core-$(CONFIG_RTC_INTF_DEV) += dev.o
+rtc-core-$(CONFIG_RTC_INTF_PROC) += proc.o
+rtc-core-$(CONFIG_RTC_INTF_SYSFS) += sysfs.o
# Keep the list ordered.
@@ -75,6 +75,7 @@ obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o
obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o
obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o
+obj-$(CONFIG_RTC_DRV_IMX_SC) += rtc-imx-sc.o
obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 3b43787f154b..ac93b76f2b11 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -178,9 +178,9 @@ static struct rtc_device *rtc_allocate_device(void)
timerqueue_init_head(&rtc->timerqueue);
INIT_WORK(&rtc->irqwork, rtc_timer_do_work);
/* Init aie timer */
- rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc);
+ rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, rtc);
/* Init uie timer */
- rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc);
+ rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, rtc);
/* Init pie timer */
hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
rtc->pie_timer.function = rtc_pie_update_irq;
@@ -278,82 +278,6 @@ static void rtc_device_get_offset(struct rtc_device *rtc)
}
/**
- * rtc_device_register - register w/ RTC class
- * @dev: the device to register
- *
- * rtc_device_unregister() must be called when the class device is no
- * longer needed.
- *
- * Returns the pointer to the new struct class device.
- */
-static struct rtc_device *rtc_device_register(const char *name,
- struct device *dev,
- const struct rtc_class_ops *ops,
- struct module *owner)
-{
- struct rtc_device *rtc;
- struct rtc_wkalrm alrm;
- int id, err;
-
- id = rtc_device_get_id(dev);
- if (id < 0) {
- err = id;
- goto exit;
- }
-
- rtc = rtc_allocate_device();
- if (!rtc) {
- err = -ENOMEM;
- goto exit_ida;
- }
-
- rtc->id = id;
- rtc->ops = ops;
- rtc->owner = owner;
- rtc->dev.parent = dev;
-
- dev_set_name(&rtc->dev, "rtc%d", id);
-
- rtc_device_get_offset(rtc);
-
- /* Check to see if there is an ALARM already set in hw */
- err = __rtc_read_alarm(rtc, &alrm);
-
- if (!err && !rtc_valid_tm(&alrm.time))
- rtc_initialize_alarm(rtc, &alrm);
-
- rtc_dev_prepare(rtc);
-
- err = cdev_device_add(&rtc->char_dev, &rtc->dev);
- if (err) {
- dev_warn(&rtc->dev, "%s: failed to add char device %d:%d\n",
- name, MAJOR(rtc->dev.devt), rtc->id);
-
- /* This will free both memory and the ID */
- put_device(&rtc->dev);
- goto exit;
- } else {
- dev_dbg(&rtc->dev, "%s: dev (%d:%d)\n", name,
- MAJOR(rtc->dev.devt), rtc->id);
- }
-
- rtc_proc_add_device(rtc);
-
- dev_info(dev, "rtc core: registered %s as %s\n",
- name, dev_name(&rtc->dev));
-
- return rtc;
-
-exit_ida:
- ida_simple_remove(&rtc_ida, id);
-
-exit:
- dev_err(dev, "rtc core: unable to register %s, err = %d\n",
- name, err);
- return ERR_PTR(err);
-}
-
-/**
* rtc_device_unregister - removes the previously registered RTC class device
*
* @rtc: the RTC class device to destroy
@@ -372,77 +296,6 @@ static void rtc_device_unregister(struct rtc_device *rtc)
put_device(&rtc->dev);
}
-static void devm_rtc_device_release(struct device *dev, void *res)
-{
- struct rtc_device *rtc = *(struct rtc_device **)res;
-
- rtc_nvmem_unregister(rtc);
- rtc_device_unregister(rtc);
-}
-
-static int devm_rtc_device_match(struct device *dev, void *res, void *data)
-{
- struct rtc **r = res;
-
- return *r == data;
-}
-
-/**
- * devm_rtc_device_register - resource managed rtc_device_register()
- * @dev: the device to register
- * @name: the name of the device
- * @ops: the rtc operations structure
- * @owner: the module owner
- *
- * @return a struct rtc on success, or an ERR_PTR on error
- *
- * Managed rtc_device_register(). The rtc_device returned from this function
- * are automatically freed on driver detach. See rtc_device_register()
- * for more information.
- */
-
-struct rtc_device *devm_rtc_device_register(struct device *dev,
- const char *name,
- const struct rtc_class_ops *ops,
- struct module *owner)
-{
- struct rtc_device **ptr, *rtc;
-
- ptr = devres_alloc(devm_rtc_device_release, sizeof(*ptr), GFP_KERNEL);
- if (!ptr)
- return ERR_PTR(-ENOMEM);
-
- rtc = rtc_device_register(name, dev, ops, owner);
- if (!IS_ERR(rtc)) {
- *ptr = rtc;
- devres_add(dev, ptr);
- } else {
- devres_free(ptr);
- }
-
- return rtc;
-}
-EXPORT_SYMBOL_GPL(devm_rtc_device_register);
-
-/**
- * devm_rtc_device_unregister - resource managed devm_rtc_device_unregister()
- * @dev: the device to unregister
- * @rtc: the RTC class device to unregister
- *
- * Deallocated a rtc allocated with devm_rtc_device_register(). Normally this
- * function will not need to be called and the resource management code will
- * ensure that the resource is freed.
- */
-void devm_rtc_device_unregister(struct device *dev, struct rtc_device *rtc)
-{
- int rc;
-
- rc = devres_release(dev, devm_rtc_device_release,
- devm_rtc_device_match, rtc);
- WARN_ON(rc);
-}
-EXPORT_SYMBOL_GPL(devm_rtc_device_unregister);
-
static void devm_rtc_release_device(struct device *dev, void *res)
{
struct rtc_device *rtc = *(struct rtc_device **)res;
@@ -529,6 +382,42 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
}
EXPORT_SYMBOL_GPL(__rtc_register_device);
+/**
+ * devm_rtc_device_register - resource managed rtc_device_register()
+ * @dev: the device to register
+ * @name: the name of the device (unused)
+ * @ops: the rtc operations structure
+ * @owner: the module owner
+ *
+ * @return a struct rtc on success, or an ERR_PTR on error
+ *
+ * Managed rtc_device_register(). The rtc_device returned from this function
+ * are automatically freed on driver detach.
+ * This function is deprecated, use devm_rtc_allocate_device and
+ * rtc_register_device instead
+ */
+struct rtc_device *devm_rtc_device_register(struct device *dev,
+ const char *name,
+ const struct rtc_class_ops *ops,
+ struct module *owner)
+{
+ struct rtc_device *rtc;
+ int err;
+
+ rtc = devm_rtc_allocate_device(dev);
+ if (IS_ERR(rtc))
+ return rtc;
+
+ rtc->ops = ops;
+
+ err = __rtc_register_device(owner, rtc);
+ if (err)
+ return ERR_PTR(err);
+
+ return rtc;
+}
+EXPORT_SYMBOL_GPL(devm_rtc_device_register);
+
static int __init rtc_init(void)
{
rtc_class = class_create(THIS_MODULE, "rtc");
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/dev.c
index 43d962a9c210..43d962a9c210 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/dev.c
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
index b9ec4a16db1f..ff2092a0d38c 100644
--- a/drivers/rtc/hctosys.c
+++ b/drivers/rtc/hctosys.c
@@ -58,12 +58,8 @@ static int __init rtc_hctosys(void)
err = do_settimeofday64(&tv64);
- dev_info(rtc->dev.parent,
- "setting system clock to "
- "%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- (long long) tv64.tv_sec);
+ dev_info(rtc->dev.parent, "setting system clock to %ptR UTC (%lld)\n",
+ &tm, (long long)tv64.tv_sec);
err_read:
rtc_class_close(rtc);
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 612a83d3ddcc..98d9c87b0d1b 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -368,12 +368,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
err = rtc_valid_tm(&alarm->time);
done:
- if (err) {
- dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n",
- alarm->time.tm_year + 1900, alarm->time.tm_mon + 1,
- alarm->time.tm_mday, alarm->time.tm_hour, alarm->time.tm_min,
- alarm->time.tm_sec);
- }
+ if (err)
+ dev_warn(&rtc->dev, "invalid alarm value: %ptR\n", &alarm->time);
return err;
}
@@ -613,26 +609,24 @@ void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
/**
* rtc_aie_update_irq - AIE mode rtctimer hook
- * @private: pointer to the rtc_device
+ * @rtc: pointer to the rtc_device
*
* This functions is called when the aie_timer expires.
*/
-void rtc_aie_update_irq(void *private)
+void rtc_aie_update_irq(struct rtc_device *rtc)
{
- struct rtc_device *rtc = (struct rtc_device *)private;
rtc_handle_legacy_irq(rtc, 1, RTC_AF);
}
/**
* rtc_uie_update_irq - UIE mode rtctimer hook
- * @private: pointer to the rtc_device
+ * @rtc: pointer to the rtc_device
*
* This functions is called when the uie_timer expires.
*/
-void rtc_uie_update_irq(void *private)
+void rtc_uie_update_irq(struct rtc_device *rtc)
{
- struct rtc_device *rtc = (struct rtc_device *)private;
rtc_handle_legacy_irq(rtc, 1, RTC_UF);
}
@@ -912,7 +906,7 @@ again:
trace_rtc_timer_dequeue(timer);
timer->enabled = 0;
if (timer->func)
- timer->func(timer->private_data);
+ timer->func(timer->rtc);
trace_rtc_timer_fired(timer);
/* Re-add/fwd periodic timers */
@@ -959,16 +953,17 @@ reprogram:
/* rtc_timer_init - Initializes an rtc_timer
* @timer: timer to be intiialized
* @f: function pointer to be called when timer fires
- * @data: private data passed to function pointer
+ * @rtc: pointer to the rtc_device
*
* Kernel interface to initializing an rtc_timer.
*/
-void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data)
+void rtc_timer_init(struct rtc_timer *timer, void (*f)(struct rtc_device *r),
+ struct rtc_device *rtc)
{
timerqueue_init(&timer->node);
timer->enabled = 0;
timer->func = f;
- timer->private_data = data;
+ timer->rtc = rtc;
}
/* rtc_timer_start - Sets an rtc_timer to fire in the future
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/lib.c
index ef160da84220..ef160da84220 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/lib.c
diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c
index 36ab183c42f1..dce518d5e50e 100644
--- a/drivers/rtc/nvmem.c
+++ b/drivers/rtc/nvmem.c
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/nvmem-consumer.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
#include <linux/sysfs.h>
/*
@@ -25,11 +26,9 @@ rtc_nvram_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
- struct rtc_device *rtc = attr->private;
-
dev_warn_once(kobj_to_dev(kobj), nvram_warning);
- return nvmem_device_read(rtc->nvmem, off, count, buf);
+ return nvmem_device_read(attr->private, off, count, buf);
}
static ssize_t
@@ -37,26 +36,23 @@ rtc_nvram_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
- struct rtc_device *rtc = attr->private;
-
dev_warn_once(kobj_to_dev(kobj), nvram_warning);
- return nvmem_device_write(rtc->nvmem, off, count, buf);
+ return nvmem_device_write(attr->private, off, count, buf);
}
-static int rtc_nvram_register(struct rtc_device *rtc, size_t size)
+static int rtc_nvram_register(struct rtc_device *rtc,
+ struct nvmem_device *nvmem, size_t size)
{
int err;
- rtc->nvram = devm_kzalloc(rtc->dev.parent,
- sizeof(struct bin_attribute),
- GFP_KERNEL);
+ rtc->nvram = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL);
if (!rtc->nvram)
return -ENOMEM;
rtc->nvram->attr.name = "nvram";
rtc->nvram->attr.mode = 0644;
- rtc->nvram->private = rtc;
+ rtc->nvram->private = nvmem;
sysfs_bin_attr_init(rtc->nvram);
@@ -67,7 +63,7 @@ static int rtc_nvram_register(struct rtc_device *rtc, size_t size)
err = sysfs_create_bin_file(&rtc->dev.parent->kobj,
rtc->nvram);
if (err) {
- devm_kfree(rtc->dev.parent, rtc->nvram);
+ kfree(rtc->nvram);
rtc->nvram = NULL;
}
@@ -77,6 +73,8 @@ static int rtc_nvram_register(struct rtc_device *rtc, size_t size)
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;
}
/*
@@ -85,21 +83,20 @@ static void rtc_nvram_unregister(struct rtc_device *rtc)
int rtc_nvmem_register(struct rtc_device *rtc,
struct nvmem_config *nvmem_config)
{
- if (!IS_ERR_OR_NULL(rtc->nvmem))
- return -EBUSY;
+ struct nvmem_device *nvmem;
if (!nvmem_config)
return -ENODEV;
nvmem_config->dev = rtc->dev.parent;
nvmem_config->owner = rtc->owner;
- rtc->nvmem = nvmem_register(nvmem_config);
- if (IS_ERR(rtc->nvmem))
- return PTR_ERR(rtc->nvmem);
+ nvmem = devm_nvmem_register(rtc->dev.parent, nvmem_config);
+ if (IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
/* Register the old ABI */
if (rtc->nvram_old_abi)
- rtc_nvram_register(rtc, nvmem_config->size);
+ rtc_nvram_register(rtc, nvmem, nvmem_config->size);
return 0;
}
@@ -107,12 +104,7 @@ EXPORT_SYMBOL_GPL(rtc_nvmem_register);
void rtc_nvmem_unregister(struct rtc_device *rtc)
{
- if (IS_ERR_OR_NULL(rtc->nvmem))
- return;
-
/* unregister the old ABI */
if (rtc->nvram)
rtc_nvram_unregister(rtc);
-
- nvmem_unregister(rtc->nvmem);
}
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/proc.c
index a9dd9218fae2..4d74e4f4ff30 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/proc.c
@@ -50,41 +50,15 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
err = rtc_read_time(rtc, &tm);
if (err == 0) {
seq_printf(seq,
- "rtc_time\t: %02d:%02d:%02d\n"
- "rtc_date\t: %04d-%02d-%02d\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
+ "rtc_time\t: %ptRt\n"
+ "rtc_date\t: %ptRd\n",
+ &tm, &tm);
}
err = rtc_read_alarm(rtc, &alrm);
if (err == 0) {
- seq_printf(seq, "alrm_time\t: ");
- if ((unsigned int)alrm.time.tm_hour <= 24)
- seq_printf(seq, "%02d:", alrm.time.tm_hour);
- else
- seq_printf(seq, "**:");
- if ((unsigned int)alrm.time.tm_min <= 59)
- seq_printf(seq, "%02d:", alrm.time.tm_min);
- else
- seq_printf(seq, "**:");
- if ((unsigned int)alrm.time.tm_sec <= 59)
- seq_printf(seq, "%02d\n", alrm.time.tm_sec);
- else
- seq_printf(seq, "**\n");
-
- seq_printf(seq, "alrm_date\t: ");
- if ((unsigned int)alrm.time.tm_year <= 200)
- seq_printf(seq, "%04d-", alrm.time.tm_year + 1900);
- else
- seq_printf(seq, "****-");
- if ((unsigned int)alrm.time.tm_mon <= 11)
- seq_printf(seq, "%02d-", alrm.time.tm_mon + 1);
- else
- seq_printf(seq, "**-");
- if (alrm.time.tm_mday && (unsigned int)alrm.time.tm_mday <= 31)
- seq_printf(seq, "%02d\n", alrm.time.tm_mday);
- else
- seq_printf(seq, "**\n");
+ seq_printf(seq, "alrm_time\t: %ptRt\n", &alrm.time);
+ seq_printf(seq, "alrm_date\t: %ptRd\n", &alrm.time);
seq_printf(seq, "alarm_IRQ\t: %s\n",
alrm.enabled ? "yes" : "no");
seq_printf(seq, "alrm_pending\t: %s\n",
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c
index d8e94edcb0ba..4d24f7288ad7 100644
--- a/drivers/rtc/rtc-abx80x.c
+++ b/drivers/rtc/rtc-abx80x.c
@@ -38,6 +38,7 @@
#define ABX8XX_REG_STATUS 0x0f
#define ABX8XX_STATUS_AF BIT(2)
+#define ABX8XX_STATUS_BLF BIT(4)
#define ABX8XX_STATUS_WDT BIT(6)
#define ABX8XX_REG_CTRL1 0x10
@@ -507,12 +508,49 @@ static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled)
return err;
}
+static int abx80x_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ int status, tmp;
+
+ switch (cmd) {
+ case RTC_VL_READ:
+ status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
+ if (status < 0)
+ return status;
+
+ tmp = !!(status & ABX8XX_STATUS_BLF);
+
+ if (copy_to_user((void __user *)arg, &tmp, sizeof(int)))
+ return -EFAULT;
+
+ return 0;
+
+ case RTC_VL_CLR:
+ status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
+ if (status < 0)
+ return status;
+
+ status &= ~ABX8XX_STATUS_BLF;
+
+ tmp = i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0);
+ if (tmp < 0)
+ return tmp;
+
+ return 0;
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
static const struct rtc_class_ops abx80x_rtc_ops = {
.read_time = abx80x_rtc_read_time,
.set_time = abx80x_rtc_set_time,
.read_alarm = abx80x_read_alarm,
.set_alarm = abx80x_set_alarm,
.alarm_irq_enable = abx80x_alarm_irq_enable,
+ .ioctl = abx80x_ioctl,
};
static int abx80x_dt_trickle_cfg(struct device_node *np)
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index caa71d04e989..862b993c3142 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -147,9 +147,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm)
tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
tm->tm_year = tm->tm_year - 1900;
- dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "%s(): %ptR\n", __func__, tm);
return 0;
}
@@ -161,9 +159,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
{
unsigned long cr;
- dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "%s(): %ptR\n", __func__, tm);
wait_for_completion(&at91_rtc_upd_rdy);
@@ -209,8 +205,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM)
? 1 : 0;
- dev_dbg(dev, "%s(): %02d-%02d %02d:%02d:%02d %sabled\n", __func__,
- tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
+ dev_dbg(dev, "%s(): %ptR %sabled\n", __func__, tm,
alrm->enabled ? "en" : "dis");
return 0;
@@ -247,9 +242,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
at91_rtc_write_ier(AT91_RTC_ALARM);
}
- dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
- tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
- tm.tm_min, tm.tm_sec);
+ dev_dbg(dev, "%s(): %ptR\n", __func__, &tm);
return 0;
}
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index ee71e647fd43..1d31c0ae6334 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -124,9 +124,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm)
rtc_time_to_tm(offset + secs, tm);
- dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readtime",
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "%s: %ptR\n", __func__, tm);
return 0;
}
@@ -141,9 +139,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
u32 offset, alarm, mr;
unsigned long secs;
- dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "settime",
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "%s: %ptR\n", __func__, tm);
err = rtc_tm_to_time(tm, &secs);
if (err != 0)
@@ -199,9 +195,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
if (alarm != ALARM_DISABLED && offset != 0) {
rtc_time_to_tm(offset + alarm, tm);
- dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readalarm",
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "%s: %ptR\n", __func__, tm);
if (rtt_readl(rtc, MR) & AT91_RTT_ALMIEN)
alrm->enabled = 1;
@@ -242,9 +236,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
if (alrm->enabled)
rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
- dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "setalarm",
- tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
- tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "%s: %ptR\n", __func__, tm);
return 0;
}
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index 694038208745..1932a4f861d1 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -61,7 +61,7 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev);
unsigned long time;
- time = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA);
+ time = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA);
rtc_time_to_tm(time, tm);
return 0;
diff --git a/drivers/rtc/rtc-imx-sc.c b/drivers/rtc/rtc-imx-sc.c
new file mode 100644
index 000000000000..7ff08544532a
--- /dev/null
+++ b/drivers/rtc/rtc-imx-sc.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP.
+ */
+
+#include <linux/firmware/imx/sci.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#define IMX_SC_TIMER_FUNC_GET_RTC_SEC1970 9
+#define IMX_SC_TIMER_FUNC_SET_RTC_TIME 6
+
+static struct imx_sc_ipc *rtc_ipc_handle;
+static struct rtc_device *imx_sc_rtc;
+
+struct imx_sc_msg_timer_get_rtc_time {
+ struct imx_sc_rpc_msg hdr;
+ u32 time;
+} __packed;
+
+static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct imx_sc_msg_timer_get_rtc_time msg;
+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
+ int ret;
+
+ hdr->ver = IMX_SC_RPC_VERSION;
+ hdr->svc = IMX_SC_RPC_SVC_TIMER;
+ hdr->func = IMX_SC_TIMER_FUNC_GET_RTC_SEC1970;
+ hdr->size = 1;
+
+ ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true);
+ if (ret) {
+ dev_err(dev, "read rtc time failed, ret %d\n", ret);
+ return ret;
+ }
+
+ rtc_time_to_tm(msg.time, tm);
+
+ return 0;
+}
+
+static const struct rtc_class_ops imx_sc_rtc_ops = {
+ .read_time = imx_sc_rtc_read_time,
+};
+
+static int imx_sc_rtc_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = imx_scu_get_handle(&rtc_ipc_handle);
+ if (ret)
+ return ret;
+
+ imx_sc_rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(imx_sc_rtc))
+ return PTR_ERR(imx_sc_rtc);
+
+ imx_sc_rtc->ops = &imx_sc_rtc_ops;
+ imx_sc_rtc->range_min = 0;
+ imx_sc_rtc->range_max = U32_MAX;
+
+ ret = rtc_register_device(imx_sc_rtc);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id imx_sc_dt_ids[] = {
+ { .compatible = "fsl,imx8qxp-sc-rtc", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, imx_sc_dt_ids);
+
+static struct platform_driver imx_sc_rtc_driver = {
+ .driver = {
+ .name = "imx-sc-rtc",
+ .of_match_table = imx_sc_dt_ids,
+ },
+ .probe = imx_sc_rtc_probe,
+};
+module_platform_driver(imx_sc_rtc_driver);
+
+MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX System Controller RTC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index ec5ef518a09b..37ab3e1d25f5 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -84,29 +84,13 @@ static int
isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
unsigned len)
{
- u8 reg_addr[1] = { reg };
- struct i2c_msg msgs[2] = {
- {
- .addr = client->addr,
- .len = sizeof(reg_addr),
- .buf = reg_addr
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = len,
- .buf = buf
- }
- };
int ret;
WARN_ON(reg > ISL1219_REG_YRT);
WARN_ON(reg + len > ISL1219_REG_YRT + 1);
- ret = i2c_transfer(client->adapter, msgs, 2);
- if (ret > 0)
- ret = 0;
- return ret;
+ ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf);
+ return (ret < 0) ? ret : 0;
}
/* block write */
@@ -114,26 +98,13 @@ static int
isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
unsigned len)
{
- u8 i2c_buf[ISL1208_REG_USR2 + 2];
- struct i2c_msg msgs[1] = {
- {
- .addr = client->addr,
- .len = len + 1,
- .buf = i2c_buf
- }
- };
int ret;
WARN_ON(reg > ISL1219_REG_YRT);
WARN_ON(reg + len > ISL1219_REG_YRT + 1);
- i2c_buf[0] = reg;
- memcpy(&i2c_buf[1], &buf[0], len);
-
- ret = i2c_transfer(client->adapter, msgs, 1);
- if (ret > 0)
- ret = 0;
- return ret;
+ ret = i2c_smbus_write_i2c_block_data(client, reg, len, buf);
+ return (ret < 0) ? ret : 0;
}
/* simple check to see whether we have a isl1208 */
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index a3fb235fea0d..ebf50b1540f2 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -217,7 +217,7 @@ static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
sizeof(buf), buf);
if (err < 0) {
dev_err(&client->dev, "Unable to read date\n");
- return -EIO;
+ return err;
}
tm->tm_sec = bcd2bin(buf[M41T80_REG_SEC] & 0x7f);
@@ -274,10 +274,11 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
if (flags < 0)
return flags;
- if (i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
- flags & ~M41T80_FLAGS_OF)) {
+ err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
+ flags & ~M41T80_FLAGS_OF);
+ if (err < 0) {
dev_err(&client->dev, "Unable to write flags register\n");
- return -EIO;
+ return err;
}
return err;
@@ -287,10 +288,12 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
{
struct i2c_client *client = to_i2c_client(dev);
struct m41t80_data *clientdata = i2c_get_clientdata(client);
- u8 reg;
+ int reg;
if (clientdata->features & M41T80_FEATURE_BL) {
reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
+ if (reg < 0)
+ return reg;
seq_printf(seq, "battery\t\t: %s\n",
(reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
}
@@ -393,7 +396,7 @@ static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->time.tm_min = bcd2bin(alarmvals[3] & 0x7f);
alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f);
alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f);
- alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f);
+ alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f) - 1;
alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE);
alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled;
@@ -939,11 +942,7 @@ static int m41t80_probe(struct i2c_client *client,
if (m41t80_data->features & M41T80_FEATURE_HT) {
m41t80_rtc_read_time(&client->dev, &tm);
dev_info(&client->dev, "HT bit was set!\n");
- dev_info(&client->dev,
- "Power Down at %04i-%02i-%02i %02i:%02i:%02i\n",
- tm.tm_year + 1900,
- tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
- tm.tm_min, tm.tm_sec);
+ dev_info(&client->dev, "Power Down at %ptR\n", &tm);
}
rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR,
rc & ~M41T80_ALHOUR_HT);
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index ac9ca1042889..3c8ad1cdfd7c 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -99,9 +99,7 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
spin_unlock_irqrestore(&m48t59->lock, flags);
- dev_dbg(dev, "RTC read time %04d-%02d-%02d %02d/%02d/%02d\n",
- tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "RTC read time %ptR\n", tm);
return 0;
}
@@ -188,9 +186,7 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
spin_unlock_irqrestore(&m48t59->lock, flags);
- dev_dbg(dev, "RTC read alarm time %04d-%02d-%02d %02d/%02d/%02d\n",
- tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "RTC read alarm time %ptR\n", tm);
return rtc_valid_tm(tm);
}
diff --git a/drivers/rtc/rtc-max6916.c b/drivers/rtc/rtc-max6916.c
index 7e908a490cf6..9d4b407cc4b8 100644
--- a/drivers/rtc/rtc-max6916.c
+++ b/drivers/rtc/rtc-max6916.c
@@ -86,7 +86,7 @@ static int max6916_set_time(struct device *dev, struct rtc_time *dt)
if (dt->tm_year < 100 || dt->tm_year > 199) {
dev_err(&spi->dev, "Year must be between 2000 and 2099. It's %d.\n",
dt->tm_year + 1900);
- return -EINVAL;
+ return -EINVAL;
}
buf[0] = MAX6916_CLOCK_BURST & 0x7F;
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 8a60900d6b8b..4aff349ae301 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -360,7 +360,7 @@ static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm)
out:
mutex_unlock(&info->lock);
- return 0;
+ return ret;
}
static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c
index 08c661a332ec..20e50d9fdf88 100644
--- a/drivers/rtc/rtc-max8997.c
+++ b/drivers/rtc/rtc-max8997.c
@@ -215,7 +215,7 @@ static int max8997_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
out:
mutex_unlock(&info->lock);
- return 0;
+ return ret;
}
static int max8997_rtc_stop_alarm(struct max8997_rtc_info *info)
diff --git a/drivers/rtc/rtc-mcp795.c b/drivers/rtc/rtc-mcp795.c
index 00e11c1b2186..f22a945a3794 100644
--- a/drivers/rtc/rtc-mcp795.c
+++ b/drivers/rtc/rtc-mcp795.c
@@ -233,9 +233,7 @@ static int mcp795_set_time(struct device *dev, struct rtc_time *tim)
if (ret)
return ret;
- dev_dbg(dev, "Set mcp795: %04d-%02d-%02d(%d) %02d:%02d:%02d\n",
- tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
- tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec);
+ dev_dbg(dev, "Set mcp795: %ptR\n", tim);
return 0;
}
@@ -258,9 +256,7 @@ static int mcp795_read_time(struct device *dev, struct rtc_time *tim)
tim->tm_mon = bcd2bin(data[5] & 0x1F) - 1;
tim->tm_year = bcd2bin(data[6]) + 100; /* Assume we are in 20xx */
- dev_dbg(dev, "Read from mcp795: %04d-%02d-%02d(%d) %02d:%02d:%02d\n",
- tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
- tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec);
+ dev_dbg(dev, "Read from mcp795: %ptR\n", tim);
return 0;
}
@@ -319,9 +315,8 @@ static int mcp795_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
return ret;
dev_dbg(dev, "Alarm IRQ armed\n");
}
- dev_dbg(dev, "Set alarm: %02d-%02d(%d) %02d:%02d:%02d\n",
- alm->time.tm_mon, alm->time.tm_mday, alm->time.tm_wday,
- alm->time.tm_hour, alm->time.tm_min, alm->time.tm_sec);
+ dev_dbg(dev, "Set alarm: %ptRdr(%d) %ptRt\n",
+ &alm->time, alm->time.tm_wday, &alm->time);
return 0;
}
@@ -345,9 +340,8 @@ static int mcp795_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
alm->time.tm_isdst = -1;
alm->time.tm_yday = -1;
- dev_dbg(dev, "Read alarm: %02d-%02d(%d) %02d:%02d:%02d\n",
- alm->time.tm_mon, alm->time.tm_mday, alm->time.tm_wday,
- alm->time.tm_hour, alm->time.tm_min, alm->time.tm_sec);
+ dev_dbg(dev, "Read alarm: %ptRdr(%d) %ptRt\n",
+ &alm->time, alm->time.tm_wday, &alm->time);
return 0;
}
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 320b4a520eb3..bbff0e2deb84 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -566,9 +566,7 @@ static const struct pinctrl_ops rtc_pinctrl_ops = {
.dt_free_map = pinconf_generic_dt_free_map,
};
-enum rtc_pin_config_param {
- PIN_CONFIG_ACTIVE_HIGH = PIN_CONFIG_END + 1,
-};
+#define PIN_CONFIG_ACTIVE_HIGH (PIN_CONFIG_END + 1)
static const struct pinconf_generic_params rtc_params[] = {
{"ti,active-high", PIN_CONFIG_ACTIVE_HIGH, 0},
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
index e5222c5d8223..39da8b214275 100644
--- a/drivers/rtc/rtc-pcf2123.c
+++ b/drivers/rtc/rtc-pcf2123.c
@@ -453,6 +453,7 @@ static int pcf2123_remove(struct spi_device *spi)
#ifdef CONFIG_OF
static const struct of_device_id pcf2123_dt_ids[] = {
{ .compatible = "nxp,rtc-pcf2123", },
+ { .compatible = "microcrystal,rv2123", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, pcf2123_dt_ids);
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
index ef72b0c389d7..0eb05b1d0b94 100644
--- a/drivers/rtc/rtc-pcf50633.c
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -131,9 +131,7 @@ static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
pcf2rtc_time(tm, &pcf_tm);
- dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
- tm->tm_mday, tm->tm_mon, tm->tm_year,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "RTC_TIME: %ptRr\n", tm);
return 0;
}
@@ -146,9 +144,7 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc = dev_get_drvdata(dev);
- dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
- tm->tm_mday, tm->tm_mon, tm->tm_year,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "RTC_TIME: %ptRr\n", tm);
rtc2pcf_time(&pcf_tm, tm);
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c
index 453615f8ac9a..3fcd2cbafc84 100644
--- a/drivers/rtc/rtc-pcf8523.c
+++ b/drivers/rtc/rtc-pcf8523.c
@@ -85,6 +85,18 @@ static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value)
return 0;
}
+static int pcf8523_voltage_low(struct i2c_client *client)
+{
+ u8 value;
+ int err;
+
+ err = pcf8523_read(client, REG_CONTROL3, &value);
+ if (err < 0)
+ return err;
+
+ return !!(value & REG_CONTROL3_BLF);
+}
+
static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
{
u8 value;
@@ -167,6 +179,14 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
struct i2c_msg msgs[2];
int err;
+ err = pcf8523_voltage_low(client);
+ if (err < 0) {
+ return err;
+ } else if (err > 0) {
+ dev_err(dev, "low voltage detected, time is unreliable\n");
+ return -EINVAL;
+ }
+
msgs[0].addr = client->addr;
msgs[0].flags = 0;
msgs[0].len = 1;
@@ -251,17 +271,13 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
struct i2c_client *client = to_i2c_client(dev);
- u8 value;
- int ret = 0, err;
+ int ret;
switch (cmd) {
case RTC_VL_READ:
- err = pcf8523_read(client, REG_CONTROL3, &value);
- if (err < 0)
- return err;
-
- if (value & REG_CONTROL3_BLF)
- ret = 1;
+ ret = pcf8523_voltage_low(client);
+ if (ret < 0)
+ return ret;
if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
return -EFAULT;
diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c
index c04a1edcd571..a3988079f60a 100644
--- a/drivers/rtc/rtc-pcf85363.c
+++ b/drivers/rtc/rtc-pcf85363.c
@@ -120,6 +120,11 @@ struct pcf85363 {
struct regmap *regmap;
};
+struct pcf85x63_config {
+ struct regmap_config regmap;
+ unsigned int num_nvram;
+};
+
static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct pcf85363 *pcf85363 = dev_get_drvdata(dev);
@@ -311,25 +316,75 @@ static int pcf85363_nvram_write(void *priv, unsigned int offset, void *val,
val, bytes);
}
-static const struct regmap_config regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 0x7f,
+static int pcf85x63_nvram_read(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct pcf85363 *pcf85363 = priv;
+ unsigned int tmp_val;
+ int ret;
+
+ ret = regmap_read(pcf85363->regmap, CTRL_RAMBYTE, &tmp_val);
+ (*(unsigned char *) val) = (unsigned char) tmp_val;
+
+ return ret;
+}
+
+static int pcf85x63_nvram_write(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct pcf85363 *pcf85363 = priv;
+ unsigned char tmp_val;
+
+ tmp_val = *((unsigned char *)val);
+ return regmap_write(pcf85363->regmap, CTRL_RAMBYTE,
+ (unsigned int)tmp_val);
+}
+
+static const struct pcf85x63_config pcf_85263_config = {
+ .regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0x2f,
+ },
+ .num_nvram = 1
+};
+
+static const struct pcf85x63_config pcf_85363_config = {
+ .regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0x7f,
+ },
+ .num_nvram = 2
};
static int pcf85363_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pcf85363 *pcf85363;
- struct nvmem_config nvmem_cfg = {
- .name = "pcf85363-",
- .word_size = 1,
- .stride = 1,
- .size = NVRAM_SIZE,
- .reg_read = pcf85363_nvram_read,
- .reg_write = pcf85363_nvram_write,
+ const struct pcf85x63_config *config = &pcf_85363_config;
+ const void *data = of_device_get_match_data(&client->dev);
+ static struct nvmem_config nvmem_cfg[] = {
+ {
+ .name = "pcf85x63-",
+ .word_size = 1,
+ .stride = 1,
+ .size = 1,
+ .reg_read = pcf85x63_nvram_read,
+ .reg_write = pcf85x63_nvram_write,
+ }, {
+ .name = "pcf85363-",
+ .word_size = 1,
+ .stride = 1,
+ .size = NVRAM_SIZE,
+ .reg_read = pcf85363_nvram_read,
+ .reg_write = pcf85363_nvram_write,
+ },
};
- int ret;
+ int ret, i;
+
+ if (data)
+ config = data;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
@@ -339,7 +394,7 @@ static int pcf85363_probe(struct i2c_client *client,
if (!pcf85363)
return -ENOMEM;
- pcf85363->regmap = devm_regmap_init_i2c(client, &regmap_config);
+ pcf85363->regmap = devm_regmap_init_i2c(client, &config->regmap);
if (IS_ERR(pcf85363->regmap)) {
dev_err(&client->dev, "regmap allocation failed\n");
return PTR_ERR(pcf85363->regmap);
@@ -370,15 +425,18 @@ static int pcf85363_probe(struct i2c_client *client,
ret = rtc_register_device(pcf85363->rtc);
- nvmem_cfg.priv = pcf85363;
- rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg);
+ for (i = 0; i < config->num_nvram; i++) {
+ nvmem_cfg[i].priv = pcf85363;
+ rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg[i]);
+ }
return ret;
}
static const struct of_device_id dev_ids[] = {
- { .compatible = "nxp,pcf85363" },
- {}
+ { .compatible = "nxp,pcf85263", .data = &pcf_85263_config },
+ { .compatible = "nxp,pcf85363", .data = &pcf_85363_config },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dev_ids);
@@ -393,5 +451,5 @@ static struct i2c_driver pcf85363_driver = {
module_i2c_driver(pcf85363_driver);
MODULE_AUTHOR("Eric Nelson");
-MODULE_DESCRIPTION("pcf85363 I2C RTC driver");
+MODULE_DESCRIPTION("pcf85263/pcf85363 I2C RTC driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c
index 3c08eab4f1a8..d7ef0a6f8931 100644
--- a/drivers/rtc/rtc-pic32.c
+++ b/drivers/rtc/rtc-pic32.c
@@ -170,9 +170,7 @@ static int pic32_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_year += 100;
- dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n",
- 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
- rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
+ dev_dbg(dev, "read time %ptR\n", rtc_tm);
clk_disable(pdata->clk);
return 0;
@@ -184,9 +182,7 @@ static int pic32_rtc_settime(struct device *dev, struct rtc_time *tm)
void __iomem *base = pdata->reg_base;
int year = tm->tm_year - 100;
- dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n",
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "set time %ptR\n", tm);
if (year < 0 || year >= 100) {
dev_err(dev, "rtc only supports 100 years\n");
@@ -224,10 +220,7 @@ static int pic32_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->enabled = (alm_en & PIC32_RTCALRM_ALRMEN) ? 1 : 0;
- dev_dbg(dev, "getalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n",
- alm_en,
- 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
- alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
+ dev_dbg(dev, "getalarm: %d, %ptR\n", alm_en, alm_tm);
alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
alm_tm->tm_min = bcd2bin(alm_tm->tm_min);
@@ -247,10 +240,7 @@ static int pic32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
void __iomem *base = pdata->reg_base;
clk_enable(pdata->clk);
- dev_dbg(dev, "setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n",
- alrm->enabled,
- 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "setalarm: %d, %ptR\n", alrm->enabled, tm);
writel(0x00, base + PIC32_ALRMTIME);
writel(0x00, base + PIC32_ALRMDATE);
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index 29358a045925..1074e3dbfc1d 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -217,9 +217,7 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time_to_tm(secs, tm);
- dev_dbg(dev, "secs = %lu, h:m:s == %d:%d:%d, d/m/y = %d/%d/%d\n",
- secs, tm->tm_hour, tm->tm_min, tm->tm_sec,
- tm->tm_mday, tm->tm_mon, tm->tm_year);
+ dev_dbg(dev, "secs = %lu, h:m:s == %ptRt, y-m-d = %ptRdr\n", secs, tm, tm);
return 0;
}
@@ -264,10 +262,8 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
goto rtc_rw_fail;
}
- dev_dbg(dev, "Alarm Set for h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n",
- alarm->time.tm_hour, alarm->time.tm_min,
- alarm->time.tm_sec, alarm->time.tm_mday,
- alarm->time.tm_mon, alarm->time.tm_year);
+ dev_dbg(dev, "Alarm Set for h:m:s=%ptRt, y-m-d=%ptRdr\n",
+ &alarm->time, &alarm->time);
rtc_rw_fail:
spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
return rc;
@@ -298,10 +294,8 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
return rc;
}
- dev_dbg(dev, "Alarm set for - h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n",
- alarm->time.tm_hour, alarm->time.tm_min,
- alarm->time.tm_sec, alarm->time.tm_mday,
- alarm->time.tm_mon, alarm->time.tm_year);
+ dev_dbg(dev, "Alarm set for - h:m:s=%ptRt, y-m-d=%ptRdr\n",
+ &alarm->time, &alarm->time);
return 0;
}
diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c
index 9e83be32ff43..f77ef282f013 100644
--- a/drivers/rtc/rtc-puv3.c
+++ b/drivers/rtc/rtc-puv3.c
@@ -90,9 +90,7 @@ static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
{
rtc_time_to_tm(readl(RTC_RCNR), rtc_tm);
- dev_dbg(dev, "read time %02x.%02x.%02x %02x/%02x/%02x\n",
- rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
- rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
+ dev_dbg(dev, "read time %ptRr\n", rtc_tm);
return 0;
}
@@ -101,9 +99,7 @@ static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm)
{
unsigned long rtc_count = 0;
- dev_dbg(dev, "set time %02d.%02d.%02d %02d/%02d/%02d\n",
- tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "set time %ptRr\n", tm);
rtc_tm_to_time(tm, &rtc_count);
writel(rtc_count, RTC_RCNR);
@@ -119,10 +115,7 @@ static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE;
- dev_dbg(dev, "read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
- alrm->enabled,
- alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
- alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
+ dev_dbg(dev, "read alarm: %d, %ptRr\n", alrm->enabled, alm_tm);
return 0;
}
@@ -132,10 +125,7 @@ static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rtc_time *tm = &alrm->time;
unsigned long rtcalarm_count = 0;
- dev_dbg(dev, "puv3_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n",
- alrm->enabled,
- tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,
- tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
+ dev_dbg(dev, "set alarm: %d, %ptRr\n", alrm->enabled, tm);
rtc_tm_to_time(tm, &rtcalarm_count);
writel(rtcalarm_count, RTC_RTAR);
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index 739c0d42e835..1fb864d4ef83 100644
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -138,9 +138,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100;
tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
rockchip_to_gregorian(tm);
- dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
- 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "RTC date/time %ptRd(%d) %ptRt\n", tm, tm->tm_wday, tm);
return ret;
}
@@ -153,9 +151,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
u8 rtc_data[NUM_TIME_REGS];
int ret;
- dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
- 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "set RTC date/time %ptRd(%d) %ptRt\n", tm, tm->tm_wday, tm);
gregorian_to_rockchip(tm);
rtc_data[0] = bin2bcd(tm->tm_sec);
rtc_data[1] = bin2bcd(tm->tm_min);
@@ -216,10 +212,8 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret;
}
- dev_dbg(dev, "alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
- 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
- alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
- alrm->time.tm_min, alrm->time.tm_sec);
+ dev_dbg(dev, "alrm read RTC date/time %ptRd(%d) %ptRt\n",
+ &alrm->time, alrm->time.tm_wday, &alrm->time);
alrm->enabled = (int_reg & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M) ? 1 : 0;
@@ -261,10 +255,8 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
dev_err(dev, "Failed to stop alarm: %d\n", ret);
return ret;
}
- dev_dbg(dev, "alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
- 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
- alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
- alrm->time.tm_min, alrm->time.tm_sec);
+ dev_dbg(dev, "alrm set RTC date/time %ptRd(%d) %ptRt\n",
+ &alrm->time, alrm->time.tm_wday, &alrm->time);
gregorian_to_rockchip(&alrm->time);
alrm_data[0] = bin2bcd(alrm->time.tm_sec);
@@ -400,7 +392,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev,
"Failed to write RTC status: %d\n", ret);
- return ret;
+ return ret;
}
device_init_wakeup(&pdev->dev, 1);
diff --git a/drivers/rtc/rtc-rx6110.c b/drivers/rtc/rtc-rx6110.c
index 8e322d884cc2..5899ca368d59 100644
--- a/drivers/rtc/rtc-rx6110.c
+++ b/drivers/rtc/rtc-rx6110.c
@@ -114,9 +114,7 @@ struct rx6110_data {
*/
static int rx6110_rtc_tm_to_data(struct rtc_time *tm, u8 *data)
{
- pr_debug("%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
- tm->tm_sec, tm->tm_min, tm->tm_hour,
- tm->tm_mday, tm->tm_mon, tm->tm_year);
+ pr_debug("%s: date %ptRr\n", __func__, tm);
/*
* The year in the RTC is a value between 0 and 99.
@@ -154,9 +152,7 @@ static int rx6110_data_to_rtc_tm(u8 *data, struct rtc_time *tm)
tm->tm_mon = bcd2bin(data[RTC_MONTH] & 0x1f) - 1;
tm->tm_year = bcd2bin(data[RTC_YEAR]) + 100;
- pr_debug("%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
- tm->tm_sec, tm->tm_min, tm->tm_hour,
- tm->tm_mday, tm->tm_mon, tm->tm_year);
+ pr_debug("%s: date %ptRr\n", __func__, tm);
/*
* The year in the RTC is a value between 0 and 99.
@@ -248,9 +244,7 @@ static int rx6110_get_time(struct device *dev, struct rtc_time *tm)
if (ret)
return ret;
- dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
- tm->tm_sec, tm->tm_min, tm->tm_hour,
- tm->tm_mday, tm->tm_mon, tm->tm_year);
+ dev_dbg(dev, "%s: date %ptRr\n", __func__, tm);
return 0;
}
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index 41127adf5765..41de38acc570 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -193,10 +193,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
if (err)
return err;
- dev_dbg(dev, "%s: read 0x%02x 0x%02x "
- "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", __func__,
- date[0], date[1], date[2], date[3], date[4],
- date[5], date[6]);
+ dev_dbg(dev, "%s: read %7ph\n", __func__, date);
dt->tm_sec = bcd2bin(date[RX8025_REG_SEC] & 0x7f);
dt->tm_min = bcd2bin(date[RX8025_REG_MIN] & 0x7f);
@@ -210,9 +207,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
dt->tm_mon = bcd2bin(date[RX8025_REG_MONTH] & 0x1f) - 1;
dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]) + 100;
- dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
- dt->tm_sec, dt->tm_min, dt->tm_hour,
- dt->tm_mday, dt->tm_mon, dt->tm_year);
+ dev_dbg(dev, "%s: date %ptRr\n", __func__, dt);
return 0;
}
@@ -243,10 +238,7 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
date[RX8025_REG_MONTH] = bin2bcd(dt->tm_mon + 1);
date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year - 100);
- dev_dbg(dev,
- "%s: write 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
- __func__,
- date[0], date[1], date[2], date[3], date[4], date[5], date[6]);
+ dev_dbg(dev, "%s: write %7ph\n", __func__, date);
ret = rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date);
if (ret < 0)
@@ -319,10 +311,7 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)
t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12
+ (ald[1] & 0x20 ? 12 : 0);
- dev_dbg(dev, "%s: date: %ds %dm %dh %dmd %dm %dy\n",
- __func__,
- t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
- t->time.tm_mday, t->time.tm_mon, t->time.tm_year);
+ dev_dbg(dev, "%s: date: %ptRr\n", __func__, t);
t->enabled = !!(rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE);
t->pending = (ctrl2 & RX8025_BIT_CTRL2_DAFG) && t->enabled;
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 75c8c5033e08..04c68178c42d 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -225,13 +225,9 @@ retry_get_time:
s3c_rtc_disable_clk(info);
rtc_tm->tm_year += 100;
-
- dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n",
- 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
- rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
-
rtc_tm->tm_mon -= 1;
+ dev_dbg(dev, "read time %ptR\n", rtc_tm);
return 0;
}
@@ -241,9 +237,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
int year = tm->tm_year - 100;
int ret;
- dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n",
- 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "set time %ptR\n", tm);
/* we get around y2k by simply not supporting it */
@@ -292,10 +286,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
- dev_dbg(dev, "read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n",
- alm_en,
- 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
- alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
+ dev_dbg(dev, "read alarm %d, %ptR\n", alm_en, alm_tm);
/* decode the alarm enable field */
if (alm_en & S3C2410_RTCALM_SECEN)
@@ -327,12 +318,8 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rtc_time *tm = &alrm->time;
unsigned int alrm_en;
int ret;
- int year = tm->tm_year - 100;
- dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n",
- alrm->enabled,
- 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ dev_dbg(dev, "s3c_rtc_setalarm: %d, %ptR\n", alrm->enabled, tm);
ret = s3c_rtc_enable_clk(info);
if (ret)
@@ -356,11 +343,6 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_ALMHOUR);
}
- if (year < 100 && year >= 0) {
- alrm_en |= S3C2410_RTCALM_YEAREN;
- writeb(bin2bcd(year), info->base + S3C2410_ALMYEAR);
- }
-
if (tm->tm_mon < 12 && tm->tm_mon >= 0) {
alrm_en |= S3C2410_RTCALM_MONEN;
writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_ALMMON);
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
index 6495f84f7428..c7f1bf823ea0 100644
--- a/drivers/rtc/rtc-s5m.c
+++ b/drivers/rtc/rtc-s5m.c
@@ -406,9 +406,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
return -EINVAL;
}
- dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
- 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
+ dev_dbg(dev, "%s: %ptR(%d)\n", __func__, tm, tm->tm_wday);
return 0;
}
@@ -436,9 +434,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
if (ret < 0)
return ret;
- dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
- 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
+ dev_dbg(dev, "%s: %ptR(%d)\n", __func__, tm, tm->tm_wday);
ret = regmap_raw_write(info->regmap, info->regs->time, data,
info->regs->regs_count);
@@ -490,11 +486,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return -EINVAL;
}
- dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
- 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
- alrm->time.tm_mday, alrm->time.tm_hour,
- alrm->time.tm_min, alrm->time.tm_sec,
- alrm->time.tm_wday);
+ dev_dbg(dev, "%s: %ptR(%d)\n", __func__, &alrm->time, alrm->time.tm_wday);
ret = s5m_check_peding_alarm_interrupt(info, alrm);
@@ -513,9 +505,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
return ret;
s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
- dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
- 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
+ dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday);
switch (info->device_type) {
case S5M8763X:
@@ -558,9 +548,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
return ret;
s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
- dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
- 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
+ dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday);
switch (info->device_type) {
case S5M8763X:
@@ -620,10 +608,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return -EINVAL;
}
- dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
- 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
- alrm->time.tm_mday, alrm->time.tm_hour, alrm->time.tm_min,
- alrm->time.tm_sec, alrm->time.tm_wday);
+ dev_dbg(dev, "%s: %ptR(%d)\n", __func__, &alrm->time, alrm->time.tm_wday);
ret = s5m_rtc_stop_alarm(info);
if (ret < 0)
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 51ba414798a8..d417b203cbc5 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* SuperH On-Chip RTC Support
*
@@ -9,10 +10,6 @@
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
*/
#include <linux/module.h>
#include <linux/mod_devicetable.h>
@@ -681,5 +678,5 @@ MODULE_DESCRIPTION("SuperH on-chip RTC driver");
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, "
"Jamie Lenehan <lenehan@twibble.org>, "
"Angelo Castello <angelo.castello@st.com>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index fe07310952df..11f56de52179 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -118,9 +118,31 @@
#define SUN6I_YEAR_MAX 2033
#define SUN6I_YEAR_OFF (SUN6I_YEAR_MIN - 1900)
+/*
+ * There are other differences between models, including:
+ *
+ * - number of GPIO pins that can be configured to hold a certain level
+ * - crypto-key related registers (H5, H6)
+ * - boot process related (super standby, secondary processor entry address)
+ * registers (R40, H6)
+ * - SYS power domain controls (R40)
+ * - DCXO controls (H6)
+ * - RC oscillator calibration (H6)
+ *
+ * These functions are not covered by this driver.
+ */
+struct sun6i_rtc_clk_data {
+ unsigned long rc_osc_rate;
+ unsigned int fixed_prescaler : 16;
+ unsigned int has_prescaler : 1;
+ unsigned int has_out_clk : 1;
+ unsigned int export_iosc : 1;
+};
+
struct sun6i_rtc_dev {
struct rtc_device *rtc;
struct device *dev;
+ const struct sun6i_rtc_clk_data *data;
void __iomem *base;
int irq;
unsigned long alarm;
@@ -139,14 +161,19 @@ static unsigned long sun6i_rtc_osc_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
- u32 val;
+ u32 val = 0;
val = readl(rtc->base + SUN6I_LOSC_CTRL);
if (val & SUN6I_LOSC_CTRL_EXT_OSC)
return parent_rate;
- val = readl(rtc->base + SUN6I_LOSC_CLK_PRESCAL);
- val &= GENMASK(4, 0);
+ if (rtc->data->fixed_prescaler)
+ parent_rate /= rtc->data->fixed_prescaler;
+
+ if (rtc->data->has_prescaler) {
+ val = readl(rtc->base + SUN6I_LOSC_CLK_PRESCAL);
+ val &= GENMASK(4, 0);
+ }
return parent_rate / (val + 1);
}
@@ -185,13 +212,16 @@ static const struct clk_ops sun6i_rtc_osc_ops = {
.set_parent = sun6i_rtc_osc_set_parent,
};
-static void __init sun6i_rtc_clk_init(struct device_node *node)
+static void __init sun6i_rtc_clk_init(struct device_node *node,
+ const struct sun6i_rtc_clk_data *data)
{
struct clk_hw_onecell_data *clk_data;
struct sun6i_rtc_dev *rtc;
struct clk_init_data init = {
.ops = &sun6i_rtc_osc_ops,
+ .name = "losc",
};
+ const char *iosc_name = "rtc-int-osc";
const char *clkout_name = "osc32k-out";
const char *parents[2];
@@ -199,7 +229,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
if (!rtc)
return;
- clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
+ rtc->data = data;
+ clk_data = kzalloc(struct_size(clk_data, hws, 3), GFP_KERNEL);
if (!clk_data) {
kfree(rtc);
return;
@@ -224,10 +255,15 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
if (!of_get_property(node, "clocks", NULL))
goto err;
+ /* Only read IOSC name from device tree if it is exported */
+ if (rtc->data->export_iosc)
+ of_property_read_string_index(node, "clock-output-names", 2,
+ &iosc_name);
+
rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
- "rtc-int-osc",
+ iosc_name,
NULL, 0,
- 667000,
+ rtc->data->rc_osc_rate,
300000000);
if (IS_ERR(rtc->int_osc)) {
pr_crit("Couldn't register the internal oscillator\n");
@@ -264,14 +300,71 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
clk_data->num = 2;
clk_data->hws[0] = &rtc->hw;
clk_data->hws[1] = __clk_get_hw(rtc->ext_losc);
+ if (rtc->data->export_iosc) {
+ clk_data->hws[2] = rtc->int_osc;
+ clk_data->num = 3;
+ }
of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
return;
err:
kfree(clk_data);
}
-CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
- sun6i_rtc_clk_init);
+
+static const struct sun6i_rtc_clk_data sun6i_a31_rtc_data = {
+ .rc_osc_rate = 667000, /* datasheet says 600 ~ 700 KHz */
+ .has_prescaler = 1,
+};
+
+static void __init sun6i_a31_rtc_clk_init(struct device_node *node)
+{
+ sun6i_rtc_clk_init(node, &sun6i_a31_rtc_data);
+}
+CLK_OF_DECLARE_DRIVER(sun6i_a31_rtc_clk, "allwinner,sun6i-a31-rtc",
+ sun6i_a31_rtc_clk_init);
+
+static const struct sun6i_rtc_clk_data sun8i_a23_rtc_data = {
+ .rc_osc_rate = 667000, /* datasheet says 600 ~ 700 KHz */
+ .has_prescaler = 1,
+ .has_out_clk = 1,
+};
+
+static void __init sun8i_a23_rtc_clk_init(struct device_node *node)
+{
+ sun6i_rtc_clk_init(node, &sun8i_a23_rtc_data);
+}
+CLK_OF_DECLARE_DRIVER(sun8i_a23_rtc_clk, "allwinner,sun8i-a23-rtc",
+ sun8i_a23_rtc_clk_init);
+
+static const struct sun6i_rtc_clk_data sun8i_h3_rtc_data = {
+ .rc_osc_rate = 16000000,
+ .fixed_prescaler = 32,
+ .has_prescaler = 1,
+ .has_out_clk = 1,
+ .export_iosc = 1,
+};
+
+static void __init sun8i_h3_rtc_clk_init(struct device_node *node)
+{
+ sun6i_rtc_clk_init(node, &sun8i_h3_rtc_data);
+}
+CLK_OF_DECLARE_DRIVER(sun8i_h3_rtc_clk, "allwinner,sun8i-h3-rtc",
+ sun8i_h3_rtc_clk_init);
+/* As far as we are concerned, clocks for H5 are the same as H3 */
+CLK_OF_DECLARE_DRIVER(sun50i_h5_rtc_clk, "allwinner,sun50i-h5-rtc",
+ sun8i_h3_rtc_clk_init);
+
+static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = {
+ .rc_osc_rate = 32000,
+ .has_out_clk = 1,
+};
+
+static void __init sun8i_v3_rtc_clk_init(struct device_node *node)
+{
+ sun6i_rtc_clk_init(node, &sun8i_v3_rtc_data);
+}
+CLK_OF_DECLARE_DRIVER(sun8i_v3_rtc_clk, "allwinner,sun8i-v3-rtc",
+ sun8i_v3_rtc_clk_init);
static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
{
@@ -578,8 +671,18 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
return 0;
}
+/*
+ * As far as RTC functionality goes, all models are the same. The
+ * datasheets claim that different models have different number of
+ * registers available for non-volatile storage, but experiments show
+ * that all SoCs have 16 registers available for this purpose.
+ */
static const struct of_device_id sun6i_rtc_dt_ids[] = {
{ .compatible = "allwinner,sun6i-a31-rtc" },
+ { .compatible = "allwinner,sun8i-a23-rtc" },
+ { .compatible = "allwinner,sun8i-h3-rtc" },
+ { .compatible = "allwinner,sun8i-v3-rtc" },
+ { .compatible = "allwinner,sun50i-h5-rtc" },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c
index c9e77a83cd1b..c6b0a99aa3a9 100644
--- a/drivers/rtc/rtc-tegra.c
+++ b/drivers/rtc/rtc-tegra.c
@@ -125,15 +125,7 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time_to_tm(sec, tm);
- dev_vdbg(dev, "time read as %lu. %d/%d/%d %d:%02u:%02u\n",
- sec,
- tm->tm_mon + 1,
- tm->tm_mday,
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec
- );
+ dev_vdbg(dev, "time read as %lu. %ptR\n", sec, tm);
return 0;
}
@@ -147,15 +139,7 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* convert tm to seconds. */
rtc_tm_to_time(tm, &sec);
- dev_vdbg(dev, "time set to %lu. %d/%d/%d %d:%02u:%02u\n",
- sec,
- tm->tm_mon+1,
- tm->tm_mday,
- tm->tm_year+1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec
- );
+ dev_vdbg(dev, "time set to %lu. %ptR\n", sec, tm);
/* seconds only written if wait succeeded. */
ret = tegra_rtc_wait_while_busy(dev);
@@ -232,15 +216,7 @@ static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
/* if successfully written and alarm is enabled ... */
if (sec) {
tegra_rtc_alarm_irq_enable(dev, 1);
-
- dev_vdbg(dev, "alarm set as %lu. %d/%d/%d %d:%02u:%02u\n",
- sec,
- alarm->time.tm_mon+1,
- alarm->time.tm_mday,
- alarm->time.tm_year+1900,
- alarm->time.tm_hour,
- alarm->time.tm_min,
- alarm->time.tm_sec);
+ dev_vdbg(dev, "alarm set as %lu. %ptR\n", sec, &alarm->time);
} else {
/* disable alarm if 0 or write error. */
dev_vdbg(dev, "alarm disabled\n");
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/sysfs.c
index 9746c32eee2e..a8f22ee726bb 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/sysfs.c
@@ -39,12 +39,10 @@ date_show(struct device *dev, struct device_attribute *attr, char *buf)
struct rtc_time tm;
retval = rtc_read_time(to_rtc_device(dev), &tm);
- if (retval == 0) {
- retval = sprintf(buf, "%04d-%02d-%02d\n",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
- }
+ if (retval)
+ return retval;
- return retval;
+ return sprintf(buf, "%ptRd\n", &tm);
}
static DEVICE_ATTR_RO(date);
@@ -55,12 +53,10 @@ time_show(struct device *dev, struct device_attribute *attr, char *buf)
struct rtc_time tm;
retval = rtc_read_time(to_rtc_device(dev), &tm);
- if (retval == 0) {
- retval = sprintf(buf, "%02d:%02d:%02d\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- }
+ if (retval)
+ return retval;
- return retval;
+ return sprintf(buf, "%ptRt\n", &tm);
}
static DEVICE_ATTR_RO(time);
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index c8bb4a2b48c3..c1089fe5344a 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -87,15 +87,16 @@ struct rtc_class_ops {
int (*set_offset)(struct device *, long offset);
};
+struct rtc_device;
+
struct rtc_timer {
struct timerqueue_node node;
ktime_t period;
- void (*func)(void *private_data);
- void *private_data;
+ void (*func)(struct rtc_device *rtc);
+ struct rtc_device *rtc;
int enabled;
};
-
/* flags */
#define RTC_DEV_BUSY 0
@@ -138,7 +139,6 @@ struct rtc_device {
bool registered;
- struct nvmem_device *nvmem;
/* Old ABI support */
bool nvram_old_abi;
struct bin_attribute *nvram;
@@ -173,8 +173,6 @@ extern struct rtc_device *devm_rtc_device_register(struct device *dev,
struct module *owner);
struct rtc_device *devm_rtc_allocate_device(struct device *dev);
int __rtc_register_device(struct module *owner, struct rtc_device *rtc);
-extern void devm_rtc_device_unregister(struct device *dev,
- struct rtc_device *rtc);
extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
@@ -200,11 +198,12 @@ extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc,
unsigned int enabled);
void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode);
-void rtc_aie_update_irq(void *private);
-void rtc_uie_update_irq(void *private);
+void rtc_aie_update_irq(struct rtc_device *rtc);
+void rtc_uie_update_irq(struct rtc_device *rtc);
enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer);
-void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data);
+void rtc_timer_init(struct rtc_timer *timer, void (*f)(struct rtc_device *r),
+ struct rtc_device *rtc);
int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer,
ktime_t expires, ktime_t period);
void rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer);
diff --git a/lib/test_printf.c b/lib/test_printf.c
index 53527ea822b5..659b6cc0d483 100644
--- a/lib/test_printf.c
+++ b/lib/test_printf.c
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/random.h>
+#include <linux/rtc.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -249,12 +250,11 @@ plain_format(void)
#endif /* BITS_PER_LONG == 64 */
static int __init
-plain_hash(void)
+plain_hash_to_buffer(const void *p, char *buf, size_t len)
{
- char buf[PLAIN_BUF_SIZE];
int nchars;
- nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR);
+ nchars = snprintf(buf, len, "%p", p);
if (nchars != PTR_WIDTH)
return -1;
@@ -265,6 +265,20 @@ plain_hash(void)
return 0;
}
+ return 0;
+}
+
+
+static int __init
+plain_hash(void)
+{
+ char buf[PLAIN_BUF_SIZE];
+ int ret;
+
+ ret = plain_hash_to_buffer(PTR, buf, PLAIN_BUF_SIZE);
+ if (ret)
+ return ret;
+
if (strncmp(buf, PTR_STR, PTR_WIDTH) == 0)
return -1;
@@ -295,6 +309,23 @@ plain(void)
}
static void __init
+test_hashed(const char *fmt, const void *p)
+{
+ char buf[PLAIN_BUF_SIZE];
+ int ret;
+
+ /*
+ * No need to increase failed test counter since this is assumed
+ * to be called after plain().
+ */
+ ret = plain_hash_to_buffer(p, buf, PLAIN_BUF_SIZE);
+ if (ret)
+ return;
+
+ test(buf, fmt, p);
+}
+
+static void __init
symbol_ptr(void)
{
}
@@ -419,6 +450,29 @@ struct_va_format(void)
}
static void __init
+struct_rtc_time(void)
+{
+ /* 1543210543 */
+ const struct rtc_time tm = {
+ .tm_sec = 43,
+ .tm_min = 35,
+ .tm_hour = 5,
+ .tm_mday = 26,
+ .tm_mon = 10,
+ .tm_year = 118,
+ };
+
+ test_hashed("%pt", &tm);
+
+ test("2018-11-26T05:35:43", "%ptR", &tm);
+ test("0118-10-26T05:35:43", "%ptRr", &tm);
+ test("05:35:43|2018-11-26", "%ptRt|%ptRd", &tm, &tm);
+ test("05:35:43|0118-10-26", "%ptRtr|%ptRdr", &tm, &tm);
+ test("05:35:43|2018-11-26", "%ptRttr|%ptRdtr", &tm, &tm);
+ test("05:35:43 tr|2018-11-26 tr", "%ptRt tr|%ptRd tr", &tm, &tm);
+}
+
+static void __init
struct_clk(void)
{
}
@@ -529,6 +583,7 @@ test_pointer(void)
uuid();
dentry();
struct_va_format();
+ struct_rtc_time();
struct_clk();
bitmap();
netdev_features();
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 37a54a6dd594..3add92329bae 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -30,6 +30,7 @@
#include <linux/ioport.h>
#include <linux/dcache.h>
#include <linux/cred.h>
+#include <linux/rtc.h>
#include <linux/uuid.h>
#include <linux/of.h>
#include <net/addrconf.h>
@@ -822,6 +823,20 @@ static const struct printf_spec default_dec_spec = {
.precision = -1,
};
+static const struct printf_spec default_dec02_spec = {
+ .base = 10,
+ .field_width = 2,
+ .precision = -1,
+ .flags = ZEROPAD,
+};
+
+static const struct printf_spec default_dec04_spec = {
+ .base = 10,
+ .field_width = 4,
+ .precision = -1,
+ .flags = ZEROPAD,
+};
+
static noinline_for_stack
char *resource_string(char *buf, char *end, struct resource *res,
struct printf_spec spec, const char *fmt)
@@ -1550,6 +1565,87 @@ char *address_val(char *buf, char *end, const void *addr, const char *fmt)
}
static noinline_for_stack
+char *date_str(char *buf, char *end, const struct rtc_time *tm, bool r)
+{
+ int year = tm->tm_year + (r ? 0 : 1900);
+ int mon = tm->tm_mon + (r ? 0 : 1);
+
+ buf = number(buf, end, year, default_dec04_spec);
+ if (buf < end)
+ *buf = '-';
+ buf++;
+
+ buf = number(buf, end, mon, default_dec02_spec);
+ if (buf < end)
+ *buf = '-';
+ buf++;
+
+ return number(buf, end, tm->tm_mday, default_dec02_spec);
+}
+
+static noinline_for_stack
+char *time_str(char *buf, char *end, const struct rtc_time *tm, bool r)
+{
+ buf = number(buf, end, tm->tm_hour, default_dec02_spec);
+ if (buf < end)
+ *buf = ':';
+ buf++;
+
+ buf = number(buf, end, tm->tm_min, default_dec02_spec);
+ if (buf < end)
+ *buf = ':';
+ buf++;
+
+ return number(buf, end, tm->tm_sec, default_dec02_spec);
+}
+
+static noinline_for_stack
+char *rtc_str(char *buf, char *end, const struct rtc_time *tm, const char *fmt)
+{
+ bool have_t = true, have_d = true;
+ bool raw = false;
+ int count = 2;
+
+ switch (fmt[count]) {
+ case 'd':
+ have_t = false;
+ count++;
+ break;
+ case 't':
+ have_d = false;
+ count++;
+ break;
+ }
+
+ raw = fmt[count] == 'r';
+
+ if (have_d)
+ buf = date_str(buf, end, tm, raw);
+ if (have_d && have_t) {
+ /* Respect ISO 8601 */
+ if (buf < end)
+ *buf = 'T';
+ buf++;
+ }
+ if (have_t)
+ buf = time_str(buf, end, tm, raw);
+
+ return buf;
+}
+
+static noinline_for_stack
+char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec,
+ const char *fmt)
+{
+ switch (fmt[1]) {
+ case 'R':
+ return rtc_str(buf, end, (const struct rtc_time *)ptr, fmt);
+ default:
+ return ptr_to_id(buf, end, ptr, spec);
+ }
+}
+
+static noinline_for_stack
char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec,
const char *fmt)
{
@@ -1828,6 +1924,8 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
* - 'd[234]' For a dentry name (optionally 2-4 last components)
* - 'D[234]' Same as 'd' but for a struct file
* - 'g' For block_device name (gendisk + partition number)
+ * - 't[R][dt][r]' For time and date as represented:
+ * R struct rtc_time
* - 'C' For a clock, it prints the name (Common Clock Framework) or address
* (legacy clock framework) of the clock
* - 'Cn' For a clock, it prints the name (Common Clock Framework) or address
@@ -1952,6 +2050,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
return address_val(buf, end, ptr, fmt);
case 'd':
return dentry_name(buf, end, ptr, spec, fmt);
+ case 't':
+ return time_and_date(buf, end, ptr, spec, fmt);
case 'C':
return clock(buf, end, ptr, spec, fmt);
case 'D':