RTC for 4.21
Subsystem: - new %ptR printk format - rename core files - allow registration of multiple nvmem devices New driver: - i.MX system controller RTC Drivers: - 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEXx9Viay1+e7J/aM4AyWl4gNJNJIFAlwqU44ACgkQAyWl4gNJ NJJjGxAAgQMTkarMx16icKpN35iuXgwZdIKKmWIHGyCJeB1ykHS8TgwkP+4pE1aN UwTw6x9TBxa9KpuexCgrx8/zppM0i1jacaxJkDbrj1OBPAlGrbJrwcSH029qHAu6 N1Oo0GvAIPlEmIJkKVWkgZhGqUwvMvcy2amk06S92PPOIfr5zJsRzNmduEE7bpcl 86EckuFOp9c1p4IayeQhIT+GHPtum4WkmGVw3+j0j/E6aCUD3thLohT+KuGfzzKn jHbtZ+/d17etKtxxI26YrmixH603t66ZSuc64rSvKRKYR8u/qqR3ZTotYVonsPHj NNQsWiNRzwkpiN9n1Big0tLJyXJ6qbYQIrJLMc19Jr10tS815WF5rjmNinfdSazX 4xucIJpMh7VgA3W5BpvN1+UEahiznp2QGiLjauoruMrB7XUUSLPv6VohFiKAfd9S 7SyV2moPWVnj4pJPH6Af2zVLE9YyPoWGvUSwosLZKhpoFNLOnVZAU0vo32M/23wv ejv4YPhtqxqT94XUyrWKE1DaTpxMqBHcHj2ThV+NGCWe4C0+KfW0zmbKm1X588UJ ZhmGODV9acU+46It5mFoE2Zb9WPyEwljjxbvXKQZhdONKIoZ6lz1i7nzy6C2qerQ ZW5baiaCvQ5e/NyWLxEZwvHukBo2OBxkXe8isuk/wz+7Qyw3l34= =5He5 -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
28e8c4bc8e
|
@ -412,6 +412,24 @@ Examples::
|
|||
|
||||
Passed by reference.
|
||||
|
||||
Time and date (struct rtc_time)
|
||||
-------------------------------
|
||||
|
||||
::
|
||||
|
||||
%ptR YYYY-mm-ddTHH:MM:SS
|
||||
%ptRd YYYY-mm-dd
|
||||
%ptRt HH:MM:SS
|
||||
%ptR[dt][r]
|
||||
|
||||
For printing date and time as represented by struct rtc_time structure in
|
||||
human readable format.
|
||||
|
||||
By default year will be incremented by 1900 and month by 1. Use %ptRr (raw)
|
||||
to suppress this behaviour.
|
||||
|
||||
Passed by reference.
|
||||
|
||||
struct clk
|
||||
----------
|
||||
|
||||
|
|
|
@ -109,6 +109,12 @@ Required properties for Pinctrl sub nodes:
|
|||
[2] Documentation/devicetree/bindings/power/power_domain.txt
|
||||
[3] Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
|
||||
|
||||
RTC bindings based on SCU Message Protocol
|
||||
------------------------------------------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "fsl,imx8qxp-sc-rtc";
|
||||
|
||||
Example (imx8qxp):
|
||||
-------------
|
||||
lsio_mu1: mailbox@5d1c0000 {
|
||||
|
@ -151,6 +157,10 @@ firmware {
|
|||
compatible = "fsl,imx8qxp-scu-pd";
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
rtc: rtc {
|
||||
compatible = "fsl,imx8qxp-sc-rtc";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -27,4 +27,4 @@ and valid to enable charging:
|
|||
|
||||
- "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
|
||||
- "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
|
||||
resistor, the other values are in ohm.
|
||||
resistor, the other values are in kOhm.
|
||||
|
|
|
@ -2,6 +2,7 @@ NXP PCF2123 SPI Real Time Clock
|
|||
|
||||
Required properties:
|
||||
- compatible: should be: "nxp,rtc-pcf2123"
|
||||
or "microcrystal,rv2123"
|
||||
- reg: should be the SPI slave chipselect address
|
||||
|
||||
Optional properties:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
NXP PCF85363 Real Time Clock
|
||||
NXP PCF85263/PCF85363 Real Time Clock
|
||||
============================
|
||||
|
||||
Required properties:
|
||||
- compatible: Should contain "nxp,pcf85363".
|
||||
- compatible: Should contain "nxp,pcf85263" or "nxp,pcf85363".
|
||||
- reg: I2C address for chip.
|
||||
|
||||
Optional properties:
|
||||
|
|
|
@ -35,7 +35,7 @@ Optional properties:
|
|||
Should be given if internal trickle charger diode should be disabled
|
||||
|
||||
Example:
|
||||
rtc1: ds1339@68 {
|
||||
ds1339: rtc@68 {
|
||||
compatible = "dallas,ds1339";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&gpio4>;
|
||||
|
|
|
@ -3,25 +3,44 @@
|
|||
RTC controller for the Allwinner A31
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "allwinner,sun6i-a31-rtc"
|
||||
- compatible : Should be one of the following combinations:
|
||||
- "allwinner,sun6i-a31-rtc"
|
||||
- "allwinner,sun8i-a23-rtc"
|
||||
- "allwinner,sun8i-h3-rtc"
|
||||
- "allwinner,sun8i-r40-rtc", "allwinner,sun8i-h3-rtc"
|
||||
- "allwinner,sun8i-v3-rtc"
|
||||
- "allwinner,sun50i-a64-rtc", "allwinner,sun8i-h3-rtc"
|
||||
- "allwinner,sun50i-h5-rtc"
|
||||
|
||||
Where there are two or more compatible strings, this
|
||||
denotes the hardware covered by the most specific one
|
||||
is backward-compatible with the latter ones, and the
|
||||
implementation for the latter ones can be used, albeit
|
||||
with reduced functionality.
|
||||
|
||||
- reg : physical base address of the controller and length of
|
||||
memory mapped region.
|
||||
- interrupts : IRQ lines for the RTC alarm 0 and alarm 1, in that order.
|
||||
|
||||
Required properties for new device trees
|
||||
- clocks : phandle to the 32kHz external oscillator
|
||||
- clock-output-names : names of the LOSC and its external output clocks created
|
||||
- #clock-cells : must be equals to 1. The RTC provides two clocks: the
|
||||
LOSC and its external output, with index 0 and 1
|
||||
respectively.
|
||||
- clock-output-names : names of up to three clock outputs. See below.
|
||||
- #clock-cells : must be equal to 1.
|
||||
|
||||
The RTC provides the following clocks at the given indices:
|
||||
- 0: LOSC
|
||||
- 1: LOSC external output, known as X32KFOUT in the datasheet.
|
||||
This clock is not available on the A31 and is deprecated for old
|
||||
device trees still using the "allwinner,sun6i-a31-rtc" compatible.
|
||||
- 2: InternalOSC, or internal RC oscillator (A64/H3/H5 only)
|
||||
|
||||
Example:
|
||||
|
||||
rtc: rtc@1f00000 {
|
||||
compatible = "allwinner,sun6i-a31-rtc";
|
||||
reg = <0x01f00000 0x54>;
|
||||
reg = <0x01f00000 0x400>;
|
||||
interrupts = <0 40 4>, <0 41 4>;
|
||||
clock-output-names = "osc32k", "osc32k-out";
|
||||
clock-output-names = "osc32k";
|
||||
clocks = <&ext_osc32k>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
|
|
@ -605,13 +605,9 @@ int mac_hwclk(int op, struct rtc_time *t)
|
|||
unmktime(now, 0,
|
||||
&t->tm_year, &t->tm_mon, &t->tm_mday,
|
||||
&t->tm_hour, &t->tm_min, &t->tm_sec);
|
||||
pr_debug("%s: read %04d-%02d-%-2d %02d:%02d:%02d\n",
|
||||
__func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec);
|
||||
pr_debug("%s: read %ptR\n", __func__, t);
|
||||
} else { /* write */
|
||||
pr_debug("%s: tried to write %04d-%02d-%-2d %02d:%02d:%02d\n",
|
||||
__func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec);
|
||||
pr_debug("%s: tried to write %ptR\n", __func__, t);
|
||||
|
||||
switch (macintosh_config->adb_type) {
|
||||
case MAC_ADB_IOP:
|
||||
|
|
|
@ -118,9 +118,7 @@ static unsigned int read_magic_time(void)
|
|||
unsigned int val;
|
||||
|
||||
mc146818_get_time(&time);
|
||||
pr_info("RTC time: %2d:%02d:%02d, date: %02d/%02d/%02d\n",
|
||||
time.tm_hour, time.tm_min, time.tm_sec,
|
||||
time.tm_mon + 1, time.tm_mday, time.tm_year % 100);
|
||||
pr_info("RTC time: %ptRt, date: %ptRd\n", &time, &time);
|
||||
val = time.tm_year; /* 100 years */
|
||||
if (val > 100)
|
||||
val -= 100;
|
||||
|
|
|
@ -1125,11 +1125,10 @@ static int rtc_proc_show(struct seq_file *seq, void *v)
|
|||
* time or for Universal Standard Time (GMT). Probably local though.
|
||||
*/
|
||||
seq_printf(seq,
|
||||
"rtc_time\t: %02d:%02d:%02d\n"
|
||||
"rtc_date\t: %04d-%02d-%02d\n"
|
||||
"rtc_time\t: %ptRt\n"
|
||||
"rtc_date\t: %ptRd\n"
|
||||
"rtc_epoch\t: %04lu\n",
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
|
||||
&tm, &tm, epoch);
|
||||
|
||||
get_rtc_alm_time(&tm);
|
||||
|
||||
|
|
|
@ -441,12 +441,10 @@ static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v)
|
|||
seq_puts(m, "BBRTC\t\t: READ FAILED!\n");
|
||||
} else {
|
||||
seq_printf(m,
|
||||
"rtc_time\t: %02d:%02d:%02d\n"
|
||||
"rtc_date\t: %04d-%02d-%02d\n"
|
||||
"rtc_time\t: %ptRt\n"
|
||||
"rtc_date\t: %ptRd\n"
|
||||
"rtc_epoch\t: %04lu\n",
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||
tm.tm_year + 1900, tm.tm_mon + 1,
|
||||
tm.tm_mday, epoch);
|
||||
&tm, &tm, epoch);
|
||||
}
|
||||
|
||||
if (hp_sdc_rtc_read_rt(&tv)) {
|
||||
|
|
|
@ -1677,6 +1677,13 @@ config RTC_DRV_SNVS
|
|||
This driver can also be built as a module, if so, the module
|
||||
will be called "rtc-snvs".
|
||||
|
||||
config RTC_DRV_IMX_SC
|
||||
depends on IMX_SCU
|
||||
tristate "NXP i.MX System Controller RTC support"
|
||||
help
|
||||
If you say yes here you get support for the NXP i.MX System
|
||||
Controller RTC module.
|
||||
|
||||
config RTC_DRV_SIRFSOC
|
||||
tristate "SiRFSOC RTC"
|
||||
depends on ARCH_SIRF
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
ccflags-$(CONFIG_RTC_DEBUG) := -DDEBUG
|
||||
|
||||
obj-$(CONFIG_RTC_LIB) += rtc-lib.o
|
||||
obj-$(CONFIG_RTC_LIB) += lib.o
|
||||
obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
|
||||
obj-$(CONFIG_RTC_SYSTOHC) += systohc.o
|
||||
obj-$(CONFIG_RTC_CLASS) += rtc-core.o
|
||||
|
@ -17,9 +17,9 @@ rtc-core-y += rtc-efi-platform.o
|
|||
endif
|
||||
|
||||
rtc-core-$(CONFIG_RTC_NVMEM) += nvmem.o
|
||||
rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
|
||||
rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
|
||||
rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
|
||||
rtc-core-$(CONFIG_RTC_INTF_DEV) += dev.o
|
||||
rtc-core-$(CONFIG_RTC_INTF_PROC) += proc.o
|
||||
rtc-core-$(CONFIG_RTC_INTF_SYSFS) += sysfs.o
|
||||
|
||||
# Keep the list ordered.
|
||||
|
||||
|
@ -75,6 +75,7 @@ obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o
|
|||
obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
|
||||
obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o
|
||||
obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o
|
||||
obj-$(CONFIG_RTC_DRV_IMX_SC) += rtc-imx-sc.o
|
||||
obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
|
||||
obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o
|
||||
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
|
||||
|
|
|
@ -178,9 +178,9 @@ static struct rtc_device *rtc_allocate_device(void)
|
|||
timerqueue_init_head(&rtc->timerqueue);
|
||||
INIT_WORK(&rtc->irqwork, rtc_timer_do_work);
|
||||
/* Init aie timer */
|
||||
rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc);
|
||||
rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, rtc);
|
||||
/* Init uie timer */
|
||||
rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc);
|
||||
rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, rtc);
|
||||
/* Init pie timer */
|
||||
hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
rtc->pie_timer.function = rtc_pie_update_irq;
|
||||
|
@ -277,82 +277,6 @@ static void rtc_device_get_offset(struct rtc_device *rtc)
|
|||
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
|
||||
*
|
||||
|
@ -372,77 +296,6 @@ static void rtc_device_unregister(struct rtc_device *rtc)
|
|||
put_device(&rtc->dev);
|
||||
}
|
||||
|
||||
static void devm_rtc_device_release(struct device *dev, void *res)
|
||||
{
|
||||
struct rtc_device *rtc = *(struct rtc_device **)res;
|
||||
|
||||
rtc_nvmem_unregister(rtc);
|
||||
rtc_device_unregister(rtc);
|
||||
}
|
||||
|
||||
static int devm_rtc_device_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct rtc **r = res;
|
||||
|
||||
return *r == data;
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_rtc_device_register - resource managed rtc_device_register()
|
||||
* @dev: the device to register
|
||||
* @name: the name of the device
|
||||
* @ops: the rtc operations structure
|
||||
* @owner: the module owner
|
||||
*
|
||||
* @return a struct rtc on success, or an ERR_PTR on error
|
||||
*
|
||||
* Managed rtc_device_register(). The rtc_device returned from this function
|
||||
* are automatically freed on driver detach. See rtc_device_register()
|
||||
* for more information.
|
||||
*/
|
||||
|
||||
struct rtc_device *devm_rtc_device_register(struct device *dev,
|
||||
const char *name,
|
||||
const struct rtc_class_ops *ops,
|
||||
struct module *owner)
|
||||
{
|
||||
struct rtc_device **ptr, *rtc;
|
||||
|
||||
ptr = devres_alloc(devm_rtc_device_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
rtc = rtc_device_register(name, dev, ops, owner);
|
||||
if (!IS_ERR(rtc)) {
|
||||
*ptr = rtc;
|
||||
devres_add(dev, ptr);
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
|
||||
return rtc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_rtc_device_register);
|
||||
|
||||
/**
|
||||
* devm_rtc_device_unregister - resource managed devm_rtc_device_unregister()
|
||||
* @dev: the device to unregister
|
||||
* @rtc: the RTC class device to unregister
|
||||
*
|
||||
* Deallocated a rtc allocated with devm_rtc_device_register(). Normally this
|
||||
* function will not need to be called and the resource management code will
|
||||
* ensure that the resource is freed.
|
||||
*/
|
||||
void devm_rtc_device_unregister(struct device *dev, struct rtc_device *rtc)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = devres_release(dev, devm_rtc_device_release,
|
||||
devm_rtc_device_match, rtc);
|
||||
WARN_ON(rc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_rtc_device_unregister);
|
||||
|
||||
static void devm_rtc_release_device(struct device *dev, void *res)
|
||||
{
|
||||
struct rtc_device *rtc = *(struct rtc_device **)res;
|
||||
|
@ -529,6 +382,42 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(__rtc_register_device);
|
||||
|
||||
/**
|
||||
* devm_rtc_device_register - resource managed rtc_device_register()
|
||||
* @dev: the device to register
|
||||
* @name: the name of the device (unused)
|
||||
* @ops: the rtc operations structure
|
||||
* @owner: the module owner
|
||||
*
|
||||
* @return a struct rtc on success, or an ERR_PTR on error
|
||||
*
|
||||
* Managed rtc_device_register(). The rtc_device returned from this function
|
||||
* are automatically freed on driver detach.
|
||||
* This function is deprecated, use devm_rtc_allocate_device and
|
||||
* rtc_register_device instead
|
||||
*/
|
||||
struct rtc_device *devm_rtc_device_register(struct device *dev,
|
||||
const char *name,
|
||||
const struct rtc_class_ops *ops,
|
||||
struct module *owner)
|
||||
{
|
||||
struct rtc_device *rtc;
|
||||
int err;
|
||||
|
||||
rtc = devm_rtc_allocate_device(dev);
|
||||
if (IS_ERR(rtc))
|
||||
return rtc;
|
||||
|
||||
rtc->ops = ops;
|
||||
|
||||
err = __rtc_register_device(owner, rtc);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
return rtc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_rtc_device_register);
|
||||
|
||||
static int __init rtc_init(void)
|
||||
{
|
||||
rtc_class = class_create(THIS_MODULE, "rtc");
|
||||
|
|
|
@ -58,12 +58,8 @@ static int __init rtc_hctosys(void)
|
|||
|
||||
err = do_settimeofday64(&tv64);
|
||||
|
||||
dev_info(rtc->dev.parent,
|
||||
"setting system clock to "
|
||||
"%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||
(long long) tv64.tv_sec);
|
||||
dev_info(rtc->dev.parent, "setting system clock to %ptR UTC (%lld)\n",
|
||||
&tm, (long long)tv64.tv_sec);
|
||||
|
||||
err_read:
|
||||
rtc_class_close(rtc);
|
||||
|
|
|
@ -368,12 +368,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
|||
err = rtc_valid_tm(&alarm->time);
|
||||
|
||||
done:
|
||||
if (err) {
|
||||
dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n",
|
||||
alarm->time.tm_year + 1900, alarm->time.tm_mon + 1,
|
||||
alarm->time.tm_mday, alarm->time.tm_hour, alarm->time.tm_min,
|
||||
alarm->time.tm_sec);
|
||||
}
|
||||
if (err)
|
||||
dev_warn(&rtc->dev, "invalid alarm value: %ptR\n", &alarm->time);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -613,26 +609,24 @@ void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
|
|||
|
||||
/**
|
||||
* rtc_aie_update_irq - AIE mode rtctimer hook
|
||||
* @private: pointer to the rtc_device
|
||||
* @rtc: pointer to the rtc_device
|
||||
*
|
||||
* This functions is called when the aie_timer expires.
|
||||
*/
|
||||
void rtc_aie_update_irq(void *private)
|
||||
void rtc_aie_update_irq(struct rtc_device *rtc)
|
||||
{
|
||||
struct rtc_device *rtc = (struct rtc_device *)private;
|
||||
rtc_handle_legacy_irq(rtc, 1, RTC_AF);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* rtc_uie_update_irq - UIE mode rtctimer hook
|
||||
* @private: pointer to the rtc_device
|
||||
* @rtc: pointer to the rtc_device
|
||||
*
|
||||
* This functions is called when the uie_timer expires.
|
||||
*/
|
||||
void rtc_uie_update_irq(void *private)
|
||||
void rtc_uie_update_irq(struct rtc_device *rtc)
|
||||
{
|
||||
struct rtc_device *rtc = (struct rtc_device *)private;
|
||||
rtc_handle_legacy_irq(rtc, 1, RTC_UF);
|
||||
}
|
||||
|
||||
|
@ -912,7 +906,7 @@ again:
|
|||
trace_rtc_timer_dequeue(timer);
|
||||
timer->enabled = 0;
|
||||
if (timer->func)
|
||||
timer->func(timer->private_data);
|
||||
timer->func(timer->rtc);
|
||||
|
||||
trace_rtc_timer_fired(timer);
|
||||
/* Re-add/fwd periodic timers */
|
||||
|
@ -959,16 +953,17 @@ reprogram:
|
|||
/* rtc_timer_init - Initializes an rtc_timer
|
||||
* @timer: timer to be intiialized
|
||||
* @f: function pointer to be called when timer fires
|
||||
* @data: private data passed to function pointer
|
||||
* @rtc: pointer to the rtc_device
|
||||
*
|
||||
* Kernel interface to initializing an rtc_timer.
|
||||
*/
|
||||
void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data)
|
||||
void rtc_timer_init(struct rtc_timer *timer, void (*f)(struct rtc_device *r),
|
||||
struct rtc_device *rtc)
|
||||
{
|
||||
timerqueue_init(&timer->node);
|
||||
timer->enabled = 0;
|
||||
timer->func = f;
|
||||
timer->private_data = data;
|
||||
timer->rtc = rtc;
|
||||
}
|
||||
|
||||
/* rtc_timer_start - Sets an rtc_timer to fire in the future
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
/*
|
||||
|
@ -25,11 +26,9 @@ rtc_nvram_read(struct file *filp, struct kobject *kobj,
|
|||
struct bin_attribute *attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct rtc_device *rtc = attr->private;
|
||||
|
||||
dev_warn_once(kobj_to_dev(kobj), nvram_warning);
|
||||
|
||||
return nvmem_device_read(rtc->nvmem, off, count, buf);
|
||||
return nvmem_device_read(attr->private, off, count, buf);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
|
@ -37,26 +36,23 @@ rtc_nvram_write(struct file *filp, struct kobject *kobj,
|
|||
struct bin_attribute *attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct rtc_device *rtc = attr->private;
|
||||
|
||||
dev_warn_once(kobj_to_dev(kobj), nvram_warning);
|
||||
|
||||
return nvmem_device_write(rtc->nvmem, off, count, buf);
|
||||
return nvmem_device_write(attr->private, off, count, buf);
|
||||
}
|
||||
|
||||
static int rtc_nvram_register(struct rtc_device *rtc, size_t size)
|
||||
static int rtc_nvram_register(struct rtc_device *rtc,
|
||||
struct nvmem_device *nvmem, size_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
rtc->nvram = devm_kzalloc(rtc->dev.parent,
|
||||
sizeof(struct bin_attribute),
|
||||
GFP_KERNEL);
|
||||
rtc->nvram = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL);
|
||||
if (!rtc->nvram)
|
||||
return -ENOMEM;
|
||||
|
||||
rtc->nvram->attr.name = "nvram";
|
||||
rtc->nvram->attr.mode = 0644;
|
||||
rtc->nvram->private = rtc;
|
||||
rtc->nvram->private = nvmem;
|
||||
|
||||
sysfs_bin_attr_init(rtc->nvram);
|
||||
|
||||
|
@ -67,7 +63,7 @@ static int rtc_nvram_register(struct rtc_device *rtc, size_t size)
|
|||
err = sysfs_create_bin_file(&rtc->dev.parent->kobj,
|
||||
rtc->nvram);
|
||||
if (err) {
|
||||
devm_kfree(rtc->dev.parent, rtc->nvram);
|
||||
kfree(rtc->nvram);
|
||||
rtc->nvram = NULL;
|
||||
}
|
||||
|
||||
|
@ -77,6 +73,8 @@ static int rtc_nvram_register(struct rtc_device *rtc, size_t size)
|
|||
static void rtc_nvram_unregister(struct rtc_device *rtc)
|
||||
{
|
||||
sysfs_remove_bin_file(&rtc->dev.parent->kobj, rtc->nvram);
|
||||
kfree(rtc->nvram);
|
||||
rtc->nvram = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -85,21 +83,20 @@ static void rtc_nvram_unregister(struct rtc_device *rtc)
|
|||
int rtc_nvmem_register(struct rtc_device *rtc,
|
||||
struct nvmem_config *nvmem_config)
|
||||
{
|
||||
if (!IS_ERR_OR_NULL(rtc->nvmem))
|
||||
return -EBUSY;
|
||||
struct nvmem_device *nvmem;
|
||||
|
||||
if (!nvmem_config)
|
||||
return -ENODEV;
|
||||
|
||||
nvmem_config->dev = rtc->dev.parent;
|
||||
nvmem_config->owner = rtc->owner;
|
||||
rtc->nvmem = nvmem_register(nvmem_config);
|
||||
if (IS_ERR(rtc->nvmem))
|
||||
return PTR_ERR(rtc->nvmem);
|
||||
nvmem = devm_nvmem_register(rtc->dev.parent, nvmem_config);
|
||||
if (IS_ERR(nvmem))
|
||||
return PTR_ERR(nvmem);
|
||||
|
||||
/* Register the old ABI */
|
||||
if (rtc->nvram_old_abi)
|
||||
rtc_nvram_register(rtc, nvmem_config->size);
|
||||
rtc_nvram_register(rtc, nvmem, nvmem_config->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -107,12 +104,7 @@ EXPORT_SYMBOL_GPL(rtc_nvmem_register);
|
|||
|
||||
void rtc_nvmem_unregister(struct rtc_device *rtc)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(rtc->nvmem))
|
||||
return;
|
||||
|
||||
/* unregister the old ABI */
|
||||
if (rtc->nvram)
|
||||
rtc_nvram_unregister(rtc);
|
||||
|
||||
nvmem_unregister(rtc->nvmem);
|
||||
}
|
||||
|
|
|
@ -50,41 +50,15 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
|
|||
err = rtc_read_time(rtc, &tm);
|
||||
if (err == 0) {
|
||||
seq_printf(seq,
|
||||
"rtc_time\t: %02d:%02d:%02d\n"
|
||||
"rtc_date\t: %04d-%02d-%02d\n",
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
|
||||
"rtc_time\t: %ptRt\n"
|
||||
"rtc_date\t: %ptRd\n",
|
||||
&tm, &tm);
|
||||
}
|
||||
|
||||
err = rtc_read_alarm(rtc, &alrm);
|
||||
if (err == 0) {
|
||||
seq_printf(seq, "alrm_time\t: ");
|
||||
if ((unsigned int)alrm.time.tm_hour <= 24)
|
||||
seq_printf(seq, "%02d:", alrm.time.tm_hour);
|
||||
else
|
||||
seq_printf(seq, "**:");
|
||||
if ((unsigned int)alrm.time.tm_min <= 59)
|
||||
seq_printf(seq, "%02d:", alrm.time.tm_min);
|
||||
else
|
||||
seq_printf(seq, "**:");
|
||||
if ((unsigned int)alrm.time.tm_sec <= 59)
|
||||
seq_printf(seq, "%02d\n", alrm.time.tm_sec);
|
||||
else
|
||||
seq_printf(seq, "**\n");
|
||||
|
||||
seq_printf(seq, "alrm_date\t: ");
|
||||
if ((unsigned int)alrm.time.tm_year <= 200)
|
||||
seq_printf(seq, "%04d-", alrm.time.tm_year + 1900);
|
||||
else
|
||||
seq_printf(seq, "****-");
|
||||
if ((unsigned int)alrm.time.tm_mon <= 11)
|
||||
seq_printf(seq, "%02d-", alrm.time.tm_mon + 1);
|
||||
else
|
||||
seq_printf(seq, "**-");
|
||||
if (alrm.time.tm_mday && (unsigned int)alrm.time.tm_mday <= 31)
|
||||
seq_printf(seq, "%02d\n", alrm.time.tm_mday);
|
||||
else
|
||||
seq_printf(seq, "**\n");
|
||||
seq_printf(seq, "alrm_time\t: %ptRt\n", &alrm.time);
|
||||
seq_printf(seq, "alrm_date\t: %ptRd\n", &alrm.time);
|
||||
seq_printf(seq, "alarm_IRQ\t: %s\n",
|
||||
alrm.enabled ? "yes" : "no");
|
||||
seq_printf(seq, "alrm_pending\t: %s\n",
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#define ABX8XX_REG_STATUS 0x0f
|
||||
#define ABX8XX_STATUS_AF BIT(2)
|
||||
#define ABX8XX_STATUS_BLF BIT(4)
|
||||
#define ABX8XX_STATUS_WDT BIT(6)
|
||||
|
||||
#define ABX8XX_REG_CTRL1 0x10
|
||||
|
@ -507,12 +508,49 @@ static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int abx80x_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int status, tmp;
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_VL_READ:
|
||||
status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
tmp = !!(status & ABX8XX_STATUS_BLF);
|
||||
|
||||
if (copy_to_user((void __user *)arg, &tmp, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
||||
case RTC_VL_CLR:
|
||||
status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
status &= ~ABX8XX_STATUS_BLF;
|
||||
|
||||
tmp = i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0);
|
||||
if (tmp < 0)
|
||||
return tmp;
|
||||
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops abx80x_rtc_ops = {
|
||||
.read_time = abx80x_rtc_read_time,
|
||||
.set_time = abx80x_rtc_set_time,
|
||||
.read_alarm = abx80x_read_alarm,
|
||||
.set_alarm = abx80x_set_alarm,
|
||||
.alarm_irq_enable = abx80x_alarm_irq_enable,
|
||||
.ioctl = abx80x_ioctl,
|
||||
};
|
||||
|
||||
static int abx80x_dt_trickle_cfg(struct device_node *np)
|
||||
|
|
|
@ -147,9 +147,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm)
|
|||
tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
|
||||
tm->tm_year = tm->tm_year - 1900;
|
||||
|
||||
dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
|
||||
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "%s(): %ptR\n", __func__, tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -161,9 +159,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
|
|||
{
|
||||
unsigned long cr;
|
||||
|
||||
dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
|
||||
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "%s(): %ptR\n", __func__, tm);
|
||||
|
||||
wait_for_completion(&at91_rtc_upd_rdy);
|
||||
|
||||
|
@ -209,8 +205,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM)
|
||||
? 1 : 0;
|
||||
|
||||
dev_dbg(dev, "%s(): %02d-%02d %02d:%02d:%02d %sabled\n", __func__,
|
||||
tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||
dev_dbg(dev, "%s(): %ptR %sabled\n", __func__, tm,
|
||||
alrm->enabled ? "en" : "dis");
|
||||
|
||||
return 0;
|
||||
|
@ -247,9 +242,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
at91_rtc_write_ier(AT91_RTC_ALARM);
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
|
||||
tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
|
||||
tm.tm_min, tm.tm_sec);
|
||||
dev_dbg(dev, "%s(): %ptR\n", __func__, &tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -124,9 +124,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm)
|
|||
|
||||
rtc_time_to_tm(offset + secs, tm);
|
||||
|
||||
dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readtime",
|
||||
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "%s: %ptR\n", __func__, tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -141,9 +139,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
|
|||
u32 offset, alarm, mr;
|
||||
unsigned long secs;
|
||||
|
||||
dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "settime",
|
||||
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "%s: %ptR\n", __func__, tm);
|
||||
|
||||
err = rtc_tm_to_time(tm, &secs);
|
||||
if (err != 0)
|
||||
|
@ -199,9 +195,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
if (alarm != ALARM_DISABLED && offset != 0) {
|
||||
rtc_time_to_tm(offset + alarm, tm);
|
||||
|
||||
dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readalarm",
|
||||
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "%s: %ptR\n", __func__, tm);
|
||||
|
||||
if (rtt_readl(rtc, MR) & AT91_RTT_ALMIEN)
|
||||
alrm->enabled = 1;
|
||||
|
@ -242,9 +236,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
if (alrm->enabled)
|
||||
rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
|
||||
|
||||
dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "setalarm",
|
||||
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
|
||||
tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "%s: %ptR\n", __func__, tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP.
|
||||
*/
|
||||
|
||||
#include <linux/firmware/imx/sci.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
#define IMX_SC_TIMER_FUNC_GET_RTC_SEC1970 9
|
||||
#define IMX_SC_TIMER_FUNC_SET_RTC_TIME 6
|
||||
|
||||
static struct imx_sc_ipc *rtc_ipc_handle;
|
||||
static struct rtc_device *imx_sc_rtc;
|
||||
|
||||
struct imx_sc_msg_timer_get_rtc_time {
|
||||
struct imx_sc_rpc_msg hdr;
|
||||
u32 time;
|
||||
} __packed;
|
||||
|
||||
static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct imx_sc_msg_timer_get_rtc_time msg;
|
||||
struct imx_sc_rpc_msg *hdr = &msg.hdr;
|
||||
int ret;
|
||||
|
||||
hdr->ver = IMX_SC_RPC_VERSION;
|
||||
hdr->svc = IMX_SC_RPC_SVC_TIMER;
|
||||
hdr->func = IMX_SC_TIMER_FUNC_GET_RTC_SEC1970;
|
||||
hdr->size = 1;
|
||||
|
||||
ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true);
|
||||
if (ret) {
|
||||
dev_err(dev, "read rtc time failed, ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rtc_time_to_tm(msg.time, tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops imx_sc_rtc_ops = {
|
||||
.read_time = imx_sc_rtc_read_time,
|
||||
};
|
||||
|
||||
static int imx_sc_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = imx_scu_get_handle(&rtc_ipc_handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
imx_sc_rtc = devm_rtc_allocate_device(&pdev->dev);
|
||||
if (IS_ERR(imx_sc_rtc))
|
||||
return PTR_ERR(imx_sc_rtc);
|
||||
|
||||
imx_sc_rtc->ops = &imx_sc_rtc_ops;
|
||||
imx_sc_rtc->range_min = 0;
|
||||
imx_sc_rtc->range_max = U32_MAX;
|
||||
|
||||
ret = rtc_register_device(imx_sc_rtc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id imx_sc_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx8qxp-sc-rtc", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_sc_dt_ids);
|
||||
|
||||
static struct platform_driver imx_sc_rtc_driver = {
|
||||
.driver = {
|
||||
.name = "imx-sc-rtc",
|
||||
.of_match_table = imx_sc_dt_ids,
|
||||
},
|
||||
.probe = imx_sc_rtc_probe,
|
||||
};
|
||||
module_platform_driver(imx_sc_rtc_driver);
|
||||
|
||||
MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX System Controller RTC Driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -84,29 +84,13 @@ static int
|
|||
isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
|
||||
unsigned len)
|
||||
{
|
||||
u8 reg_addr[1] = { reg };
|
||||
struct i2c_msg msgs[2] = {
|
||||
{
|
||||
.addr = client->addr,
|
||||
.len = sizeof(reg_addr),
|
||||
.buf = reg_addr
|
||||
},
|
||||
{
|
||||
.addr = client->addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
.buf = buf
|
||||
}
|
||||
};
|
||||
int ret;
|
||||
|
||||
WARN_ON(reg > ISL1219_REG_YRT);
|
||||
WARN_ON(reg + len > ISL1219_REG_YRT + 1);
|
||||
|
||||
ret = i2c_transfer(client->adapter, msgs, 2);
|
||||
if (ret > 0)
|
||||
ret = 0;
|
||||
return ret;
|
||||
ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf);
|
||||
return (ret < 0) ? ret : 0;
|
||||
}
|
||||
|
||||
/* block write */
|
||||
|
@ -114,26 +98,13 @@ static int
|
|||
isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
|
||||
unsigned len)
|
||||
{
|
||||
u8 i2c_buf[ISL1208_REG_USR2 + 2];
|
||||
struct i2c_msg msgs[1] = {
|
||||
{
|
||||
.addr = client->addr,
|
||||
.len = len + 1,
|
||||
.buf = i2c_buf
|
||||
}
|
||||
};
|
||||
int ret;
|
||||
|
||||
WARN_ON(reg > ISL1219_REG_YRT);
|
||||
WARN_ON(reg + len > ISL1219_REG_YRT + 1);
|
||||
|
||||
i2c_buf[0] = reg;
|
||||
memcpy(&i2c_buf[1], &buf[0], len);
|
||||
|
||||
ret = i2c_transfer(client->adapter, msgs, 1);
|
||||
if (ret > 0)
|
||||
ret = 0;
|
||||
return ret;
|
||||
ret = i2c_smbus_write_i2c_block_data(client, reg, len, buf);
|
||||
return (ret < 0) ? ret : 0;
|
||||
}
|
||||
|
||||
/* simple check to see whether we have a isl1208 */
|
||||
|
|
|
@ -217,7 +217,7 @@ static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|||
sizeof(buf), buf);
|
||||
if (err < 0) {
|
||||
dev_err(&client->dev, "Unable to read date\n");
|
||||
return -EIO;
|
||||
return err;
|
||||
}
|
||||
|
||||
tm->tm_sec = bcd2bin(buf[M41T80_REG_SEC] & 0x7f);
|
||||
|
@ -274,10 +274,11 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
|||
if (flags < 0)
|
||||
return flags;
|
||||
|
||||
if (i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
|
||||
flags & ~M41T80_FLAGS_OF)) {
|
||||
err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
|
||||
flags & ~M41T80_FLAGS_OF);
|
||||
if (err < 0) {
|
||||
dev_err(&client->dev, "Unable to write flags register\n");
|
||||
return -EIO;
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -287,10 +288,12 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
|
|||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct m41t80_data *clientdata = i2c_get_clientdata(client);
|
||||
u8 reg;
|
||||
int reg;
|
||||
|
||||
if (clientdata->features & M41T80_FEATURE_BL) {
|
||||
reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
seq_printf(seq, "battery\t\t: %s\n",
|
||||
(reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
|
||||
}
|
||||
|
@ -393,7 +396,7 @@ static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
alrm->time.tm_min = bcd2bin(alarmvals[3] & 0x7f);
|
||||
alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f);
|
||||
alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f);
|
||||
alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f);
|
||||
alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f) - 1;
|
||||
|
||||
alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE);
|
||||
alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled;
|
||||
|
@ -939,11 +942,7 @@ static int m41t80_probe(struct i2c_client *client,
|
|||
if (m41t80_data->features & M41T80_FEATURE_HT) {
|
||||
m41t80_rtc_read_time(&client->dev, &tm);
|
||||
dev_info(&client->dev, "HT bit was set!\n");
|
||||
dev_info(&client->dev,
|
||||
"Power Down at %04i-%02i-%02i %02i:%02i:%02i\n",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
|
||||
tm.tm_min, tm.tm_sec);
|
||||
dev_info(&client->dev, "Power Down at %ptR\n", &tm);
|
||||
}
|
||||
rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR,
|
||||
rc & ~M41T80_ALHOUR_HT);
|
||||
|
|
|
@ -99,9 +99,7 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|||
M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
|
||||
spin_unlock_irqrestore(&m48t59->lock, flags);
|
||||
|
||||
dev_dbg(dev, "RTC read time %04d-%02d-%02d %02d/%02d/%02d\n",
|
||||
tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "RTC read time %ptR\n", tm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -188,9 +186,7 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
|
||||
spin_unlock_irqrestore(&m48t59->lock, flags);
|
||||
|
||||
dev_dbg(dev, "RTC read alarm time %04d-%02d-%02d %02d/%02d/%02d\n",
|
||||
tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "RTC read alarm time %ptR\n", tm);
|
||||
return rtc_valid_tm(tm);
|
||||
}
|
||||
|
||||
|
|
|
@ -360,7 +360,7 @@ static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|||
|
||||
out:
|
||||
mutex_unlock(&info->lock);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
|
|
|
@ -215,7 +215,7 @@ static int max8997_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
|
||||
out:
|
||||
mutex_unlock(&info->lock);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max8997_rtc_stop_alarm(struct max8997_rtc_info *info)
|
||||
|
|
|
@ -233,9 +233,7 @@ static int mcp795_set_time(struct device *dev, struct rtc_time *tim)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_dbg(dev, "Set mcp795: %04d-%02d-%02d(%d) %02d:%02d:%02d\n",
|
||||
tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
|
||||
tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec);
|
||||
dev_dbg(dev, "Set mcp795: %ptR\n", tim);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -258,9 +256,7 @@ static int mcp795_read_time(struct device *dev, struct rtc_time *tim)
|
|||
tim->tm_mon = bcd2bin(data[5] & 0x1F) - 1;
|
||||
tim->tm_year = bcd2bin(data[6]) + 100; /* Assume we are in 20xx */
|
||||
|
||||
dev_dbg(dev, "Read from mcp795: %04d-%02d-%02d(%d) %02d:%02d:%02d\n",
|
||||
tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
|
||||
tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec);
|
||||
dev_dbg(dev, "Read from mcp795: %ptR\n", tim);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -319,9 +315,8 @@ static int mcp795_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
|
|||
return ret;
|
||||
dev_dbg(dev, "Alarm IRQ armed\n");
|
||||
}
|
||||
dev_dbg(dev, "Set alarm: %02d-%02d(%d) %02d:%02d:%02d\n",
|
||||
alm->time.tm_mon, alm->time.tm_mday, alm->time.tm_wday,
|
||||
alm->time.tm_hour, alm->time.tm_min, alm->time.tm_sec);
|
||||
dev_dbg(dev, "Set alarm: %ptRdr(%d) %ptRt\n",
|
||||
&alm->time, alm->time.tm_wday, &alm->time);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -345,9 +340,8 @@ static int mcp795_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
|
|||
alm->time.tm_isdst = -1;
|
||||
alm->time.tm_yday = -1;
|
||||
|
||||
dev_dbg(dev, "Read alarm: %02d-%02d(%d) %02d:%02d:%02d\n",
|
||||
alm->time.tm_mon, alm->time.tm_mday, alm->time.tm_wday,
|
||||
alm->time.tm_hour, alm->time.tm_min, alm->time.tm_sec);
|
||||
dev_dbg(dev, "Read alarm: %ptRdr(%d) %ptRt\n",
|
||||
&alm->time, alm->time.tm_wday, &alm->time);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -566,9 +566,7 @@ static const struct pinctrl_ops rtc_pinctrl_ops = {
|
|||
.dt_free_map = pinconf_generic_dt_free_map,
|
||||
};
|
||||
|
||||
enum rtc_pin_config_param {
|
||||
PIN_CONFIG_ACTIVE_HIGH = PIN_CONFIG_END + 1,
|
||||
};
|
||||
#define PIN_CONFIG_ACTIVE_HIGH (PIN_CONFIG_END + 1)
|
||||
|
||||
static const struct pinconf_generic_params rtc_params[] = {
|
||||
{"ti,active-high", PIN_CONFIG_ACTIVE_HIGH, 0},
|
||||
|
|
|
@ -453,6 +453,7 @@ static int pcf2123_remove(struct spi_device *spi)
|
|||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id pcf2123_dt_ids[] = {
|
||||
{ .compatible = "nxp,rtc-pcf2123", },
|
||||
{ .compatible = "microcrystal,rv2123", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pcf2123_dt_ids);
|
||||
|
|
|
@ -131,9 +131,7 @@ static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|||
|
||||
pcf2rtc_time(tm, &pcf_tm);
|
||||
|
||||
dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
|
||||
tm->tm_mday, tm->tm_mon, tm->tm_year,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "RTC_TIME: %ptRr\n", tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -146,9 +144,7 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
|||
|
||||
rtc = dev_get_drvdata(dev);
|
||||
|
||||
dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
|
||||
tm->tm_mday, tm->tm_mon, tm->tm_year,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "RTC_TIME: %ptRr\n", tm);
|
||||
|
||||
rtc2pcf_time(&pcf_tm, tm);
|
||||
|
||||
|
|
|
@ -85,6 +85,18 @@ static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pcf8523_voltage_low(struct i2c_client *client)
|
||||
{
|
||||
u8 value;
|
||||
int err;
|
||||
|
||||
err = pcf8523_read(client, REG_CONTROL3, &value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return !!(value & REG_CONTROL3_BLF);
|
||||
}
|
||||
|
||||
static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
|
||||
{
|
||||
u8 value;
|
||||
|
@ -167,6 +179,14 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|||
struct i2c_msg msgs[2];
|
||||
int err;
|
||||
|
||||
err = pcf8523_voltage_low(client);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
} else if (err > 0) {
|
||||
dev_err(dev, "low voltage detected, time is unreliable\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msgs[0].addr = client->addr;
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].len = 1;
|
||||
|
@ -251,17 +271,13 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
|
|||
unsigned long arg)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
u8 value;
|
||||
int ret = 0, err;
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_VL_READ:
|
||||
err = pcf8523_read(client, REG_CONTROL3, &value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (value & REG_CONTROL3_BLF)
|
||||
ret = 1;
|
||||
ret = pcf8523_voltage_low(client);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
|
|
@ -120,6 +120,11 @@ struct pcf85363 {
|
|||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
struct pcf85x63_config {
|
||||
struct regmap_config regmap;
|
||||
unsigned int num_nvram;
|
||||
};
|
||||
|
||||
static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct pcf85363 *pcf85363 = dev_get_drvdata(dev);
|
||||
|
@ -311,25 +316,75 @@ static int pcf85363_nvram_write(void *priv, unsigned int offset, void *val,
|
|||
val, bytes);
|
||||
}
|
||||
|
||||
static const struct regmap_config regmap_config = {
|
||||
static int pcf85x63_nvram_read(void *priv, unsigned int offset, void *val,
|
||||
size_t bytes)
|
||||
{
|
||||
struct pcf85363 *pcf85363 = priv;
|
||||
unsigned int tmp_val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(pcf85363->regmap, CTRL_RAMBYTE, &tmp_val);
|
||||
(*(unsigned char *) val) = (unsigned char) tmp_val;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pcf85x63_nvram_write(void *priv, unsigned int offset, void *val,
|
||||
size_t bytes)
|
||||
{
|
||||
struct pcf85363 *pcf85363 = priv;
|
||||
unsigned char tmp_val;
|
||||
|
||||
tmp_val = *((unsigned char *)val);
|
||||
return regmap_write(pcf85363->regmap, CTRL_RAMBYTE,
|
||||
(unsigned int)tmp_val);
|
||||
}
|
||||
|
||||
static const struct pcf85x63_config pcf_85263_config = {
|
||||
.regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0x2f,
|
||||
},
|
||||
.num_nvram = 1
|
||||
};
|
||||
|
||||
static const struct pcf85x63_config pcf_85363_config = {
|
||||
.regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0x7f,
|
||||
},
|
||||
.num_nvram = 2
|
||||
};
|
||||
|
||||
static int pcf85363_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct pcf85363 *pcf85363;
|
||||
struct nvmem_config nvmem_cfg = {
|
||||
const struct pcf85x63_config *config = &pcf_85363_config;
|
||||
const void *data = of_device_get_match_data(&client->dev);
|
||||
static struct nvmem_config nvmem_cfg[] = {
|
||||
{
|
||||
.name = "pcf85x63-",
|
||||
.word_size = 1,
|
||||
.stride = 1,
|
||||
.size = 1,
|
||||
.reg_read = pcf85x63_nvram_read,
|
||||
.reg_write = pcf85x63_nvram_write,
|
||||
}, {
|
||||
.name = "pcf85363-",
|
||||
.word_size = 1,
|
||||
.stride = 1,
|
||||
.size = NVRAM_SIZE,
|
||||
.reg_read = pcf85363_nvram_read,
|
||||
.reg_write = pcf85363_nvram_write,
|
||||
},
|
||||
};
|
||||
int ret;
|
||||
int ret, i;
|
||||
|
||||
if (data)
|
||||
config = data;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
return -ENODEV;
|
||||
|
@ -339,7 +394,7 @@ static int pcf85363_probe(struct i2c_client *client,
|
|||
if (!pcf85363)
|
||||
return -ENOMEM;
|
||||
|
||||
pcf85363->regmap = devm_regmap_init_i2c(client, ®map_config);
|
||||
pcf85363->regmap = devm_regmap_init_i2c(client, &config->regmap);
|
||||
if (IS_ERR(pcf85363->regmap)) {
|
||||
dev_err(&client->dev, "regmap allocation failed\n");
|
||||
return PTR_ERR(pcf85363->regmap);
|
||||
|
@ -370,15 +425,18 @@ static int pcf85363_probe(struct i2c_client *client,
|
|||
|
||||
ret = rtc_register_device(pcf85363->rtc);
|
||||
|
||||
nvmem_cfg.priv = pcf85363;
|
||||
rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg);
|
||||
for (i = 0; i < config->num_nvram; i++) {
|
||||
nvmem_cfg[i].priv = pcf85363;
|
||||
rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id dev_ids[] = {
|
||||
{ .compatible = "nxp,pcf85363" },
|
||||
{}
|
||||
{ .compatible = "nxp,pcf85263", .data = &pcf_85263_config },
|
||||
{ .compatible = "nxp,pcf85363", .data = &pcf_85363_config },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dev_ids);
|
||||
|
||||
|
@ -393,5 +451,5 @@ static struct i2c_driver pcf85363_driver = {
|
|||
module_i2c_driver(pcf85363_driver);
|
||||
|
||||
MODULE_AUTHOR("Eric Nelson");
|
||||
MODULE_DESCRIPTION("pcf85363 I2C RTC driver");
|
||||
MODULE_DESCRIPTION("pcf85263/pcf85363 I2C RTC driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -170,9 +170,7 @@ static int pic32_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
|
|||
|
||||
rtc_tm->tm_year += 100;
|
||||
|
||||
dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n",
|
||||
1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
|
||||
rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
|
||||
dev_dbg(dev, "read time %ptR\n", rtc_tm);
|
||||
|
||||
clk_disable(pdata->clk);
|
||||
return 0;
|
||||
|
@ -184,9 +182,7 @@ static int pic32_rtc_settime(struct device *dev, struct rtc_time *tm)
|
|||
void __iomem *base = pdata->reg_base;
|
||||
int year = tm->tm_year - 100;
|
||||
|
||||
dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n",
|
||||
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "set time %ptR\n", tm);
|
||||
|
||||
if (year < 0 || year >= 100) {
|
||||
dev_err(dev, "rtc only supports 100 years\n");
|
||||
|
@ -224,10 +220,7 @@ static int pic32_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
|
||||
alrm->enabled = (alm_en & PIC32_RTCALRM_ALRMEN) ? 1 : 0;
|
||||
|
||||
dev_dbg(dev, "getalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n",
|
||||
alm_en,
|
||||
1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
|
||||
alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
|
||||
dev_dbg(dev, "getalarm: %d, %ptR\n", alm_en, alm_tm);
|
||||
|
||||
alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
|
||||
alm_tm->tm_min = bcd2bin(alm_tm->tm_min);
|
||||
|
@ -247,10 +240,7 @@ static int pic32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
void __iomem *base = pdata->reg_base;
|
||||
|
||||
clk_enable(pdata->clk);
|
||||
dev_dbg(dev, "setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n",
|
||||
alrm->enabled,
|
||||
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "setalarm: %d, %ptR\n", alrm->enabled, tm);
|
||||
|
||||
writel(0x00, base + PIC32_ALRMTIME);
|
||||
writel(0x00, base + PIC32_ALRMDATE);
|
||||
|
|
|
@ -217,9 +217,7 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|||
|
||||
rtc_time_to_tm(secs, tm);
|
||||
|
||||
dev_dbg(dev, "secs = %lu, h:m:s == %d:%d:%d, d/m/y = %d/%d/%d\n",
|
||||
secs, tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||
tm->tm_mday, tm->tm_mon, tm->tm_year);
|
||||
dev_dbg(dev, "secs = %lu, h:m:s == %ptRt, y-m-d = %ptRdr\n", secs, tm, tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -264,10 +262,8 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
|||
goto rtc_rw_fail;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Alarm Set for h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n",
|
||||
alarm->time.tm_hour, alarm->time.tm_min,
|
||||
alarm->time.tm_sec, alarm->time.tm_mday,
|
||||
alarm->time.tm_mon, alarm->time.tm_year);
|
||||
dev_dbg(dev, "Alarm Set for h:m:s=%ptRt, y-m-d=%ptRdr\n",
|
||||
&alarm->time, &alarm->time);
|
||||
rtc_rw_fail:
|
||||
spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
|
||||
return rc;
|
||||
|
@ -298,10 +294,8 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
|||
return rc;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Alarm set for - h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n",
|
||||
alarm->time.tm_hour, alarm->time.tm_min,
|
||||
alarm->time.tm_sec, alarm->time.tm_mday,
|
||||
alarm->time.tm_mon, alarm->time.tm_year);
|
||||
dev_dbg(dev, "Alarm set for - h:m:s=%ptRt, y-m-d=%ptRdr\n",
|
||||
&alarm->time, &alarm->time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -90,9 +90,7 @@ static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
|
|||
{
|
||||
rtc_time_to_tm(readl(RTC_RCNR), rtc_tm);
|
||||
|
||||
dev_dbg(dev, "read time %02x.%02x.%02x %02x/%02x/%02x\n",
|
||||
rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
|
||||
rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
|
||||
dev_dbg(dev, "read time %ptRr\n", rtc_tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -101,9 +99,7 @@ static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm)
|
|||
{
|
||||
unsigned long rtc_count = 0;
|
||||
|
||||
dev_dbg(dev, "set time %02d.%02d.%02d %02d/%02d/%02d\n",
|
||||
tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "set time %ptRr\n", tm);
|
||||
|
||||
rtc_tm_to_time(tm, &rtc_count);
|
||||
writel(rtc_count, RTC_RCNR);
|
||||
|
@ -119,10 +115,7 @@ static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
|
||||
alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE;
|
||||
|
||||
dev_dbg(dev, "read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
|
||||
alrm->enabled,
|
||||
alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
|
||||
alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
|
||||
dev_dbg(dev, "read alarm: %d, %ptRr\n", alrm->enabled, alm_tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -132,10 +125,7 @@ static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
struct rtc_time *tm = &alrm->time;
|
||||
unsigned long rtcalarm_count = 0;
|
||||
|
||||
dev_dbg(dev, "puv3_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n",
|
||||
alrm->enabled,
|
||||
tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,
|
||||
tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
|
||||
dev_dbg(dev, "set alarm: %d, %ptRr\n", alrm->enabled, tm);
|
||||
|
||||
rtc_tm_to_time(tm, &rtcalarm_count);
|
||||
writel(rtcalarm_count, RTC_RTAR);
|
||||
|
|
|
@ -138,9 +138,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
|
|||
tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100;
|
||||
tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK);
|
||||
rockchip_to_gregorian(tm);
|
||||
dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
|
||||
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "RTC date/time %ptRd(%d) %ptRt\n", tm, tm->tm_wday, tm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -153,9 +151,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
|||
u8 rtc_data[NUM_TIME_REGS];
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
|
||||
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "set RTC date/time %ptRd(%d) %ptRt\n", tm, tm->tm_wday, tm);
|
||||
gregorian_to_rockchip(tm);
|
||||
rtc_data[0] = bin2bcd(tm->tm_sec);
|
||||
rtc_data[1] = bin2bcd(tm->tm_min);
|
||||
|
@ -216,10 +212,8 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
|
||||
1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
|
||||
alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
|
||||
alrm->time.tm_min, alrm->time.tm_sec);
|
||||
dev_dbg(dev, "alrm read RTC date/time %ptRd(%d) %ptRt\n",
|
||||
&alrm->time, alrm->time.tm_wday, &alrm->time);
|
||||
|
||||
alrm->enabled = (int_reg & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M) ? 1 : 0;
|
||||
|
||||
|
@ -261,10 +255,8 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
dev_err(dev, "Failed to stop alarm: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
dev_dbg(dev, "alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
|
||||
1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
|
||||
alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
|
||||
alrm->time.tm_min, alrm->time.tm_sec);
|
||||
dev_dbg(dev, "alrm set RTC date/time %ptRd(%d) %ptRt\n",
|
||||
&alrm->time, alrm->time.tm_wday, &alrm->time);
|
||||
|
||||
gregorian_to_rockchip(&alrm->time);
|
||||
alrm_data[0] = bin2bcd(alrm->time.tm_sec);
|
||||
|
|
|
@ -114,9 +114,7 @@ struct rx6110_data {
|
|||
*/
|
||||
static int rx6110_rtc_tm_to_data(struct rtc_time *tm, u8 *data)
|
||||
{
|
||||
pr_debug("%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
|
||||
tm->tm_sec, tm->tm_min, tm->tm_hour,
|
||||
tm->tm_mday, tm->tm_mon, tm->tm_year);
|
||||
pr_debug("%s: date %ptRr\n", __func__, tm);
|
||||
|
||||
/*
|
||||
* The year in the RTC is a value between 0 and 99.
|
||||
|
@ -154,9 +152,7 @@ static int rx6110_data_to_rtc_tm(u8 *data, struct rtc_time *tm)
|
|||
tm->tm_mon = bcd2bin(data[RTC_MONTH] & 0x1f) - 1;
|
||||
tm->tm_year = bcd2bin(data[RTC_YEAR]) + 100;
|
||||
|
||||
pr_debug("%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
|
||||
tm->tm_sec, tm->tm_min, tm->tm_hour,
|
||||
tm->tm_mday, tm->tm_mon, tm->tm_year);
|
||||
pr_debug("%s: date %ptRr\n", __func__, tm);
|
||||
|
||||
/*
|
||||
* The year in the RTC is a value between 0 and 99.
|
||||
|
@ -248,9 +244,7 @@ static int rx6110_get_time(struct device *dev, struct rtc_time *tm)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
|
||||
tm->tm_sec, tm->tm_min, tm->tm_hour,
|
||||
tm->tm_mday, tm->tm_mon, tm->tm_year);
|
||||
dev_dbg(dev, "%s: date %ptRr\n", __func__, tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -193,10 +193,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
dev_dbg(dev, "%s: read 0x%02x 0x%02x "
|
||||
"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", __func__,
|
||||
date[0], date[1], date[2], date[3], date[4],
|
||||
date[5], date[6]);
|
||||
dev_dbg(dev, "%s: read %7ph\n", __func__, date);
|
||||
|
||||
dt->tm_sec = bcd2bin(date[RX8025_REG_SEC] & 0x7f);
|
||||
dt->tm_min = bcd2bin(date[RX8025_REG_MIN] & 0x7f);
|
||||
|
@ -210,9 +207,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
|
|||
dt->tm_mon = bcd2bin(date[RX8025_REG_MONTH] & 0x1f) - 1;
|
||||
dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]) + 100;
|
||||
|
||||
dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
|
||||
dt->tm_sec, dt->tm_min, dt->tm_hour,
|
||||
dt->tm_mday, dt->tm_mon, dt->tm_year);
|
||||
dev_dbg(dev, "%s: date %ptRr\n", __func__, dt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -243,10 +238,7 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
|
|||
date[RX8025_REG_MONTH] = bin2bcd(dt->tm_mon + 1);
|
||||
date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year - 100);
|
||||
|
||||
dev_dbg(dev,
|
||||
"%s: write 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
__func__,
|
||||
date[0], date[1], date[2], date[3], date[4], date[5], date[6]);
|
||||
dev_dbg(dev, "%s: write %7ph\n", __func__, date);
|
||||
|
||||
ret = rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date);
|
||||
if (ret < 0)
|
||||
|
@ -319,10 +311,7 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12
|
||||
+ (ald[1] & 0x20 ? 12 : 0);
|
||||
|
||||
dev_dbg(dev, "%s: date: %ds %dm %dh %dmd %dm %dy\n",
|
||||
__func__,
|
||||
t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
|
||||
t->time.tm_mday, t->time.tm_mon, t->time.tm_year);
|
||||
dev_dbg(dev, "%s: date: %ptRr\n", __func__, t);
|
||||
t->enabled = !!(rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE);
|
||||
t->pending = (ctrl2 & RX8025_BIT_CTRL2_DAFG) && t->enabled;
|
||||
|
||||
|
|
|
@ -225,13 +225,9 @@ retry_get_time:
|
|||
s3c_rtc_disable_clk(info);
|
||||
|
||||
rtc_tm->tm_year += 100;
|
||||
|
||||
dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n",
|
||||
1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
|
||||
rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
|
||||
|
||||
rtc_tm->tm_mon -= 1;
|
||||
|
||||
dev_dbg(dev, "read time %ptR\n", rtc_tm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -241,9 +237,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
|
|||
int year = tm->tm_year - 100;
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n",
|
||||
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "set time %ptR\n", tm);
|
||||
|
||||
/* we get around y2k by simply not supporting it */
|
||||
|
||||
|
@ -292,10 +286,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
|
||||
alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
|
||||
|
||||
dev_dbg(dev, "read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n",
|
||||
alm_en,
|
||||
1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
|
||||
alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
|
||||
dev_dbg(dev, "read alarm %d, %ptR\n", alm_en, alm_tm);
|
||||
|
||||
/* decode the alarm enable field */
|
||||
if (alm_en & S3C2410_RTCALM_SECEN)
|
||||
|
@ -327,12 +318,8 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
struct rtc_time *tm = &alrm->time;
|
||||
unsigned int alrm_en;
|
||||
int ret;
|
||||
int year = tm->tm_year - 100;
|
||||
|
||||
dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n",
|
||||
alrm->enabled,
|
||||
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
dev_dbg(dev, "s3c_rtc_setalarm: %d, %ptR\n", alrm->enabled, tm);
|
||||
|
||||
ret = s3c_rtc_enable_clk(info);
|
||||
if (ret)
|
||||
|
@ -356,11 +343,6 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_ALMHOUR);
|
||||
}
|
||||
|
||||
if (year < 100 && year >= 0) {
|
||||
alrm_en |= S3C2410_RTCALM_YEAREN;
|
||||
writeb(bin2bcd(year), info->base + S3C2410_ALMYEAR);
|
||||
}
|
||||
|
||||
if (tm->tm_mon < 12 && tm->tm_mon >= 0) {
|
||||
alrm_en |= S3C2410_RTCALM_MONEN;
|
||||
writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_ALMMON);
|
||||
|
|
|
@ -406,9 +406,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
|
||||
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
|
||||
dev_dbg(dev, "%s: %ptR(%d)\n", __func__, tm, tm->tm_wday);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -436,9 +434,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
|
||||
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
|
||||
dev_dbg(dev, "%s: %ptR(%d)\n", __func__, tm, tm->tm_wday);
|
||||
|
||||
ret = regmap_raw_write(info->regmap, info->regs->time, data,
|
||||
info->regs->regs_count);
|
||||
|
@ -490,11 +486,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
|
||||
1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
|
||||
alrm->time.tm_mday, alrm->time.tm_hour,
|
||||
alrm->time.tm_min, alrm->time.tm_sec,
|
||||
alrm->time.tm_wday);
|
||||
dev_dbg(dev, "%s: %ptR(%d)\n", __func__, &alrm->time, alrm->time.tm_wday);
|
||||
|
||||
ret = s5m_check_peding_alarm_interrupt(info, alrm);
|
||||
|
||||
|
@ -513,9 +505,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
|
|||
return ret;
|
||||
|
||||
s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
|
||||
dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
|
||||
1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
|
||||
dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday);
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
|
@ -558,9 +548,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
|
|||
return ret;
|
||||
|
||||
s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
|
||||
dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
|
||||
1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
|
||||
dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday);
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
|
@ -620,10 +608,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
|
||||
1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
|
||||
alrm->time.tm_mday, alrm->time.tm_hour, alrm->time.tm_min,
|
||||
alrm->time.tm_sec, alrm->time.tm_wday);
|
||||
dev_dbg(dev, "%s: %ptR(%d)\n", __func__, &alrm->time, alrm->time.tm_wday);
|
||||
|
||||
ret = s5m_rtc_stop_alarm(info);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* SuperH On-Chip RTC Support
|
||||
*
|
||||
|
@ -9,10 +10,6 @@
|
|||
*
|
||||
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
|
||||
* Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
|
@ -681,5 +678,5 @@ MODULE_DESCRIPTION("SuperH on-chip RTC driver");
|
|||
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, "
|
||||
"Jamie Lenehan <lenehan@twibble.org>, "
|
||||
"Angelo Castello <angelo.castello@st.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
||||
|
|
|
@ -118,9 +118,31 @@
|
|||
#define SUN6I_YEAR_MAX 2033
|
||||
#define SUN6I_YEAR_OFF (SUN6I_YEAR_MIN - 1900)
|
||||
|
||||
/*
|
||||
* There are other differences between models, including:
|
||||
*
|
||||
* - number of GPIO pins that can be configured to hold a certain level
|
||||
* - crypto-key related registers (H5, H6)
|
||||
* - boot process related (super standby, secondary processor entry address)
|
||||
* registers (R40, H6)
|
||||
* - SYS power domain controls (R40)
|
||||
* - DCXO controls (H6)
|
||||
* - RC oscillator calibration (H6)
|
||||
*
|
||||
* These functions are not covered by this driver.
|
||||
*/
|
||||
struct sun6i_rtc_clk_data {
|
||||
unsigned long rc_osc_rate;
|
||||
unsigned int fixed_prescaler : 16;
|
||||
unsigned int has_prescaler : 1;
|
||||
unsigned int has_out_clk : 1;
|
||||
unsigned int export_iosc : 1;
|
||||
};
|
||||
|
||||
struct sun6i_rtc_dev {
|
||||
struct rtc_device *rtc;
|
||||
struct device *dev;
|
||||
const struct sun6i_rtc_clk_data *data;
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
unsigned long alarm;
|
||||
|
@ -139,14 +161,19 @@ static unsigned long sun6i_rtc_osc_recalc_rate(struct clk_hw *hw,
|
|||
unsigned long parent_rate)
|
||||
{
|
||||
struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
|
||||
u32 val;
|
||||
u32 val = 0;
|
||||
|
||||
val = readl(rtc->base + SUN6I_LOSC_CTRL);
|
||||
if (val & SUN6I_LOSC_CTRL_EXT_OSC)
|
||||
return parent_rate;
|
||||
|
||||
if (rtc->data->fixed_prescaler)
|
||||
parent_rate /= rtc->data->fixed_prescaler;
|
||||
|
||||
if (rtc->data->has_prescaler) {
|
||||
val = readl(rtc->base + SUN6I_LOSC_CLK_PRESCAL);
|
||||
val &= GENMASK(4, 0);
|
||||
}
|
||||
|
||||
return parent_rate / (val + 1);
|
||||
}
|
||||
|
@ -185,13 +212,16 @@ static const struct clk_ops sun6i_rtc_osc_ops = {
|
|||
.set_parent = sun6i_rtc_osc_set_parent,
|
||||
};
|
||||
|
||||
static void __init sun6i_rtc_clk_init(struct device_node *node)
|
||||
static void __init sun6i_rtc_clk_init(struct device_node *node,
|
||||
const struct sun6i_rtc_clk_data *data)
|
||||
{
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct sun6i_rtc_dev *rtc;
|
||||
struct clk_init_data init = {
|
||||
.ops = &sun6i_rtc_osc_ops,
|
||||
.name = "losc",
|
||||
};
|
||||
const char *iosc_name = "rtc-int-osc";
|
||||
const char *clkout_name = "osc32k-out";
|
||||
const char *parents[2];
|
||||
|
||||
|
@ -199,7 +229,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
|
|||
if (!rtc)
|
||||
return;
|
||||
|
||||
clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
|
||||
rtc->data = data;
|
||||
clk_data = kzalloc(struct_size(clk_data, hws, 3), GFP_KERNEL);
|
||||
if (!clk_data) {
|
||||
kfree(rtc);
|
||||
return;
|
||||
|
@ -224,10 +255,15 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
|
|||
if (!of_get_property(node, "clocks", NULL))
|
||||
goto err;
|
||||
|
||||
/* Only read IOSC name from device tree if it is exported */
|
||||
if (rtc->data->export_iosc)
|
||||
of_property_read_string_index(node, "clock-output-names", 2,
|
||||
&iosc_name);
|
||||
|
||||
rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
|
||||
"rtc-int-osc",
|
||||
iosc_name,
|
||||
NULL, 0,
|
||||
667000,
|
||||
rtc->data->rc_osc_rate,
|
||||
300000000);
|
||||
if (IS_ERR(rtc->int_osc)) {
|
||||
pr_crit("Couldn't register the internal oscillator\n");
|
||||
|
@ -264,14 +300,71 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
|
|||
clk_data->num = 2;
|
||||
clk_data->hws[0] = &rtc->hw;
|
||||
clk_data->hws[1] = __clk_get_hw(rtc->ext_losc);
|
||||
if (rtc->data->export_iosc) {
|
||||
clk_data->hws[2] = rtc->int_osc;
|
||||
clk_data->num = 3;
|
||||
}
|
||||
of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||
return;
|
||||
|
||||
err:
|
||||
kfree(clk_data);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
|
||||
sun6i_rtc_clk_init);
|
||||
|
||||
static const struct sun6i_rtc_clk_data sun6i_a31_rtc_data = {
|
||||
.rc_osc_rate = 667000, /* datasheet says 600 ~ 700 KHz */
|
||||
.has_prescaler = 1,
|
||||
};
|
||||
|
||||
static void __init sun6i_a31_rtc_clk_init(struct device_node *node)
|
||||
{
|
||||
sun6i_rtc_clk_init(node, &sun6i_a31_rtc_data);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(sun6i_a31_rtc_clk, "allwinner,sun6i-a31-rtc",
|
||||
sun6i_a31_rtc_clk_init);
|
||||
|
||||
static const struct sun6i_rtc_clk_data sun8i_a23_rtc_data = {
|
||||
.rc_osc_rate = 667000, /* datasheet says 600 ~ 700 KHz */
|
||||
.has_prescaler = 1,
|
||||
.has_out_clk = 1,
|
||||
};
|
||||
|
||||
static void __init sun8i_a23_rtc_clk_init(struct device_node *node)
|
||||
{
|
||||
sun6i_rtc_clk_init(node, &sun8i_a23_rtc_data);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(sun8i_a23_rtc_clk, "allwinner,sun8i-a23-rtc",
|
||||
sun8i_a23_rtc_clk_init);
|
||||
|
||||
static const struct sun6i_rtc_clk_data sun8i_h3_rtc_data = {
|
||||
.rc_osc_rate = 16000000,
|
||||
.fixed_prescaler = 32,
|
||||
.has_prescaler = 1,
|
||||
.has_out_clk = 1,
|
||||
.export_iosc = 1,
|
||||
};
|
||||
|
||||
static void __init sun8i_h3_rtc_clk_init(struct device_node *node)
|
||||
{
|
||||
sun6i_rtc_clk_init(node, &sun8i_h3_rtc_data);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(sun8i_h3_rtc_clk, "allwinner,sun8i-h3-rtc",
|
||||
sun8i_h3_rtc_clk_init);
|
||||
/* As far as we are concerned, clocks for H5 are the same as H3 */
|
||||
CLK_OF_DECLARE_DRIVER(sun50i_h5_rtc_clk, "allwinner,sun50i-h5-rtc",
|
||||
sun8i_h3_rtc_clk_init);
|
||||
|
||||
static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = {
|
||||
.rc_osc_rate = 32000,
|
||||
.has_out_clk = 1,
|
||||
};
|
||||
|
||||
static void __init sun8i_v3_rtc_clk_init(struct device_node *node)
|
||||
{
|
||||
sun6i_rtc_clk_init(node, &sun8i_v3_rtc_data);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(sun8i_v3_rtc_clk, "allwinner,sun8i-v3-rtc",
|
||||
sun8i_v3_rtc_clk_init);
|
||||
|
||||
static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
|
||||
{
|
||||
|
@ -578,8 +671,18 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* As far as RTC functionality goes, all models are the same. The
|
||||
* datasheets claim that different models have different number of
|
||||
* registers available for non-volatile storage, but experiments show
|
||||
* that all SoCs have 16 registers available for this purpose.
|
||||
*/
|
||||
static const struct of_device_id sun6i_rtc_dt_ids[] = {
|
||||
{ .compatible = "allwinner,sun6i-a31-rtc" },
|
||||
{ .compatible = "allwinner,sun8i-a23-rtc" },
|
||||
{ .compatible = "allwinner,sun8i-h3-rtc" },
|
||||
{ .compatible = "allwinner,sun8i-v3-rtc" },
|
||||
{ .compatible = "allwinner,sun50i-h5-rtc" },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
|
||||
|
|
|
@ -125,15 +125,7 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|||
|
||||
rtc_time_to_tm(sec, tm);
|
||||
|
||||
dev_vdbg(dev, "time read as %lu. %d/%d/%d %d:%02u:%02u\n",
|
||||
sec,
|
||||
tm->tm_mon + 1,
|
||||
tm->tm_mday,
|
||||
tm->tm_year + 1900,
|
||||
tm->tm_hour,
|
||||
tm->tm_min,
|
||||
tm->tm_sec
|
||||
);
|
||||
dev_vdbg(dev, "time read as %lu. %ptR\n", sec, tm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -147,15 +139,7 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
|||
/* convert tm to seconds. */
|
||||
rtc_tm_to_time(tm, &sec);
|
||||
|
||||
dev_vdbg(dev, "time set to %lu. %d/%d/%d %d:%02u:%02u\n",
|
||||
sec,
|
||||
tm->tm_mon+1,
|
||||
tm->tm_mday,
|
||||
tm->tm_year+1900,
|
||||
tm->tm_hour,
|
||||
tm->tm_min,
|
||||
tm->tm_sec
|
||||
);
|
||||
dev_vdbg(dev, "time set to %lu. %ptR\n", sec, tm);
|
||||
|
||||
/* seconds only written if wait succeeded. */
|
||||
ret = tegra_rtc_wait_while_busy(dev);
|
||||
|
@ -232,15 +216,7 @@ static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
|||
/* if successfully written and alarm is enabled ... */
|
||||
if (sec) {
|
||||
tegra_rtc_alarm_irq_enable(dev, 1);
|
||||
|
||||
dev_vdbg(dev, "alarm set as %lu. %d/%d/%d %d:%02u:%02u\n",
|
||||
sec,
|
||||
alarm->time.tm_mon+1,
|
||||
alarm->time.tm_mday,
|
||||
alarm->time.tm_year+1900,
|
||||
alarm->time.tm_hour,
|
||||
alarm->time.tm_min,
|
||||
alarm->time.tm_sec);
|
||||
dev_vdbg(dev, "alarm set as %lu. %ptR\n", sec, &alarm->time);
|
||||
} else {
|
||||
/* disable alarm if 0 or write error. */
|
||||
dev_vdbg(dev, "alarm disabled\n");
|
||||
|
|
|
@ -39,12 +39,10 @@ date_show(struct device *dev, struct device_attribute *attr, char *buf)
|
|||
struct rtc_time tm;
|
||||
|
||||
retval = rtc_read_time(to_rtc_device(dev), &tm);
|
||||
if (retval == 0) {
|
||||
retval = sprintf(buf, "%04d-%02d-%02d\n",
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
|
||||
}
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return sprintf(buf, "%ptRd\n", &tm);
|
||||
}
|
||||
static DEVICE_ATTR_RO(date);
|
||||
|
||||
|
@ -55,12 +53,10 @@ time_show(struct device *dev, struct device_attribute *attr, char *buf)
|
|||
struct rtc_time tm;
|
||||
|
||||
retval = rtc_read_time(to_rtc_device(dev), &tm);
|
||||
if (retval == 0) {
|
||||
retval = sprintf(buf, "%02d:%02d:%02d\n",
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
}
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return sprintf(buf, "%ptRt\n", &tm);
|
||||
}
|
||||
static DEVICE_ATTR_RO(time);
|
||||
|
|
@ -87,15 +87,16 @@ struct rtc_class_ops {
|
|||
int (*set_offset)(struct device *, long offset);
|
||||
};
|
||||
|
||||
struct rtc_device;
|
||||
|
||||
struct rtc_timer {
|
||||
struct timerqueue_node node;
|
||||
ktime_t period;
|
||||
void (*func)(void *private_data);
|
||||
void *private_data;
|
||||
void (*func)(struct rtc_device *rtc);
|
||||
struct rtc_device *rtc;
|
||||
int enabled;
|
||||
};
|
||||
|
||||
|
||||
/* flags */
|
||||
#define RTC_DEV_BUSY 0
|
||||
|
||||
|
@ -138,7 +139,6 @@ struct rtc_device {
|
|||
|
||||
bool registered;
|
||||
|
||||
struct nvmem_device *nvmem;
|
||||
/* Old ABI support */
|
||||
bool nvram_old_abi;
|
||||
struct bin_attribute *nvram;
|
||||
|
@ -173,8 +173,6 @@ extern struct rtc_device *devm_rtc_device_register(struct device *dev,
|
|||
struct module *owner);
|
||||
struct rtc_device *devm_rtc_allocate_device(struct device *dev);
|
||||
int __rtc_register_device(struct module *owner, struct rtc_device *rtc);
|
||||
extern void devm_rtc_device_unregister(struct device *dev,
|
||||
struct rtc_device *rtc);
|
||||
|
||||
extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
|
||||
extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
|
||||
|
@ -200,11 +198,12 @@ extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc,
|
|||
unsigned int enabled);
|
||||
|
||||
void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode);
|
||||
void rtc_aie_update_irq(void *private);
|
||||
void rtc_uie_update_irq(void *private);
|
||||
void rtc_aie_update_irq(struct rtc_device *rtc);
|
||||
void rtc_uie_update_irq(struct rtc_device *rtc);
|
||||
enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer);
|
||||
|
||||
void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data);
|
||||
void rtc_timer_init(struct rtc_timer *timer, void (*f)(struct rtc_device *r),
|
||||
struct rtc_device *rtc);
|
||||
int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer,
|
||||
ktime_t expires, ktime_t period);
|
||||
void rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
|
@ -249,12 +250,11 @@ plain_format(void)
|
|||
#endif /* BITS_PER_LONG == 64 */
|
||||
|
||||
static int __init
|
||||
plain_hash(void)
|
||||
plain_hash_to_buffer(const void *p, char *buf, size_t len)
|
||||
{
|
||||
char buf[PLAIN_BUF_SIZE];
|
||||
int nchars;
|
||||
|
||||
nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR);
|
||||
nchars = snprintf(buf, len, "%p", p);
|
||||
|
||||
if (nchars != PTR_WIDTH)
|
||||
return -1;
|
||||
|
@ -265,6 +265,20 @@ plain_hash(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int __init
|
||||
plain_hash(void)
|
||||
{
|
||||
char buf[PLAIN_BUF_SIZE];
|
||||
int ret;
|
||||
|
||||
ret = plain_hash_to_buffer(PTR, buf, PLAIN_BUF_SIZE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (strncmp(buf, PTR_STR, PTR_WIDTH) == 0)
|
||||
return -1;
|
||||
|
||||
|
@ -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
|
||||
symbol_ptr(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
|
||||
struct_clk(void)
|
||||
{
|
||||
|
@ -529,6 +583,7 @@ test_pointer(void)
|
|||
uuid();
|
||||
dentry();
|
||||
struct_va_format();
|
||||
struct_rtc_time();
|
||||
struct_clk();
|
||||
bitmap();
|
||||
netdev_features();
|
||||
|
|
100
lib/vsprintf.c
100
lib/vsprintf.c
|
@ -30,6 +30,7 @@
|
|||
#include <linux/ioport.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/uuid.h>
|
||||
#include <linux/of.h>
|
||||
#include <net/addrconf.h>
|
||||
|
@ -822,6 +823,20 @@ static const struct printf_spec default_dec_spec = {
|
|||
.precision = -1,
|
||||
};
|
||||
|
||||
static const struct printf_spec default_dec02_spec = {
|
||||
.base = 10,
|
||||
.field_width = 2,
|
||||
.precision = -1,
|
||||
.flags = ZEROPAD,
|
||||
};
|
||||
|
||||
static const struct printf_spec default_dec04_spec = {
|
||||
.base = 10,
|
||||
.field_width = 4,
|
||||
.precision = -1,
|
||||
.flags = ZEROPAD,
|
||||
};
|
||||
|
||||
static noinline_for_stack
|
||||
char *resource_string(char *buf, char *end, struct resource *res,
|
||||
struct printf_spec spec, const char *fmt)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
char *date_str(char *buf, char *end, const struct rtc_time *tm, bool r)
|
||||
{
|
||||
int year = tm->tm_year + (r ? 0 : 1900);
|
||||
int mon = tm->tm_mon + (r ? 0 : 1);
|
||||
|
||||
buf = number(buf, end, year, default_dec04_spec);
|
||||
if (buf < end)
|
||||
*buf = '-';
|
||||
buf++;
|
||||
|
||||
buf = number(buf, end, mon, default_dec02_spec);
|
||||
if (buf < end)
|
||||
*buf = '-';
|
||||
buf++;
|
||||
|
||||
return number(buf, end, tm->tm_mday, default_dec02_spec);
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
char *time_str(char *buf, char *end, const struct rtc_time *tm, bool r)
|
||||
{
|
||||
buf = number(buf, end, tm->tm_hour, default_dec02_spec);
|
||||
if (buf < end)
|
||||
*buf = ':';
|
||||
buf++;
|
||||
|
||||
buf = number(buf, end, tm->tm_min, default_dec02_spec);
|
||||
if (buf < end)
|
||||
*buf = ':';
|
||||
buf++;
|
||||
|
||||
return number(buf, end, tm->tm_sec, default_dec02_spec);
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
char *rtc_str(char *buf, char *end, const struct rtc_time *tm, const char *fmt)
|
||||
{
|
||||
bool have_t = true, have_d = true;
|
||||
bool raw = false;
|
||||
int count = 2;
|
||||
|
||||
switch (fmt[count]) {
|
||||
case 'd':
|
||||
have_t = false;
|
||||
count++;
|
||||
break;
|
||||
case 't':
|
||||
have_d = false;
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
|
||||
raw = fmt[count] == 'r';
|
||||
|
||||
if (have_d)
|
||||
buf = date_str(buf, end, tm, raw);
|
||||
if (have_d && have_t) {
|
||||
/* Respect ISO 8601 */
|
||||
if (buf < end)
|
||||
*buf = 'T';
|
||||
buf++;
|
||||
}
|
||||
if (have_t)
|
||||
buf = time_str(buf, end, tm, raw);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec,
|
||||
const char *fmt)
|
||||
{
|
||||
switch (fmt[1]) {
|
||||
case 'R':
|
||||
return rtc_str(buf, end, (const struct rtc_time *)ptr, fmt);
|
||||
default:
|
||||
return ptr_to_id(buf, end, ptr, spec);
|
||||
}
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec,
|
||||
const char *fmt)
|
||||
|
@ -1828,6 +1924,8 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
|
|||
* - 'd[234]' For a dentry name (optionally 2-4 last components)
|
||||
* - 'D[234]' Same as 'd' but for a struct file
|
||||
* - 'g' For block_device name (gendisk + partition number)
|
||||
* - 't[R][dt][r]' For time and date as represented:
|
||||
* R struct rtc_time
|
||||
* - 'C' For a clock, it prints the name (Common Clock Framework) or address
|
||||
* (legacy clock framework) of the clock
|
||||
* - 'Cn' For a clock, it prints the name (Common Clock Framework) or address
|
||||
|
@ -1952,6 +2050,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
|||
return address_val(buf, end, ptr, fmt);
|
||||
case 'd':
|
||||
return dentry_name(buf, end, ptr, spec, fmt);
|
||||
case 't':
|
||||
return time_and_date(buf, end, ptr, spec, fmt);
|
||||
case 'C':
|
||||
return clock(buf, end, ptr, spec, fmt);
|
||||
case 'D':
|
||||
|
|
Loading…
Reference in New Issue