Commit 28e8c4bc authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents c9bef4a6 36e14f5f
...@@ -412,6 +412,24 @@ Examples:: ...@@ -412,6 +412,24 @@ Examples::
Passed by reference. 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 struct clk
---------- ----------
......
...@@ -109,6 +109,12 @@ Required properties for Pinctrl sub nodes: ...@@ -109,6 +109,12 @@ Required properties for Pinctrl sub nodes:
[2] Documentation/devicetree/bindings/power/power_domain.txt [2] Documentation/devicetree/bindings/power/power_domain.txt
[3] Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.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): Example (imx8qxp):
------------- -------------
lsio_mu1: mailbox@5d1c0000 { lsio_mu1: mailbox@5d1c0000 {
...@@ -151,6 +157,10 @@ firmware { ...@@ -151,6 +157,10 @@ firmware {
compatible = "fsl,imx8qxp-scu-pd"; compatible = "fsl,imx8qxp-scu-pd";
#power-domain-cells = <1>; #power-domain-cells = <1>;
}; };
rtc: rtc {
compatible = "fsl,imx8qxp-sc-rtc";
};
}; };
}; };
......
...@@ -27,4 +27,4 @@ and valid to enable charging: ...@@ -27,4 +27,4 @@ and valid to enable charging:
- "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V) - "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 - "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.
...@@ -2,6 +2,7 @@ NXP PCF2123 SPI Real Time Clock ...@@ -2,6 +2,7 @@ NXP PCF2123 SPI Real Time Clock
Required properties: Required properties:
- compatible: should be: "nxp,rtc-pcf2123" - compatible: should be: "nxp,rtc-pcf2123"
or "microcrystal,rv2123"
- reg: should be the SPI slave chipselect address - reg: should be the SPI slave chipselect address
Optional properties: Optional properties:
......
NXP PCF85363 Real Time Clock NXP PCF85263/PCF85363 Real Time Clock
============================ ============================
Required properties: Required properties:
- compatible: Should contain "nxp,pcf85363". - compatible: Should contain "nxp,pcf85263" or "nxp,pcf85363".
- reg: I2C address for chip. - reg: I2C address for chip.
Optional properties: Optional properties:
......
...@@ -35,7 +35,7 @@ Optional properties: ...@@ -35,7 +35,7 @@ Optional properties:
Should be given if internal trickle charger diode should be disabled Should be given if internal trickle charger diode should be disabled
Example: Example:
rtc1: ds1339@68 { ds1339: rtc@68 {
compatible = "dallas,ds1339"; compatible = "dallas,ds1339";
reg = <0x68>; reg = <0x68>;
interrupt-parent = <&gpio4>; interrupt-parent = <&gpio4>;
......
...@@ -3,25 +3,44 @@ ...@@ -3,25 +3,44 @@
RTC controller for the Allwinner A31 RTC controller for the Allwinner A31
Required properties: 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 - reg : physical base address of the controller and length of
memory mapped region. memory mapped region.
- interrupts : IRQ lines for the RTC alarm 0 and alarm 1, in that order. - interrupts : IRQ lines for the RTC alarm 0 and alarm 1, in that order.
Required properties for new device trees Required properties for new device trees
- clocks : phandle to the 32kHz external oscillator - clocks : phandle to the 32kHz external oscillator
- clock-output-names : names of the LOSC and its external output clocks created - clock-output-names : names of up to three clock outputs. See below.
- #clock-cells : must be equals to 1. The RTC provides two clocks: the - #clock-cells : must be equal to 1.
LOSC and its external output, with index 0 and 1
respectively. 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: Example:
rtc: rtc@1f00000 { rtc: rtc@1f00000 {
compatible = "allwinner,sun6i-a31-rtc"; compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x54>; reg = <0x01f00000 0x400>;
interrupts = <0 40 4>, <0 41 4>; interrupts = <0 40 4>, <0 41 4>;
clock-output-names = "osc32k", "osc32k-out"; clock-output-names = "osc32k";
clocks = <&ext_osc32k>; clocks = <&ext_osc32k>;
#clock-cells = <1>; #clock-cells = <1>;
}; };
...@@ -605,13 +605,9 @@ int mac_hwclk(int op, struct rtc_time *t) ...@@ -605,13 +605,9 @@ int mac_hwclk(int op, struct rtc_time *t)
unmktime(now, 0, unmktime(now, 0,
&t->tm_year, &t->tm_mon, &t->tm_mday, &t->tm_year, &t->tm_mon, &t->tm_mday,
&t->tm_hour, &t->tm_min, &t->tm_sec); &t->tm_hour, &t->tm_min, &t->tm_sec);
pr_debug("%s: read %04d-%02d-%-2d %02d:%02d:%02d\n", pr_debug("%s: read %ptR\n", __func__, t);
__func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
} else { /* write */ } else { /* write */
pr_debug("%s: tried to write %04d-%02d-%-2d %02d:%02d:%02d\n", pr_debug("%s: tried to write %ptR\n", __func__, t);
__func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
switch (macintosh_config->adb_type) { switch (macintosh_config->adb_type) {
case MAC_ADB_IOP: case MAC_ADB_IOP:
......
...@@ -118,9 +118,7 @@ static unsigned int read_magic_time(void) ...@@ -118,9 +118,7 @@ static unsigned int read_magic_time(void)
unsigned int val; unsigned int val;
mc146818_get_time(&time); mc146818_get_time(&time);
pr_info("RTC time: %2d:%02d:%02d, date: %02d/%02d/%02d\n", pr_info("RTC time: %ptRt, date: %ptRd\n", &time, &time);
time.tm_hour, time.tm_min, time.tm_sec,
time.tm_mon + 1, time.tm_mday, time.tm_year % 100);
val = time.tm_year; /* 100 years */ val = time.tm_year; /* 100 years */
if (val > 100) if (val > 100)
val -= 100; val -= 100;
......
...@@ -1125,11 +1125,10 @@ static int rtc_proc_show(struct seq_file *seq, void *v) ...@@ -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. * time or for Universal Standard Time (GMT). Probably local though.
*/ */
seq_printf(seq, seq_printf(seq,
"rtc_time\t: %02d:%02d:%02d\n" "rtc_time\t: %ptRt\n"
"rtc_date\t: %04d-%02d-%02d\n" "rtc_date\t: %ptRd\n"
"rtc_epoch\t: %04lu\n", "rtc_epoch\t: %04lu\n",
tm.tm_hour, tm.tm_min, tm.tm_sec, &tm, &tm, epoch);
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
get_rtc_alm_time(&tm); get_rtc_alm_time(&tm);
......
...@@ -441,12 +441,10 @@ static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v) ...@@ -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"); seq_puts(m, "BBRTC\t\t: READ FAILED!\n");
} else { } else {
seq_printf(m, seq_printf(m,
"rtc_time\t: %02d:%02d:%02d\n" "rtc_time\t: %ptRt\n"
"rtc_date\t: %04d-%02d-%02d\n" "rtc_date\t: %ptRd\n"
"rtc_epoch\t: %04lu\n", "rtc_epoch\t: %04lu\n",
tm.tm_hour, tm.tm_min, tm.tm_sec, &tm, &tm, epoch);
tm.tm_year + 1900, tm.tm_mon + 1,
tm.tm_mday, epoch);
} }
if (hp_sdc_rtc_read_rt(&tv)) { if (hp_sdc_rtc_read_rt(&tv)) {
......
...@@ -1677,6 +1677,13 @@ config RTC_DRV_SNVS ...@@ -1677,6 +1677,13 @@ config RTC_DRV_SNVS
This driver can also be built as a module, if so, the module This driver can also be built as a module, if so, the module
will be called "rtc-snvs". 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 config RTC_DRV_SIRFSOC
tristate "SiRFSOC RTC" tristate "SiRFSOC RTC"
depends on ARCH_SIRF depends on ARCH_SIRF
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
ccflags-$(CONFIG_RTC_DEBUG) := -DDEBUG 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_HCTOSYS) += hctosys.o
obj-$(CONFIG_RTC_SYSTOHC) += systohc.o obj-$(CONFIG_RTC_SYSTOHC) += systohc.o
obj-$(CONFIG_RTC_CLASS) += rtc-core.o obj-$(CONFIG_RTC_CLASS) += rtc-core.o
...@@ -17,9 +17,9 @@ rtc-core-y += rtc-efi-platform.o ...@@ -17,9 +17,9 @@ rtc-core-y += rtc-efi-platform.o
endif endif
rtc-core-$(CONFIG_RTC_NVMEM) += nvmem.o rtc-core-$(CONFIG_RTC_NVMEM) += nvmem.o
rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o rtc-core-$(CONFIG_RTC_INTF_DEV) += dev.o
rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o rtc-core-$(CONFIG_RTC_INTF_PROC) += proc.o
rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o rtc-core-$(CONFIG_RTC_INTF_SYSFS) += sysfs.o
# Keep the list ordered. # Keep the list ordered.
...@@ -75,6 +75,7 @@ obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o ...@@ -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_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o
obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.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_ISL12022) += rtc-isl12022.o
obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
......
...@@ -178,9 +178,9 @@ static struct rtc_device *rtc_allocate_device(void) ...@@ -178,9 +178,9 @@ static struct rtc_device *rtc_allocate_device(void)
timerqueue_init_head(&rtc->timerqueue); timerqueue_init_head(&rtc->timerqueue);
INIT_WORK(&rtc->irqwork, rtc_timer_do_work); INIT_WORK(&rtc->irqwork, rtc_timer_do_work);
/* Init aie timer */ /* 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 */ /* 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 */ /* Init pie timer */
hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
rtc->pie_timer.function = rtc_pie_update_irq; rtc->pie_timer.function = rtc_pie_update_irq;
...@@ -277,82 +277,6 @@ static void rtc_device_get_offset(struct rtc_device *rtc) ...@@ -277,82 +277,6 @@ static void rtc_device_get_offset(struct rtc_device *rtc)
rtc->offset_secs = 0; rtc->offset_secs = 0;
} }
/**
* 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_device_unregister - removes the previously registered RTC class device
* *
...@@ -372,77 +296,6 @@ static void rtc_device_unregister(struct rtc_device *rtc) ...@@ -372,77 +296,6 @@ static void rtc_device_unregister(struct rtc_device *rtc)
put_device(&rtc->dev); 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) static void devm_rtc_release_device(struct device *dev, void *res)
{ {
struct rtc_device *rtc = *(struct rtc_device **)res; struct rtc_device *rtc = *(struct rtc_device **)res;
...@@ -529,6 +382,42 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc) ...@@ -529,6 +382,42 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
} }
EXPORT_SYMBOL_GPL(__rtc_register_device); 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) static int __init rtc_init(void)
{ {
rtc_class = class_create(THIS_MODULE, "rtc"); rtc_class = class_create(THIS_MODULE, "rtc");
......
...@@ -58,12 +58,8 @@ static int __init rtc_hctosys(void) ...@@ -58,12 +58,8 @@ static int __init rtc_hctosys(void)
err = do_settimeofday64(&tv64); err = do_settimeofday64(&tv64);
dev_info(rtc->dev.parent, dev_info(rtc->dev.parent, "setting system clock to %ptR UTC (%lld)\n",
"setting system clock to " &tm, (long long)tv64.tv_sec);
"%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);
err_read: err_read:
rtc_class_close(rtc); rtc_class_close(rtc);
......
...@@ -368,12 +368,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) ...@@ -368,12 +368,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
err = rtc_valid_tm(&alarm->time); err = rtc_valid_tm(&alarm->time);
done: done:
if (err) { if (err)
dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n", dev_warn(&rtc->dev, "invalid alarm value: %ptR\n", &alarm->time);
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);
}
return err; return err;
} }
...@@ -613,26 +609,24 @@ void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) ...@@ -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 * 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. * 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_handle_legacy_irq(rtc, 1, RTC_AF);
} }
/** /**
* rtc_uie_update_irq - UIE mode rtctimer hook * 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. * 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); rtc_handle_legacy_irq(rtc, 1, RTC_UF);
} }
...@@ -912,7 +906,7 @@ void rtc_timer_do_work(struct work_struct *work) ...@@ -912,7 +906,7 @@ void rtc_timer_do_work(struct work_struct *work)
trace_rtc_timer_dequeue(timer); trace_rtc_timer_dequeue(timer);
timer->enabled = 0; timer->enabled = 0;
if (timer->func) if (timer->func)
timer->func(timer->private_data); timer->func(timer->rtc);
trace_rtc_timer_fired(timer); trace_rtc_timer_fired(timer);
/* Re-add/fwd periodic timers */ /* Re-add/fwd periodic timers */
...@@ -959,16 +953,17 @@ void rtc_timer_do_work(struct work_struct *work) ...@@ -959,16 +953,17 @@ void rtc_timer_do_work(struct work_struct *work)
/* rtc_timer_init - Initializes an rtc_timer /* rtc_timer_init - Initializes an rtc_timer
* @timer: timer to be intiialized * @timer: timer to be intiialized
* @f: function pointer to be called when timer fires * @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. * 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); timerqueue_init(&timer->node);
timer->enabled = 0; timer->enabled = 0;
timer->func = f; timer->func = f;
timer->private_data = data; timer->rtc = rtc;
} }
/* rtc_timer_start - Sets an rtc_timer to fire in the future /* rtc_timer_start - Sets an rtc_timer to fire in the future
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/nvmem-consumer.h> #include <linux/nvmem-consumer.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/slab.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
/* /*
...@@ -25,11 +26,9 @@ rtc_nvram_read(struct file *filp, struct kobject *kobj, ...@@ -25,11 +26,9 @@ rtc_nvram_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, struct bin_attribute *attr,
char *buf, loff_t off, size_t count) char *buf, loff_t off, size_t count)
{ {
struct rtc_device *rtc = attr->private;
dev_warn_once(kobj_to_dev(kobj), nvram_warning); 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 static ssize_t
...@@ -37,26 +36,23 @@ rtc_nvram_write(struct file *filp, struct kobject *kobj, ...@@ -37,26 +36,23 @@ rtc_nvram_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, struct bin_attribute *attr,
char *buf, loff_t off, size_t count) char *buf, loff_t off, size_t count)
{ {
struct rtc_device *rtc = attr->private;
dev_warn_once(kobj_to_dev(kobj), nvram_warning); 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; int err;
rtc->nvram = devm_kzalloc(rtc->dev.parent, rtc->nvram = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL);
sizeof(struct bin_attribute),
GFP_KERNEL);
if (!rtc->nvram) if (!rtc->nvram)
return -ENOMEM; return -ENOMEM;
rtc->nvram->attr.name = "nvram"; rtc->nvram->attr.name = "nvram";
rtc->nvram->attr.mode = 0644; rtc->nvram->attr.mode = 0644;
rtc->nvram->private = rtc; rtc->nvram->private = nvmem;
sysfs_bin_attr_init(rtc->nvram); sysfs_bin_attr_init(rtc->nvram);
...@@ -67,7 +63,7 @@ static int rtc_nvram_register(struct rtc_device *rtc, size_t size) ...@@ -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, err = sysfs_create_bin_file(&rtc->dev.parent->kobj,
rtc->nvram); rtc->nvram);
if (err) { if (err) {
devm_kfree(rtc->dev.parent, rtc->nvram); kfree(rtc->nvram);
rtc->nvram = NULL; rtc->nvram = NULL;
} }
...@@ -77,6 +73,8 @@ static int rtc_nvram_register(struct rtc_device *rtc, size_t size) ...@@ -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) static void rtc_nvram_unregister(struct rtc_device *rtc)
{ {
sysfs_remove_bin_file(&rtc->dev.parent->kobj, rtc->nvram); 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) ...@@ -85,21 +83,20 @@ static void rtc_nvram_unregister(struct rtc_device *rtc)
int rtc_nvmem_register(struct rtc_device *rtc, int rtc_nvmem_register(struct rtc_device *rtc,
struct nvmem_config *nvmem_config) struct nvmem_config *nvmem_config)
{ {
if (!IS_ERR_OR_NULL(rtc->nvmem)) struct nvmem_device *nvmem;
return -EBUSY;
if (!nvmem_config) if (!nvmem_config)
return -ENODEV; return -ENODEV;
nvmem_config->dev = rtc->dev.parent; nvmem_config->dev = rtc->dev.parent;
nvmem_config->owner = rtc->owner; nvmem_config->owner = rtc->owner;
rtc->nvmem = nvmem_register(nvmem_config); nvmem = devm_nvmem_register(rtc->dev.parent, nvmem_config);
if (IS_ERR(rtc->nvmem)) if (IS_ERR(nvmem))
return PTR_ERR(rtc->nvmem); return PTR_ERR(nvmem);
/* Register the old ABI */ /* Register the old ABI */
if (rtc->nvram_old_abi) if (rtc->nvram_old_abi)
rtc_nvram_register(rtc, nvmem_config->size); rtc_nvram_register(rtc, nvmem, nvmem_config->size);
return 0; return 0;
} }
...@@ -107,12 +104,7 @@ EXPORT_SYMBOL_GPL(rtc_nvmem_register); ...@@ -107,12 +104,7 @@ EXPORT_SYMBOL_GPL(rtc_nvmem_register);
void rtc_nvmem_unregister(struct rtc_device *rtc) void rtc_nvmem_unregister(struct rtc_device *rtc)
{ {
if (IS_ERR_OR_NULL(rtc->nvmem))
return;
/* unregister the old ABI */ /* unregister the old ABI */
if (rtc->nvram) if (rtc->nvram)
rtc_nvram_unregister(rtc); rtc_nvram_unregister(rtc);
nvmem_unregister(rtc->nvmem);
} }
...@@ -50,41 +50,15 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) ...@@ -50,41 +50,15 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
err = rtc_read_time(rtc, &tm); err = rtc_read_time(rtc, &tm);
if (err == 0) { if (err == 0) {
seq_printf(seq, seq_printf(seq,
"rtc_time\t: %02d:%02d:%02d\n" "rtc_time\t: %ptRt\n"
"rtc_date\t: %04d-%02d-%02d\n", "rtc_date\t: %ptRd\n",
tm.tm_hour, tm.tm_min, tm.tm_sec, &tm, &tm);
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
} }
err = rtc_read_alarm(rtc, &alrm); err = rtc_read_alarm(rtc, &alrm);
if (err == 0) { if (err == 0) {
seq_printf(seq, "alrm_time\t: "); seq_printf(seq, "alrm_time\t: %ptRt\n", &alrm.time);
if ((unsigned int)alrm.time.tm_hour <= 24) seq_printf(seq, "alrm_date\t: %ptRd\n", &alrm.time);
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, "alarm_IRQ\t: %s\n", seq_printf(seq, "alarm_IRQ\t: %s\n",
alrm.enabled ? "yes" : "no"); alrm.enabled ? "yes" : "no");
seq_printf(seq, "alrm_pending\t: %s\n", seq_printf(seq, "alrm_pending\t: %s\n",
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#define ABX8XX_REG_STATUS 0x0f #define ABX8XX_REG_STATUS 0x0f
#define ABX8XX_STATUS_AF BIT(2) #define ABX8XX_STATUS_AF BIT(2)
#define ABX8XX_STATUS_BLF BIT(4)
#define ABX8XX_STATUS_WDT BIT(6) #define ABX8XX_STATUS_WDT BIT(6)
#define ABX8XX_REG_CTRL1 0x10 #define ABX8XX_REG_CTRL1 0x10
...@@ -507,12 +508,49 @@ static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -507,12 +508,49 @@ static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled)
return err; 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 = { static const struct rtc_class_ops abx80x_rtc_ops = {
.read_time = abx80x_rtc_read_time, .read_time = abx80x_rtc_read_time,
.set_time = abx80x_rtc_set_time, .set_time = abx80x_rtc_set_time,
.read_alarm = abx80x_read_alarm, .read_alarm = abx80x_read_alarm,
.set_alarm = abx80x_set_alarm, .set_alarm = abx80x_set_alarm,
.alarm_irq_enable = abx80x_alarm_irq_enable, .alarm_irq_enable = abx80x_alarm_irq_enable,
.ioctl = abx80x_ioctl,
}; };
static int abx80x_dt_trickle_cfg(struct device_node *np) static int abx80x_dt_trickle_cfg(struct device_node *np)
......
...@@ -147,9 +147,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) ...@@ -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_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
tm->tm_year = tm->tm_year - 1900; tm->tm_year = tm->tm_year - 1900;
dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, dev_dbg(dev, "%s(): %ptR\n", __func__, tm);
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return 0; return 0;
} }
...@@ -161,9 +159,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) ...@@ -161,9 +159,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
{ {
unsigned long cr; unsigned long cr;
dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, dev_dbg(dev, "%s(): %ptR\n", __func__, tm);
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
wait_for_completion(&at91_rtc_upd_rdy); wait_for_completion(&at91_rtc_upd_rdy);
...@@ -209,8 +205,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -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) alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM)
? 1 : 0; ? 1 : 0;
dev_dbg(dev, "%s(): %02d-%02d %02d:%02d:%02d %sabled\n", __func__, dev_dbg(dev, "%s(): %ptR %sabled\n", __func__, tm,
tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
alrm->enabled ? "en" : "dis"); alrm->enabled ? "en" : "dis");
return 0; return 0;
...@@ -247,9 +242,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -247,9 +242,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
at91_rtc_write_ier(AT91_RTC_ALARM); at91_rtc_write_ier(AT91_RTC_ALARM);
} }
dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, dev_dbg(dev, "%s(): %ptR\n", __func__, &tm);
tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
tm.tm_min, tm.tm_sec);
return 0; return 0;
} }
......
...@@ -124,9 +124,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) ...@@ -124,9 +124,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm)
rtc_time_to_tm(offset + secs, tm); rtc_time_to_tm(offset + secs, tm);
dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readtime", dev_dbg(dev, "%s: %ptR\n", __func__, tm);
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return 0; return 0;
} }
...@@ -141,9 +139,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) ...@@ -141,9 +139,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
u32 offset, alarm, mr; u32 offset, alarm, mr;
unsigned long secs; unsigned long secs;
dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "settime", dev_dbg(dev, "%s: %ptR\n", __func__, tm);
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
err = rtc_tm_to_time(tm, &secs); err = rtc_tm_to_time(tm, &secs);
if (err != 0) if (err != 0)
...@@ -199,9 +195,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -199,9 +195,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
if (alarm != ALARM_DISABLED && offset != 0) { if (alarm != ALARM_DISABLED && offset != 0) {
rtc_time_to_tm(offset + alarm, tm); rtc_time_to_tm(offset + alarm, tm);
dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readalarm", dev_dbg(dev, "%s: %ptR\n", __func__, tm);
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
if (rtt_readl(rtc, MR) & AT91_RTT_ALMIEN) if (rtt_readl(rtc, MR) & AT91_RTT_ALMIEN)
alrm->enabled = 1; alrm->enabled = 1;
...@@ -242,9 +236,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -242,9 +236,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
if (alrm->enabled) if (alrm->enabled)
rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "setalarm", dev_dbg(dev, "%s: %ptR\n", __func__, tm);
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
tm->tm_min, tm->tm_sec);
return 0; return 0;
} }
......
...@@ -61,7 +61,7 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -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); struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev);
unsigned long time; 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); rtc_time_to_tm(time, tm);
return 0; return 0;
......
// 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");
...@@ -84,29 +84,13 @@ static int ...@@ -84,29 +84,13 @@ static int
isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
unsigned len) 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; int ret;
WARN_ON(reg > ISL1219_REG_YRT); WARN_ON(reg > ISL1219_REG_YRT);
WARN_ON(reg + len > ISL1219_REG_YRT + 1); WARN_ON(reg + len > ISL1219_REG_YRT + 1);
ret = i2c_transfer(client->adapter, msgs, 2); ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf);
if (ret > 0) return (ret < 0) ? ret : 0;
ret = 0;
return ret;
} }
/* block write */ /* block write */
...@@ -114,26 +98,13 @@ static int ...@@ -114,26 +98,13 @@ static int
isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
unsigned len) 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; int ret;
WARN_ON(reg > ISL1219_REG_YRT); WARN_ON(reg > ISL1219_REG_YRT);
WARN_ON(reg + len > ISL1219_REG_YRT + 1); WARN_ON(reg + len > ISL1219_REG_YRT + 1);
i2c_buf[0] = reg; ret = i2c_smbus_write_i2c_block_data(client, reg, len, buf);
memcpy(&i2c_buf[1], &buf[0], len); return (ret < 0) ? ret : 0;
ret = i2c_transfer(client->adapter, msgs, 1);
if (ret > 0)
ret = 0;
return ret;
} }
/* simple check to see whether we have a isl1208 */ /* simple check to see whether we have a isl1208 */
......
...@@ -217,7 +217,7 @@ static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -217,7 +217,7 @@ static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
sizeof(buf), buf); sizeof(buf), buf);
if (err < 0) { if (err < 0) {
dev_err(&client->dev, "Unable to read date\n"); dev_err(&client->dev, "Unable to read date\n");
return -EIO; return err;
} }
tm->tm_sec = bcd2bin(buf[M41T80_REG_SEC] & 0x7f); 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) ...@@ -274,10 +274,11 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
if (flags < 0) if (flags < 0)
return flags; return flags;
if (i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
flags & ~M41T80_FLAGS_OF)) { flags & ~M41T80_FLAGS_OF);
if (err < 0) {
dev_err(&client->dev, "Unable to write flags register\n"); dev_err(&client->dev, "Unable to write flags register\n");
return -EIO; return err;
} }
return err; return err;
...@@ -287,10 +288,12 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq) ...@@ -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 i2c_client *client = to_i2c_client(dev);
struct m41t80_data *clientdata = i2c_get_clientdata(client); struct m41t80_data *clientdata = i2c_get_clientdata(client);
u8 reg; int reg;
if (clientdata->features & M41T80_FEATURE_BL) { if (clientdata->features & M41T80_FEATURE_BL) {
reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
if (reg < 0)
return reg;
seq_printf(seq, "battery\t\t: %s\n", seq_printf(seq, "battery\t\t: %s\n",
(reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok"); (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
} }
...@@ -393,7 +396,7 @@ static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -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_min = bcd2bin(alarmvals[3] & 0x7f);
alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f); alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f);
alrm->time.tm_mday = bcd2bin(alarmvals[1] & 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->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE);
alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled; alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled;
...@@ -939,11 +942,7 @@ static int m41t80_probe(struct i2c_client *client, ...@@ -939,11 +942,7 @@ static int m41t80_probe(struct i2c_client *client,
if (m41t80_data->features & M41T80_FEATURE_HT) { if (m41t80_data->features & M41T80_FEATURE_HT) {
m41t80_rtc_read_time(&client->dev, &tm); m41t80_rtc_read_time(&client->dev, &tm);
dev_info(&client->dev, "HT bit was set!\n"); dev_info(&client->dev, "HT bit was set!\n");
dev_info(&client->dev, dev_info(&client->dev, "Power Down at %ptR\n", &tm);
"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);
} }
rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR, rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR,
rc & ~M41T80_ALHOUR_HT); rc & ~M41T80_ALHOUR_HT);
......
...@@ -99,9 +99,7 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -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); M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
spin_unlock_irqrestore(&m48t59->lock, flags); spin_unlock_irqrestore(&m48t59->lock, flags);
dev_dbg(dev, "RTC read time %04d-%02d-%02d %02d/%02d/%02d\n", dev_dbg(dev, "RTC read time %ptR\n", tm);
tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return 0; return 0;
} }
...@@ -188,9 +186,7 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -188,9 +186,7 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL); M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
spin_unlock_irqrestore(&m48t59->lock, flags); spin_unlock_irqrestore(&m48t59->lock, flags);
dev_dbg(dev, "RTC read alarm time %04d-%02d-%02d %02d/%02d/%02d\n", dev_dbg(dev, "RTC read alarm time %ptR\n", tm);
tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return rtc_valid_tm(tm); return rtc_valid_tm(tm);
} }
......
...@@ -86,7 +86,7 @@ static int max6916_set_time(struct device *dev, struct rtc_time *dt) ...@@ -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) { if (dt->tm_year < 100 || dt->tm_year > 199) {
dev_err(&spi->dev, "Year must be between 2000 and 2099. It's %d.\n", dev_err(&spi->dev, "Year must be between 2000 and 2099. It's %d.\n",
dt->tm_year + 1900); dt->tm_year + 1900);
return -EINVAL; return -EINVAL;
} }
buf[0] = MAX6916_CLOCK_BURST & 0x7F; buf[0] = MAX6916_CLOCK_BURST & 0x7F;
......
...@@ -360,7 +360,7 @@ static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -360,7 +360,7 @@ static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm)
out: out:
mutex_unlock(&info->lock); mutex_unlock(&info->lock);
return 0; return ret;
} }
static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm) static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm)
......
...@@ -215,7 +215,7 @@ static int max8997_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -215,7 +215,7 @@ static int max8997_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
out: out:
mutex_unlock(&info->lock); mutex_unlock(&info->lock);
return 0; return ret;
} }
static int max8997_rtc_stop_alarm(struct max8997_rtc_info *info) static int max8997_rtc_stop_alarm(struct max8997_rtc_info *info)
......
...@@ -233,9 +233,7 @@ static int mcp795_set_time(struct device *dev, struct rtc_time *tim) ...@@ -233,9 +233,7 @@ static int mcp795_set_time(struct device *dev, struct rtc_time *tim)
if (ret) if (ret)
return ret; return ret;
dev_dbg(dev, "Set mcp795: %04d-%02d-%02d(%d) %02d:%02d:%02d\n", dev_dbg(dev, "Set mcp795: %ptR\n", tim);
tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec);
return 0; return 0;
} }
...@@ -258,9 +256,7 @@ static int mcp795_read_time(struct device *dev, struct rtc_time *tim) ...@@ -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_mon = bcd2bin(data[5] & 0x1F) - 1;
tim->tm_year = bcd2bin(data[6]) + 100; /* Assume we are in 20xx */ 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", dev_dbg(dev, "Read from mcp795: %ptR\n", tim);
tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec);
return 0; return 0;
} }
...@@ -319,9 +315,8 @@ static int mcp795_set_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -319,9 +315,8 @@ static int mcp795_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
return ret; return ret;
dev_dbg(dev, "Alarm IRQ armed\n"); dev_dbg(dev, "Alarm IRQ armed\n");
} }
dev_dbg(dev, "Set alarm: %02d-%02d(%d) %02d:%02d:%02d\n", dev_dbg(dev, "Set alarm: %ptRdr(%d) %ptRt\n",
alm->time.tm_mon, alm->time.tm_mday, alm->time.tm_wday, &alm->time, alm->time.tm_wday, &alm->time);
alm->time.tm_hour, alm->time.tm_min, alm->time.tm_sec);
return 0; return 0;
} }
...@@ -345,9 +340,8 @@ static int mcp795_read_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -345,9 +340,8 @@ static int mcp795_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
alm->time.tm_isdst = -1; alm->time.tm_isdst = -1;
alm->time.tm_yday = -1; alm->time.tm_yday = -1;
dev_dbg(dev, "Read alarm: %02d-%02d(%d) %02d:%02d:%02d\n", dev_dbg(dev, "Read alarm: %ptRdr(%d) %ptRt\n",
alm->time.tm_mon, alm->time.tm_mday, alm->time.tm_wday, &alm->time, alm->time.tm_wday, &alm->time);
alm->time.tm_hour, alm->time.tm_min, alm->time.tm_sec);
return 0; return 0;
} }
......
...@@ -566,9 +566,7 @@ static const struct pinctrl_ops rtc_pinctrl_ops = { ...@@ -566,9 +566,7 @@ static const struct pinctrl_ops rtc_pinctrl_ops = {
.dt_free_map = pinconf_generic_dt_free_map, .dt_free_map = pinconf_generic_dt_free_map,
}; };
enum rtc_pin_config_param { #define PIN_CONFIG_ACTIVE_HIGH (PIN_CONFIG_END + 1)
PIN_CONFIG_ACTIVE_HIGH = PIN_CONFIG_END + 1,
};
static const struct pinconf_generic_params rtc_params[] = { static const struct pinconf_generic_params rtc_params[] = {
{"ti,active-high", PIN_CONFIG_ACTIVE_HIGH, 0}, {"ti,active-high", PIN_CONFIG_ACTIVE_HIGH, 0},
......
...@@ -453,6 +453,7 @@ static int pcf2123_remove(struct spi_device *spi) ...@@ -453,6 +453,7 @@ static int pcf2123_remove(struct spi_device *spi)
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id pcf2123_dt_ids[] = { static const struct of_device_id pcf2123_dt_ids[] = {
{ .compatible = "nxp,rtc-pcf2123", }, { .compatible = "nxp,rtc-pcf2123", },
{ .compatible = "microcrystal,rv2123", },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, pcf2123_dt_ids); MODULE_DEVICE_TABLE(of, pcf2123_dt_ids);
......
...@@ -131,9 +131,7 @@ static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -131,9 +131,7 @@ static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
pcf2rtc_time(tm, &pcf_tm); pcf2rtc_time(tm, &pcf_tm);
dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", dev_dbg(dev, "RTC_TIME: %ptRr\n", tm);
tm->tm_mday, tm->tm_mon, tm->tm_year,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return 0; return 0;
} }
...@@ -146,9 +144,7 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -146,9 +144,7 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc = dev_get_drvdata(dev); rtc = dev_get_drvdata(dev);
dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", dev_dbg(dev, "RTC_TIME: %ptRr\n", tm);
tm->tm_mday, tm->tm_mon, tm->tm_year,
tm->tm_hour, tm->tm_min, tm->tm_sec);
rtc2pcf_time(&pcf_tm, tm); rtc2pcf_time(&pcf_tm, tm);
......
...@@ -85,6 +85,18 @@ static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value) ...@@ -85,6 +85,18 @@ static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value)
return 0; 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) static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
{ {
u8 value; u8 value;
...@@ -167,6 +179,14 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -167,6 +179,14 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
struct i2c_msg msgs[2]; struct i2c_msg msgs[2];
int err; 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].addr = client->addr;
msgs[0].flags = 0; msgs[0].flags = 0;
msgs[0].len = 1; msgs[0].len = 1;
...@@ -251,17 +271,13 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd, ...@@ -251,17 +271,13 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
u8 value; int ret;
int ret = 0, err;
switch (cmd) { switch (cmd) {
case RTC_VL_READ: case RTC_VL_READ:
err = pcf8523_read(client, REG_CONTROL3, &value); ret = pcf8523_voltage_low(client);
if (err < 0) if (ret < 0)
return err; return ret;
if (value & REG_CONTROL3_BLF)
ret = 1;
if (copy_to_user((void __user *)arg, &ret, sizeof(int))) if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
return -EFAULT; return -EFAULT;
......
...@@ -120,6 +120,11 @@ struct pcf85363 { ...@@ -120,6 +120,11 @@ struct pcf85363 {
struct regmap *regmap; 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) static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct pcf85363 *pcf85363 = dev_get_drvdata(dev); struct pcf85363 *pcf85363 = dev_get_drvdata(dev);
...@@ -311,25 +316,75 @@ static int pcf85363_nvram_write(void *priv, unsigned int offset, void *val, ...@@ -311,25 +316,75 @@ static int pcf85363_nvram_write(void *priv, unsigned int offset, void *val,
val, bytes); val, bytes);
} }
static const struct regmap_config regmap_config = { static int pcf85x63_nvram_read(void *priv, unsigned int offset, void *val,
.reg_bits = 8, size_t bytes)
.val_bits = 8, {
.max_register = 0x7f, 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, static int pcf85363_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct pcf85363 *pcf85363; struct pcf85363 *pcf85363;
struct nvmem_config nvmem_cfg = { const struct pcf85x63_config *config = &pcf_85363_config;
.name = "pcf85363-", const void *data = of_device_get_match_data(&client->dev);
.word_size = 1, static struct nvmem_config nvmem_cfg[] = {
.stride = 1, {
.size = NVRAM_SIZE, .name = "pcf85x63-",
.reg_read = pcf85363_nvram_read, .word_size = 1,
.reg_write = pcf85363_nvram_write, .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)) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV; return -ENODEV;
...@@ -339,7 +394,7 @@ static int pcf85363_probe(struct i2c_client *client, ...@@ -339,7 +394,7 @@ static int pcf85363_probe(struct i2c_client *client,
if (!pcf85363) if (!pcf85363)
return -ENOMEM; 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)) { if (IS_ERR(pcf85363->regmap)) {
dev_err(&client->dev, "regmap allocation failed\n"); dev_err(&client->dev, "regmap allocation failed\n");
return PTR_ERR(pcf85363->regmap); return PTR_ERR(pcf85363->regmap);
...@@ -370,15 +425,18 @@ static int pcf85363_probe(struct i2c_client *client, ...@@ -370,15 +425,18 @@ static int pcf85363_probe(struct i2c_client *client,
ret = rtc_register_device(pcf85363->rtc); ret = rtc_register_device(pcf85363->rtc);
nvmem_cfg.priv = pcf85363; for (i = 0; i < config->num_nvram; i++) {
rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg); nvmem_cfg[i].priv = pcf85363;
rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg[i]);
}
return ret; return ret;
} }
static const struct of_device_id dev_ids[] = { 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); MODULE_DEVICE_TABLE(of, dev_ids);
...@@ -393,5 +451,5 @@ static struct i2c_driver pcf85363_driver = { ...@@ -393,5 +451,5 @@ static struct i2c_driver pcf85363_driver = {
module_i2c_driver(pcf85363_driver); module_i2c_driver(pcf85363_driver);
MODULE_AUTHOR("Eric Nelson"); MODULE_AUTHOR("Eric Nelson");
MODULE_DESCRIPTION("pcf85363 I2C RTC driver"); MODULE_DESCRIPTION("pcf85263/pcf85363 I2C RTC driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -170,9 +170,7 @@ static int pic32_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) ...@@ -170,9 +170,7 @@ static int pic32_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_year += 100; rtc_tm->tm_year += 100;
dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n", dev_dbg(dev, "read time %ptR\n", rtc_tm);
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);
clk_disable(pdata->clk); clk_disable(pdata->clk);
return 0; return 0;
...@@ -184,9 +182,7 @@ static int pic32_rtc_settime(struct device *dev, struct rtc_time *tm) ...@@ -184,9 +182,7 @@ static int pic32_rtc_settime(struct device *dev, struct rtc_time *tm)
void __iomem *base = pdata->reg_base; void __iomem *base = pdata->reg_base;
int year = tm->tm_year - 100; int year = tm->tm_year - 100;
dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n", dev_dbg(dev, "set time %ptR\n", tm);
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
if (year < 0 || year >= 100) { if (year < 0 || year >= 100) {
dev_err(dev, "rtc only supports 100 years\n"); 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) ...@@ -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; alrm->enabled = (alm_en & PIC32_RTCALRM_ALRMEN) ? 1 : 0;
dev_dbg(dev, "getalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", dev_dbg(dev, "getalarm: %d, %ptR\n", alm_en, alm_tm);
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);
alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
alm_tm->tm_min = bcd2bin(alm_tm->tm_min); 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) ...@@ -247,10 +240,7 @@ static int pic32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
void __iomem *base = pdata->reg_base; void __iomem *base = pdata->reg_base;
clk_enable(pdata->clk); clk_enable(pdata->clk);
dev_dbg(dev, "setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", dev_dbg(dev, "setalarm: %d, %ptR\n", alrm->enabled, tm);
alrm->enabled,
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
writel(0x00, base + PIC32_ALRMTIME); writel(0x00, base + PIC32_ALRMTIME);
writel(0x00, base + PIC32_ALRMDATE); writel(0x00, base + PIC32_ALRMDATE);
......
...@@ -217,9 +217,7 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -217,9 +217,7 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time_to_tm(secs, 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", dev_dbg(dev, "secs = %lu, h:m:s == %ptRt, y-m-d = %ptRdr\n", secs, tm, tm);
secs, tm->tm_hour, tm->tm_min, tm->tm_sec,
tm->tm_mday, tm->tm_mon, tm->tm_year);
return 0; return 0;
} }
...@@ -264,10 +262,8 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) ...@@ -264,10 +262,8 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
goto rtc_rw_fail; goto rtc_rw_fail;
} }
dev_dbg(dev, "Alarm Set for h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n", dev_dbg(dev, "Alarm Set for h:m:s=%ptRt, y-m-d=%ptRdr\n",
alarm->time.tm_hour, alarm->time.tm_min, &alarm->time, &alarm->time);
alarm->time.tm_sec, alarm->time.tm_mday,
alarm->time.tm_mon, alarm->time.tm_year);
rtc_rw_fail: rtc_rw_fail:
spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
return rc; return rc;
...@@ -298,10 +294,8 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) ...@@ -298,10 +294,8 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
return rc; return rc;
} }
dev_dbg(dev, "Alarm set for - h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n", dev_dbg(dev, "Alarm set for - h:m:s=%ptRt, y-m-d=%ptRdr\n",
alarm->time.tm_hour, alarm->time.tm_min, &alarm->time, &alarm->time);
alarm->time.tm_sec, alarm->time.tm_mday,
alarm->time.tm_mon, alarm->time.tm_year);
return 0; return 0;
} }
......
...@@ -90,9 +90,7 @@ static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) ...@@ -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); rtc_time_to_tm(readl(RTC_RCNR), rtc_tm);
dev_dbg(dev, "read time %02x.%02x.%02x %02x/%02x/%02x\n", dev_dbg(dev, "read time %ptRr\n", rtc_tm);
rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
return 0; return 0;
} }
...@@ -101,9 +99,7 @@ static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm) ...@@ -101,9 +99,7 @@ static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm)
{ {
unsigned long rtc_count = 0; unsigned long rtc_count = 0;
dev_dbg(dev, "set time %02d.%02d.%02d %02d/%02d/%02d\n", dev_dbg(dev, "set time %ptRr\n", tm);
tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
rtc_tm_to_time(tm, &rtc_count); rtc_tm_to_time(tm, &rtc_count);
writel(rtc_count, RTC_RCNR); writel(rtc_count, RTC_RCNR);
...@@ -119,10 +115,7 @@ static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -119,10 +115,7 @@ static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE; alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE;
dev_dbg(dev, "read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n", dev_dbg(dev, "read alarm: %d, %ptRr\n", alrm->enabled, alm_tm);
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);
return 0; return 0;
} }
...@@ -132,10 +125,7 @@ static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -132,10 +125,7 @@ static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rtc_time *tm = &alrm->time; struct rtc_time *tm = &alrm->time;
unsigned long rtcalarm_count = 0; unsigned long rtcalarm_count = 0;
dev_dbg(dev, "puv3_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", dev_dbg(dev, "set alarm: %d, %ptRr\n", alrm->enabled, tm);
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);
rtc_tm_to_time(tm, &rtcalarm_count); rtc_tm_to_time(tm, &rtcalarm_count);
writel(rtcalarm_count, RTC_RTAR); writel(rtcalarm_count, RTC_RTAR);
......
...@@ -138,9 +138,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) ...@@ -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_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100;
tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK); tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
rockchip_to_gregorian(tm); rockchip_to_gregorian(tm);
dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", dev_dbg(dev, "RTC date/time %ptRd(%d) %ptRt\n", tm, tm->tm_wday, tm);
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
return ret; return ret;
} }
...@@ -153,9 +151,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -153,9 +151,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
u8 rtc_data[NUM_TIME_REGS]; u8 rtc_data[NUM_TIME_REGS];
int ret; int ret;
dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", dev_dbg(dev, "set RTC date/time %ptRd(%d) %ptRt\n", tm, tm->tm_wday, tm);
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
gregorian_to_rockchip(tm); gregorian_to_rockchip(tm);
rtc_data[0] = bin2bcd(tm->tm_sec); rtc_data[0] = bin2bcd(tm->tm_sec);
rtc_data[1] = bin2bcd(tm->tm_min); rtc_data[1] = bin2bcd(tm->tm_min);
...@@ -216,10 +212,8 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -216,10 +212,8 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret; return ret;
} }
dev_dbg(dev, "alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", dev_dbg(dev, "alrm read RTC date/time %ptRd(%d) %ptRt\n",
1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, &alrm->time, alrm->time.tm_wday, &alrm->time);
alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
alrm->time.tm_min, alrm->time.tm_sec);
alrm->enabled = (int_reg & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M) ? 1 : 0; 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) ...@@ -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); dev_err(dev, "Failed to stop alarm: %d\n", ret);
return ret; return ret;
} }
dev_dbg(dev, "alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", dev_dbg(dev, "alrm set RTC date/time %ptRd(%d) %ptRt\n",
1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, &alrm->time, alrm->time.tm_wday, &alrm->time);
alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
alrm->time.tm_min, alrm->time.tm_sec);
gregorian_to_rockchip(&alrm->time); gregorian_to_rockchip(&alrm->time);
alrm_data[0] = bin2bcd(alrm->time.tm_sec); alrm_data[0] = bin2bcd(alrm->time.tm_sec);
...@@ -400,7 +392,7 @@ static int rk808_rtc_probe(struct platform_device *pdev) ...@@ -400,7 +392,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Failed to write RTC status: %d\n", ret); "Failed to write RTC status: %d\n", ret);
return ret; return ret;
} }
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
......
...@@ -114,9 +114,7 @@ struct rx6110_data { ...@@ -114,9 +114,7 @@ struct rx6110_data {
*/ */
static int rx6110_rtc_tm_to_data(struct rtc_time *tm, u8 *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__, pr_debug("%s: date %ptRr\n", __func__, tm);
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year);
/* /*
* The year in the RTC is a value between 0 and 99. * 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) ...@@ -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_mon = bcd2bin(data[RTC_MONTH] & 0x1f) - 1;
tm->tm_year = bcd2bin(data[RTC_YEAR]) + 100; tm->tm_year = bcd2bin(data[RTC_YEAR]) + 100;
pr_debug("%s: date %ds %dm %dh %dmd %dm %dy\n", __func__, pr_debug("%s: date %ptRr\n", __func__, tm);
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year);
/* /*
* The year in the RTC is a value between 0 and 99. * 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) ...@@ -248,9 +244,7 @@ static int rx6110_get_time(struct device *dev, struct rtc_time *tm)
if (ret) if (ret)
return ret; return ret;
dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__, dev_dbg(dev, "%s: date %ptRr\n", __func__, tm);
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year);
return 0; return 0;
} }
......
...@@ -193,10 +193,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt) ...@@ -193,10 +193,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
if (err) if (err)
return err; return err;
dev_dbg(dev, "%s: read 0x%02x 0x%02x " dev_dbg(dev, "%s: read %7ph\n", __func__, date);
"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]);
dt->tm_sec = bcd2bin(date[RX8025_REG_SEC] & 0x7f); dt->tm_sec = bcd2bin(date[RX8025_REG_SEC] & 0x7f);
dt->tm_min = bcd2bin(date[RX8025_REG_MIN] & 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) ...@@ -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_mon = bcd2bin(date[RX8025_REG_MONTH] & 0x1f) - 1;
dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]) + 100; dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]) + 100;
dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__, dev_dbg(dev, "%s: date %ptRr\n", __func__, dt);
dt->tm_sec, dt->tm_min, dt->tm_hour,
dt->tm_mday, dt->tm_mon, dt->tm_year);
return 0; return 0;
} }
...@@ -243,10 +238,7 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt) ...@@ -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_MONTH] = bin2bcd(dt->tm_mon + 1);
date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year - 100); date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year - 100);
dev_dbg(dev, dev_dbg(dev, "%s: write %7ph\n", __func__, date);
"%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]);
ret = rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date); ret = rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date);
if (ret < 0) if (ret < 0)
...@@ -319,10 +311,7 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -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 t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12
+ (ald[1] & 0x20 ? 12 : 0); + (ald[1] & 0x20 ? 12 : 0);
dev_dbg(dev, "%s: date: %ds %dm %dh %dmd %dm %dy\n", dev_dbg(dev, "%s: date: %ptRr\n", __func__, t);
__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);
t->enabled = !!(rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE); t->enabled = !!(rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE);
t->pending = (ctrl2 & RX8025_BIT_CTRL2_DAFG) && t->enabled; t->pending = (ctrl2 & RX8025_BIT_CTRL2_DAFG) && t->enabled;
......
...@@ -225,13 +225,9 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) ...@@ -225,13 +225,9 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
s3c_rtc_disable_clk(info); s3c_rtc_disable_clk(info);
rtc_tm->tm_year += 100; 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; rtc_tm->tm_mon -= 1;
dev_dbg(dev, "read time %ptR\n", rtc_tm);
return 0; return 0;
} }
...@@ -241,9 +237,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) ...@@ -241,9 +237,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
int year = tm->tm_year - 100; int year = tm->tm_year - 100;
int ret; int ret;
dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n", dev_dbg(dev, "set time %ptR\n", tm);
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
/* we get around y2k by simply not supporting it */ /* 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) ...@@ -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; alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
dev_dbg(dev, "read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n", dev_dbg(dev, "read alarm %d, %ptR\n", alm_en, alm_tm);
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);
/* decode the alarm enable field */ /* decode the alarm enable field */
if (alm_en & S3C2410_RTCALM_SECEN) if (alm_en & S3C2410_RTCALM_SECEN)
...@@ -327,12 +318,8 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -327,12 +318,8 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rtc_time *tm = &alrm->time; struct rtc_time *tm = &alrm->time;
unsigned int alrm_en; unsigned int alrm_en;
int ret; int ret;
int year = tm->tm_year - 100;
dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", dev_dbg(dev, "s3c_rtc_setalarm: %d, %ptR\n", alrm->enabled, tm);
alrm->enabled,
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
ret = s3c_rtc_enable_clk(info); ret = s3c_rtc_enable_clk(info);
if (ret) if (ret)
...@@ -356,11 +343,6 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -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); 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) { if (tm->tm_mon < 12 && tm->tm_mon >= 0) {
alrm_en |= S3C2410_RTCALM_MONEN; alrm_en |= S3C2410_RTCALM_MONEN;
writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_ALMMON); writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_ALMMON);
......
...@@ -406,9 +406,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -406,9 +406,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
return -EINVAL; return -EINVAL;
} }
dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, dev_dbg(dev, "%s: %ptR(%d)\n", __func__, tm, tm->tm_wday);
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
return 0; return 0;
} }
...@@ -436,9 +434,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -436,9 +434,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
if (ret < 0) if (ret < 0)
return ret; return ret;
dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, dev_dbg(dev, "%s: %ptR(%d)\n", __func__, tm, tm->tm_wday);
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
ret = regmap_raw_write(info->regmap, info->regs->time, data, ret = regmap_raw_write(info->regmap, info->regs->time, data,
info->regs->regs_count); info->regs->regs_count);
...@@ -490,11 +486,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -490,11 +486,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return -EINVAL; return -EINVAL;
} }
dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, dev_dbg(dev, "%s: %ptR(%d)\n", __func__, &alrm->time, alrm->time.tm_wday);
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);
ret = s5m_check_peding_alarm_interrupt(info, alrm); ret = s5m_check_peding_alarm_interrupt(info, alrm);
...@@ -513,9 +505,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) ...@@ -513,9 +505,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
return ret; return ret;
s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode); s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday);
1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
switch (info->device_type) { switch (info->device_type) {
case S5M8763X: case S5M8763X:
...@@ -558,9 +548,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) ...@@ -558,9 +548,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
return ret; return ret;
s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode); s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday);
1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
switch (info->device_type) { switch (info->device_type) {
case S5M8763X: case S5M8763X:
...@@ -620,10 +608,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -620,10 +608,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return -EINVAL; return -EINVAL;
} }
dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, dev_dbg(dev, "%s: %ptR(%d)\n", __func__, &alrm->time, alrm->time.tm_wday);
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);
ret = s5m_rtc_stop_alarm(info); ret = s5m_rtc_stop_alarm(info);
if (ret < 0) if (ret < 0)
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* SuperH On-Chip RTC Support * SuperH On-Chip RTC Support
* *
...@@ -9,10 +10,6 @@ ...@@ -9,10 +10,6 @@
* *
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka * 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/module.h>
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
...@@ -681,5 +678,5 @@ MODULE_DESCRIPTION("SuperH on-chip RTC driver"); ...@@ -681,5 +678,5 @@ MODULE_DESCRIPTION("SuperH on-chip RTC driver");
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, " MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, "
"Jamie Lenehan <lenehan@twibble.org>, " "Jamie Lenehan <lenehan@twibble.org>, "
"Angelo Castello <angelo.castello@st.com>"); "Angelo Castello <angelo.castello@st.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME); MODULE_ALIAS("platform:" DRV_NAME);
...@@ -118,9 +118,31 @@ ...@@ -118,9 +118,31 @@
#define SUN6I_YEAR_MAX 2033 #define SUN6I_YEAR_MAX 2033
#define SUN6I_YEAR_OFF (SUN6I_YEAR_MIN - 1900) #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 sun6i_rtc_dev {
struct rtc_device *rtc; struct rtc_device *rtc;
struct device *dev; struct device *dev;
const struct sun6i_rtc_clk_data *data;
void __iomem *base; void __iomem *base;
int irq; int irq;
unsigned long alarm; unsigned long alarm;
...@@ -139,14 +161,19 @@ static unsigned long sun6i_rtc_osc_recalc_rate(struct clk_hw *hw, ...@@ -139,14 +161,19 @@ static unsigned long sun6i_rtc_osc_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate) unsigned long parent_rate)
{ {
struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw); 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); val = readl(rtc->base + SUN6I_LOSC_CTRL);
if (val & SUN6I_LOSC_CTRL_EXT_OSC) if (val & SUN6I_LOSC_CTRL_EXT_OSC)
return parent_rate; return parent_rate;
val = readl(rtc->base + SUN6I_LOSC_CLK_PRESCAL); if (rtc->data->fixed_prescaler)
val &= GENMASK(4, 0); 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); return parent_rate / (val + 1);
} }
...@@ -185,13 +212,16 @@ static const struct clk_ops sun6i_rtc_osc_ops = { ...@@ -185,13 +212,16 @@ static const struct clk_ops sun6i_rtc_osc_ops = {
.set_parent = sun6i_rtc_osc_set_parent, .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 clk_hw_onecell_data *clk_data;
struct sun6i_rtc_dev *rtc; struct sun6i_rtc_dev *rtc;
struct clk_init_data init = { struct clk_init_data init = {
.ops = &sun6i_rtc_osc_ops, .ops = &sun6i_rtc_osc_ops,
.name = "losc",
}; };
const char *iosc_name = "rtc-int-osc";
const char *clkout_name = "osc32k-out"; const char *clkout_name = "osc32k-out";
const char *parents[2]; const char *parents[2];
...@@ -199,7 +229,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) ...@@ -199,7 +229,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
if (!rtc) if (!rtc)
return; 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) { if (!clk_data) {
kfree(rtc); kfree(rtc);
return; return;
...@@ -224,10 +255,15 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) ...@@ -224,10 +255,15 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
if (!of_get_property(node, "clocks", NULL)) if (!of_get_property(node, "clocks", NULL))
goto err; 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 = clk_hw_register_fixed_rate_with_accuracy(NULL,
"rtc-int-osc", iosc_name,
NULL, 0, NULL, 0,
667000, rtc->data->rc_osc_rate,
300000000); 300000000);
if (IS_ERR(rtc->int_osc)) { if (IS_ERR(rtc->int_osc)) {
pr_crit("Couldn't register the internal oscillator\n"); pr_crit("Couldn't register the internal oscillator\n");
...@@ -264,14 +300,71 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) ...@@ -264,14 +300,71 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
clk_data->num = 2; clk_data->num = 2;
clk_data->hws[0] = &rtc->hw; clk_data->hws[0] = &rtc->hw;
clk_data->hws[1] = __clk_get_hw(rtc->ext_losc); 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); of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
return; return;
err: err:
kfree(clk_data); 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) static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
{ {
...@@ -578,8 +671,18 @@ static int sun6i_rtc_probe(struct platform_device *pdev) ...@@ -578,8 +671,18 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
return 0; 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[] = { static const struct of_device_id sun6i_rtc_dt_ids[] = {
{ .compatible = "allwinner,sun6i-a31-rtc" }, { .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 */ }, { /* sentinel */ },
}; };
MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids); MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
......
...@@ -125,15 +125,7 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -125,15 +125,7 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
rtc_time_to_tm(sec, tm); rtc_time_to_tm(sec, tm);
dev_vdbg(dev, "time read as %lu. %d/%d/%d %d:%02u:%02u\n", dev_vdbg(dev, "time read as %lu. %ptR\n", sec, tm);
sec,
tm->tm_mon + 1,
tm->tm_mday,
tm->tm_year + 1900,
tm->tm_hour,
tm->tm_min,
tm->tm_sec
);
return 0; return 0;
} }
...@@ -147,15 +139,7 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -147,15 +139,7 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* convert tm to seconds. */ /* convert tm to seconds. */
rtc_tm_to_time(tm, &sec); rtc_tm_to_time(tm, &sec);
dev_vdbg(dev, "time set to %lu. %d/%d/%d %d:%02u:%02u\n", dev_vdbg(dev, "time set to %lu. %ptR\n", sec, tm);
sec,
tm->tm_mon+1,
tm->tm_mday,
tm->tm_year+1900,
tm->tm_hour,
tm->tm_min,
tm->tm_sec
);
/* seconds only written if wait succeeded. */ /* seconds only written if wait succeeded. */
ret = tegra_rtc_wait_while_busy(dev); ret = tegra_rtc_wait_while_busy(dev);
...@@ -232,15 +216,7 @@ static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) ...@@ -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 successfully written and alarm is enabled ... */
if (sec) { if (sec) {
tegra_rtc_alarm_irq_enable(dev, 1); tegra_rtc_alarm_irq_enable(dev, 1);
dev_vdbg(dev, "alarm set as %lu. %ptR\n", sec, &alarm->time);
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);
} else { } else {
/* disable alarm if 0 or write error. */ /* disable alarm if 0 or write error. */
dev_vdbg(dev, "alarm disabled\n"); dev_vdbg(dev, "alarm disabled\n");
......
...@@ -39,12 +39,10 @@ date_show(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -39,12 +39,10 @@ date_show(struct device *dev, struct device_attribute *attr, char *buf)
struct rtc_time tm; struct rtc_time tm;
retval = rtc_read_time(to_rtc_device(dev), &tm); retval = rtc_read_time(to_rtc_device(dev), &tm);
if (retval == 0) { if (retval)
retval = sprintf(buf, "%04d-%02d-%02d\n", return retval;
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
}
return retval; return sprintf(buf, "%ptRd\n", &tm);
} }
static DEVICE_ATTR_RO(date); static DEVICE_ATTR_RO(date);
...@@ -55,12 +53,10 @@ time_show(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -55,12 +53,10 @@ time_show(struct device *dev, struct device_attribute *attr, char *buf)
struct rtc_time tm; struct rtc_time tm;
retval = rtc_read_time(to_rtc_device(dev), &tm); retval = rtc_read_time(to_rtc_device(dev), &tm);
if (retval == 0) { if (retval)
retval = sprintf(buf, "%02d:%02d:%02d\n", return retval;
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
return retval; return sprintf(buf, "%ptRt\n", &tm);
} }
static DEVICE_ATTR_RO(time); static DEVICE_ATTR_RO(time);
......
...@@ -87,15 +87,16 @@ struct rtc_class_ops { ...@@ -87,15 +87,16 @@ struct rtc_class_ops {
int (*set_offset)(struct device *, long offset); int (*set_offset)(struct device *, long offset);
}; };
struct rtc_device;
struct rtc_timer { struct rtc_timer {
struct timerqueue_node node; struct timerqueue_node node;
ktime_t period; ktime_t period;
void (*func)(void *private_data); void (*func)(struct rtc_device *rtc);
void *private_data; struct rtc_device *rtc;
int enabled; int enabled;
}; };
/* flags */ /* flags */
#define RTC_DEV_BUSY 0 #define RTC_DEV_BUSY 0
...@@ -138,7 +139,6 @@ struct rtc_device { ...@@ -138,7 +139,6 @@ struct rtc_device {
bool registered; bool registered;
struct nvmem_device *nvmem;
/* Old ABI support */ /* Old ABI support */
bool nvram_old_abi; bool nvram_old_abi;
struct bin_attribute *nvram; struct bin_attribute *nvram;
...@@ -173,8 +173,6 @@ extern struct rtc_device *devm_rtc_device_register(struct device *dev, ...@@ -173,8 +173,6 @@ extern struct rtc_device *devm_rtc_device_register(struct device *dev,
struct module *owner); struct module *owner);
struct rtc_device *devm_rtc_allocate_device(struct device *dev); struct rtc_device *devm_rtc_allocate_device(struct device *dev);
int __rtc_register_device(struct module *owner, struct rtc_device *rtc); 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_read_time(struct rtc_device *rtc, struct rtc_time *tm);
extern int rtc_set_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, ...@@ -200,11 +198,12 @@ extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc,
unsigned int enabled); unsigned int enabled);
void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode); void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode);
void rtc_aie_update_irq(void *private); void rtc_aie_update_irq(struct rtc_device *rtc);
void rtc_uie_update_irq(void *private); void rtc_uie_update_irq(struct rtc_device *rtc);
enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer); 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, int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer,
ktime_t expires, ktime_t period); ktime_t expires, ktime_t period);
void rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer); void rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/printk.h> #include <linux/printk.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/rtc.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -249,12 +250,11 @@ plain_format(void) ...@@ -249,12 +250,11 @@ plain_format(void)
#endif /* BITS_PER_LONG == 64 */ #endif /* BITS_PER_LONG == 64 */
static int __init 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; int nchars;
nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); nchars = snprintf(buf, len, "%p", p);
if (nchars != PTR_WIDTH) if (nchars != PTR_WIDTH)
return -1; return -1;
...@@ -265,6 +265,20 @@ plain_hash(void) ...@@ -265,6 +265,20 @@ plain_hash(void)
return 0; 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) if (strncmp(buf, PTR_STR, PTR_WIDTH) == 0)
return -1; return -1;
...@@ -294,6 +308,23 @@ plain(void) ...@@ -294,6 +308,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 static void __init
symbol_ptr(void) symbol_ptr(void)
{ {
...@@ -418,6 +449,29 @@ struct_va_format(void) ...@@ -418,6 +449,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 static void __init
struct_clk(void) struct_clk(void)
{ {
...@@ -529,6 +583,7 @@ test_pointer(void) ...@@ -529,6 +583,7 @@ test_pointer(void)
uuid(); uuid();
dentry(); dentry();
struct_va_format(); struct_va_format();
struct_rtc_time();
struct_clk(); struct_clk();
bitmap(); bitmap();
netdev_features(); netdev_features();
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/dcache.h> #include <linux/dcache.h>
#include <linux/cred.h> #include <linux/cred.h>
#include <linux/rtc.h>
#include <linux/uuid.h> #include <linux/uuid.h>
#include <linux/of.h> #include <linux/of.h>
#include <net/addrconf.h> #include <net/addrconf.h>
...@@ -822,6 +823,20 @@ static const struct printf_spec default_dec_spec = { ...@@ -822,6 +823,20 @@ static const struct printf_spec default_dec_spec = {
.precision = -1, .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 static noinline_for_stack
char *resource_string(char *buf, char *end, struct resource *res, char *resource_string(char *buf, char *end, struct resource *res,
struct printf_spec spec, const char *fmt) struct printf_spec spec, const char *fmt)
...@@ -1549,6 +1564,87 @@ char *address_val(char *buf, char *end, const void *addr, const char *fmt) ...@@ -1549,6 +1564,87 @@ char *address_val(char *buf, char *end, const void *addr, const char *fmt)
return special_hex_number(buf, end, num, size); return special_hex_number(buf, end, num, size);
} }
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 static noinline_for_stack
char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec, char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec,
const char *fmt) const char *fmt)
...@@ -1828,6 +1924,8 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, ...@@ -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]' For a dentry name (optionally 2-4 last components)
* - 'D[234]' Same as 'd' but for a struct file * - 'D[234]' Same as 'd' but for a struct file
* - 'g' For block_device name (gendisk + partition number) * - '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 * - 'C' For a clock, it prints the name (Common Clock Framework) or address
* (legacy clock framework) of the clock * (legacy clock framework) of the clock
* - 'Cn' For a clock, it prints the name (Common Clock Framework) or address * - '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, ...@@ -1952,6 +2050,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
return address_val(buf, end, ptr, fmt); return address_val(buf, end, ptr, fmt);
case 'd': case 'd':
return dentry_name(buf, end, ptr, spec, fmt); return dentry_name(buf, end, ptr, spec, fmt);
case 't':
return time_and_date(buf, end, ptr, spec, fmt);
case 'C': case 'C':
return clock(buf, end, ptr, spec, fmt); return clock(buf, end, ptr, spec, fmt);
case 'D': case 'D':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment