Commit 1aaccb5f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'rtc-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux

Pull RTC updates from Alexandre Belloni:
 "Setting the supported range from drivers for RTCs failing soon has
  started. A few fixes are developed along the way. Some drivers have
  been switched to SPDX by their maintainers.

  Subsystem:

   - rework of the rtc-test driver which allows to test the core more
     thoroughly

   - rtc_set_alarm() now fails early when alarms are not supported

  Drivers:

   - mktime() is now replaced by mktime64()

   - RTC range added for 88pm80x, ab-b5ze-s3, at91rm9200,
     brcmstb-waketimer, ds1685, ftrtc010, ls1x, mxc_v2, rx8581, sprd,
     st-lpc, tps6586x, tps65910 and vr41xx

   - fixed a possible race condition in probe functions

   - pxa: fix the probe function that is broken since v4.3

   - stm32: now supports stm32mp1"

* tag 'rtc-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (78 commits)
  rtc: pxa: fix probe function
  rtc: cros-ec: Switch to SPDX identifier.
  rtc: cros-ec: Make license text and module license match.
  rtc: ensure rtc_set_alarm fails when alarms are not supported
  rtc: test: remove alarm support from the first device
  rtc: test: convert to devm_rtc_allocate_device
  rtc: ftrtc010: let the core handle range
  rtc: ftrtc010: handle dates after 2106
  rtc: ftrtc010: switch to devm_rtc_allocate_device
  rtc: mrst: switch to devm functions
  rtc: sunxi: fix possible race condition
  rtc: test: remove irq sysfs file
  rtc: test: emulate alarms using timers
  rtc: test: store time as an offset to system time
  rtc: test: allow registering many devices
  rtc: test: remove useless proc info
  rtc: ds1685: Add range
  rtc: ds1685: fix possible race condition
  rtc: sprd: Add new RTC power down check method
  rtc: sun6i: Fix bit_idx value for clk_register_gate
  ...
parents ab0b2e59 e4302aec
...@@ -9,7 +9,7 @@ Optional properties: ...@@ -9,7 +9,7 @@ Optional properties:
Example: Example:
rtc: nxp,rtc-pcf2123@3 { pcf2123: rtc@3 {
compatible = "nxp,rtc-pcf2123" compatible = "nxp,rtc-pcf2123"
reg = <3> reg = <3>
spi-cs-high; spi-cs-high;
......
STM32 Real Time Clock STM32 Real Time Clock
Required properties: Required properties:
- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on - compatible: can be one of the following:
the device is compatible with stm32(f4/f7) or stm32h7. - "st,stm32-rtc" for devices compatible with stm32(f4/f7).
- "st,stm32h7-rtc" for devices compatible with stm32h7.
- "st,stm32mp1-rtc" for devices compatible with stm32mp1.
- reg: address range of rtc register set. - reg: address range of rtc register set.
- clocks: can use up to two clocks, depending on part used: - clocks: can use up to two clocks, depending on part used:
- "rtc_ck": RTC clock source. - "rtc_ck": RTC clock source.
It is required on stm32(f4/f7) and stm32h7.
- "pclk": RTC APB interface clock. - "pclk": RTC APB interface clock.
It is not present on stm32(f4/f7). It is not present on stm32(f4/f7).
It is required on stm32h7. It is required on stm32(h7/mp1).
- clock-names: must be "rtc_ck" and "pclk". - clock-names: must be "rtc_ck" and "pclk".
It is required only on stm32h7. It is required on stm32(h7/mp1).
- interrupt-parent: phandle for the interrupt controller. - interrupt-parent: phandle for the interrupt controller.
- interrupts: rtc alarm interrupt. It is required on stm32(f4/f7/h7).
- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain - interrupts: rtc alarm interrupt. On stm32mp1, a second interrupt is required
(RTC registers) write protection. for rtc alarm wakeup interrupt.
- st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
access control register at offset, and change the dbp (Disable Backup
Protection) bit represented by the mask, mandatory to disable/enable backup
domain (RTC registers) write protection.
It is required on stm32(f4/f7/h7).
Optional properties (to override default rtc_ck parent clock): Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
- assigned-clocks: reference to the rtc_ck clock entry. - assigned-clocks: reference to the rtc_ck clock entry.
- assigned-clock-parents: phandle of the new parent clock of rtc_ck. - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
...@@ -31,7 +37,7 @@ Example: ...@@ -31,7 +37,7 @@ Example:
assigned-clock-parents = <&rcc 1 CLK_LSE>; assigned-clock-parents = <&rcc 1 CLK_LSE>;
interrupt-parent = <&exti>; interrupt-parent = <&exti>;
interrupts = <17 1>; interrupts = <17 1>;
st,syscfg = <&pwrcfg>; st,syscfg = <&pwrcfg 0x00 0x100>;
}; };
rtc: rtc@58004000 { rtc: rtc@58004000 {
...@@ -44,5 +50,14 @@ Example: ...@@ -44,5 +50,14 @@ Example:
interrupt-parent = <&exti>; interrupt-parent = <&exti>;
interrupts = <17 1>; interrupts = <17 1>;
interrupt-names = "alarm"; interrupt-names = "alarm";
st,syscfg = <&pwrcfg>; st,syscfg = <&pwrcfg 0x00 0x100>;
};
rtc: rtc@5c004000 {
compatible = "st,stm32mp1-rtc";
reg = <0x5c004000 0x400>;
clocks = <&rcc RTCAPB>, <&rcc RTC>;
clock-names = "pclk", "rtc_ck";
interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
<&exti 19 1>;
}; };
...@@ -1613,7 +1613,7 @@ config RTC_DRV_JZ4740 ...@@ -1613,7 +1613,7 @@ config RTC_DRV_JZ4740
If you say yes here you get support for the Ingenic JZ47xx SoCs RTC If you say yes here you get support for the Ingenic JZ47xx SoCs RTC
controllers. controllers.
This driver can also be buillt as a module. If so, the module This driver can also be built as a module. If so, the module
will be called rtc-jz4740. will be called rtc-jz4740.
config RTC_DRV_LPC24XX config RTC_DRV_LPC24XX
......
...@@ -441,6 +441,11 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) ...@@ -441,6 +441,11 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{ {
int err; int err;
if (!rtc->ops)
return -ENODEV;
else if (!rtc->ops->set_alarm)
return -EINVAL;
err = rtc_valid_tm(&alarm->time); err = rtc_valid_tm(&alarm->time);
if (err != 0) if (err != 0)
return err; return err;
......
...@@ -94,7 +94,7 @@ int rtc_nvmem_register(struct rtc_device *rtc, ...@@ -94,7 +94,7 @@ int rtc_nvmem_register(struct rtc_device *rtc,
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); rtc->nvmem = nvmem_register(nvmem_config);
if (IS_ERR_OR_NULL(rtc->nvmem)) if (IS_ERR(rtc->nvmem))
return PTR_ERR(rtc->nvmem); return PTR_ERR(rtc->nvmem);
/* Register the old ABI */ /* Register the old ABI */
......
...@@ -52,10 +52,8 @@ struct pm80x_rtc_info { ...@@ -52,10 +52,8 @@ struct pm80x_rtc_info {
struct regmap *map; struct regmap *map;
struct rtc_device *rtc_dev; struct rtc_device *rtc_dev;
struct device *dev; struct device *dev;
struct delayed_work calib_work;
int irq; int irq;
int vrtc;
}; };
static irqreturn_t rtc_update_handler(int irq, void *data) static irqreturn_t rtc_update_handler(int irq, void *data)
...@@ -100,13 +98,13 @@ static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, ...@@ -100,13 +98,13 @@ static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
next->tm_min = alrm->tm_min; next->tm_min = alrm->tm_min;
next->tm_sec = alrm->tm_sec; next->tm_sec = alrm->tm_sec;
rtc_tm_to_time(now, &now_time); now_time = rtc_tm_to_time64(now);
rtc_tm_to_time(next, &next_time); next_time = rtc_tm_to_time64(next);
if (next_time < now_time) { if (next_time < now_time) {
/* Advance one day */ /* Advance one day */
next_time += 60 * 60 * 24; next_time += 60 * 60 * 24;
rtc_time_to_tm(next_time, next); rtc_time64_to_tm(next_time, next);
} }
} }
...@@ -125,7 +123,7 @@ static int pm80x_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -125,7 +123,7 @@ static int pm80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
ticks = base + data; ticks = base + data;
dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
base, data, ticks); base, data, ticks);
rtc_time_to_tm(ticks, tm); rtc_time64_to_tm(ticks, tm);
return 0; return 0;
} }
...@@ -134,13 +132,8 @@ static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -134,13 +132,8 @@ static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
struct pm80x_rtc_info *info = dev_get_drvdata(dev); struct pm80x_rtc_info *info = dev_get_drvdata(dev);
unsigned char buf[4]; unsigned char buf[4];
unsigned long ticks, base, data; unsigned long ticks, base, data;
if (tm->tm_year > 206) {
dev_dbg(info->dev, ticks = rtc_tm_to_time64(tm);
"Set time %d out of range. Please set time between 1970 to 2106.\n",
1900 + tm->tm_year);
return -EINVAL;
}
rtc_tm_to_time(tm, &ticks);
/* load 32-bit read-only counter */ /* load 32-bit read-only counter */
regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4); regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
...@@ -174,7 +167,7 @@ static int pm80x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -174,7 +167,7 @@ static int pm80x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
base, data, ticks); base, data, ticks);
rtc_time_to_tm(ticks, &alrm->time); rtc_time64_to_tm(ticks, &alrm->time);
regmap_read(info->map, PM800_RTC_CONTROL, &ret); regmap_read(info->map, PM800_RTC_CONTROL, &ret);
alrm->enabled = (ret & PM800_ALARM1_EN) ? 1 : 0; alrm->enabled = (ret & PM800_ALARM1_EN) ? 1 : 0;
alrm->pending = (ret & (PM800_ALARM | PM800_ALARM_WAKEUP)) ? 1 : 0; alrm->pending = (ret & (PM800_ALARM | PM800_ALARM_WAKEUP)) ? 1 : 0;
...@@ -202,11 +195,11 @@ static int pm80x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -202,11 +195,11 @@ static int pm80x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
base, data, ticks); base, data, ticks);
rtc_time_to_tm(ticks, &now_tm); rtc_time64_to_tm(ticks, &now_tm);
dev_dbg(info->dev, "%s, now time : %lu\n", __func__, ticks); dev_dbg(info->dev, "%s, now time : %lu\n", __func__, ticks);
rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time);
/* get new ticks for alarm in 24 hours */ /* get new ticks for alarm in 24 hours */
rtc_tm_to_time(&alarm_tm, &ticks); ticks = rtc_tm_to_time64(&alarm_tm);
dev_dbg(info->dev, "%s, alarm time: %lu\n", __func__, ticks); dev_dbg(info->dev, "%s, alarm time: %lu\n", __func__, ticks);
data = ticks - base; data = ticks - base;
...@@ -254,8 +247,6 @@ static int pm80x_rtc_probe(struct platform_device *pdev) ...@@ -254,8 +247,6 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
struct pm80x_rtc_pdata *pdata = dev_get_platdata(&pdev->dev); struct pm80x_rtc_pdata *pdata = dev_get_platdata(&pdev->dev);
struct pm80x_rtc_info *info; struct pm80x_rtc_info *info;
struct device_node *node = pdev->dev.of_node; struct device_node *node = pdev->dev.of_node;
struct rtc_time tm;
unsigned long ticks = 0;
int ret; int ret;
if (!pdata && !node) { if (!pdata && !node) {
...@@ -294,6 +285,10 @@ static int pm80x_rtc_probe(struct platform_device *pdev) ...@@ -294,6 +285,10 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
info->dev = &pdev->dev; info->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, info); dev_set_drvdata(&pdev->dev, info);
info->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(info->rtc_dev))
return PTR_ERR(info->rtc_dev);
ret = pm80x_request_irq(chip, info->irq, rtc_update_handler, ret = pm80x_request_irq(chip, info->irq, rtc_update_handler,
IRQF_ONESHOT, "rtc", info); IRQF_ONESHOT, "rtc", info);
if (ret < 0) { if (ret < 0) {
...@@ -302,30 +297,11 @@ static int pm80x_rtc_probe(struct platform_device *pdev) ...@@ -302,30 +297,11 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
goto out; goto out;
} }
ret = pm80x_rtc_read_time(&pdev->dev, &tm); info->rtc_dev->ops = &pm80x_rtc_ops;
if (ret < 0) { info->rtc_dev->range_max = U32_MAX;
dev_err(&pdev->dev, "Failed to read initial time.\n");
goto out_rtc;
}
if ((tm.tm_year < 70) || (tm.tm_year > 138)) {
tm.tm_year = 70;
tm.tm_mon = 0;
tm.tm_mday = 1;
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
ret = pm80x_rtc_set_time(&pdev->dev, &tm);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to set initial time.\n");
goto out_rtc;
}
}
rtc_tm_to_time(&tm, &ticks);
info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm80x-rtc", ret = rtc_register_device(info->rtc_dev);
&pm80x_rtc_ops, THIS_MODULE); if (ret) {
if (IS_ERR(info->rtc_dev)) {
ret = PTR_ERR(info->rtc_dev);
dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
goto out_rtc; goto out_rtc;
} }
......
...@@ -265,15 +265,6 @@ static int abb5zes3_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -265,15 +265,6 @@ static int abb5zes3_rtc_set_time(struct device *dev, struct rtc_time *tm)
u8 regs[ABB5ZES3_REG_RTC_SC + ABB5ZES3_RTC_SEC_LEN]; u8 regs[ABB5ZES3_REG_RTC_SC + ABB5ZES3_RTC_SEC_LEN];
int ret; int ret;
/*
* Year register is 8-bit wide and bcd-coded, i.e records values
* between 0 and 99. tm_year is an offset from 1900 and we are
* interested in the 2000-2099 range, so any value less than 100
* is invalid.
*/
if (tm->tm_year < 100)
return -EINVAL;
regs[ABB5ZES3_REG_RTC_SC] = bin2bcd(tm->tm_sec); /* MSB=0 clears OSC */ regs[ABB5ZES3_REG_RTC_SC] = bin2bcd(tm->tm_sec); /* MSB=0 clears OSC */
regs[ABB5ZES3_REG_RTC_MN] = bin2bcd(tm->tm_min); regs[ABB5ZES3_REG_RTC_MN] = bin2bcd(tm->tm_min);
regs[ABB5ZES3_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */ regs[ABB5ZES3_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */
...@@ -925,6 +916,14 @@ static int abb5zes3_probe(struct i2c_client *client, ...@@ -925,6 +916,14 @@ static int abb5zes3_probe(struct i2c_client *client,
if (ret) if (ret)
goto err; goto err;
data->rtc = devm_rtc_allocate_device(dev);
ret = PTR_ERR_OR_ZERO(data->rtc);
if (ret) {
dev_err(dev, "%s: unable to allocate RTC device (%d)\n",
__func__, ret);
goto err;
}
if (client->irq > 0) { if (client->irq > 0) {
ret = devm_request_threaded_irq(dev, client->irq, NULL, ret = devm_request_threaded_irq(dev, client->irq, NULL,
_abb5zes3_rtc_interrupt, _abb5zes3_rtc_interrupt,
...@@ -942,14 +941,9 @@ static int abb5zes3_probe(struct i2c_client *client, ...@@ -942,14 +941,9 @@ static int abb5zes3_probe(struct i2c_client *client,
} }
} }
data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, data->rtc->ops = &rtc_ops;
THIS_MODULE); data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
ret = PTR_ERR_OR_ZERO(data->rtc); data->rtc->range_max = RTC_TIMESTAMP_END_2099;
if (ret) {
dev_err(dev, "%s: unable to register RTC device (%d)\n",
__func__, ret);
goto err;
}
/* Enable battery low detection interrupt if battery not already low */ /* Enable battery low detection interrupt if battery not already low */
if (!data->battery_low && data->irq) { if (!data->battery_low && data->irq) {
...@@ -961,6 +955,8 @@ static int abb5zes3_probe(struct i2c_client *client, ...@@ -961,6 +955,8 @@ static int abb5zes3_probe(struct i2c_client *client,
} }
} }
ret = rtc_register_device(data->rtc);
err: err:
if (ret && data && data->irq) if (ret && data && data->irq)
device_init_wakeup(dev, false); device_init_wakeup(dev, false);
......
...@@ -440,6 +440,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev) ...@@ -440,6 +440,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
rtc->ops = &at91_rtc_ops; rtc->ops = &at91_rtc_ops;
rtc->range_min = RTC_TIMESTAMP_BEGIN_1900;
rtc->range_max = RTC_TIMESTAMP_END_2099;
ret = rtc_register_device(rtc); ret = rtc_register_device(rtc);
if (ret) if (ret)
goto err_clk; goto err_clk;
......
...@@ -48,8 +48,7 @@ static void bq4802_write_mem(struct bq4802 *p, int off, u8 val) ...@@ -48,8 +48,7 @@ static void bq4802_write_mem(struct bq4802 *p, int off, u8 val)
static int bq4802_read_time(struct device *dev, struct rtc_time *tm) static int bq4802_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct bq4802 *p = dev_get_drvdata(dev);
struct bq4802 *p = platform_get_drvdata(pdev);
unsigned long flags; unsigned long flags;
unsigned int century; unsigned int century;
u8 val; u8 val;
...@@ -91,8 +90,7 @@ static int bq4802_read_time(struct device *dev, struct rtc_time *tm) ...@@ -91,8 +90,7 @@ static int bq4802_read_time(struct device *dev, struct rtc_time *tm)
static int bq4802_set_time(struct device *dev, struct rtc_time *tm) static int bq4802_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct bq4802 *p = dev_get_drvdata(dev);
struct bq4802 *p = platform_get_drvdata(pdev);
u8 sec, min, hrs, day, mon, yrs, century, val; u8 sec, min, hrs, day, mon, yrs, century, val;
unsigned long flags; unsigned long flags;
unsigned int year; unsigned int year;
......
...@@ -145,9 +145,6 @@ static int brcmstb_waketmr_settime(struct device *dev, ...@@ -145,9 +145,6 @@ static int brcmstb_waketmr_settime(struct device *dev,
sec = rtc_tm_to_time64(tm); sec = rtc_tm_to_time64(tm);
if (sec > U32_MAX || sec < 0)
return -EINVAL;
writel_relaxed(sec, timer->base + BRCMSTB_WKTMR_COUNTER); writel_relaxed(sec, timer->base + BRCMSTB_WKTMR_COUNTER);
return 0; return 0;
...@@ -184,9 +181,6 @@ static int brcmstb_waketmr_setalarm(struct device *dev, ...@@ -184,9 +181,6 @@ static int brcmstb_waketmr_setalarm(struct device *dev,
else else
sec = 0; sec = 0;
if (sec > U32_MAX || sec < 0)
return -EINVAL;
brcmstb_waketmr_set_alarm(timer, sec); brcmstb_waketmr_set_alarm(timer, sec);
return 0; return 0;
...@@ -229,6 +223,10 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev) ...@@ -229,6 +223,10 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
if (IS_ERR(timer->base)) if (IS_ERR(timer->base))
return PTR_ERR(timer->base); return PTR_ERR(timer->base);
timer->rtc = devm_rtc_allocate_device(dev);
if (IS_ERR(timer->rtc))
return PTR_ERR(timer->rtc);
/* /*
* Set wakeup capability before requesting wakeup interrupt, so we can * Set wakeup capability before requesting wakeup interrupt, so we can
* process boot-time "wakeups" (e.g., from S5 soft-off) * process boot-time "wakeups" (e.g., from S5 soft-off)
...@@ -261,11 +259,12 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev) ...@@ -261,11 +259,12 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot; timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot;
register_reboot_notifier(&timer->reboot_notifier); register_reboot_notifier(&timer->reboot_notifier);
timer->rtc = rtc_device_register("brcmstb-waketmr", dev, timer->rtc->ops = &brcmstb_waketmr_ops;
&brcmstb_waketmr_ops, THIS_MODULE); timer->rtc->range_max = U32_MAX;
if (IS_ERR(timer->rtc)) {
ret = rtc_register_device(timer->rtc);
if (ret) {
dev_err(dev, "unable to register device\n"); dev_err(dev, "unable to register device\n");
ret = PTR_ERR(timer->rtc);
goto err_notifier; goto err_notifier;
} }
...@@ -288,7 +287,6 @@ static int brcmstb_waketmr_remove(struct platform_device *pdev) ...@@ -288,7 +287,6 @@ static int brcmstb_waketmr_remove(struct platform_device *pdev)
struct brcmstb_waketmr *timer = dev_get_drvdata(&pdev->dev); struct brcmstb_waketmr *timer = dev_get_drvdata(&pdev->dev);
unregister_reboot_notifier(&timer->reboot_notifier); unregister_reboot_notifier(&timer->reboot_notifier);
rtc_device_unregister(timer->rtc);
return 0; return 0;
} }
......
...@@ -43,11 +43,24 @@ ...@@ -43,11 +43,24 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#ifdef CONFIG_X86 #ifdef CONFIG_X86
#include <asm/i8259.h> #include <asm/i8259.h>
#include <asm/processor.h>
#include <linux/dmi.h>
#endif #endif
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
#include <linux/mc146818rtc.h> #include <linux/mc146818rtc.h>
/*
* Use ACPI SCI to replace HPET interrupt for RTC Alarm event
*
* If cleared, ACPI SCI is only used to wake up the system from suspend
*
* If set, ACPI SCI is used to handle UIE/AIE and system wakeup
*/
static bool use_acpi_alarm;
module_param(use_acpi_alarm, bool, 0444);
struct cmos_rtc { struct cmos_rtc {
struct rtc_device *rtc; struct rtc_device *rtc;
struct device *dev; struct device *dev;
...@@ -153,6 +166,12 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler) ...@@ -153,6 +166,12 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler)
#endif #endif
/* Don't use HPET for RTC Alarm event if ACPI Fixed event is used */
static int use_hpet_alarm(void)
{
return is_hpet_enabled() && !use_acpi_alarm;
}
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
#ifdef RTC_PORT #ifdef RTC_PORT
...@@ -298,7 +317,7 @@ static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control) ...@@ -298,7 +317,7 @@ static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control)
*/ */
rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
if (is_hpet_enabled()) if (use_hpet_alarm())
return; return;
rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
...@@ -318,8 +337,14 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask) ...@@ -318,8 +337,14 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)
rtc_control |= mask; rtc_control |= mask;
CMOS_WRITE(rtc_control, RTC_CONTROL); CMOS_WRITE(rtc_control, RTC_CONTROL);
if (use_hpet_alarm())
hpet_set_rtc_irq_bit(mask); hpet_set_rtc_irq_bit(mask);
if ((mask & RTC_AIE) && use_acpi_alarm) {
if (cmos->wake_on)
cmos->wake_on(cmos->dev);
}
cmos_checkintr(cmos, rtc_control); cmos_checkintr(cmos, rtc_control);
} }
...@@ -330,8 +355,14 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) ...@@ -330,8 +355,14 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)
rtc_control = CMOS_READ(RTC_CONTROL); rtc_control = CMOS_READ(RTC_CONTROL);
rtc_control &= ~mask; rtc_control &= ~mask;
CMOS_WRITE(rtc_control, RTC_CONTROL); CMOS_WRITE(rtc_control, RTC_CONTROL);
if (use_hpet_alarm())
hpet_mask_rtc_irq_bit(mask); hpet_mask_rtc_irq_bit(mask);
if ((mask & RTC_AIE) && use_acpi_alarm) {
if (cmos->wake_off)
cmos->wake_off(cmos->dev);
}
cmos_checkintr(cmos, rtc_control); cmos_checkintr(cmos, rtc_control);
} }
...@@ -448,10 +479,14 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -448,10 +479,14 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
CMOS_WRITE(mon, cmos->mon_alrm); CMOS_WRITE(mon, cmos->mon_alrm);
} }
/* FIXME the HPET alarm glue currently ignores day_alrm if (use_hpet_alarm()) {
/*
* FIXME the HPET alarm glue currently ignores day_alrm
* and mon_alrm ... * and mon_alrm ...
*/ */
hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec); hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min,
t->time.tm_sec);
}
if (t->enabled) if (t->enabled)
cmos_irq_enable(cmos, RTC_AIE); cmos_irq_enable(cmos, RTC_AIE);
...@@ -508,7 +543,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) ...@@ -508,7 +543,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
"batt_status\t: %s\n", "batt_status\t: %s\n",
(rtc_control & RTC_PIE) ? "yes" : "no", (rtc_control & RTC_PIE) ? "yes" : "no",
(rtc_control & RTC_UIE) ? "yes" : "no", (rtc_control & RTC_UIE) ? "yes" : "no",
is_hpet_enabled() ? "yes" : "no", use_hpet_alarm() ? "yes" : "no",
// (rtc_control & RTC_SQWE) ? "yes" : "no", // (rtc_control & RTC_SQWE) ? "yes" : "no",
(rtc_control & RTC_DM_BINARY) ? "no" : "yes", (rtc_control & RTC_DM_BINARY) ? "no" : "yes",
(rtc_control & RTC_DST_EN) ? "yes" : "no", (rtc_control & RTC_DST_EN) ? "yes" : "no",
...@@ -614,7 +649,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p) ...@@ -614,7 +649,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
*/ */
irqstat = CMOS_READ(RTC_INTR_FLAGS); irqstat = CMOS_READ(RTC_INTR_FLAGS);
rtc_control = CMOS_READ(RTC_CONTROL); rtc_control = CMOS_READ(RTC_CONTROL);
if (is_hpet_enabled()) if (use_hpet_alarm())
irqstat = (unsigned long)irq & 0xF0; irqstat = (unsigned long)irq & 0xF0;
/* If we were suspended, RTC_CONTROL may not be accurate since the /* If we were suspended, RTC_CONTROL may not be accurate since the
...@@ -633,6 +668,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p) ...@@ -633,6 +668,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
cmos_rtc.suspend_ctrl &= ~RTC_AIE; cmos_rtc.suspend_ctrl &= ~RTC_AIE;
rtc_control &= ~RTC_AIE; rtc_control &= ~RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL); CMOS_WRITE(rtc_control, RTC_CONTROL);
if (use_hpet_alarm())
hpet_mask_rtc_irq_bit(RTC_AIE); hpet_mask_rtc_irq_bit(RTC_AIE);
CMOS_READ(RTC_INTR_FLAGS); CMOS_READ(RTC_INTR_FLAGS);
} }
...@@ -762,6 +798,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) ...@@ -762,6 +798,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
* need to do something about other clock frequencies. * need to do something about other clock frequencies.
*/ */
cmos_rtc.rtc->irq_freq = 1024; cmos_rtc.rtc->irq_freq = 1024;
if (use_hpet_alarm())
hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq);
CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT);
} }
...@@ -780,12 +817,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) ...@@ -780,12 +817,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
goto cleanup1; goto cleanup1;
} }
if (use_hpet_alarm())
hpet_rtc_timer_init(); hpet_rtc_timer_init();
if (is_valid_irq(rtc_irq)) { if (is_valid_irq(rtc_irq)) {
irq_handler_t rtc_cmos_int_handler; irq_handler_t rtc_cmos_int_handler;
if (is_hpet_enabled()) { if (use_hpet_alarm()) {
rtc_cmos_int_handler = hpet_rtc_interrupt; rtc_cmos_int_handler = hpet_rtc_interrupt;
retval = hpet_register_irq_handler(cmos_interrupt); retval = hpet_register_irq_handler(cmos_interrupt);
if (retval) { if (retval) {
...@@ -824,7 +862,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) ...@@ -824,7 +862,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
"alarms up to one day", "alarms up to one day",
cmos_rtc.century ? ", y3k" : "", cmos_rtc.century ? ", y3k" : "",
nvmem_cfg.size, nvmem_cfg.size,
is_hpet_enabled() ? ", hpet irqs" : ""); use_hpet_alarm() ? ", hpet irqs" : "");
return 0; return 0;
...@@ -858,6 +896,7 @@ static void cmos_do_remove(struct device *dev) ...@@ -858,6 +896,7 @@ static void cmos_do_remove(struct device *dev)
if (is_valid_irq(cmos->irq)) { if (is_valid_irq(cmos->irq)) {
free_irq(cmos->irq, cmos->rtc); free_irq(cmos->irq, cmos->rtc);
if (use_hpet_alarm())
hpet_unregister_irq_handler(cmos_interrupt); hpet_unregister_irq_handler(cmos_interrupt);
} }
...@@ -935,13 +974,13 @@ static int cmos_suspend(struct device *dev) ...@@ -935,13 +974,13 @@ static int cmos_suspend(struct device *dev)
mask = RTC_IRQMASK; mask = RTC_IRQMASK;
tmp &= ~mask; tmp &= ~mask;
CMOS_WRITE(tmp, RTC_CONTROL); CMOS_WRITE(tmp, RTC_CONTROL);
if (use_hpet_alarm())
hpet_mask_rtc_irq_bit(mask); hpet_mask_rtc_irq_bit(mask);
cmos_checkintr(cmos, tmp); cmos_checkintr(cmos, tmp);
} }
spin_unlock_irq(&rtc_lock); spin_unlock_irq(&rtc_lock);
if (tmp & RTC_AIE) { if ((tmp & RTC_AIE) && !use_acpi_alarm) {
cmos->enabled_wake = 1; cmos->enabled_wake = 1;
if (cmos->wake_on) if (cmos->wake_on)
cmos->wake_on(dev); cmos->wake_on(dev);
...@@ -976,8 +1015,26 @@ static void cmos_check_wkalrm(struct device *dev) ...@@ -976,8 +1015,26 @@ static void cmos_check_wkalrm(struct device *dev)
{ {
struct cmos_rtc *cmos = dev_get_drvdata(dev); struct cmos_rtc *cmos = dev_get_drvdata(dev);
struct rtc_wkalrm current_alarm; struct rtc_wkalrm current_alarm;
time64_t t_now;
time64_t t_current_expires; time64_t t_current_expires;
time64_t t_saved_expires; time64_t t_saved_expires;
struct rtc_time now;
/* Check if we have RTC Alarm armed */
if (!(cmos->suspend_ctrl & RTC_AIE))
return;
cmos_read_time(dev, &now);
t_now = rtc_tm_to_time64(&now);
/*
* ACPI RTC wake event is cleared after resume from STR,
* ACK the rtc irq here
*/
if (t_now >= cmos->alarm_expires && use_acpi_alarm) {
cmos_interrupt(0, (void *)cmos->rtc);
return;
}
cmos_read_alarm(dev, &current_alarm); cmos_read_alarm(dev, &current_alarm);
t_current_expires = rtc_tm_to_time64(&current_alarm.time); t_current_expires = rtc_tm_to_time64(&current_alarm.time);
...@@ -996,7 +1053,7 @@ static int __maybe_unused cmos_resume(struct device *dev) ...@@ -996,7 +1053,7 @@ static int __maybe_unused cmos_resume(struct device *dev)
struct cmos_rtc *cmos = dev_get_drvdata(dev); struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char tmp; unsigned char tmp;
if (cmos->enabled_wake) { if (cmos->enabled_wake && !use_acpi_alarm) {
if (cmos->wake_off) if (cmos->wake_off)
cmos->wake_off(dev); cmos->wake_off(dev);
else else
...@@ -1014,16 +1071,17 @@ static int __maybe_unused cmos_resume(struct device *dev) ...@@ -1014,16 +1071,17 @@ static int __maybe_unused cmos_resume(struct device *dev)
if (tmp & RTC_IRQMASK) { if (tmp & RTC_IRQMASK) {
unsigned char mask; unsigned char mask;
if (device_may_wakeup(dev)) if (device_may_wakeup(dev) && use_hpet_alarm())
hpet_rtc_timer_init(); hpet_rtc_timer_init();
do { do {
CMOS_WRITE(tmp, RTC_CONTROL); CMOS_WRITE(tmp, RTC_CONTROL);
if (use_hpet_alarm())
hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK); hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK);
mask = CMOS_READ(RTC_INTR_FLAGS); mask = CMOS_READ(RTC_INTR_FLAGS);
mask &= (tmp & RTC_IRQMASK) | RTC_IRQF; mask &= (tmp & RTC_IRQMASK) | RTC_IRQF;
if (!is_hpet_enabled() || !is_intr(mask)) if (!use_hpet_alarm() || !is_intr(mask))
break; break;
/* force one-shot behavior if HPET blocked /* force one-shot behavior if HPET blocked
...@@ -1068,6 +1126,16 @@ static u32 rtc_handler(void *context) ...@@ -1068,6 +1126,16 @@ static u32 rtc_handler(void *context)
unsigned char rtc_intr; unsigned char rtc_intr;
unsigned long flags; unsigned long flags;
/*
* Always update rtc irq when ACPI is used as RTC Alarm.
* Or else, ACPI SCI is enabled during suspend/resume only,
* update rtc irq in that case.
*/
if (use_acpi_alarm)
cmos_interrupt(0, (void *)cmos->rtc);
else {
/* Fix me: can we use cmos_interrupt() here as well? */
spin_lock_irqsave(&rtc_lock, flags); spin_lock_irqsave(&rtc_lock, flags);
if (cmos_rtc.suspend_ctrl) if (cmos_rtc.suspend_ctrl)
rtc_control = CMOS_READ(RTC_CONTROL); rtc_control = CMOS_READ(RTC_CONTROL);
...@@ -1078,6 +1146,7 @@ static u32 rtc_handler(void *context) ...@@ -1078,6 +1146,7 @@ static u32 rtc_handler(void *context)
rtc_update_irq(cmos->rtc, 1, rtc_intr); rtc_update_irq(cmos->rtc, 1, rtc_intr);
} }
spin_unlock_irqrestore(&rtc_lock, flags); spin_unlock_irqrestore(&rtc_lock, flags);
}
pm_wakeup_hard_event(dev); pm_wakeup_hard_event(dev);
acpi_clear_event(ACPI_EVENT_RTC); acpi_clear_event(ACPI_EVENT_RTC);
...@@ -1107,6 +1176,28 @@ static void rtc_wake_off(struct device *dev) ...@@ -1107,6 +1176,28 @@ static void rtc_wake_off(struct device *dev)
acpi_disable_event(ACPI_EVENT_RTC, 0); acpi_disable_event(ACPI_EVENT_RTC, 0);
} }
#ifdef CONFIG_X86
/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
static void use_acpi_alarm_quirks(void)
{
int year;
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
return;
if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
return;
if (!is_hpet_enabled())
return;
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2015)
use_acpi_alarm = true;
}
#else
static inline void use_acpi_alarm_quirks(void) { }
#endif
/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find /* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
* its device node and pass extra config data. This helps its driver use * its device node and pass extra config data. This helps its driver use
* capabilities that the now-obsolete mc146818 didn't have, and informs it * capabilities that the now-obsolete mc146818 didn't have, and informs it
...@@ -1119,6 +1210,8 @@ static void cmos_wake_setup(struct device *dev) ...@@ -1119,6 +1210,8 @@ static void cmos_wake_setup(struct device *dev)
if (acpi_disabled) if (acpi_disabled)
return; return;
use_acpi_alarm_quirks();
rtc_wake_setup(dev); rtc_wake_setup(dev);
acpi_rtc_info.wake_on = rtc_wake_on; acpi_rtc_info.wake_on = rtc_wake_on;
acpi_rtc_info.wake_off = rtc_wake_off; acpi_rtc_info.wake_off = rtc_wake_off;
......
/* // SPDX-License-Identifier: GPL-2.0
* RTC driver for Chrome OS Embedded Controller // RTC driver for ChromeOS Embedded Controller.
* //
* Copyright (c) 2017, Google, Inc // Copyright (C) 2017 Google, Inc.
* // Author: Stephen Barber <smbarber@chromium.org>
* Author: Stephen Barber <smbarber@chromium.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mfd/cros_ec.h> #include <linux/mfd/cros_ec.h>
...@@ -409,5 +398,5 @@ module_platform_driver(cros_ec_rtc_driver); ...@@ -409,5 +398,5 @@ module_platform_driver(cros_ec_rtc_driver);
MODULE_DESCRIPTION("RTC driver for Chrome OS ECs"); MODULE_DESCRIPTION("RTC driver for Chrome OS ECs");
MODULE_AUTHOR("Stephen Barber <smbarber@chromium.org>"); MODULE_AUTHOR("Stephen Barber <smbarber@chromium.org>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME); MODULE_ALIAS("platform:" DRV_NAME);
...@@ -76,8 +76,7 @@ static void ds1216_switch_ds_to_clock(u8 __iomem *ioaddr) ...@@ -76,8 +76,7 @@ static void ds1216_switch_ds_to_clock(u8 __iomem *ioaddr)
static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm) static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1216_priv *priv = dev_get_drvdata(dev);
struct ds1216_priv *priv = platform_get_drvdata(pdev);
struct ds1216_regs regs; struct ds1216_regs regs;
ds1216_switch_ds_to_clock(priv->ioaddr); ds1216_switch_ds_to_clock(priv->ioaddr);
...@@ -104,8 +103,7 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -104,8 +103,7 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm) static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1216_priv *priv = dev_get_drvdata(dev);
struct ds1216_priv *priv = platform_get_drvdata(pdev);
struct ds1216_regs regs; struct ds1216_regs regs;
ds1216_switch_ds_to_clock(priv->ioaddr); ds1216_switch_ds_to_clock(priv->ioaddr);
......
...@@ -201,6 +201,7 @@ static const struct chip_desc chips[last_ds_type] = { ...@@ -201,6 +201,7 @@ static const struct chip_desc chips[last_ds_type] = {
.century_reg = DS1307_REG_HOUR, .century_reg = DS1307_REG_HOUR,
.century_enable_bit = DS1340_BIT_CENTURY_EN, .century_enable_bit = DS1340_BIT_CENTURY_EN,
.century_bit = DS1340_BIT_CENTURY, .century_bit = DS1340_BIT_CENTURY,
.do_trickle_setup = &do_trickle_setup_ds1339,
.trickle_charger_reg = 0x08, .trickle_charger_reg = 0x08,
}, },
[ds_1341] = { [ds_1341] = {
...@@ -1371,6 +1372,7 @@ static void ds1307_clks_register(struct ds1307 *ds1307) ...@@ -1371,6 +1372,7 @@ static void ds1307_clks_register(struct ds1307 *ds1307)
static const struct regmap_config regmap_config = { static const struct regmap_config regmap_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
.max_register = 0x9,
}; };
static int ds1307_probe(struct i2c_client *client, static int ds1307_probe(struct i2c_client *client,
......
...@@ -314,8 +314,7 @@ ds1511_rtc_update_alarm(struct rtc_plat_data *pdata) ...@@ -314,8 +314,7 @@ ds1511_rtc_update_alarm(struct rtc_plat_data *pdata)
static int static int
ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
...@@ -334,8 +333,7 @@ ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -334,8 +333,7 @@ ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int static int
ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
...@@ -373,8 +371,7 @@ ds1511_interrupt(int irq, void *dev_id) ...@@ -373,8 +371,7 @@ ds1511_interrupt(int irq, void *dev_id)
static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
......
...@@ -73,8 +73,7 @@ struct rtc_plat_data { ...@@ -73,8 +73,7 @@ struct rtc_plat_data {
static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm) static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
u8 century; u8 century;
...@@ -98,8 +97,7 @@ static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -98,8 +97,7 @@ static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm) static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
unsigned int year, month, day, hour, minute, second, week; unsigned int year, month, day, hour, minute, second, week;
unsigned int century; unsigned int century;
...@@ -155,8 +153,7 @@ static void ds1553_rtc_update_alarm(struct rtc_plat_data *pdata) ...@@ -155,8 +153,7 @@ static void ds1553_rtc_update_alarm(struct rtc_plat_data *pdata)
static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
...@@ -172,8 +169,7 @@ static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -172,8 +169,7 @@ static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
...@@ -208,8 +204,7 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id) ...@@ -208,8 +204,7 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id)
static int ds1553_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static int ds1553_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
......
...@@ -267,8 +267,7 @@ ds1685_rtc_get_ssn(struct ds1685_priv *rtc, u8 *ssn) ...@@ -267,8 +267,7 @@ ds1685_rtc_get_ssn(struct ds1685_priv *rtc, u8 *ssn)
static int static int
ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm) ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrlb, century; u8 ctrlb, century;
u8 seconds, minutes, hours, wday, mday, month, years; u8 seconds, minutes, hours, wday, mday, month, years;
...@@ -317,8 +316,7 @@ ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -317,8 +316,7 @@ ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int static int
ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm) ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrlb, seconds, minutes, hours, wday, mday, month, years, century; u8 ctrlb, seconds, minutes, hours, wday, mday, month, years, century;
/* Fetch the time info from rtc_time. */ /* Fetch the time info from rtc_time. */
...@@ -394,8 +392,7 @@ ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -394,8 +392,7 @@ ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int static int
ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 seconds, minutes, hours, mday, ctrlb, ctrlc; u8 seconds, minutes, hours, mday, ctrlb, ctrlc;
int ret; int ret;
...@@ -453,8 +450,7 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -453,8 +450,7 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int static int
ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrlb, seconds, minutes, hours, mday; u8 ctrlb, seconds, minutes, hours, mday;
int ret; int ret;
...@@ -1119,8 +1115,7 @@ static ssize_t ...@@ -1119,8 +1115,7 @@ static ssize_t
ds1685_rtc_sysfs_battery_show(struct device *dev, ds1685_rtc_sysfs_battery_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrld; u8 ctrld;
ctrld = rtc->read(rtc, RTC_CTRL_D); ctrld = rtc->read(rtc, RTC_CTRL_D);
...@@ -1140,8 +1135,7 @@ static ssize_t ...@@ -1140,8 +1135,7 @@ static ssize_t
ds1685_rtc_sysfs_auxbatt_show(struct device *dev, ds1685_rtc_sysfs_auxbatt_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrl4a; u8 ctrl4a;
ds1685_rtc_switch_to_bank1(rtc); ds1685_rtc_switch_to_bank1(rtc);
...@@ -1163,8 +1157,7 @@ static ssize_t ...@@ -1163,8 +1157,7 @@ static ssize_t
ds1685_rtc_sysfs_serial_show(struct device *dev, ds1685_rtc_sysfs_serial_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ssn[8]; u8 ssn[8];
ds1685_rtc_switch_to_bank1(rtc); ds1685_rtc_switch_to_bank1(rtc);
...@@ -2044,6 +2037,26 @@ ds1685_rtc_probe(struct platform_device *pdev) ...@@ -2044,6 +2037,26 @@ ds1685_rtc_probe(struct platform_device *pdev)
rtc->write(rtc, RTC_EXT_CTRL_4B, rtc->write(rtc, RTC_EXT_CTRL_4B,
(rtc->read(rtc, RTC_EXT_CTRL_4B) | RTC_CTRL_4B_KSE)); (rtc->read(rtc, RTC_EXT_CTRL_4B) | RTC_CTRL_4B_KSE));
rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc_dev))
return PTR_ERR(rtc_dev);
rtc_dev->ops = &ds1685_rtc_ops;
/* Century bit is useless because leap year fails in 1900 and 2100 */
rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000;
rtc_dev->range_max = RTC_TIMESTAMP_END_2099;
/* Maximum periodic rate is 8192Hz (0.122070ms). */
rtc_dev->max_user_freq = RTC_MAX_USER_FREQ;
/* See if the platform doesn't support UIE. */
if (pdata->uie_unsupported)
rtc_dev->uie_unsupported = 1;
rtc->uie_unsupported = pdata->uie_unsupported;
rtc->dev = rtc_dev;
/* /*
* Fetch the IRQ and setup the interrupt handler. * Fetch the IRQ and setup the interrupt handler.
* *
...@@ -2076,32 +2089,13 @@ ds1685_rtc_probe(struct platform_device *pdev) ...@@ -2076,32 +2089,13 @@ ds1685_rtc_probe(struct platform_device *pdev)
/* Setup complete. */ /* Setup complete. */
ds1685_rtc_switch_to_bank0(rtc); ds1685_rtc_switch_to_bank0(rtc);
/* Register the device as an RTC. */
rtc_dev = rtc_device_register(pdev->name, &pdev->dev,
&ds1685_rtc_ops, THIS_MODULE);
/* Success? */
if (IS_ERR(rtc_dev))
return PTR_ERR(rtc_dev);
/* Maximum periodic rate is 8192Hz (0.122070ms). */
rtc_dev->max_user_freq = RTC_MAX_USER_FREQ;
/* See if the platform doesn't support UIE. */
if (pdata->uie_unsupported)
rtc_dev->uie_unsupported = 1;
rtc->uie_unsupported = pdata->uie_unsupported;
rtc->dev = rtc_dev;
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
ret = ds1685_rtc_sysfs_register(&pdev->dev); ret = ds1685_rtc_sysfs_register(&pdev->dev);
if (ret) if (ret)
rtc_device_unregister(rtc->dev); return ret;
#endif #endif
/* Done! */ return rtc_register_device(rtc_dev);
return ret;
} }
/** /**
...@@ -2117,8 +2111,6 @@ ds1685_rtc_remove(struct platform_device *pdev) ...@@ -2117,8 +2111,6 @@ ds1685_rtc_remove(struct platform_device *pdev)
ds1685_rtc_sysfs_unregister(&pdev->dev); ds1685_rtc_sysfs_unregister(&pdev->dev);
#endif #endif
rtc_device_unregister(rtc->dev);
/* Read Ctrl B and clear PIE/AIE/UIE. */ /* Read Ctrl B and clear PIE/AIE/UIE. */
rtc->write(rtc, RTC_CTRL_B, rtc->write(rtc, RTC_CTRL_B,
(rtc->read(rtc, RTC_CTRL_B) & (rtc->read(rtc, RTC_CTRL_B) &
......
...@@ -58,8 +58,7 @@ struct rtc_plat_data { ...@@ -58,8 +58,7 @@ struct rtc_plat_data {
static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm) static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr_rtc; void __iomem *ioaddr = pdata->ioaddr_rtc;
u8 century; u8 century;
...@@ -83,8 +82,7 @@ static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -83,8 +82,7 @@ static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm) static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr_rtc; void __iomem *ioaddr = pdata->ioaddr_rtc;
unsigned int year, month, day, hour, minute, second, week; unsigned int year, month, day, hour, minute, second, week;
unsigned int century; unsigned int century;
...@@ -154,8 +152,6 @@ static int ds1742_rtc_probe(struct platform_device *pdev) ...@@ -154,8 +152,6 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
int ret = 0; int ret = 0;
struct nvmem_config nvmem_cfg = { struct nvmem_config nvmem_cfg = {
.name = "ds1742_nvram", .name = "ds1742_nvram",
.word_size = 1,
.stride = 1,
.reg_read = ds1742_nvram_read, .reg_read = ds1742_nvram_read,
.reg_write = ds1742_nvram_write, .reg_write = ds1742_nvram_write,
}; };
......
...@@ -73,8 +73,8 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -73,8 +73,8 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct ftrtc010_rtc *rtc = dev_get_drvdata(dev); struct ftrtc010_rtc *rtc = dev_get_drvdata(dev);
unsigned int days, hour, min, sec; u32 days, hour, min, sec, offset;
unsigned long offset, time; timeu64_t time;
sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND); sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE); min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
...@@ -84,7 +84,7 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -84,7 +84,7 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
time = offset + days * 86400 + hour * 3600 + min * 60 + sec; time = offset + days * 86400 + hour * 3600 + min * 60 + sec;
rtc_time_to_tm(time, tm); rtc_time64_to_tm(time, tm);
return 0; return 0;
} }
...@@ -92,13 +92,10 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -92,13 +92,10 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int ftrtc010_rtc_set_time(struct device *dev, struct rtc_time *tm) static int ftrtc010_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct ftrtc010_rtc *rtc = dev_get_drvdata(dev); struct ftrtc010_rtc *rtc = dev_get_drvdata(dev);
unsigned int sec, min, hour, day; u32 sec, min, hour, day, offset;
unsigned long offset, time; timeu64_t time;
if (tm->tm_year >= 2148) /* EPOCH Year + 179 */ time = rtc_tm_to_time64(tm);
return -EINVAL;
rtc_tm_to_time(tm, &time);
sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND); sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE); min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
...@@ -120,6 +117,7 @@ static const struct rtc_class_ops ftrtc010_rtc_ops = { ...@@ -120,6 +117,7 @@ static const struct rtc_class_ops ftrtc010_rtc_ops = {
static int ftrtc010_rtc_probe(struct platform_device *pdev) static int ftrtc010_rtc_probe(struct platform_device *pdev)
{ {
u32 days, hour, min, sec;
struct ftrtc010_rtc *rtc; struct ftrtc010_rtc *rtc;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *res; struct resource *res;
...@@ -166,14 +164,27 @@ static int ftrtc010_rtc_probe(struct platform_device *pdev) ...@@ -166,14 +164,27 @@ static int ftrtc010_rtc_probe(struct platform_device *pdev)
if (!rtc->rtc_base) if (!rtc->rtc_base)
return -ENOMEM; return -ENOMEM;
rtc->rtc_dev = devm_rtc_allocate_device(dev);
if (IS_ERR(rtc->rtc_dev))
return PTR_ERR(rtc->rtc_dev);
rtc->rtc_dev->ops = &ftrtc010_rtc_ops;
sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
hour = readl(rtc->rtc_base + FTRTC010_RTC_HOUR);
days = readl(rtc->rtc_base + FTRTC010_RTC_DAYS);
rtc->rtc_dev->range_min = (u64)days * 86400 + hour * 3600 +
min * 60 + sec;
rtc->rtc_dev->range_max = U32_MAX + rtc->rtc_dev->range_min;
ret = devm_request_irq(dev, rtc->rtc_irq, ftrtc010_rtc_interrupt, ret = devm_request_irq(dev, rtc->rtc_irq, ftrtc010_rtc_interrupt,
IRQF_SHARED, pdev->name, dev); IRQF_SHARED, pdev->name, dev);
if (unlikely(ret)) if (unlikely(ret))
return ret; return ret;
rtc->rtc_dev = rtc_device_register(pdev->name, dev, return rtc_register_device(rtc->rtc_dev);
&ftrtc010_rtc_ops, THIS_MODULE);
return PTR_ERR_OR_ZERO(rtc->rtc_dev);
} }
static int ftrtc010_rtc_remove(struct platform_device *pdev) static int ftrtc010_rtc_remove(struct platform_device *pdev)
...@@ -184,7 +195,6 @@ static int ftrtc010_rtc_remove(struct platform_device *pdev) ...@@ -184,7 +195,6 @@ static int ftrtc010_rtc_remove(struct platform_device *pdev)
clk_disable_unprepare(rtc->extclk); clk_disable_unprepare(rtc->extclk);
if (!IS_ERR(rtc->pclk)) if (!IS_ERR(rtc->pclk))
clk_disable_unprepare(rtc->pclk); clk_disable_unprepare(rtc->pclk);
rtc_device_unregister(rtc->rtc_dev);
return 0; return 0;
} }
......
...@@ -294,11 +294,10 @@ static int lpc32xx_rtc_remove(struct platform_device *pdev) ...@@ -294,11 +294,10 @@ static int lpc32xx_rtc_remove(struct platform_device *pdev)
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int lpc32xx_rtc_suspend(struct device *dev) static int lpc32xx_rtc_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
if (rtc->irq >= 0) { if (rtc->irq >= 0) {
if (device_may_wakeup(&pdev->dev)) if (device_may_wakeup(dev))
enable_irq_wake(rtc->irq); enable_irq_wake(rtc->irq);
else else
disable_irq_wake(rtc->irq); disable_irq_wake(rtc->irq);
...@@ -309,10 +308,9 @@ static int lpc32xx_rtc_suspend(struct device *dev) ...@@ -309,10 +308,9 @@ static int lpc32xx_rtc_suspend(struct device *dev)
static int lpc32xx_rtc_resume(struct device *dev) static int lpc32xx_rtc_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
if (rtc->irq >= 0 && device_may_wakeup(&pdev->dev)) if (rtc->irq >= 0 && device_may_wakeup(dev))
disable_irq_wake(rtc->irq); disable_irq_wake(rtc->irq);
return 0; return 0;
...@@ -321,8 +319,7 @@ static int lpc32xx_rtc_resume(struct device *dev) ...@@ -321,8 +319,7 @@ static int lpc32xx_rtc_resume(struct device *dev)
/* Unconditionally disable the alarm */ /* Unconditionally disable the alarm */
static int lpc32xx_rtc_freeze(struct device *dev) static int lpc32xx_rtc_freeze(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
spin_lock_irq(&rtc->lock); spin_lock_irq(&rtc->lock);
...@@ -337,8 +334,7 @@ static int lpc32xx_rtc_freeze(struct device *dev) ...@@ -337,8 +334,7 @@ static int lpc32xx_rtc_freeze(struct device *dev)
static int lpc32xx_rtc_thaw(struct device *dev) static int lpc32xx_rtc_thaw(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
if (rtc->alarm_enabled) { if (rtc->alarm_enabled) {
spin_lock_irq(&rtc->lock); spin_lock_irq(&rtc->lock);
......
...@@ -87,16 +87,17 @@ ...@@ -87,16 +87,17 @@
static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm) static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm)
{ {
unsigned long v, t; unsigned long v;
time64_t t;
v = readl(SYS_TOYREAD0); v = readl(SYS_TOYREAD0);
t = readl(SYS_TOYREAD1); t = readl(SYS_TOYREAD1);
memset(rtm, 0, sizeof(struct rtc_time)); memset(rtm, 0, sizeof(struct rtc_time));
t = mktime((t & LS1X_YEAR_MASK), ls1x_get_month(v), t = mktime64((t & LS1X_YEAR_MASK), ls1x_get_month(v),
ls1x_get_day(v), ls1x_get_hour(v), ls1x_get_day(v), ls1x_get_hour(v),
ls1x_get_min(v), ls1x_get_sec(v)); ls1x_get_min(v), ls1x_get_sec(v));
rtc_time_to_tm(t, rtm); rtc_time64_to_tm(t, rtm);
return 0; return 0;
} }
...@@ -147,15 +148,13 @@ static int ls1x_rtc_probe(struct platform_device *pdev) ...@@ -147,15 +148,13 @@ static int ls1x_rtc_probe(struct platform_device *pdev)
{ {
struct rtc_device *rtcdev; struct rtc_device *rtcdev;
unsigned long v; unsigned long v;
int ret;
v = readl(SYS_COUNTER_CNTRL); v = readl(SYS_COUNTER_CNTRL);
if (!(v & RTC_CNTR_OK)) { if (!(v & RTC_CNTR_OK)) {
dev_err(&pdev->dev, "rtc counters not working\n"); dev_err(&pdev->dev, "rtc counters not working\n");
ret = -ENODEV; return -ENODEV;
goto err;
} }
ret = -ETIMEDOUT;
/* set to 1 HZ if needed */ /* set to 1 HZ if needed */
if (readl(SYS_TOYTRIM) != 32767) { if (readl(SYS_TOYTRIM) != 32767) {
v = 0x100000; v = 0x100000;
...@@ -164,7 +163,7 @@ static int ls1x_rtc_probe(struct platform_device *pdev) ...@@ -164,7 +163,7 @@ static int ls1x_rtc_probe(struct platform_device *pdev)
if (!v) { if (!v) {
dev_err(&pdev->dev, "time out\n"); dev_err(&pdev->dev, "time out\n");
goto err; return -ETIMEDOUT;
} }
writel(32767, SYS_TOYTRIM); writel(32767, SYS_TOYTRIM);
} }
...@@ -172,17 +171,16 @@ static int ls1x_rtc_probe(struct platform_device *pdev) ...@@ -172,17 +171,16 @@ static int ls1x_rtc_probe(struct platform_device *pdev)
while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS)
usleep_range(1000, 3000); usleep_range(1000, 3000);
rtcdev = devm_rtc_device_register(&pdev->dev, "ls1x-rtc", rtcdev = devm_rtc_allocate_device(&pdev->dev);
&ls1x_rtc_ops , THIS_MODULE); if (IS_ERR(rtcdev))
if (IS_ERR(rtcdev)) { return PTR_ERR(rtcdev);
ret = PTR_ERR(rtcdev);
goto err;
}
platform_set_drvdata(pdev, rtcdev); platform_set_drvdata(pdev, rtcdev);
return 0; rtcdev->ops = &ls1x_rtc_ops;
err: rtcdev->range_min = RTC_TIMESTAMP_BEGIN_1900;
return ret; rtcdev->range_max = RTC_TIMESTAMP_END_2099;
return rtc_register_device(rtcdev);
} }
static struct platform_driver ls1x_rtc_driver = { static struct platform_driver ls1x_rtc_driver = {
......
...@@ -47,8 +47,7 @@ struct m48t59_private { ...@@ -47,8 +47,7 @@ struct m48t59_private {
static void static void
m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val) m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val)
{ {
struct platform_device *pdev = to_platform_device(dev); struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
writeb(val, m48t59->ioaddr+ofs); writeb(val, m48t59->ioaddr+ofs);
} }
...@@ -56,8 +55,7 @@ m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val) ...@@ -56,8 +55,7 @@ m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val)
static u8 static u8
m48t59_mem_readb(struct device *dev, u32 ofs) m48t59_mem_readb(struct device *dev, u32 ofs)
{ {
struct platform_device *pdev = to_platform_device(dev); struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
return readb(m48t59->ioaddr+ofs); return readb(m48t59->ioaddr+ofs);
} }
...@@ -67,9 +65,8 @@ m48t59_mem_readb(struct device *dev, u32 ofs) ...@@ -67,9 +65,8 @@ m48t59_mem_readb(struct device *dev, u32 ofs)
*/ */
static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
unsigned long flags; unsigned long flags;
u8 val; u8 val;
...@@ -110,9 +107,8 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -110,9 +107,8 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
unsigned long flags; unsigned long flags;
u8 val = 0; u8 val = 0;
int year = tm->tm_year; int year = tm->tm_year;
...@@ -157,9 +153,8 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -157,9 +153,8 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm)
*/ */
static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct rtc_time *tm = &alrm->time; struct rtc_time *tm = &alrm->time;
unsigned long flags; unsigned long flags;
u8 val; u8 val;
...@@ -204,9 +199,8 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -204,9 +199,8 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
*/ */
static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct rtc_time *tm = &alrm->time; struct rtc_time *tm = &alrm->time;
u8 mday, hour, min, sec; u8 mday, hour, min, sec;
unsigned long flags; unsigned long flags;
...@@ -265,9 +259,8 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -265,9 +259,8 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
*/ */
static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{ {
struct platform_device *pdev = to_platform_device(dev); struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&m48t59->lock, flags); spin_lock_irqsave(&m48t59->lock, flags);
...@@ -282,9 +275,8 @@ static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -282,9 +275,8 @@ static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq) static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq)
{ {
struct platform_device *pdev = to_platform_device(dev); struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
unsigned long flags; unsigned long flags;
u8 val; u8 val;
...@@ -303,9 +295,8 @@ static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq) ...@@ -303,9 +295,8 @@ static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq)
static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id) static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id)
{ {
struct device *dev = (struct device *)dev_id; struct device *dev = (struct device *)dev_id;
struct platform_device *pdev = to_platform_device(dev); struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
u8 event; u8 event;
spin_lock(&m48t59->lock); spin_lock(&m48t59->lock);
......
...@@ -45,7 +45,6 @@ struct mrst_rtc { ...@@ -45,7 +45,6 @@ struct mrst_rtc {
struct rtc_device *rtc; struct rtc_device *rtc;
struct device *dev; struct device *dev;
int irq; int irq;
struct resource *iomem;
u8 enabled_wake; u8 enabled_wake;
u8 suspend_ctrl; u8 suspend_ctrl;
...@@ -329,7 +328,7 @@ static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, ...@@ -329,7 +328,7 @@ static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem,
if (!iomem) if (!iomem)
return -ENODEV; return -ENODEV;
iomem = request_mem_region(iomem->start, resource_size(iomem), iomem = devm_request_mem_region(dev, iomem->start, resource_size(iomem),
driver_name); driver_name);
if (!iomem) { if (!iomem) {
dev_dbg(dev, "i/o mem already in use.\n"); dev_dbg(dev, "i/o mem already in use.\n");
...@@ -337,16 +336,14 @@ static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, ...@@ -337,16 +336,14 @@ static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem,
} }
mrst_rtc.irq = rtc_irq; mrst_rtc.irq = rtc_irq;
mrst_rtc.iomem = iomem;
mrst_rtc.dev = dev; mrst_rtc.dev = dev;
dev_set_drvdata(dev, &mrst_rtc); dev_set_drvdata(dev, &mrst_rtc);
mrst_rtc.rtc = rtc_device_register(driver_name, dev, mrst_rtc.rtc = devm_rtc_allocate_device(dev);
&mrst_rtc_ops, THIS_MODULE); if (IS_ERR(mrst_rtc.rtc))
if (IS_ERR(mrst_rtc.rtc)) { return PTR_ERR(mrst_rtc.rtc);
retval = PTR_ERR(mrst_rtc.rtc);
goto cleanup0; mrst_rtc.rtc->ops = &mrst_rtc_ops;
}
rename_region(iomem, dev_name(&mrst_rtc.rtc->dev)); rename_region(iomem, dev_name(&mrst_rtc.rtc->dev));
...@@ -359,23 +356,27 @@ static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, ...@@ -359,23 +356,27 @@ static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem,
dev_dbg(dev, "TODO: support more than 24-hr BCD mode\n"); dev_dbg(dev, "TODO: support more than 24-hr BCD mode\n");
if (rtc_irq) { if (rtc_irq) {
retval = request_irq(rtc_irq, mrst_rtc_irq, retval = devm_request_irq(dev, rtc_irq, mrst_rtc_irq,
0, dev_name(&mrst_rtc.rtc->dev), 0, dev_name(&mrst_rtc.rtc->dev),
mrst_rtc.rtc); mrst_rtc.rtc);
if (retval < 0) { if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use, err %d\n", dev_dbg(dev, "IRQ %d is already in use, err %d\n",
rtc_irq, retval); rtc_irq, retval);
goto cleanup1; goto cleanup0;
} }
} }
retval = rtc_register_device(mrst_rtc.rtc);
if (retval) {
retval = PTR_ERR(mrst_rtc.rtc);
goto cleanup0;
}
dev_dbg(dev, "initialised\n"); dev_dbg(dev, "initialised\n");
return 0; return 0;
cleanup1:
rtc_device_unregister(mrst_rtc.rtc);
cleanup0: cleanup0:
mrst_rtc.dev = NULL; mrst_rtc.dev = NULL;
release_mem_region(iomem->start, resource_size(iomem));
dev_err(dev, "rtc-mrst: unable to initialise\n"); dev_err(dev, "rtc-mrst: unable to initialise\n");
return retval; return retval;
} }
...@@ -390,20 +391,10 @@ static void rtc_mrst_do_shutdown(void) ...@@ -390,20 +391,10 @@ static void rtc_mrst_do_shutdown(void)
static void rtc_mrst_do_remove(struct device *dev) static void rtc_mrst_do_remove(struct device *dev)
{ {
struct mrst_rtc *mrst = dev_get_drvdata(dev); struct mrst_rtc *mrst = dev_get_drvdata(dev);
struct resource *iomem;
rtc_mrst_do_shutdown(); rtc_mrst_do_shutdown();
if (mrst->irq)
free_irq(mrst->irq, mrst->rtc);
rtc_device_unregister(mrst->rtc);
mrst->rtc = NULL; mrst->rtc = NULL;
iomem = mrst->iomem;
release_mem_region(iomem->start, resource_size(iomem));
mrst->iomem = NULL;
mrst->dev = NULL; mrst->dev = NULL;
} }
......
...@@ -176,8 +176,7 @@ static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -176,8 +176,7 @@ static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
static int mv_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static int mv_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
if (pdata->irq < 0) if (pdata->irq < 0)
......
/* // SPDX-License-Identifier: GPL-2.0+
* Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. //
* // Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/io.h> #include <linux/io.h>
#include <linux/rtc.h> #include <linux/rtc.h>
...@@ -109,8 +102,7 @@ static inline int is_imx1_rtc(struct rtc_plat_data *data) ...@@ -109,8 +102,7 @@ static inline int is_imx1_rtc(struct rtc_plat_data *data)
*/ */
static time64_t get_alarm_or_time(struct device *dev, int time_alarm) static time64_t get_alarm_or_time(struct device *dev, int time_alarm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
u32 day = 0, hr = 0, min = 0, sec = 0, hr_min = 0; u32 day = 0, hr = 0, min = 0, sec = 0, hr_min = 0;
...@@ -139,8 +131,7 @@ static time64_t get_alarm_or_time(struct device *dev, int time_alarm) ...@@ -139,8 +131,7 @@ static time64_t get_alarm_or_time(struct device *dev, int time_alarm)
static void set_alarm_or_time(struct device *dev, int time_alarm, time64_t time) static void set_alarm_or_time(struct device *dev, int time_alarm, time64_t time)
{ {
u32 tod, day, hr, min, sec, temp; u32 tod, day, hr, min, sec, temp;
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
day = div_s64_rem(time, 86400, &tod); day = div_s64_rem(time, 86400, &tod);
...@@ -176,8 +167,7 @@ static void set_alarm_or_time(struct device *dev, int time_alarm, time64_t time) ...@@ -176,8 +167,7 @@ static void set_alarm_or_time(struct device *dev, int time_alarm, time64_t time)
static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm) static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
{ {
time64_t time; time64_t time;
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
time = rtc_tm_to_time64(alrm); time = rtc_tm_to_time64(alrm);
...@@ -190,8 +180,7 @@ static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm) ...@@ -190,8 +180,7 @@ static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit, static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit,
unsigned int enabled) unsigned int enabled)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
u32 reg; u32 reg;
...@@ -266,8 +255,7 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -266,8 +255,7 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
*/ */
static int mxc_rtc_set_mmss(struct device *dev, time64_t time) static int mxc_rtc_set_mmss(struct device *dev, time64_t time)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
/* /*
* TTC_DAYR register is 9-bit in MX1 SoC, save time and day of year only * TTC_DAYR register is 9-bit in MX1 SoC, save time and day of year only
...@@ -295,8 +283,7 @@ static int mxc_rtc_set_mmss(struct device *dev, time64_t time) ...@@ -295,8 +283,7 @@ static int mxc_rtc_set_mmss(struct device *dev, time64_t time)
*/ */
static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
rtc_time64_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time); rtc_time64_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time);
...@@ -310,8 +297,7 @@ static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -310,8 +297,7 @@ static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
*/ */
static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
rtc_update_alarm(dev, &alrm->time); rtc_update_alarm(dev, &alrm->time);
......
...@@ -165,11 +165,6 @@ static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -165,11 +165,6 @@ static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm)
time64_t time = rtc_tm_to_time64(tm); time64_t time = rtc_tm_to_time64(tm);
int ret; int ret;
if (time > U32_MAX) {
dev_err(dev, "RTC exceeded by %llus\n", time - U32_MAX);
return -EINVAL;
}
ret = mxc_rtc_lock(pdata); ret = mxc_rtc_lock(pdata);
if (ret) if (ret)
return ret; return ret;
...@@ -198,7 +193,7 @@ static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -198,7 +193,7 @@ static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (ret) if (ret)
return ret; return ret;
rtc_time_to_tm(readl(ioaddr + SRTC_LPSAR), &alrm->time); rtc_time64_to_tm(readl(ioaddr + SRTC_LPSAR), &alrm->time);
alrm->pending = !!(readl(ioaddr + SRTC_LPSR) & SRTC_LPSR_ALP); alrm->pending = !!(readl(ioaddr + SRTC_LPSR) & SRTC_LPSR_ALP);
return mxc_rtc_unlock(pdata); return mxc_rtc_unlock(pdata);
} }
...@@ -248,11 +243,6 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -248,11 +243,6 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (ret) if (ret)
return ret; return ret;
if (time > U32_MAX) {
dev_err(dev, "Hopefully I am out of service by then :-(\n");
return -EINVAL;
}
writel((u32)time, pdata->ioaddr + SRTC_LPSAR); writel((u32)time, pdata->ioaddr + SRTC_LPSAR);
/* clear alarm interrupt status bit */ /* clear alarm interrupt status bit */
...@@ -343,6 +333,13 @@ static int mxc_rtc_probe(struct platform_device *pdev) ...@@ -343,6 +333,13 @@ static int mxc_rtc_probe(struct platform_device *pdev)
return ret; return ret;
} }
pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(pdata->rtc))
return PTR_ERR(pdata->rtc);
pdata->rtc->ops = &mxc_rtc_ops;
pdata->rtc->range_max = U32_MAX;
clk_disable(pdata->clk); clk_disable(pdata->clk);
platform_set_drvdata(pdev, pdata); platform_set_drvdata(pdev, pdata);
ret = ret =
...@@ -354,15 +351,11 @@ static int mxc_rtc_probe(struct platform_device *pdev) ...@@ -354,15 +351,11 @@ static int mxc_rtc_probe(struct platform_device *pdev)
return ret; return ret;
} }
pdata->rtc = ret = rtc_register_device(pdata->rtc);
devm_rtc_device_register(&pdev->dev, pdev->name, &mxc_rtc_ops, if (ret < 0)
THIS_MODULE);
if (IS_ERR(pdata->rtc)) {
clk_unprepare(pdata->clk); clk_unprepare(pdata->clk);
return PTR_ERR(pdata->rtc);
}
return 0; return ret;
} }
static int mxc_rtc_remove(struct platform_device *pdev) static int mxc_rtc_remove(struct platform_device *pdev)
......
...@@ -43,8 +43,7 @@ static irqreturn_t pcap_rtc_irq(int irq, void *_pcap_rtc) ...@@ -43,8 +43,7 @@ static irqreturn_t pcap_rtc_irq(int irq, void *_pcap_rtc)
static int pcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int pcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
struct rtc_time *tm = &alrm->time; struct rtc_time *tm = &alrm->time;
unsigned long secs; unsigned long secs;
u32 tod; /* time of day, seconds since midnight */ u32 tod; /* time of day, seconds since midnight */
...@@ -63,8 +62,7 @@ static int pcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -63,8 +62,7 @@ static int pcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int pcap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int pcap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
struct rtc_time *tm = &alrm->time; struct rtc_time *tm = &alrm->time;
unsigned long secs; unsigned long secs;
u32 tod, days; u32 tod, days;
...@@ -82,8 +80,7 @@ static int pcap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -82,8 +80,7 @@ static int pcap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm) static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
unsigned long secs; unsigned long secs;
u32 tod, days; u32 tod, days;
...@@ -100,8 +97,7 @@ static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -100,8 +97,7 @@ static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int pcap_rtc_set_mmss(struct device *dev, unsigned long secs) static int pcap_rtc_set_mmss(struct device *dev, unsigned long secs)
{ {
struct platform_device *pdev = to_platform_device(dev); struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
u32 tod, days; u32 tod, days;
tod = secs % SEC_PER_DAY; tod = secs % SEC_PER_DAY;
...@@ -115,8 +111,7 @@ static int pcap_rtc_set_mmss(struct device *dev, unsigned long secs) ...@@ -115,8 +111,7 @@ static int pcap_rtc_set_mmss(struct device *dev, unsigned long secs)
static int pcap_rtc_irq_enable(struct device *dev, int pirq, unsigned int en) static int pcap_rtc_irq_enable(struct device *dev, int pirq, unsigned int en)
{ {
struct platform_device *pdev = to_platform_device(dev); struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
if (en) if (en)
enable_irq(pcap_to_irq(pcap_rtc->pcap, pirq)); enable_irq(pcap_to_irq(pcap_rtc->pcap, pirq));
......
...@@ -363,7 +363,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev) ...@@ -363,7 +363,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
sa1100_rtc->rtar = pxa_rtc->base + 0x4; sa1100_rtc->rtar = pxa_rtc->base + 0x4;
sa1100_rtc->rttr = pxa_rtc->base + 0xc; sa1100_rtc->rttr = pxa_rtc->base + 0xc;
ret = sa1100_rtc_init(pdev, sa1100_rtc); ret = sa1100_rtc_init(pdev, sa1100_rtc);
if (!ret) { if (ret) {
dev_err(dev, "Unable to init SA1100 RTC sub-device\n"); dev_err(dev, "Unable to init SA1100 RTC sub-device\n");
return ret; return ret;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/regmap.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/log2.h> #include <linux/log2.h>
...@@ -51,52 +52,20 @@ ...@@ -51,52 +52,20 @@
#define RX8581_CTRL_RESET 0x01 /* RESET bit */ #define RX8581_CTRL_RESET 0x01 /* RESET bit */
struct rx8581 { struct rx8581 {
struct i2c_client *client; struct regmap *regmap;
struct rtc_device *rtc; struct rtc_device *rtc;
s32 (*read_block_data)(const struct i2c_client *client, u8 command,
u8 length, u8 *values);
s32 (*write_block_data)(const struct i2c_client *client, u8 command,
u8 length, const u8 *values);
}; };
static struct i2c_driver rx8581_driver;
static int rx8581_read_block_data(const struct i2c_client *client, u8 command,
u8 length, u8 *values)
{
s32 i, data;
for (i = 0; i < length; i++) {
data = i2c_smbus_read_byte_data(client, command + i);
if (data < 0)
return data;
values[i] = data;
}
return i;
}
static int rx8581_write_block_data(const struct i2c_client *client, u8 command,
u8 length, const u8 *values)
{
s32 i, ret;
for (i = 0; i < length; i++) {
ret = i2c_smbus_write_byte_data(client, command + i,
values[i]);
if (ret < 0)
return ret;
}
return length;
}
/* /*
* In the routines that deal directly with the rx8581 hardware, we use * In the routines that deal directly with the rx8581 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
*/ */
static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm) static int rx8581_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct i2c_client *client = to_i2c_client(dev);
unsigned char date[7]; unsigned char date[7];
int data, err; unsigned int data;
int err;
struct rx8581 *rx8581 = i2c_get_clientdata(client); struct rx8581 *rx8581 = i2c_get_clientdata(client);
/* First we ensure that the "update flag" is not set, we read the /* First we ensure that the "update flag" is not set, we read the
...@@ -104,45 +73,38 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm) ...@@ -104,45 +73,38 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm)
* has been set, we know that the time has changed during the read so * has been set, we know that the time has changed during the read so
* we repeat the whole process again. * we repeat the whole process again.
*/ */
data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG); err = regmap_read(rx8581->regmap, RX8581_REG_FLAG, &data);
if (data < 0) { if (err < 0)
dev_err(&client->dev, "Unable to read device flags\n"); return err;
return -EIO;
if (data & RX8581_FLAG_VLF) {
dev_warn(dev,
"low voltage detected, date/time is not reliable.\n");
return -EINVAL;
} }
do { do {
/* If update flag set, clear it */ /* If update flag set, clear it */
if (data & RX8581_FLAG_UF) { if (data & RX8581_FLAG_UF) {
err = i2c_smbus_write_byte_data(client, err = regmap_write(rx8581->regmap, RX8581_REG_FLAG,
RX8581_REG_FLAG, (data & ~RX8581_FLAG_UF)); data & ~RX8581_FLAG_UF);
if (err != 0) { if (err < 0)
dev_err(&client->dev, "Unable to write device flags\n"); return err;
return -EIO;
}
} }
/* Now read time and date */ /* Now read time and date */
err = rx8581->read_block_data(client, RX8581_REG_SC, err = regmap_bulk_read(rx8581->regmap, RX8581_REG_SC, date,
7, date); sizeof(date));
if (err < 0) { if (err < 0)
dev_err(&client->dev, "Unable to read date\n"); return err;
return -EIO;
}
/* Check flag register */ /* Check flag register */
data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG); err = regmap_read(rx8581->regmap, RX8581_REG_FLAG, &data);
if (data < 0) { if (err < 0)
dev_err(&client->dev, "Unable to read device flags\n"); return err;
return -EIO;
}
} while (data & RX8581_FLAG_UF); } while (data & RX8581_FLAG_UF);
if (data & RX8581_FLAG_VLF) dev_dbg(dev, "%s: raw data is sec=%02x, min=%02x, hr=%02x, "
dev_info(&client->dev,
"low voltage detected, date/time is not reliable.\n");
dev_dbg(&client->dev,
"%s: raw data is sec=%02x, min=%02x, hr=%02x, "
"wday=%02x, mday=%02x, mon=%02x, year=%02x\n", "wday=%02x, mday=%02x, mon=%02x, year=%02x\n",
__func__, __func__,
date[0], date[1], date[2], date[3], date[4], date[5], date[6]); date[0], date[1], date[2], date[3], date[4], date[5], date[6]);
...@@ -153,12 +115,9 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm) ...@@ -153,12 +115,9 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_wday = ilog2(date[RX8581_REG_DW] & 0x7F); tm->tm_wday = ilog2(date[RX8581_REG_DW] & 0x7F);
tm->tm_mday = bcd2bin(date[RX8581_REG_DM] & 0x3F); tm->tm_mday = bcd2bin(date[RX8581_REG_DM] & 0x3F);
tm->tm_mon = bcd2bin(date[RX8581_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ tm->tm_mon = bcd2bin(date[RX8581_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
tm->tm_year = bcd2bin(date[RX8581_REG_YR]); tm->tm_year = bcd2bin(date[RX8581_REG_YR]) + 100;
if (tm->tm_year < 70)
tm->tm_year += 100; /* assume we are in 1970...2069 */
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n", "mday=%d, mon=%d, year=%d, wday=%d\n",
__func__, __func__,
tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_sec, tm->tm_min, tm->tm_hour,
...@@ -167,13 +126,14 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm) ...@@ -167,13 +126,14 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm)
return 0; return 0;
} }
static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm) static int rx8581_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
int data, err; struct i2c_client *client = to_i2c_client(dev);
int err;
unsigned char buf[7]; unsigned char buf[7];
struct rx8581 *rx8581 = i2c_get_clientdata(client); struct rx8581 *rx8581 = i2c_get_clientdata(client);
dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n", "mday=%d, mon=%d, year=%d, wday=%d\n",
__func__, __func__,
tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_sec, tm->tm_min, tm->tm_hour,
...@@ -190,69 +150,30 @@ static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm) ...@@ -190,69 +150,30 @@ static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm)
buf[RX8581_REG_MO] = bin2bcd(tm->tm_mon + 1); buf[RX8581_REG_MO] = bin2bcd(tm->tm_mon + 1);
/* year and century */ /* year and century */
buf[RX8581_REG_YR] = bin2bcd(tm->tm_year % 100); buf[RX8581_REG_YR] = bin2bcd(tm->tm_year - 100);
buf[RX8581_REG_DW] = (0x1 << tm->tm_wday); buf[RX8581_REG_DW] = (0x1 << tm->tm_wday);
/* Stop the clock */ /* Stop the clock */
data = i2c_smbus_read_byte_data(client, RX8581_REG_CTRL); err = regmap_update_bits(rx8581->regmap, RX8581_REG_CTRL,
if (data < 0) { RX8581_CTRL_STOP, RX8581_CTRL_STOP);
dev_err(&client->dev, "Unable to read control register\n"); if (err < 0)
return -EIO; return err;
}
err = i2c_smbus_write_byte_data(client, RX8581_REG_CTRL,
(data | RX8581_CTRL_STOP));
if (err < 0) {
dev_err(&client->dev, "Unable to write control register\n");
return -EIO;
}
/* write register's data */ /* write register's data */
err = rx8581->write_block_data(client, RX8581_REG_SC, 7, buf); err = regmap_bulk_write(rx8581->regmap, RX8581_REG_SC,
if (err < 0) { buf, sizeof(buf));
dev_err(&client->dev, "Unable to write to date registers\n"); if (err < 0)
return -EIO; return err;
}
/* get VLF and clear it */ /* get VLF and clear it */
data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG); err = regmap_update_bits(rx8581->regmap, RX8581_REG_FLAG,
if (data < 0) { RX8581_FLAG_VLF, 0);
dev_err(&client->dev, "Unable to read flag register\n"); if (err < 0)
return -EIO; return err;
}
err = i2c_smbus_write_byte_data(client, RX8581_REG_FLAG,
(data & ~(RX8581_FLAG_VLF)));
if (err != 0) {
dev_err(&client->dev, "Unable to write flag register\n");
return -EIO;
}
/* Restart the clock */ /* Restart the clock */
data = i2c_smbus_read_byte_data(client, RX8581_REG_CTRL); return regmap_update_bits(rx8581->regmap, RX8581_REG_CTRL,
if (data < 0) { RX8581_CTRL_STOP, 0);
dev_err(&client->dev, "Unable to read control register\n");
return -EIO;
}
err = i2c_smbus_write_byte_data(client, RX8581_REG_CTRL,
(data & ~(RX8581_CTRL_STOP)));
if (err != 0) {
dev_err(&client->dev, "Unable to write control register\n");
return -EIO;
}
return 0;
}
static int rx8581_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
return rx8581_get_datetime(to_i2c_client(dev), tm);
}
static int rx8581_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
return rx8581_set_datetime(to_i2c_client(dev), tm);
} }
static const struct rtc_class_ops rx8581_rtc_ops = { static const struct rtc_class_ops rx8581_rtc_ops = {
...@@ -264,38 +185,35 @@ static int rx8581_probe(struct i2c_client *client, ...@@ -264,38 +185,35 @@ static int rx8581_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct rx8581 *rx8581; struct rx8581 *rx8581;
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xf,
};
dev_dbg(&client->dev, "%s\n", __func__); dev_dbg(&client->dev, "%s\n", __func__);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)
&& !i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
return -EIO;
rx8581 = devm_kzalloc(&client->dev, sizeof(struct rx8581), GFP_KERNEL); rx8581 = devm_kzalloc(&client->dev, sizeof(struct rx8581), GFP_KERNEL);
if (!rx8581) if (!rx8581)
return -ENOMEM; return -ENOMEM;
i2c_set_clientdata(client, rx8581); i2c_set_clientdata(client, rx8581);
rx8581->client = client;
if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
rx8581->read_block_data = i2c_smbus_read_i2c_block_data;
rx8581->write_block_data = i2c_smbus_write_i2c_block_data;
} else {
rx8581->read_block_data = rx8581_read_block_data;
rx8581->write_block_data = rx8581_write_block_data;
}
rx8581->rtc = devm_rtc_device_register(&client->dev, rx8581->regmap = devm_regmap_init_i2c(client, &config);
rx8581_driver.driver.name, &rx8581_rtc_ops, THIS_MODULE); if (IS_ERR(rx8581->regmap))
return PTR_ERR(rx8581->regmap);
if (IS_ERR(rx8581->rtc)) { rx8581->rtc = devm_rtc_allocate_device(&client->dev);
dev_err(&client->dev, if (IS_ERR(rx8581->rtc))
"unable to register the class device\n");
return PTR_ERR(rx8581->rtc); return PTR_ERR(rx8581->rtc);
}
return 0; rx8581->rtc->ops = &rx8581_rtc_ops;
rx8581->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rx8581->rtc->range_max = RTC_TIMESTAMP_END_2099;
rx8581->rtc->start_secs = 0;
rx8581->rtc->set_start_time = true;
return rtc_register_device(rx8581->rtc);
} }
static const struct i2c_device_id rx8581_id[] = { static const struct i2c_device_id rx8581_id[] = {
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#define SPRD_RTC_DAY_ALM_VALUE 0x4c #define SPRD_RTC_DAY_ALM_VALUE 0x4c
#define SPRD_RTC_SPG_VALUE 0x50 #define SPRD_RTC_SPG_VALUE 0x50
#define SPRD_RTC_SPG_UPD 0x54 #define SPRD_RTC_SPG_UPD 0x54
#define SPRD_RTC_PWR_CTRL 0x58
#define SPRD_RTC_PWR_STS 0x5c
#define SPRD_RTC_SEC_AUXALM_UPD 0x60 #define SPRD_RTC_SEC_AUXALM_UPD 0x60
#define SPRD_RTC_MIN_AUXALM_UPD 0x64 #define SPRD_RTC_MIN_AUXALM_UPD 0x64
#define SPRD_RTC_HOUR_AUXALM_UPD 0x68 #define SPRD_RTC_HOUR_AUXALM_UPD 0x68
...@@ -86,7 +88,13 @@ ...@@ -86,7 +88,13 @@
/* SPG values definition for SPRD_RTC_SPG_UPD register */ /* SPG values definition for SPRD_RTC_SPG_UPD register */
#define SPRD_RTC_POWEROFF_ALM_FLAG BIT(8) #define SPRD_RTC_POWEROFF_ALM_FLAG BIT(8)
#define SPRD_RTC_POWER_RESET_FLAG BIT(9)
/* power control/status definition */
#define SPRD_RTC_POWER_RESET_VALUE 0x96
#define SPRD_RTC_POWER_STS_CLEAR GENMASK(7, 0)
#define SPRD_RTC_POWER_STS_SHIFT 8
#define SPRD_RTC_POWER_STS_VALID \
(~SPRD_RTC_POWER_RESET_VALUE << SPRD_RTC_POWER_STS_SHIFT)
/* timeout of synchronizing time and alarm registers (us) */ /* timeout of synchronizing time and alarm registers (us) */
#define SPRD_RTC_POLL_TIMEOUT 200000 #define SPRD_RTC_POLL_TIMEOUT 200000
...@@ -383,7 +391,6 @@ static int sprd_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -383,7 +391,6 @@ static int sprd_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct sprd_rtc *rtc = dev_get_drvdata(dev); struct sprd_rtc *rtc = dev_get_drvdata(dev);
time64_t secs = rtc_tm_to_time64(tm); time64_t secs = rtc_tm_to_time64(tm);
u32 val;
int ret; int ret;
ret = sprd_rtc_set_secs(rtc, SPRD_RTC_TIME, secs); ret = sprd_rtc_set_secs(rtc, SPRD_RTC_TIME, secs);
...@@ -391,27 +398,20 @@ static int sprd_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -391,27 +398,20 @@ static int sprd_rtc_set_time(struct device *dev, struct rtc_time *tm)
return ret; return ret;
if (!rtc->valid) { if (!rtc->valid) {
/* /* Clear RTC power status firstly */
* Set SPRD_RTC_POWER_RESET_FLAG to indicate now RTC has valid ret = regmap_write(rtc->regmap, rtc->base + SPRD_RTC_PWR_CTRL,
* time values. SPRD_RTC_POWER_STS_CLEAR);
*/
ret = regmap_update_bits(rtc->regmap,
rtc->base + SPRD_RTC_SPG_UPD,
SPRD_RTC_POWER_RESET_FLAG,
SPRD_RTC_POWER_RESET_FLAG);
if (ret) if (ret)
return ret; return ret;
ret = regmap_read_poll_timeout(rtc->regmap, /*
rtc->base + SPRD_RTC_INT_RAW_STS, * Set RTC power status to indicate now RTC has valid time
val, (val & SPRD_RTC_SPG_UPD_EN), * values.
SPRD_RTC_POLL_DELAY_US, */
SPRD_RTC_POLL_TIMEOUT); ret = regmap_write(rtc->regmap, rtc->base + SPRD_RTC_PWR_CTRL,
if (ret) { SPRD_RTC_POWER_STS_VALID);
dev_err(rtc->dev, "failed to update SPG value:%d\n", if (ret)
ret);
return ret; return ret;
}
rtc->valid = true; rtc->valid = true;
} }
...@@ -562,15 +562,16 @@ static int sprd_rtc_check_power_down(struct sprd_rtc *rtc) ...@@ -562,15 +562,16 @@ static int sprd_rtc_check_power_down(struct sprd_rtc *rtc)
u32 val; u32 val;
int ret; int ret;
ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_SPG_VALUE, &val); ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_PWR_STS, &val);
if (ret) if (ret)
return ret; return ret;
/* /*
* If the SPRD_RTC_POWER_RESET_FLAG was not set, which means the RTC has * If the RTC power status value is SPRD_RTC_POWER_RESET_VALUE, which
* been powered down, so the RTC time values are invalid. * means the RTC has been powered down, so the RTC time values are
* invalid.
*/ */
rtc->valid = (val & SPRD_RTC_POWER_RESET_FLAG) ? true : false; rtc->valid = val == SPRD_RTC_POWER_RESET_VALUE ? false : true;
return 0; return 0;
} }
...@@ -600,6 +601,10 @@ static int sprd_rtc_probe(struct platform_device *pdev) ...@@ -600,6 +601,10 @@ static int sprd_rtc_probe(struct platform_device *pdev)
return rtc->irq; return rtc->irq;
} }
rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc))
return PTR_ERR(rtc->rtc);
rtc->dev = &pdev->dev; rtc->dev = &pdev->dev;
platform_set_drvdata(pdev, rtc); platform_set_drvdata(pdev, rtc);
...@@ -626,10 +631,14 @@ static int sprd_rtc_probe(struct platform_device *pdev) ...@@ -626,10 +631,14 @@ static int sprd_rtc_probe(struct platform_device *pdev)
return ret; return ret;
} }
rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, rtc->rtc->ops = &sprd_rtc_ops;
&sprd_rtc_ops, THIS_MODULE); rtc->rtc->range_min = 0;
if (IS_ERR(rtc->rtc)) rtc->rtc->range_max = 5662310399LL;
return PTR_ERR(rtc->rtc); ret = rtc_register_device(rtc->rtc);
if (ret) {
dev_err(&pdev->dev, "failed to register rtc device\n");
return ret;
}
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
return 0; return 0;
......
...@@ -359,8 +359,7 @@ static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -359,8 +359,7 @@ static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct sh_rtc *rtc = dev_get_drvdata(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
unsigned int sec128, sec2, yr, yr100, cf_bit; unsigned int sec128, sec2, yr, yr100, cf_bit;
do { do {
...@@ -419,8 +418,7 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -419,8 +418,7 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct sh_rtc *rtc = dev_get_drvdata(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
unsigned int tmp; unsigned int tmp;
int year; int year;
...@@ -475,8 +473,7 @@ static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off) ...@@ -475,8 +473,7 @@ static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off)
static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct sh_rtc *rtc = dev_get_drvdata(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
struct rtc_time *tm = &wkalrm->time; struct rtc_time *tm = &wkalrm->time;
spin_lock_irq(&rtc->lock); spin_lock_irq(&rtc->lock);
...@@ -509,8 +506,7 @@ static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc, ...@@ -509,8 +506,7 @@ static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc,
static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct sh_rtc *rtc = dev_get_drvdata(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
unsigned int rcr1; unsigned int rcr1;
struct rtc_time *tm = &wkalrm->time; struct rtc_time *tm = &wkalrm->time;
int mon; int mon;
...@@ -723,8 +719,7 @@ static int __exit sh_rtc_remove(struct platform_device *pdev) ...@@ -723,8 +719,7 @@ static int __exit sh_rtc_remove(struct platform_device *pdev)
static void sh_rtc_set_irq_wake(struct device *dev, int enabled) static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
{ {
struct platform_device *pdev = to_platform_device(dev); struct sh_rtc *rtc = dev_get_drvdata(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
irq_set_irq_wake(rtc->periodic_irq, enabled); irq_set_irq_wake(rtc->periodic_irq, enabled);
......
/* // SPDX-License-Identifier: GPL-2.0+
* Copyright (C) 2011-2012 Freescale Semiconductor, Inc. //
* // Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
......
...@@ -212,6 +212,10 @@ static int st_rtc_probe(struct platform_device *pdev) ...@@ -212,6 +212,10 @@ static int st_rtc_probe(struct platform_device *pdev)
if (!rtc) if (!rtc)
return -ENOMEM; return -ENOMEM;
rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc_dev))
return PTR_ERR(rtc->rtc_dev);
spin_lock_init(&rtc->lock); spin_lock_init(&rtc->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
...@@ -253,26 +257,19 @@ static int st_rtc_probe(struct platform_device *pdev) ...@@ -253,26 +257,19 @@ static int st_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc); platform_set_drvdata(pdev, rtc);
rtc->rtc_dev = rtc_device_register("st-lpc-rtc", &pdev->dev, rtc->rtc_dev->ops = &st_rtc_ops;
&st_rtc_ops, THIS_MODULE); rtc->rtc_dev->range_max = U64_MAX;
if (IS_ERR(rtc->rtc_dev)) { do_div(rtc->rtc_dev->range_max, rtc->clkrate);
ret = rtc_register_device(rtc->rtc_dev);
if (ret) {
clk_disable_unprepare(rtc->clk); clk_disable_unprepare(rtc->clk);
return PTR_ERR(rtc->rtc_dev); return ret;
} }
return 0; return 0;
} }
static int st_rtc_remove(struct platform_device *pdev)
{
struct st_rtc *rtc = platform_get_drvdata(pdev);
if (likely(rtc->rtc_dev))
rtc_device_unregister(rtc->rtc_dev);
return 0;
}
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int st_rtc_suspend(struct device *dev) static int st_rtc_suspend(struct device *dev)
{ {
...@@ -325,7 +322,6 @@ static struct platform_driver st_rtc_platform_driver = { ...@@ -325,7 +322,6 @@ static struct platform_driver st_rtc_platform_driver = {
.of_match_table = st_rtc_match, .of_match_table = st_rtc_match,
}, },
.probe = st_rtc_probe, .probe = st_rtc_probe,
.remove = st_rtc_remove,
}; };
module_platform_driver(st_rtc_platform_driver); module_platform_driver(st_rtc_platform_driver);
......
...@@ -74,8 +74,7 @@ struct rtc_plat_data { ...@@ -74,8 +74,7 @@ struct rtc_plat_data {
static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm) static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
u8 flags; u8 flags;
...@@ -97,8 +96,7 @@ static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -97,8 +96,7 @@ static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int stk17ta8_rtc_read_time(struct device *dev, struct rtc_time *tm) static int stk17ta8_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
unsigned int year, month, day, hour, minute, second, week; unsigned int year, month, day, hour, minute, second, week;
unsigned int century; unsigned int century;
...@@ -163,8 +161,7 @@ static void stk17ta8_rtc_update_alarm(struct rtc_plat_data *pdata) ...@@ -163,8 +161,7 @@ static void stk17ta8_rtc_update_alarm(struct rtc_plat_data *pdata)
static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
...@@ -180,8 +177,7 @@ static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -180,8 +177,7 @@ static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int stk17ta8_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int stk17ta8_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
...@@ -217,8 +213,7 @@ static irqreturn_t stk17ta8_rtc_interrupt(int irq, void *dev_id) ...@@ -217,8 +213,7 @@ static irqreturn_t stk17ta8_rtc_interrupt(int irq, void *dev_id)
static int stk17ta8_rtc_alarm_irq_enable(struct device *dev, static int stk17ta8_rtc_alarm_irq_enable(struct device *dev,
unsigned int enabled) unsigned int enabled)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
......
This diff is collapsed.
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
#define SUN6I_ALARM_CONFIG_WAKEUP BIT(0) #define SUN6I_ALARM_CONFIG_WAKEUP BIT(0)
#define SUN6I_LOSC_OUT_GATING 0x0060 #define SUN6I_LOSC_OUT_GATING 0x0060
#define SUN6I_LOSC_OUT_GATING_EN BIT(0) #define SUN6I_LOSC_OUT_GATING_EN_OFFSET 0
/* /*
* Get date values * Get date values
...@@ -255,7 +255,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) ...@@ -255,7 +255,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
&clkout_name); &clkout_name);
rtc->ext_losc = clk_register_gate(NULL, clkout_name, rtc->hw.init->name, rtc->ext_losc = clk_register_gate(NULL, clkout_name, rtc->hw.init->name,
0, rtc->base + SUN6I_LOSC_OUT_GATING, 0, rtc->base + SUN6I_LOSC_OUT_GATING,
SUN6I_LOSC_OUT_GATING_EN, 0, SUN6I_LOSC_OUT_GATING_EN_OFFSET, 0,
&rtc->lock); &rtc->lock);
if (IS_ERR(rtc->ext_losc)) { if (IS_ERR(rtc->ext_losc)) {
pr_crit("Couldn't register the LOSC external gate\n"); pr_crit("Couldn't register the LOSC external gate\n");
......
...@@ -445,6 +445,10 @@ static int sunxi_rtc_probe(struct platform_device *pdev) ...@@ -445,6 +445,10 @@ static int sunxi_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, chip); platform_set_drvdata(pdev, chip);
chip->dev = &pdev->dev; chip->dev = &pdev->dev;
chip->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(chip->rtc))
return PTR_ERR(chip->rtc);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
chip->base = devm_ioremap_resource(&pdev->dev, res); chip->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(chip->base)) if (IS_ERR(chip->base))
...@@ -481,11 +485,12 @@ static int sunxi_rtc_probe(struct platform_device *pdev) ...@@ -481,11 +485,12 @@ static int sunxi_rtc_probe(struct platform_device *pdev)
writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, chip->base + writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, chip->base +
SUNXI_ALRM_IRQ_STA); SUNXI_ALRM_IRQ_STA);
chip->rtc = rtc_device_register("rtc-sunxi", &pdev->dev, chip->rtc->ops = &sunxi_rtc_ops;
&sunxi_rtc_ops, THIS_MODULE);
if (IS_ERR(chip->rtc)) { ret = rtc_register_device(chip->rtc);
if (ret) {
dev_err(&pdev->dev, "unable to register device\n"); dev_err(&pdev->dev, "unable to register device\n");
return PTR_ERR(chip->rtc); return ret;
} }
dev_info(&pdev->dev, "RTC enabled\n"); dev_info(&pdev->dev, "RTC enabled\n");
...@@ -493,18 +498,8 @@ static int sunxi_rtc_probe(struct platform_device *pdev) ...@@ -493,18 +498,8 @@ static int sunxi_rtc_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int sunxi_rtc_remove(struct platform_device *pdev)
{
struct sunxi_rtc_dev *chip = platform_get_drvdata(pdev);
rtc_device_unregister(chip->rtc);
return 0;
}
static struct platform_driver sunxi_rtc_driver = { static struct platform_driver sunxi_rtc_driver = {
.probe = sunxi_rtc_probe, .probe = sunxi_rtc_probe,
.remove = sunxi_rtc_remove,
.driver = { .driver = {
.name = "sunxi-rtc", .name = "sunxi-rtc",
.of_match_table = sunxi_rtc_dt_ids, .of_match_table = sunxi_rtc_dt_ids,
......
...@@ -13,135 +13,139 @@ ...@@ -13,135 +13,139 @@
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
static int test_mmss64; #define MAX_RTC_TEST 3
module_param(test_mmss64, int, 0644);
MODULE_PARM_DESC(test_mmss64, "Test struct rtc_class_ops.set_mmss64().");
static struct platform_device *test0 = NULL, *test1 = NULL; struct rtc_test_data {
struct rtc_device *rtc;
time64_t offset;
struct timer_list alarm;
bool alarm_en;
};
static int test_rtc_read_alarm(struct device *dev, struct platform_device *pdev[MAX_RTC_TEST];
struct rtc_wkalrm *alrm)
{
return 0;
}
static int test_rtc_set_alarm(struct device *dev, static int test_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rtc_wkalrm *alrm)
{ {
return 0; struct rtc_test_data *rtd = dev_get_drvdata(dev);
} time64_t alarm;
alarm = (rtd->alarm.expires - jiffies) / HZ;
alarm += ktime_get_real_seconds() + rtd->offset;
rtc_time64_to_tm(alarm, &alrm->time);
alrm->enabled = rtd->alarm_en;
static int test_rtc_read_time(struct device *dev,
struct rtc_time *tm)
{
rtc_time64_to_tm(ktime_get_real_seconds(), tm);
return 0; return 0;
} }
static int test_rtc_set_mmss64(struct device *dev, time64_t secs) static int test_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
dev_info(dev, "%s, secs = %lld\n", __func__, (long long)secs); struct rtc_test_data *rtd = dev_get_drvdata(dev);
ktime_t timeout;
u64 expires;
timeout = rtc_tm_to_time64(&alrm->time) - ktime_get_real_seconds();
timeout -= rtd->offset;
del_timer(&rtd->alarm);
expires = jiffies + timeout * HZ;
if (expires > U32_MAX)
expires = U32_MAX;
pr_err("ABE: %s +%d %s\n", __FILE__, __LINE__, __func__);
rtd->alarm.expires = expires;
if (alrm->enabled)
add_timer(&rtd->alarm);
rtd->alarm_en = alrm->enabled;
return 0; return 0;
} }
static int test_rtc_set_mmss(struct device *dev, unsigned long secs) static int test_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
dev_info(dev, "%s, secs = %lu\n", __func__, secs); struct rtc_test_data *rtd = dev_get_drvdata(dev);
rtc_time64_to_tm(ktime_get_real_seconds() + rtd->offset, tm);
return 0; return 0;
} }
static int test_rtc_proc(struct device *dev, struct seq_file *seq) static int test_rtc_set_mmss64(struct device *dev, time64_t secs)
{ {
struct platform_device *plat_dev = to_platform_device(dev); struct rtc_test_data *rtd = dev_get_drvdata(dev);
seq_printf(seq, "test\t\t: yes\n"); rtd->offset = secs - ktime_get_real_seconds();
seq_printf(seq, "id\t\t: %d\n", plat_dev->id);
return 0; return 0;
} }
static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
{ {
struct rtc_test_data *rtd = dev_get_drvdata(dev);
rtd->alarm_en = enable;
if (enable)
add_timer(&rtd->alarm);
else
del_timer(&rtd->alarm);
return 0; return 0;
} }
static struct rtc_class_ops test_rtc_ops = { static const struct rtc_class_ops test_rtc_ops_noalm = {
.proc = test_rtc_proc, .read_time = test_rtc_read_time,
.set_mmss64 = test_rtc_set_mmss64,
.alarm_irq_enable = test_rtc_alarm_irq_enable,
};
static const struct rtc_class_ops test_rtc_ops = {
.read_time = test_rtc_read_time, .read_time = test_rtc_read_time,
.read_alarm = test_rtc_read_alarm, .read_alarm = test_rtc_read_alarm,
.set_alarm = test_rtc_set_alarm, .set_alarm = test_rtc_set_alarm,
.set_mmss = test_rtc_set_mmss, .set_mmss64 = test_rtc_set_mmss64,
.alarm_irq_enable = test_rtc_alarm_irq_enable, .alarm_irq_enable = test_rtc_alarm_irq_enable,
}; };
static ssize_t test_irq_show(struct device *dev, static void test_rtc_alarm_handler(struct timer_list *t)
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", 42);
}
static ssize_t test_irq_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{ {
int retval; struct rtc_test_data *rtd = from_timer(rtd, t, alarm);
struct platform_device *plat_dev = to_platform_device(dev);
struct rtc_device *rtc = platform_get_drvdata(plat_dev);
retval = count;
if (strncmp(buf, "tick", 4) == 0 && rtc->pie_enabled)
rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF);
else if (strncmp(buf, "alarm", 5) == 0) {
struct rtc_wkalrm alrm;
int err = rtc_read_alarm(rtc, &alrm);
if (!err && alrm.enabled)
rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
} else if (strncmp(buf, "update", 6) == 0 && rtc->uie_rtctimer.enabled)
rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF);
else
retval = -EINVAL;
return retval; rtc_update_irq(rtd->rtc, 1, RTC_AF | RTC_IRQF);
} }
static DEVICE_ATTR(irq, S_IRUGO | S_IWUSR, test_irq_show, test_irq_store);
static int test_probe(struct platform_device *plat_dev) static int test_probe(struct platform_device *plat_dev)
{ {
int err; struct rtc_test_data *rtd;
struct rtc_device *rtc;
if (test_mmss64) {
test_rtc_ops.set_mmss64 = test_rtc_set_mmss64;
test_rtc_ops.set_mmss = NULL;
}
rtc = devm_rtc_device_register(&plat_dev->dev, "test", rtd = devm_kzalloc(&plat_dev->dev, sizeof(*rtd), GFP_KERNEL);
&test_rtc_ops, THIS_MODULE); if (!rtd)
if (IS_ERR(rtc)) { return -ENOMEM;
return PTR_ERR(rtc);
}
err = device_create_file(&plat_dev->dev, &dev_attr_irq); platform_set_drvdata(plat_dev, rtd);
if (err)
dev_err(&plat_dev->dev, "Unable to create sysfs entry: %s\n",
dev_attr_irq.attr.name);
platform_set_drvdata(plat_dev, rtc); rtd->rtc = devm_rtc_allocate_device(&plat_dev->dev);
if (IS_ERR(rtd->rtc))
return PTR_ERR(rtd->rtc);
return 0; switch (plat_dev->id) {
} case 0:
rtd->rtc->ops = &test_rtc_ops_noalm;
break;
default:
rtd->rtc->ops = &test_rtc_ops;
}
static int test_remove(struct platform_device *plat_dev) timer_setup(&rtd->alarm, test_rtc_alarm_handler, 0);
{ rtd->alarm.expires = 0;
device_remove_file(&plat_dev->dev, &dev_attr_irq);
return 0; return rtc_register_device(rtd->rtc);
} }
static struct platform_driver test_driver = { static struct platform_driver test_driver = {
.probe = test_probe, .probe = test_probe,
.remove = test_remove,
.driver = { .driver = {
.name = "rtc-test", .name = "rtc-test",
}, },
...@@ -149,47 +153,45 @@ static struct platform_driver test_driver = { ...@@ -149,47 +153,45 @@ static struct platform_driver test_driver = {
static int __init test_init(void) static int __init test_init(void)
{ {
int err; int i, err;
if ((err = platform_driver_register(&test_driver))) if ((err = platform_driver_register(&test_driver)))
return err; return err;
if ((test0 = platform_device_alloc("rtc-test", 0)) == NULL) {
err = -ENOMEM; err = -ENOMEM;
goto exit_driver_unregister; for (i = 0; i < MAX_RTC_TEST; i++) {
pdev[i] = platform_device_alloc("rtc-test", i);
if (!pdev[i])
goto exit_free_mem;
} }
if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) { for (i = 0; i < MAX_RTC_TEST; i++) {
err = -ENOMEM; err = platform_device_add(pdev[i]);
goto exit_put_test0; if (err)
goto exit_device_del;
} }
if ((err = platform_device_add(test0)))
goto exit_put_test1;
if ((err = platform_device_add(test1)))
goto exit_del_test0;
return 0; return 0;
exit_del_test0: exit_device_del:
platform_device_del(test0); for (; i > 0; i--)
platform_device_del(pdev[i - 1]);
exit_put_test1: exit_free_mem:
platform_device_put(test1); for (i = 0; i < MAX_RTC_TEST; i++)
platform_device_put(pdev[i]);
exit_put_test0:
platform_device_put(test0);
exit_driver_unregister:
platform_driver_unregister(&test_driver); platform_driver_unregister(&test_driver);
return err; return err;
} }
static void __exit test_exit(void) static void __exit test_exit(void)
{ {
platform_device_unregister(test0); int i;
platform_device_unregister(test1);
for (i = 0; i < MAX_RTC_TEST; i++)
platform_device_unregister(pdev[i]);
platform_driver_unregister(&test_driver); platform_driver_unregister(&test_driver);
} }
......
...@@ -58,7 +58,6 @@ struct tps6586x_rtc { ...@@ -58,7 +58,6 @@ struct tps6586x_rtc {
struct rtc_device *rtc; struct rtc_device *rtc;
int irq; int irq;
bool irq_en; bool irq_en;
unsigned long long epoch_start;
}; };
static inline struct device *to_tps6586x_dev(struct device *dev) static inline struct device *to_tps6586x_dev(struct device *dev)
...@@ -68,10 +67,9 @@ static inline struct device *to_tps6586x_dev(struct device *dev) ...@@ -68,10 +67,9 @@ static inline struct device *to_tps6586x_dev(struct device *dev)
static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm) static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
struct device *tps_dev = to_tps6586x_dev(dev); struct device *tps_dev = to_tps6586x_dev(dev);
unsigned long long ticks = 0; unsigned long long ticks = 0;
unsigned long seconds; time64_t seconds;
u8 buff[6]; u8 buff[6];
int ret; int ret;
int i; int i;
...@@ -88,26 +86,20 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm) ...@@ -88,26 +86,20 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm)
} }
seconds = ticks >> 10; seconds = ticks >> 10;
seconds += rtc->epoch_start; rtc_time64_to_tm(seconds, tm);
rtc_time_to_tm(seconds, tm);
return 0; return 0;
} }
static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm) static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
struct device *tps_dev = to_tps6586x_dev(dev); struct device *tps_dev = to_tps6586x_dev(dev);
unsigned long long ticks; unsigned long long ticks;
unsigned long seconds; time64_t seconds;
u8 buff[5]; u8 buff[5];
int ret; int ret;
rtc_tm_to_time(tm, &seconds); seconds = rtc_tm_to_time64(tm);
if (seconds < rtc->epoch_start) {
dev_err(dev, "requested time unsupported\n");
return -EINVAL;
}
seconds -= rtc->epoch_start;
ticks = (unsigned long long)seconds << 10; ticks = (unsigned long long)seconds << 10;
buff[0] = (ticks >> 32) & 0xff; buff[0] = (ticks >> 32) & 0xff;
...@@ -155,9 +147,8 @@ static int tps6586x_rtc_alarm_irq_enable(struct device *dev, ...@@ -155,9 +147,8 @@ static int tps6586x_rtc_alarm_irq_enable(struct device *dev,
static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
struct device *tps_dev = to_tps6586x_dev(dev); struct device *tps_dev = to_tps6586x_dev(dev);
unsigned long seconds; time64_t seconds;
unsigned long ticks; unsigned long ticks;
unsigned long rtc_current_time; unsigned long rtc_current_time;
unsigned long long rticks = 0; unsigned long long rticks = 0;
...@@ -166,12 +157,7 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -166,12 +157,7 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
int ret; int ret;
int i; int i;
rtc_tm_to_time(&alrm->time, &seconds); seconds = rtc_tm_to_time64(&alrm->time);
if (alrm->enabled && (seconds < rtc->epoch_start)) {
dev_err(dev, "can't set alarm to requested time\n");
return -EINVAL;
}
ret = tps6586x_rtc_alarm_irq_enable(dev, alrm->enabled); ret = tps6586x_rtc_alarm_irq_enable(dev, alrm->enabled);
if (ret < 0) { if (ret < 0) {
...@@ -179,7 +165,6 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -179,7 +165,6 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret; return ret;
} }
seconds -= rtc->epoch_start;
ret = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD, ret = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD,
sizeof(rbuff), rbuff); sizeof(rbuff), rbuff);
if (ret < 0) { if (ret < 0) {
...@@ -210,10 +195,9 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -210,10 +195,9 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
struct device *tps_dev = to_tps6586x_dev(dev); struct device *tps_dev = to_tps6586x_dev(dev);
unsigned long ticks; unsigned long ticks;
unsigned long seconds; time64_t seconds;
u8 buff[3]; u8 buff[3];
int ret; int ret;
...@@ -225,9 +209,8 @@ static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -225,9 +209,8 @@ static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
ticks = (buff[0] << 16) | (buff[1] << 8) | buff[2]; ticks = (buff[0] << 16) | (buff[1] << 8) | buff[2];
seconds = ticks >> 10; seconds = ticks >> 10;
seconds += rtc->epoch_start;
rtc_time_to_tm(seconds, &alrm->time); rtc_time64_to_tm(seconds, &alrm->time);
return 0; return 0;
} }
...@@ -260,9 +243,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) ...@@ -260,9 +243,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
rtc->dev = &pdev->dev; rtc->dev = &pdev->dev;
rtc->irq = platform_get_irq(pdev, 0); rtc->irq = platform_get_irq(pdev, 0);
/* Set epoch start as 00:00:00:01:01:2009 */
rtc->epoch_start = mktime(2009, 1, 1, 0, 0, 0);
/* 1 kHz tick mode, enable tick counting */ /* 1 kHz tick mode, enable tick counting */
ret = tps6586x_update(tps_dev, RTC_CTRL, ret = tps6586x_update(tps_dev, RTC_CTRL,
RTC_ENABLE | OSC_SRC_SEL | RTC_ENABLE | OSC_SRC_SEL |
...@@ -276,14 +256,18 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) ...@@ -276,14 +256,18 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
platform_set_drvdata(pdev, rtc); platform_set_drvdata(pdev, rtc);
rtc->rtc = devm_rtc_device_register(&pdev->dev, dev_name(&pdev->dev), rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
&tps6586x_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) { if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc); ret = PTR_ERR(rtc->rtc);
dev_err(&pdev->dev, "RTC device register: ret %d\n", ret); dev_err(&pdev->dev, "RTC allocate device: ret %d\n", ret);
goto fail_rtc_register; goto fail_rtc_register;
} }
rtc->rtc->ops = &tps6586x_rtc_ops;
rtc->rtc->range_max = (1ULL << 30) - 1; /* 30-bit seconds */
rtc->rtc->start_secs = mktime64(2009, 1, 1, 0, 0, 0);
rtc->rtc->set_start_time = true;
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
tps6586x_rtc_irq, tps6586x_rtc_irq,
IRQF_ONESHOT, IRQF_ONESHOT,
...@@ -294,6 +278,13 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) ...@@ -294,6 +278,13 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
goto fail_rtc_register; goto fail_rtc_register;
} }
disable_irq(rtc->irq); disable_irq(rtc->irq);
ret = rtc_register_device(rtc->rtc);
if (ret) {
dev_err(&pdev->dev, "RTC device register: ret %d\n", ret);
goto fail_rtc_register;
}
return 0; return 0;
fail_rtc_register: fail_rtc_register:
......
...@@ -380,6 +380,10 @@ static int tps65910_rtc_probe(struct platform_device *pdev) ...@@ -380,6 +380,10 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
if (!tps_rtc) if (!tps_rtc)
return -ENOMEM; return -ENOMEM;
tps_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(tps_rtc->rtc))
return PTR_ERR(tps_rtc->rtc);
/* Clear pending interrupts */ /* Clear pending interrupts */
ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg); ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg);
if (ret < 0) if (ret < 0)
...@@ -421,10 +425,12 @@ static int tps65910_rtc_probe(struct platform_device *pdev) ...@@ -421,10 +425,12 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
tps_rtc->irq = irq; tps_rtc->irq = irq;
device_set_wakeup_capable(&pdev->dev, 1); device_set_wakeup_capable(&pdev->dev, 1);
tps_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, tps_rtc->rtc->ops = &tps65910_rtc_ops;
&tps65910_rtc_ops, THIS_MODULE); tps_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
if (IS_ERR(tps_rtc->rtc)) { tps_rtc->rtc->range_max = RTC_TIMESTAMP_END_2099;
ret = PTR_ERR(tps_rtc->rtc);
ret = rtc_register_device(tps_rtc->rtc);
if (ret) {
dev_err(&pdev->dev, "RTC device register: err %d\n", ret); dev_err(&pdev->dev, "RTC device register: err %d\n", ret);
return ret; return ret;
} }
...@@ -432,17 +438,6 @@ static int tps65910_rtc_probe(struct platform_device *pdev) ...@@ -432,17 +438,6 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
return 0; return 0;
} }
/*
* Disable tps65910 RTC interrupts.
* Sets status flag to free.
*/
static int tps65910_rtc_remove(struct platform_device *pdev)
{
tps65910_rtc_alarm_irq_enable(&pdev->dev, 0);
return 0;
}
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int tps65910_rtc_suspend(struct device *dev) static int tps65910_rtc_suspend(struct device *dev)
{ {
...@@ -468,7 +463,6 @@ static SIMPLE_DEV_PM_OPS(tps65910_rtc_pm_ops, tps65910_rtc_suspend, ...@@ -468,7 +463,6 @@ static SIMPLE_DEV_PM_OPS(tps65910_rtc_pm_ops, tps65910_rtc_suspend,
static struct platform_driver tps65910_rtc_driver = { static struct platform_driver tps65910_rtc_driver = {
.probe = tps65910_rtc_probe, .probe = tps65910_rtc_probe,
.remove = tps65910_rtc_remove,
.driver = { .driver = {
.name = "tps65910-rtc", .name = "tps65910-rtc",
.pm = &tps65910_rtc_pm_ops, .pm = &tps65910_rtc_pm_ops,
......
...@@ -88,7 +88,7 @@ static unsigned int alarm_enabled; ...@@ -88,7 +88,7 @@ static unsigned int alarm_enabled;
static int aie_irq; static int aie_irq;
static int pie_irq; static int pie_irq;
static inline unsigned long read_elapsed_second(void) static inline time64_t read_elapsed_second(void)
{ {
unsigned long first_low, first_mid, first_high; unsigned long first_low, first_mid, first_high;
...@@ -105,10 +105,10 @@ static inline unsigned long read_elapsed_second(void) ...@@ -105,10 +105,10 @@ static inline unsigned long read_elapsed_second(void)
} while (first_low != second_low || first_mid != second_mid || } while (first_low != second_low || first_mid != second_mid ||
first_high != second_high); first_high != second_high);
return (first_high << 17) | (first_mid << 1) | (first_low >> 15); return ((u64)first_high << 17) | (first_mid << 1) | (first_low >> 15);
} }
static inline void write_elapsed_second(unsigned long sec) static inline void write_elapsed_second(time64_t sec)
{ {
spin_lock_irq(&rtc_lock); spin_lock_irq(&rtc_lock);
...@@ -121,22 +121,22 @@ static inline void write_elapsed_second(unsigned long sec) ...@@ -121,22 +121,22 @@ static inline void write_elapsed_second(unsigned long sec)
static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time) static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time)
{ {
unsigned long epoch_sec, elapsed_sec; time64_t epoch_sec, elapsed_sec;
epoch_sec = mktime(epoch, 1, 1, 0, 0, 0); epoch_sec = mktime64(epoch, 1, 1, 0, 0, 0);
elapsed_sec = read_elapsed_second(); elapsed_sec = read_elapsed_second();
rtc_time_to_tm(epoch_sec + elapsed_sec, time); rtc_time64_to_tm(epoch_sec + elapsed_sec, time);
return 0; return 0;
} }
static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time) static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time)
{ {
unsigned long epoch_sec, current_sec; time64_t epoch_sec, current_sec;
epoch_sec = mktime(epoch, 1, 1, 0, 0, 0); epoch_sec = mktime64(epoch, 1, 1, 0, 0, 0);
current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, current_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec); time->tm_hour, time->tm_min, time->tm_sec);
write_elapsed_second(current_sec - epoch_sec); write_elapsed_second(current_sec - epoch_sec);
...@@ -165,10 +165,10 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) ...@@ -165,10 +165,10 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
{ {
unsigned long alarm_sec; time64_t alarm_sec;
struct rtc_time *time = &wkalrm->time; struct rtc_time *time = &wkalrm->time;
alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, alarm_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec); time->tm_hour, time->tm_min, time->tm_sec);
spin_lock_irq(&rtc_lock); spin_lock_irq(&rtc_lock);
...@@ -292,13 +292,16 @@ static int rtc_probe(struct platform_device *pdev) ...@@ -292,13 +292,16 @@ static int rtc_probe(struct platform_device *pdev)
goto err_rtc1_iounmap; goto err_rtc1_iounmap;
} }
rtc = devm_rtc_device_register(&pdev->dev, rtc_name, &vr41xx_rtc_ops, rtc = devm_rtc_allocate_device(&pdev->dev);
THIS_MODULE);
if (IS_ERR(rtc)) { if (IS_ERR(rtc)) {
retval = PTR_ERR(rtc); retval = PTR_ERR(rtc);
goto err_iounmap_all; goto err_iounmap_all;
} }
rtc->ops = &vr41xx_rtc_ops;
/* 48-bit counter at 32.768 kHz */
rtc->range_max = (1ULL << 33) - 1;
rtc->max_user_freq = MAX_PERIODIC_RATE; rtc->max_user_freq = MAX_PERIODIC_RATE;
spin_lock_irq(&rtc_lock); spin_lock_irq(&rtc_lock);
...@@ -340,6 +343,10 @@ static int rtc_probe(struct platform_device *pdev) ...@@ -340,6 +343,10 @@ static int rtc_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Real Time Clock of NEC VR4100 series\n"); dev_info(&pdev->dev, "Real Time Clock of NEC VR4100 series\n");
retval = rtc_register_device(rtc);
if (retval)
goto err_iounmap_all;
return 0; return 0;
err_iounmap_all: err_iounmap_all:
......
...@@ -278,10 +278,9 @@ static int xlnx_rtc_remove(struct platform_device *pdev) ...@@ -278,10 +278,9 @@ static int xlnx_rtc_remove(struct platform_device *pdev)
static int __maybe_unused xlnx_rtc_suspend(struct device *dev) static int __maybe_unused xlnx_rtc_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
if (device_may_wakeup(&pdev->dev)) if (device_may_wakeup(dev))
enable_irq_wake(xrtcdev->alarm_irq); enable_irq_wake(xrtcdev->alarm_irq);
else else
xlnx_rtc_alarm_irq_enable(dev, 0); xlnx_rtc_alarm_irq_enable(dev, 0);
...@@ -291,10 +290,9 @@ static int __maybe_unused xlnx_rtc_suspend(struct device *dev) ...@@ -291,10 +290,9 @@ static int __maybe_unused xlnx_rtc_suspend(struct device *dev)
static int __maybe_unused xlnx_rtc_resume(struct device *dev) static int __maybe_unused xlnx_rtc_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
if (device_may_wakeup(&pdev->dev)) if (device_may_wakeup(dev))
disable_irq_wake(xrtcdev->alarm_irq); disable_irq_wake(xrtcdev->alarm_irq);
else else
xlnx_rtc_alarm_irq_enable(dev, 1); xlnx_rtc_alarm_irq_enable(dev, 1);
......
...@@ -285,7 +285,7 @@ void rtc_nvmem_unregister(struct rtc_device *rtc); ...@@ -285,7 +285,7 @@ void rtc_nvmem_unregister(struct rtc_device *rtc);
static inline int rtc_nvmem_register(struct rtc_device *rtc, static inline int rtc_nvmem_register(struct rtc_device *rtc,
struct nvmem_config *nvmem_config) struct nvmem_config *nvmem_config)
{ {
return -ENODEV; return 0;
} }
static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {} static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {}
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment