Skip to content
Snippets Groups Projects
Commit 28e8c4bc authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
No related branches found
No related tags found
No related merge requests found
Showing
with 151 additions and 258 deletions
...@@ -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");
......
File moved
...@@ -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
......
File moved
...@@ -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",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment