RTC for 4.18

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
 -----BEGIN PGP SIGNATURE-----
 
 iQIyBAABCgAdFiEEXx9Viay1+e7J/aM4AyWl4gNJNJIFAlsdkVAACgkQAyWl4gNJ
 NJJMfA/3YzFFxsZZdcf84e3LWMwgA12c/YNM24nlQ3S+Fo23bAerGZyKEroBAaiq
 HVL7j6OwYkVrGJHbqvq7J0UhI0J9Fjbtp8suj7Cj5wBKOG3wUeTkpzBiHZN42WBB
 PpPC97z9HRTVjxAOmWC0wbbf622ZBOZyEti3kMVh5DwER+8iNoPJWUS6nmZdOVqR
 PjT/c79WCT3q7n2j9t+ZjQfVOqPlqTTty3WuCpYDu3ce3W7uUO/cISc3M4HA4A5d
 dw6gDcd9WQcf4qZESjlci84pn4Ktha317fX5QlkaKM2ul3x33652pbH8Yv6ynZsq
 ZlmIyE9vSWThBWUj7R4lo9/y2IsVL5FtMRIN5bvG6ms/tPuZGeX/qAZEBgMggN+r
 PgFY5U+k/1WkOeSMd4OpuE9g308wzR3xGIhtuiJOa006hvHNvyMunIeMURDWjceW
 fh1uu1eUQqf4yKt8ceB9s38pYcPrvtEOh9006VcHMp/JJpoOjIn93jdsaxCmlUZc
 poDAYgH+RudVaaMZ4VvZjzlrD/diSwjh51MpBf0ImdQut4ehfZdGna4WOzddenAT
 1nsVKRp/qxR0b9kolQYCpSVsJKHME4pZPEKY0f5UyCZgEy/l3SkMPVOkjXlAzZAd
 ZX0l857UGeVbWP5sRDTc9J1sw2QAVO2oBsSOEeK0z9kvbuz/uQ==
 =I5F0
 -----END PGP SIGNATURE-----

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
  ...
This commit is contained in:
Linus Torvalds 2018-06-10 16:13:24 -07:00
commit 1aaccb5fa0
43 changed files with 911 additions and 848 deletions

View File

@ -9,7 +9,7 @@ Optional properties:
Example:
rtc: nxp,rtc-pcf2123@3 {
pcf2123: rtc@3 {
compatible = "nxp,rtc-pcf2123"
reg = <3>
spi-cs-high;

View File

@ -1,23 +1,29 @@
STM32 Real Time Clock
Required properties:
- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
the device is compatible with stm32(f4/f7) or stm32h7.
- compatible: can be one of the following:
- "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.
- clocks: can use up to two clocks, depending on part used:
- "rtc_ck": RTC clock source.
It is required on stm32(f4/f7) and stm32h7.
- "pclk": RTC APB interface clock.
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".
It is required only on stm32h7.
It is required on stm32(h7/mp1).
- interrupt-parent: phandle for the interrupt controller.
- interrupts: rtc alarm interrupt.
- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain
(RTC registers) write protection.
It is required on stm32(f4/f7/h7).
- interrupts: rtc alarm interrupt. On stm32mp1, a second interrupt is required
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-clock-parents: phandle of the new parent clock of rtc_ck.
@ -31,7 +37,7 @@ Example:
assigned-clock-parents = <&rcc 1 CLK_LSE>;
interrupt-parent = <&exti>;
interrupts = <17 1>;
st,syscfg = <&pwrcfg>;
st,syscfg = <&pwrcfg 0x00 0x100>;
};
rtc: rtc@58004000 {
@ -44,5 +50,14 @@ Example:
interrupt-parent = <&exti>;
interrupts = <17 1>;
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>;
};

View File

@ -1613,7 +1613,7 @@ config RTC_DRV_JZ4740
If you say yes here you get support for the Ingenic JZ47xx SoCs RTC
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.
config RTC_DRV_LPC24XX

View File

@ -441,6 +441,11 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
int err;
if (!rtc->ops)
return -ENODEV;
else if (!rtc->ops->set_alarm)
return -EINVAL;
err = rtc_valid_tm(&alarm->time);
if (err != 0)
return err;

View File

@ -94,7 +94,7 @@ int rtc_nvmem_register(struct rtc_device *rtc,
nvmem_config->dev = rtc->dev.parent;
nvmem_config->owner = rtc->owner;
rtc->nvmem = nvmem_register(nvmem_config);
if (IS_ERR_OR_NULL(rtc->nvmem))
if (IS_ERR(rtc->nvmem))
return PTR_ERR(rtc->nvmem);
/* Register the old ABI */

View File

@ -52,10 +52,8 @@ struct pm80x_rtc_info {
struct regmap *map;
struct rtc_device *rtc_dev;
struct device *dev;
struct delayed_work calib_work;
int irq;
int vrtc;
};
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,
next->tm_min = alrm->tm_min;
next->tm_sec = alrm->tm_sec;
rtc_tm_to_time(now, &now_time);
rtc_tm_to_time(next, &next_time);
now_time = rtc_tm_to_time64(now);
next_time = rtc_tm_to_time64(next);
if (next_time < now_time) {
/* Advance one day */
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)
ticks = base + data;
dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
base, data, ticks);
rtc_time_to_tm(ticks, tm);
rtc_time64_to_tm(ticks, tm);
return 0;
}
@ -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);
unsigned char buf[4];
unsigned long ticks, base, data;
if (tm->tm_year > 206) {
dev_dbg(info->dev,
"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);
ticks = rtc_tm_to_time64(tm);
/* load 32-bit read-only counter */
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)
dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
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);
alrm->enabled = (ret & PM800_ALARM1_EN) ? 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)
dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
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);
rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time);
/* 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);
data = ticks - base;
@ -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_info *info;
struct device_node *node = pdev->dev.of_node;
struct rtc_time tm;
unsigned long ticks = 0;
int ret;
if (!pdata && !node) {
@ -294,6 +285,10 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
info->dev = &pdev->dev;
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,
IRQF_ONESHOT, "rtc", info);
if (ret < 0) {
@ -302,30 +297,11 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
goto out;
}
ret = pm80x_rtc_read_time(&pdev->dev, &tm);
if (ret < 0) {
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->ops = &pm80x_rtc_ops;
info->rtc_dev->range_max = U32_MAX;
info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm80x-rtc",
&pm80x_rtc_ops, THIS_MODULE);
if (IS_ERR(info->rtc_dev)) {
ret = PTR_ERR(info->rtc_dev);
ret = rtc_register_device(info->rtc_dev);
if (ret) {
dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
goto out_rtc;
}

View File

@ -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];
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_MN] = bin2bcd(tm->tm_min);
regs[ABB5ZES3_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */
@ -925,6 +916,14 @@ static int abb5zes3_probe(struct i2c_client *client,
if (ret)
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) {
ret = devm_request_threaded_irq(dev, client->irq, NULL,
_abb5zes3_rtc_interrupt,
@ -942,14 +941,9 @@ static int abb5zes3_probe(struct i2c_client *client,
}
}
data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops,
THIS_MODULE);
ret = PTR_ERR_OR_ZERO(data->rtc);
if (ret) {
dev_err(dev, "%s: unable to register RTC device (%d)\n",
__func__, ret);
goto err;
}
data->rtc->ops = &rtc_ops;
data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
data->rtc->range_max = RTC_TIMESTAMP_END_2099;
/* Enable battery low detection interrupt if battery not already low */
if (!data->battery_low && data->irq) {
@ -961,6 +955,8 @@ static int abb5zes3_probe(struct i2c_client *client,
}
}
ret = rtc_register_device(data->rtc);
err:
if (ret && data && data->irq)
device_init_wakeup(dev, false);

View File

@ -440,6 +440,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
rtc->ops = &at91_rtc_ops;
rtc->range_min = RTC_TIMESTAMP_BEGIN_1900;
rtc->range_max = RTC_TIMESTAMP_END_2099;
ret = rtc_register_device(rtc);
if (ret)
goto err_clk;

View File

@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct bq4802 *p = platform_get_drvdata(pdev);
struct bq4802 *p = dev_get_drvdata(dev);
unsigned long flags;
unsigned int century;
u8 val;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct bq4802 *p = platform_get_drvdata(pdev);
struct bq4802 *p = dev_get_drvdata(dev);
u8 sec, min, hrs, day, mon, yrs, century, val;
unsigned long flags;
unsigned int year;

View File

@ -145,9 +145,6 @@ static int brcmstb_waketmr_settime(struct device *dev,
sec = rtc_tm_to_time64(tm);
if (sec > U32_MAX || sec < 0)
return -EINVAL;
writel_relaxed(sec, timer->base + BRCMSTB_WKTMR_COUNTER);
return 0;
@ -184,9 +181,6 @@ static int brcmstb_waketmr_setalarm(struct device *dev,
else
sec = 0;
if (sec > U32_MAX || sec < 0)
return -EINVAL;
brcmstb_waketmr_set_alarm(timer, sec);
return 0;
@ -229,6 +223,10 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
if (IS_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
* process boot-time "wakeups" (e.g., from S5 soft-off)
@ -261,11 +259,12 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot;
register_reboot_notifier(&timer->reboot_notifier);
timer->rtc = rtc_device_register("brcmstb-waketmr", dev,
&brcmstb_waketmr_ops, THIS_MODULE);
if (IS_ERR(timer->rtc)) {
timer->rtc->ops = &brcmstb_waketmr_ops;
timer->rtc->range_max = U32_MAX;
ret = rtc_register_device(timer->rtc);
if (ret) {
dev_err(dev, "unable to register device\n");
ret = PTR_ERR(timer->rtc);
goto err_notifier;
}
@ -288,7 +287,6 @@ static int brcmstb_waketmr_remove(struct platform_device *pdev)
struct brcmstb_waketmr *timer = dev_get_drvdata(&pdev->dev);
unregister_reboot_notifier(&timer->reboot_notifier);
rtc_device_unregister(timer->rtc);
return 0;
}

View File

@ -43,11 +43,24 @@
#include <linux/of_platform.h>
#ifdef CONFIG_X86
#include <asm/i8259.h>
#include <asm/processor.h>
#include <linux/dmi.h>
#endif
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
#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 rtc_device *rtc;
struct device *dev;
@ -153,6 +166,12 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler)
#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
@ -298,7 +317,7 @@ static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control)
*/
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
if (is_hpet_enabled())
if (use_hpet_alarm())
return;
rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
@ -318,7 +337,13 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)
rtc_control |= mask;
CMOS_WRITE(rtc_control, RTC_CONTROL);
hpet_set_rtc_irq_bit(mask);
if (use_hpet_alarm())
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);
}
@ -330,7 +355,13 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)
rtc_control = CMOS_READ(RTC_CONTROL);
rtc_control &= ~mask;
CMOS_WRITE(rtc_control, RTC_CONTROL);
hpet_mask_rtc_irq_bit(mask);
if (use_hpet_alarm())
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);
}
@ -448,10 +479,14 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
CMOS_WRITE(mon, cmos->mon_alrm);
}
/* FIXME the HPET alarm glue currently ignores day_alrm
* and mon_alrm ...
*/
hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec);
if (use_hpet_alarm()) {
/*
* FIXME the HPET alarm glue currently ignores day_alrm
* and mon_alrm ...
*/
hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min,
t->time.tm_sec);
}
if (t->enabled)
cmos_irq_enable(cmos, RTC_AIE);
@ -508,7 +543,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
"batt_status\t: %s\n",
(rtc_control & RTC_PIE) ? "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_DM_BINARY) ? "no" : "yes",
(rtc_control & RTC_DST_EN) ? "yes" : "no",
@ -614,7 +649,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
*/
irqstat = CMOS_READ(RTC_INTR_FLAGS);
rtc_control = CMOS_READ(RTC_CONTROL);
if (is_hpet_enabled())
if (use_hpet_alarm())
irqstat = (unsigned long)irq & 0xF0;
/* If we were suspended, RTC_CONTROL may not be accurate since the
@ -633,7 +668,8 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
cmos_rtc.suspend_ctrl &= ~RTC_AIE;
rtc_control &= ~RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL);
hpet_mask_rtc_irq_bit(RTC_AIE);
if (use_hpet_alarm())
hpet_mask_rtc_irq_bit(RTC_AIE);
CMOS_READ(RTC_INTR_FLAGS);
}
spin_unlock(&rtc_lock);
@ -762,7 +798,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
* need to do something about other clock frequencies.
*/
cmos_rtc.rtc->irq_freq = 1024;
hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq);
if (use_hpet_alarm())
hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq);
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)
goto cleanup1;
}
hpet_rtc_timer_init();
if (use_hpet_alarm())
hpet_rtc_timer_init();
if (is_valid_irq(rtc_irq)) {
irq_handler_t rtc_cmos_int_handler;
if (is_hpet_enabled()) {
if (use_hpet_alarm()) {
rtc_cmos_int_handler = hpet_rtc_interrupt;
retval = hpet_register_irq_handler(cmos_interrupt);
if (retval) {
@ -824,7 +862,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
"alarms up to one day",
cmos_rtc.century ? ", y3k" : "",
nvmem_cfg.size,
is_hpet_enabled() ? ", hpet irqs" : "");
use_hpet_alarm() ? ", hpet irqs" : "");
return 0;
@ -858,7 +896,8 @@ static void cmos_do_remove(struct device *dev)
if (is_valid_irq(cmos->irq)) {
free_irq(cmos->irq, cmos->rtc);
hpet_unregister_irq_handler(cmos_interrupt);
if (use_hpet_alarm())
hpet_unregister_irq_handler(cmos_interrupt);
}
cmos->rtc = NULL;
@ -935,13 +974,13 @@ static int cmos_suspend(struct device *dev)
mask = RTC_IRQMASK;
tmp &= ~mask;
CMOS_WRITE(tmp, RTC_CONTROL);
hpet_mask_rtc_irq_bit(mask);
if (use_hpet_alarm())
hpet_mask_rtc_irq_bit(mask);
cmos_checkintr(cmos, tmp);
}
spin_unlock_irq(&rtc_lock);
if (tmp & RTC_AIE) {
if ((tmp & RTC_AIE) && !use_acpi_alarm) {
cmos->enabled_wake = 1;
if (cmos->wake_on)
cmos->wake_on(dev);
@ -976,8 +1015,26 @@ static void cmos_check_wkalrm(struct device *dev)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
struct rtc_wkalrm current_alarm;
time64_t t_now;
time64_t t_current_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);
t_current_expires = rtc_tm_to_time64(&current_alarm.time);
@ -996,7 +1053,7 @@ static int __maybe_unused cmos_resume(struct device *dev)
struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char tmp;
if (cmos->enabled_wake) {
if (cmos->enabled_wake && !use_acpi_alarm) {
if (cmos->wake_off)
cmos->wake_off(dev);
else
@ -1014,16 +1071,17 @@ static int __maybe_unused cmos_resume(struct device *dev)
if (tmp & RTC_IRQMASK) {
unsigned char mask;
if (device_may_wakeup(dev))
if (device_may_wakeup(dev) && use_hpet_alarm())
hpet_rtc_timer_init();
do {
CMOS_WRITE(tmp, RTC_CONTROL);
hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK);
if (use_hpet_alarm())
hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK);
mask = CMOS_READ(RTC_INTR_FLAGS);
mask &= (tmp & RTC_IRQMASK) | RTC_IRQF;
if (!is_hpet_enabled() || !is_intr(mask))
if (!use_hpet_alarm() || !is_intr(mask))
break;
/* force one-shot behavior if HPET blocked
@ -1068,16 +1126,27 @@ static u32 rtc_handler(void *context)
unsigned char rtc_intr;
unsigned long flags;
spin_lock_irqsave(&rtc_lock, flags);
if (cmos_rtc.suspend_ctrl)
rtc_control = CMOS_READ(RTC_CONTROL);
if (rtc_control & RTC_AIE) {
cmos_rtc.suspend_ctrl &= ~RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL);
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_update_irq(cmos->rtc, 1, rtc_intr);
/*
* 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);
if (cmos_rtc.suspend_ctrl)
rtc_control = CMOS_READ(RTC_CONTROL);
if (rtc_control & RTC_AIE) {
cmos_rtc.suspend_ctrl &= ~RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL);
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
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);
acpi_clear_event(ACPI_EVENT_RTC);
@ -1107,6 +1176,28 @@ static void rtc_wake_off(struct device *dev)
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
* 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
@ -1119,6 +1210,8 @@ static void cmos_wake_setup(struct device *dev)
if (acpi_disabled)
return;
use_acpi_alarm_quirks();
rtc_wake_setup(dev);
acpi_rtc_info.wake_on = rtc_wake_on;
acpi_rtc_info.wake_off = rtc_wake_off;

View File

@ -1,19 +1,8 @@
/*
* RTC driver for Chrome OS Embedded Controller
*
* Copyright (c) 2017, Google, Inc
*
* 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.
*/
// SPDX-License-Identifier: GPL-2.0
// RTC driver for ChromeOS Embedded Controller.
//
// Copyright (C) 2017 Google, Inc.
// Author: Stephen Barber <smbarber@chromium.org>
#include <linux/kernel.h>
#include <linux/mfd/cros_ec.h>
@ -409,5 +398,5 @@ module_platform_driver(cros_ec_rtc_driver);
MODULE_DESCRIPTION("RTC driver for Chrome OS ECs");
MODULE_AUTHOR("Stephen Barber <smbarber@chromium.org>");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);

View File

@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1216_priv *priv = platform_get_drvdata(pdev);
struct ds1216_priv *priv = dev_get_drvdata(dev);
struct ds1216_regs regs;
ds1216_switch_ds_to_clock(priv->ioaddr);
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1216_priv *priv = platform_get_drvdata(pdev);
struct ds1216_priv *priv = dev_get_drvdata(dev);
struct ds1216_regs regs;
ds1216_switch_ds_to_clock(priv->ioaddr);

View File

@ -201,6 +201,7 @@ static const struct chip_desc chips[last_ds_type] = {
.century_reg = DS1307_REG_HOUR,
.century_enable_bit = DS1340_BIT_CENTURY_EN,
.century_bit = DS1340_BIT_CENTURY,
.do_trickle_setup = &do_trickle_setup_ds1339,
.trickle_charger_reg = 0x08,
},
[ds_1341] = {
@ -1371,6 +1372,7 @@ static void ds1307_clks_register(struct ds1307 *ds1307)
static const struct regmap_config regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x9,
};
static int ds1307_probe(struct i2c_client *client,

View File

@ -314,8 +314,7 @@ ds1511_rtc_update_alarm(struct rtc_plat_data *pdata)
static int
ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
if (pdata->irq <= 0)
return -EINVAL;
@ -334,8 +333,7 @@ ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int
ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
if (pdata->irq <= 0)
return -EINVAL;
@ -373,8 +371,7 @@ ds1511_interrupt(int irq, void *dev_id)
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 = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
if (pdata->irq <= 0)
return -EINVAL;

View File

@ -73,8 +73,7 @@ struct rtc_plat_data {
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 = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
u8 century;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
unsigned int year, month, day, hour, minute, second, week;
unsigned int century;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
if (pdata->irq <= 0)
return -EINVAL;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
if (pdata->irq <= 0)
return -EINVAL;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
if (pdata->irq <= 0)
return -EINVAL;

View File

@ -267,8 +267,7 @@ ds1685_rtc_get_ssn(struct ds1685_priv *rtc, u8 *ssn)
static int
ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = dev_get_drvdata(dev);
u8 ctrlb, century;
u8 seconds, minutes, hours, wday, mday, month, years;
@ -317,8 +316,7 @@ ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int
ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = dev_get_drvdata(dev);
u8 ctrlb, seconds, minutes, hours, wday, mday, month, years, century;
/* Fetch the time info from rtc_time. */
@ -394,8 +392,7 @@ ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int
ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = dev_get_drvdata(dev);
u8 seconds, minutes, hours, mday, ctrlb, ctrlc;
int ret;
@ -453,8 +450,7 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int
ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = dev_get_drvdata(dev);
u8 ctrlb, seconds, minutes, hours, mday;
int ret;
@ -1119,8 +1115,7 @@ static ssize_t
ds1685_rtc_sysfs_battery_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = dev_get_drvdata(dev);
u8 ctrld;
ctrld = rtc->read(rtc, RTC_CTRL_D);
@ -1140,8 +1135,7 @@ static ssize_t
ds1685_rtc_sysfs_auxbatt_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = dev_get_drvdata(dev);
u8 ctrl4a;
ds1685_rtc_switch_to_bank1(rtc);
@ -1163,8 +1157,7 @@ static ssize_t
ds1685_rtc_sysfs_serial_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct ds1685_priv *rtc = dev_get_drvdata(dev);
u8 ssn[8];
ds1685_rtc_switch_to_bank1(rtc);
@ -2044,6 +2037,26 @@ ds1685_rtc_probe(struct platform_device *pdev)
rtc->write(rtc, RTC_EXT_CTRL_4B,
(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.
*
@ -2076,32 +2089,13 @@ ds1685_rtc_probe(struct platform_device *pdev)
/* Setup complete. */
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
ret = ds1685_rtc_sysfs_register(&pdev->dev);
if (ret)
rtc_device_unregister(rtc->dev);
return ret;
#endif
/* Done! */
return ret;
return rtc_register_device(rtc_dev);
}
/**
@ -2117,8 +2111,6 @@ ds1685_rtc_remove(struct platform_device *pdev)
ds1685_rtc_sysfs_unregister(&pdev->dev);
#endif
rtc_device_unregister(rtc->dev);
/* Read Ctrl B and clear PIE/AIE/UIE. */
rtc->write(rtc, RTC_CTRL_B,
(rtc->read(rtc, RTC_CTRL_B) &

View File

@ -58,8 +58,7 @@ struct rtc_plat_data {
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 = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr_rtc;
u8 century;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr_rtc;
unsigned int year, month, day, hour, minute, second, week;
unsigned int century;
@ -154,8 +152,6 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
int ret = 0;
struct nvmem_config nvmem_cfg = {
.name = "ds1742_nvram",
.word_size = 1,
.stride = 1,
.reg_read = ds1742_nvram_read,
.reg_write = ds1742_nvram_write,
};

View File

@ -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);
unsigned int days, hour, min, sec;
unsigned long offset, time;
u32 days, hour, min, sec, offset;
timeu64_t time;
sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
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)
time = offset + days * 86400 + hour * 3600 + min * 60 + sec;
rtc_time_to_tm(time, tm);
rtc_time64_to_tm(time, tm);
return 0;
}
@ -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)
{
struct ftrtc010_rtc *rtc = dev_get_drvdata(dev);
unsigned int sec, min, hour, day;
unsigned long offset, time;
u32 sec, min, hour, day, offset;
timeu64_t time;
if (tm->tm_year >= 2148) /* EPOCH Year + 179 */
return -EINVAL;
rtc_tm_to_time(tm, &time);
time = rtc_tm_to_time64(tm);
sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
@ -120,6 +117,7 @@ static const struct rtc_class_ops ftrtc010_rtc_ops = {
static int ftrtc010_rtc_probe(struct platform_device *pdev)
{
u32 days, hour, min, sec;
struct ftrtc010_rtc *rtc;
struct device *dev = &pdev->dev;
struct resource *res;
@ -166,14 +164,27 @@ static int ftrtc010_rtc_probe(struct platform_device *pdev)
if (!rtc->rtc_base)
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,
IRQF_SHARED, pdev->name, dev);
if (unlikely(ret))
return ret;
rtc->rtc_dev = rtc_device_register(pdev->name, dev,
&ftrtc010_rtc_ops, THIS_MODULE);
return PTR_ERR_OR_ZERO(rtc->rtc_dev);
return rtc_register_device(rtc->rtc_dev);
}
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);
if (!IS_ERR(rtc->pclk))
clk_disable_unprepare(rtc->pclk);
rtc_device_unregister(rtc->rtc_dev);
return 0;
}

View File

@ -294,11 +294,10 @@ static int lpc32xx_rtc_remove(struct platform_device *pdev)
#ifdef CONFIG_PM
static int lpc32xx_rtc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
if (rtc->irq >= 0) {
if (device_may_wakeup(&pdev->dev))
if (device_may_wakeup(dev))
enable_irq_wake(rtc->irq);
else
disable_irq_wake(rtc->irq);
@ -309,10 +308,9 @@ static int lpc32xx_rtc_suspend(struct device *dev)
static int lpc32xx_rtc_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
if (rtc->irq >= 0 && device_may_wakeup(&pdev->dev))
if (rtc->irq >= 0 && device_may_wakeup(dev))
disable_irq_wake(rtc->irq);
return 0;
@ -321,8 +319,7 @@ static int lpc32xx_rtc_resume(struct device *dev)
/* Unconditionally disable the alarm */
static int lpc32xx_rtc_freeze(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
spin_lock_irq(&rtc->lock);
@ -337,8 +334,7 @@ static int lpc32xx_rtc_freeze(struct device *dev)
static int lpc32xx_rtc_thaw(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
if (rtc->alarm_enabled) {
spin_lock_irq(&rtc->lock);

View File

@ -87,16 +87,17 @@
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);
t = readl(SYS_TOYREAD1);
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_min(v), ls1x_get_sec(v));
rtc_time_to_tm(t, rtm);
rtc_time64_to_tm(t, rtm);
return 0;
}
@ -147,15 +148,13 @@ static int ls1x_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtcdev;
unsigned long v;
int ret;
v = readl(SYS_COUNTER_CNTRL);
if (!(v & RTC_CNTR_OK)) {
dev_err(&pdev->dev, "rtc counters not working\n");
ret = -ENODEV;
goto err;
return -ENODEV;
}
ret = -ETIMEDOUT;
/* set to 1 HZ if needed */
if (readl(SYS_TOYTRIM) != 32767) {
v = 0x100000;
@ -164,7 +163,7 @@ static int ls1x_rtc_probe(struct platform_device *pdev)
if (!v) {
dev_err(&pdev->dev, "time out\n");
goto err;
return -ETIMEDOUT;
}
writel(32767, SYS_TOYTRIM);
}
@ -172,17 +171,16 @@ static int ls1x_rtc_probe(struct platform_device *pdev)
while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS)
usleep_range(1000, 3000);
rtcdev = devm_rtc_device_register(&pdev->dev, "ls1x-rtc",
&ls1x_rtc_ops , THIS_MODULE);
if (IS_ERR(rtcdev)) {
ret = PTR_ERR(rtcdev);
goto err;
}
rtcdev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtcdev))
return PTR_ERR(rtcdev);
platform_set_drvdata(pdev, rtcdev);
return 0;
err:
return ret;
rtcdev->ops = &ls1x_rtc_ops;
rtcdev->range_min = RTC_TIMESTAMP_BEGIN_1900;
rtcdev->range_max = RTC_TIMESTAMP_END_2099;
return rtc_register_device(rtcdev);
}
static struct platform_driver ls1x_rtc_driver = {

View File

@ -47,8 +47,7 @@ struct m48t59_private {
static void
m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val)
{
struct platform_device *pdev = to_platform_device(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct m48t59_private *m48t59 = dev_get_drvdata(dev);
writeb(val, m48t59->ioaddr+ofs);
}
@ -56,8 +55,7 @@ m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val)
static u8
m48t59_mem_readb(struct device *dev, u32 ofs)
{
struct platform_device *pdev = to_platform_device(dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct m48t59_private *m48t59 = dev_get_drvdata(dev);
return readb(m48t59->ioaddr+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)
{
struct platform_device *pdev = to_platform_device(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_private *m48t59 = dev_get_drvdata(dev);
unsigned long flags;
u8 val;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_private *m48t59 = dev_get_drvdata(dev);
unsigned long flags;
u8 val = 0;
int year = tm->tm_year;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct rtc_time *tm = &alrm->time;
unsigned long flags;
u8 val;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_private *m48t59 = dev_get_drvdata(dev);
struct rtc_time *tm = &alrm->time;
u8 mday, hour, min, sec;
unsigned long flags;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_private *m48t59 = dev_get_drvdata(dev);
unsigned long flags;
spin_lock_irqsave(&m48t59->lock, flags);
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_private *m48t59 = dev_get_drvdata(dev);
unsigned long flags;
u8 val;
@ -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)
{
struct device *dev = (struct device *)dev_id;
struct platform_device *pdev = to_platform_device(dev);
struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
struct m48t59_plat_data *pdata = dev_get_platdata(dev);
struct m48t59_private *m48t59 = dev_get_drvdata(dev);
u8 event;
spin_lock(&m48t59->lock);

View File

@ -45,7 +45,6 @@ struct mrst_rtc {
struct rtc_device *rtc;
struct device *dev;
int irq;
struct resource *iomem;
u8 enabled_wake;
u8 suspend_ctrl;
@ -329,24 +328,22 @@ static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem,
if (!iomem)
return -ENODEV;
iomem = request_mem_region(iomem->start, resource_size(iomem),
driver_name);
iomem = devm_request_mem_region(dev, iomem->start, resource_size(iomem),
driver_name);
if (!iomem) {
dev_dbg(dev, "i/o mem already in use.\n");
return -EBUSY;
}
mrst_rtc.irq = rtc_irq;
mrst_rtc.iomem = iomem;
mrst_rtc.dev = dev;
dev_set_drvdata(dev, &mrst_rtc);
mrst_rtc.rtc = rtc_device_register(driver_name, dev,
&mrst_rtc_ops, THIS_MODULE);
if (IS_ERR(mrst_rtc.rtc)) {
retval = PTR_ERR(mrst_rtc.rtc);
goto cleanup0;
}
mrst_rtc.rtc = devm_rtc_allocate_device(dev);
if (IS_ERR(mrst_rtc.rtc))
return PTR_ERR(mrst_rtc.rtc);
mrst_rtc.rtc->ops = &mrst_rtc_ops;
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,
dev_dbg(dev, "TODO: support more than 24-hr BCD mode\n");
if (rtc_irq) {
retval = request_irq(rtc_irq, mrst_rtc_irq,
0, dev_name(&mrst_rtc.rtc->dev),
mrst_rtc.rtc);
retval = devm_request_irq(dev, rtc_irq, mrst_rtc_irq,
0, dev_name(&mrst_rtc.rtc->dev),
mrst_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use, err %d\n",
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");
return 0;
cleanup1:
rtc_device_unregister(mrst_rtc.rtc);
cleanup0:
mrst_rtc.dev = NULL;
release_mem_region(iomem->start, resource_size(iomem));
dev_err(dev, "rtc-mrst: unable to initialise\n");
return retval;
}
@ -390,20 +391,10 @@ static void rtc_mrst_do_shutdown(void)
static void rtc_mrst_do_remove(struct device *dev)
{
struct mrst_rtc *mrst = dev_get_drvdata(dev);
struct resource *iomem;
rtc_mrst_do_shutdown();
if (mrst->irq)
free_irq(mrst->irq, mrst->rtc);
rtc_device_unregister(mrst->rtc);
mrst->rtc = NULL;
iomem = mrst->iomem;
release_mem_region(iomem->start, resource_size(iomem));
mrst->iomem = NULL;
mrst->dev = NULL;
}

View File

@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
if (pdata->irq < 0)

View File

@ -1,13 +1,6 @@
/*
* 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
*/
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
#include <linux/io.h>
#include <linux/rtc.h>
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
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)
static void set_alarm_or_time(struct device *dev, int time_alarm, time64_t time)
{
u32 tod, day, hr, min, sec, temp;
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
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)
static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
{
time64_t time;
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
time = rtc_tm_to_time64(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,
unsigned int enabled)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
u32 reg;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
/*
* 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)
*/
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 = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
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)
*/
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 = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
rtc_update_alarm(dev, &alrm->time);

View File

@ -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);
int ret;
if (time > U32_MAX) {
dev_err(dev, "RTC exceeded by %llus\n", time - U32_MAX);
return -EINVAL;
}
ret = mxc_rtc_lock(pdata);
if (ret)
return ret;
@ -198,7 +193,7 @@ static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (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);
return mxc_rtc_unlock(pdata);
}
@ -248,11 +243,6 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (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);
/* clear alarm interrupt status bit */
@ -343,6 +333,13 @@ static int mxc_rtc_probe(struct platform_device *pdev)
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);
platform_set_drvdata(pdev, pdata);
ret =
@ -354,15 +351,11 @@ static int mxc_rtc_probe(struct platform_device *pdev)
return ret;
}
pdata->rtc =
devm_rtc_device_register(&pdev->dev, pdev->name, &mxc_rtc_ops,
THIS_MODULE);
if (IS_ERR(pdata->rtc)) {
ret = rtc_register_device(pdata->rtc);
if (ret < 0)
clk_unprepare(pdata->clk);
return PTR_ERR(pdata->rtc);
}
return 0;
return ret;
}
static int mxc_rtc_remove(struct platform_device *pdev)

View File

@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
struct rtc_time *tm = &alrm->time;
unsigned long secs;
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)
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 = platform_get_drvdata(pdev);
struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
struct rtc_time *tm = &alrm->time;
unsigned long secs;
u32 tod, days;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
unsigned long secs;
u32 tod, days;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
u32 tod, days;
tod = secs % SEC_PER_DAY;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
if (en)
enable_irq(pcap_to_irq(pcap_rtc->pcap, pirq));

View File

@ -363,7 +363,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
sa1100_rtc->rtar = pxa_rtc->base + 0x4;
sa1100_rtc->rttr = pxa_rtc->base + 0xc;
ret = sa1100_rtc_init(pdev, sa1100_rtc);
if (!ret) {
if (ret) {
dev_err(dev, "Unable to init SA1100 RTC sub-device\n");
return ret;
}

View File

@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
#include <linux/log2.h>
@ -51,52 +52,20 @@
#define RX8581_CTRL_RESET 0x01 /* RESET bit */
struct rx8581 {
struct i2c_client *client;
struct regmap *regmap;
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
* 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];
int data, err;
unsigned int data;
int err;
struct rx8581 *rx8581 = i2c_get_clientdata(client);
/* 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)
* has been set, we know that the time has changed during the read so
* we repeat the whole process again.
*/
data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG);
if (data < 0) {
dev_err(&client->dev, "Unable to read device flags\n");
return -EIO;
err = regmap_read(rx8581->regmap, RX8581_REG_FLAG, &data);
if (err < 0)
return err;
if (data & RX8581_FLAG_VLF) {
dev_warn(dev,
"low voltage detected, date/time is not reliable.\n");
return -EINVAL;
}
do {
/* If update flag set, clear it */
if (data & RX8581_FLAG_UF) {
err = i2c_smbus_write_byte_data(client,
RX8581_REG_FLAG, (data & ~RX8581_FLAG_UF));
if (err != 0) {
dev_err(&client->dev, "Unable to write device flags\n");
return -EIO;
}
err = regmap_write(rx8581->regmap, RX8581_REG_FLAG,
data & ~RX8581_FLAG_UF);
if (err < 0)
return err;
}
/* Now read time and date */
err = rx8581->read_block_data(client, RX8581_REG_SC,
7, date);
if (err < 0) {
dev_err(&client->dev, "Unable to read date\n");
return -EIO;
}
err = regmap_bulk_read(rx8581->regmap, RX8581_REG_SC, date,
sizeof(date));
if (err < 0)
return err;
/* Check flag register */
data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG);
if (data < 0) {
dev_err(&client->dev, "Unable to read device flags\n");
return -EIO;
}
err = regmap_read(rx8581->regmap, RX8581_REG_FLAG, &data);
if (err < 0)
return err;
} while (data & RX8581_FLAG_UF);
if (data & RX8581_FLAG_VLF)
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, "
dev_dbg(dev, "%s: raw data is sec=%02x, min=%02x, hr=%02x, "
"wday=%02x, mday=%02x, mon=%02x, year=%02x\n",
__func__,
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)
tm->tm_wday = ilog2(date[RX8581_REG_DW] & 0x7F);
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_year = bcd2bin(date[RX8581_REG_YR]);
if (tm->tm_year < 70)
tm->tm_year += 100; /* assume we are in 1970...2069 */
tm->tm_year = bcd2bin(date[RX8581_REG_YR]) + 100;
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",
__func__,
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)
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];
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",
__func__,
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)
buf[RX8581_REG_MO] = bin2bcd(tm->tm_mon + 1);
/* 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);
/* Stop the clock */
data = i2c_smbus_read_byte_data(client, RX8581_REG_CTRL);
if (data < 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;
}
err = regmap_update_bits(rx8581->regmap, RX8581_REG_CTRL,
RX8581_CTRL_STOP, RX8581_CTRL_STOP);
if (err < 0)
return err;
/* write register's data */
err = rx8581->write_block_data(client, RX8581_REG_SC, 7, buf);
if (err < 0) {
dev_err(&client->dev, "Unable to write to date registers\n");
return -EIO;
}
err = regmap_bulk_write(rx8581->regmap, RX8581_REG_SC,
buf, sizeof(buf));
if (err < 0)
return err;
/* get VLF and clear it */
data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG);
if (data < 0) {
dev_err(&client->dev, "Unable to read flag register\n");
return -EIO;
}
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;
}
err = regmap_update_bits(rx8581->regmap, RX8581_REG_FLAG,
RX8581_FLAG_VLF, 0);
if (err < 0)
return err;
/* Restart the clock */
data = i2c_smbus_read_byte_data(client, RX8581_REG_CTRL);
if (data < 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);
return regmap_update_bits(rx8581->regmap, RX8581_REG_CTRL,
RX8581_CTRL_STOP, 0);
}
static const struct rtc_class_ops rx8581_rtc_ops = {
@ -264,38 +185,35 @@ static int rx8581_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
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__);
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);
if (!rx8581)
return -ENOMEM;
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->regmap = devm_regmap_init_i2c(client, &config);
if (IS_ERR(rx8581->regmap))
return PTR_ERR(rx8581->regmap);
rx8581->rtc = devm_rtc_device_register(&client->dev,
rx8581_driver.driver.name, &rx8581_rtc_ops, THIS_MODULE);
if (IS_ERR(rx8581->rtc)) {
dev_err(&client->dev,
"unable to register the class device\n");
rx8581->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_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[] = {

View File

@ -35,6 +35,8 @@
#define SPRD_RTC_DAY_ALM_VALUE 0x4c
#define SPRD_RTC_SPG_VALUE 0x50
#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_MIN_AUXALM_UPD 0x64
#define SPRD_RTC_HOUR_AUXALM_UPD 0x68
@ -86,7 +88,13 @@
/* SPG values definition for SPRD_RTC_SPG_UPD register */
#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) */
#define SPRD_RTC_POLL_TIMEOUT 200000
@ -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);
time64_t secs = rtc_tm_to_time64(tm);
u32 val;
int ret;
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)
return ret;
if (!rtc->valid) {
/*
* Set SPRD_RTC_POWER_RESET_FLAG to indicate now RTC has valid
* time values.
*/
ret = regmap_update_bits(rtc->regmap,
rtc->base + SPRD_RTC_SPG_UPD,
SPRD_RTC_POWER_RESET_FLAG,
SPRD_RTC_POWER_RESET_FLAG);
/* Clear RTC power status firstly */
ret = regmap_write(rtc->regmap, rtc->base + SPRD_RTC_PWR_CTRL,
SPRD_RTC_POWER_STS_CLEAR);
if (ret)
return ret;
ret = regmap_read_poll_timeout(rtc->regmap,
rtc->base + SPRD_RTC_INT_RAW_STS,
val, (val & SPRD_RTC_SPG_UPD_EN),
SPRD_RTC_POLL_DELAY_US,
SPRD_RTC_POLL_TIMEOUT);
if (ret) {
dev_err(rtc->dev, "failed to update SPG value:%d\n",
ret);
/*
* Set RTC power status to indicate now RTC has valid time
* values.
*/
ret = regmap_write(rtc->regmap, rtc->base + SPRD_RTC_PWR_CTRL,
SPRD_RTC_POWER_STS_VALID);
if (ret)
return ret;
}
rtc->valid = true;
}
@ -562,15 +562,16 @@ static int sprd_rtc_check_power_down(struct sprd_rtc *rtc)
u32 val;
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)
return ret;
/*
* If the SPRD_RTC_POWER_RESET_FLAG was not set, which means the RTC has
* been powered down, so the RTC time values are invalid.
* If the RTC power status value is SPRD_RTC_POWER_RESET_VALUE, which
* 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;
}
@ -600,6 +601,10 @@ static int sprd_rtc_probe(struct platform_device *pdev)
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;
platform_set_drvdata(pdev, rtc);
@ -626,10 +631,14 @@ static int sprd_rtc_probe(struct platform_device *pdev)
return ret;
}
rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&sprd_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc))
return PTR_ERR(rtc->rtc);
rtc->rtc->ops = &sprd_rtc_ops;
rtc->rtc->range_min = 0;
rtc->rtc->range_max = 5662310399LL;
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);
return 0;

View File

@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
struct sh_rtc *rtc = dev_get_drvdata(dev);
unsigned int sec128, sec2, yr, yr100, cf_bit;
do {
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
struct sh_rtc *rtc = dev_get_drvdata(dev);
unsigned int tmp;
int year;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
struct sh_rtc *rtc = dev_get_drvdata(dev);
struct rtc_time *tm = &wkalrm->time;
spin_lock_irq(&rtc->lock);
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
struct sh_rtc *rtc = dev_get_drvdata(dev);
unsigned int rcr1;
struct rtc_time *tm = &wkalrm->time;
int mon;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
struct sh_rtc *rtc = dev_get_drvdata(dev);
irq_set_irq_wake(rtc->periodic_irq, enabled);

View File

@ -1,13 +1,6 @@
/*
* 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
*/
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
#include <linux/init.h>
#include <linux/io.h>

View File

@ -212,6 +212,10 @@ static int st_rtc_probe(struct platform_device *pdev)
if (!rtc)
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);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@ -253,26 +257,19 @@ static int st_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc);
rtc->rtc_dev = rtc_device_register("st-lpc-rtc", &pdev->dev,
&st_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
rtc->rtc_dev->ops = &st_rtc_ops;
rtc->rtc_dev->range_max = U64_MAX;
do_div(rtc->rtc_dev->range_max, rtc->clkrate);
ret = rtc_register_device(rtc->rtc_dev);
if (ret) {
clk_disable_unprepare(rtc->clk);
return PTR_ERR(rtc->rtc_dev);
return ret;
}
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
static int st_rtc_suspend(struct device *dev)
{
@ -325,7 +322,6 @@ static struct platform_driver st_rtc_platform_driver = {
.of_match_table = st_rtc_match,
},
.probe = st_rtc_probe,
.remove = st_rtc_remove,
};
module_platform_driver(st_rtc_platform_driver);

View File

@ -74,8 +74,7 @@ struct rtc_plat_data {
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 = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
u8 flags;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
unsigned int year, month, day, hour, minute, second, week;
unsigned int century;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
if (pdata->irq <= 0)
return -EINVAL;
@ -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)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
if (pdata->irq <= 0)
return -EINVAL;
@ -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,
unsigned int enabled)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
if (pdata->irq <= 0)
return -EINVAL;

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2017
* Author: Amelie Delaunay <amelie.delaunay@st.com> for STMicroelectronics.
* License terms: GNU General Public License (GPL), version 2
* Copyright (C) STMicroelectronics 2017
* Author: Amelie Delaunay <amelie.delaunay@st.com>
*/
#include <linux/bcd.h>
@ -11,20 +11,12 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/pm_wakeirq.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
#define DRIVER_NAME "stm32_rtc"
/* STM32 RTC registers */
#define STM32_RTC_TR 0x00
#define STM32_RTC_DR 0x04
#define STM32_RTC_CR 0x08
#define STM32_RTC_ISR 0x0C
#define STM32_RTC_PRER 0x10
#define STM32_RTC_ALRMAR 0x1C
#define STM32_RTC_WPR 0x24
/* STM32_RTC_TR bit fields */
#define STM32_RTC_TR_SEC_SHIFT 0
#define STM32_RTC_TR_SEC GENMASK(6, 0)
@ -48,7 +40,7 @@
#define STM32_RTC_CR_ALRAE BIT(8)
#define STM32_RTC_CR_ALRAIE BIT(12)
/* STM32_RTC_ISR bit fields */
/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
#define STM32_RTC_ISR_ALRAWF BIT(0)
#define STM32_RTC_ISR_INITS BIT(4)
#define STM32_RTC_ISR_RSF BIT(5)
@ -80,52 +72,87 @@
#define STM32_RTC_ALRMXR_WDAY GENMASK(27, 24)
#define STM32_RTC_ALRMXR_DATE_MASK BIT(31)
/* STM32_RTC_SR/_SCR bit fields */
#define STM32_RTC_SR_ALRA BIT(0)
/* STM32_RTC_VERR bit fields */
#define STM32_RTC_VERR_MINREV_SHIFT 0
#define STM32_RTC_VERR_MINREV GENMASK(3, 0)
#define STM32_RTC_VERR_MAJREV_SHIFT 4
#define STM32_RTC_VERR_MAJREV GENMASK(7, 4)
/* STM32_RTC_WPR key constants */
#define RTC_WPR_1ST_KEY 0xCA
#define RTC_WPR_2ND_KEY 0x53
#define RTC_WPR_WRONG_KEY 0xFF
/*
* RTC registers are protected against parasitic write access.
* PWR_CR_DBP bit must be set to enable write access to RTC registers.
*/
/* STM32_PWR_CR */
#define PWR_CR 0x00
/* STM32_PWR_CR bit field */
#define PWR_CR_DBP BIT(8)
/* Max STM32 RTC register offset is 0x3FC */
#define UNDEF_REG 0xFFFF
struct stm32_rtc;
struct stm32_rtc_registers {
u16 tr;
u16 dr;
u16 cr;
u16 isr;
u16 prer;
u16 alrmar;
u16 wpr;
u16 sr;
u16 scr;
u16 verr;
};
struct stm32_rtc_events {
u32 alra;
};
struct stm32_rtc_data {
const struct stm32_rtc_registers regs;
const struct stm32_rtc_events events;
void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
bool has_pclk;
bool need_dbp;
bool has_wakeirq;
};
struct stm32_rtc {
struct rtc_device *rtc_dev;
void __iomem *base;
struct regmap *dbp;
struct stm32_rtc_data *data;
unsigned int dbp_reg;
unsigned int dbp_mask;
struct clk *pclk;
struct clk *rtc_ck;
const struct stm32_rtc_data *data;
int irq_alarm;
int wakeirq_alarm;
};
static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
{
writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR);
writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + regs->wpr);
writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + regs->wpr);
}
static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
{
writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
}
static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
{
unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int isr = readl_relaxed(rtc->base + regs->isr);
if (!(isr & STM32_RTC_ISR_INITF)) {
isr |= STM32_RTC_ISR_INIT;
writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
writel_relaxed(isr, rtc->base + regs->isr);
/*
* It takes around 2 rtc_ck clock cycles to enter in
@ -134,7 +161,7 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
* 1MHz, we poll every 10 us with a timeout of 100ms.
*/
return readl_relaxed_poll_timeout_atomic(
rtc->base + STM32_RTC_ISR,
rtc->base + regs->isr,
isr, (isr & STM32_RTC_ISR_INITF),
10, 100000);
}
@ -144,40 +171,50 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
{
unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int isr = readl_relaxed(rtc->base + regs->isr);
isr &= ~STM32_RTC_ISR_INIT;
writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
writel_relaxed(isr, rtc->base + regs->isr);
}
static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
{
unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int isr = readl_relaxed(rtc->base + regs->isr);
isr &= ~STM32_RTC_ISR_RSF;
writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
writel_relaxed(isr, rtc->base + regs->isr);
/*
* Wait for RSF to be set to ensure the calendar registers are
* synchronised, it takes around 2 rtc_ck clock cycles
*/
return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
return readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
isr,
(isr & STM32_RTC_ISR_RSF),
10, 100000);
}
static void stm32_rtc_clear_event_flags(struct stm32_rtc *rtc,
unsigned int flags)
{
rtc->data->clear_events(rtc, flags);
}
static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
{
struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
unsigned int isr, cr;
const struct stm32_rtc_registers *regs = &rtc->data->regs;
const struct stm32_rtc_events *evts = &rtc->data->events;
unsigned int status, cr;
mutex_lock(&rtc->rtc_dev->ops_lock);
isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
cr = readl_relaxed(rtc->base + STM32_RTC_CR);
status = readl_relaxed(rtc->base + regs->sr);
cr = readl_relaxed(rtc->base + regs->cr);
if ((isr & STM32_RTC_ISR_ALRAF) &&
if ((status & evts->alra) &&
(cr & STM32_RTC_CR_ALRAIE)) {
/* Alarm A flag - Alarm interrupt */
dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n");
@ -185,9 +222,8 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
/* Pass event to the kernel */
rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
/* Clear event flag, otherwise new events won't be received */
writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF,
rtc->base + STM32_RTC_ISR);
/* Clear event flags, otherwise new events won't be received */
stm32_rtc_clear_event_flags(rtc, evts->alra);
}
mutex_unlock(&rtc->rtc_dev->ops_lock);
@ -234,11 +270,12 @@ static void bcd2tm(struct rtc_time *tm)
static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int tr, dr;
/* Time and Date in BCD format */
tr = readl_relaxed(rtc->base + STM32_RTC_TR);
dr = readl_relaxed(rtc->base + STM32_RTC_DR);
tr = readl_relaxed(rtc->base + regs->tr);
dr = readl_relaxed(rtc->base + regs->dr);
tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
@ -259,6 +296,7 @@ static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int tr, dr;
int ret = 0;
@ -283,8 +321,8 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
goto end;
}
writel_relaxed(tr, rtc->base + STM32_RTC_TR);
writel_relaxed(dr, rtc->base + STM32_RTC_DR);
writel_relaxed(tr, rtc->base + regs->tr);
writel_relaxed(dr, rtc->base + regs->dr);
stm32_rtc_exit_init_mode(rtc);
@ -298,12 +336,14 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
const struct stm32_rtc_events *evts = &rtc->data->events;
struct rtc_time *tm = &alrm->time;
unsigned int alrmar, cr, isr;
unsigned int alrmar, cr, status;
alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR);
cr = readl_relaxed(rtc->base + STM32_RTC_CR);
isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
alrmar = readl_relaxed(rtc->base + regs->alrmar);
cr = readl_relaxed(rtc->base + regs->cr);
status = readl_relaxed(rtc->base + regs->sr);
if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
/*
@ -356,7 +396,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
bcd2tm(tm);
alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
alrm->pending = (status & evts->alra) ? 1 : 0;
return 0;
}
@ -364,9 +404,11 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
unsigned int isr, cr;
const struct stm32_rtc_registers *regs = &rtc->data->regs;
const struct stm32_rtc_events *evts = &rtc->data->events;
unsigned int cr;
cr = readl_relaxed(rtc->base + STM32_RTC_CR);
cr = readl_relaxed(rtc->base + regs->cr);
stm32_rtc_wpr_unlock(rtc);
@ -375,12 +417,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
else
cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
writel_relaxed(cr, rtc->base + STM32_RTC_CR);
writel_relaxed(cr, rtc->base + regs->cr);
/* Clear event flag, otherwise new events won't be received */
isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
isr &= ~STM32_RTC_ISR_ALRAF;
writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
/* Clear event flags, otherwise new events won't be received */
stm32_rtc_clear_event_flags(rtc, evts->alra);
stm32_rtc_wpr_lock(rtc);
@ -389,9 +429,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
{
const struct stm32_rtc_registers *regs = &rtc->data->regs;
int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
unsigned int dr = readl_relaxed(rtc->base + regs->dr);
unsigned int tr = readl_relaxed(rtc->base + regs->tr);
cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
@ -425,6 +466,7 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct stm32_rtc *rtc = dev_get_drvdata(dev);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
struct rtc_time *tm = &alrm->time;
unsigned int cr, isr, alrmar;
int ret = 0;
@ -456,15 +498,15 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
stm32_rtc_wpr_unlock(rtc);
/* Disable Alarm */
cr = readl_relaxed(rtc->base + STM32_RTC_CR);
cr = readl_relaxed(rtc->base + regs->cr);
cr &= ~STM32_RTC_CR_ALRAE;
writel_relaxed(cr, rtc->base + STM32_RTC_CR);
writel_relaxed(cr, rtc->base + regs->cr);
/*
* Poll Alarm write flag to be sure that Alarm update is allowed: it
* takes around 2 rtc_ck clock cycles
*/
ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
ret = readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
isr,
(isr & STM32_RTC_ISR_ALRAWF),
10, 100000);
@ -475,7 +517,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
}
/* Write to Alarm register */
writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR);
writel_relaxed(alrmar, rtc->base + regs->alrmar);
if (alrm->enabled)
stm32_rtc_alarm_irq_enable(dev, 1);
@ -496,17 +538,95 @@ static const struct rtc_class_ops stm32_rtc_ops = {
.alarm_irq_enable = stm32_rtc_alarm_irq_enable,
};
static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
unsigned int flags)
{
const struct stm32_rtc_registers *regs = &rtc->data->regs;
/* Flags are cleared by writing 0 in RTC_ISR */
writel_relaxed(readl_relaxed(rtc->base + regs->isr) & ~flags,
rtc->base + regs->isr);
}
static const struct stm32_rtc_data stm32_rtc_data = {
.has_pclk = false,
.need_dbp = true,
.has_wakeirq = false,
.regs = {
.tr = 0x00,
.dr = 0x04,
.cr = 0x08,
.isr = 0x0C,
.prer = 0x10,
.alrmar = 0x1C,
.wpr = 0x24,
.sr = 0x0C, /* set to ISR offset to ease alarm management */
.scr = UNDEF_REG,
.verr = UNDEF_REG,
},
.events = {
.alra = STM32_RTC_ISR_ALRAF,
},
.clear_events = stm32_rtc_clear_events,
};
static const struct stm32_rtc_data stm32h7_rtc_data = {
.has_pclk = true,
.need_dbp = true,
.has_wakeirq = false,
.regs = {
.tr = 0x00,
.dr = 0x04,
.cr = 0x08,
.isr = 0x0C,
.prer = 0x10,
.alrmar = 0x1C,
.wpr = 0x24,
.sr = 0x0C, /* set to ISR offset to ease alarm management */
.scr = UNDEF_REG,
.verr = UNDEF_REG,
},
.events = {
.alra = STM32_RTC_ISR_ALRAF,
},
.clear_events = stm32_rtc_clear_events,
};
static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
unsigned int flags)
{
struct stm32_rtc_registers regs = rtc->data->regs;
/* Flags are cleared by writing 1 in RTC_SCR */
writel_relaxed(flags, rtc->base + regs.scr);
}
static const struct stm32_rtc_data stm32mp1_data = {
.has_pclk = true,
.need_dbp = false,
.has_wakeirq = true,
.regs = {
.tr = 0x00,
.dr = 0x04,
.cr = 0x18,
.isr = 0x0C, /* named RTC_ICSR on stm32mp1 */
.prer = 0x10,
.alrmar = 0x40,
.wpr = 0x24,
.sr = 0x50,
.scr = 0x5C,
.verr = 0x3F4,
},
.events = {
.alra = STM32_RTC_SR_ALRA,
},
.clear_events = stm32mp1_rtc_clear_events,
};
static const struct of_device_id stm32_rtc_of_match[] = {
{ .compatible = "st,stm32-rtc", .data = &stm32_rtc_data },
{ .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data },
{ .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data },
{}
};
MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
@ -514,6 +634,7 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
static int stm32_rtc_init(struct platform_device *pdev,
struct stm32_rtc *rtc)
{
const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
unsigned int rate;
int ret = 0;
@ -554,14 +675,14 @@ static int stm32_rtc_init(struct platform_device *pdev,
}
prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
writel_relaxed(prer, rtc->base + regs->prer);
prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
writel_relaxed(prer, rtc->base + regs->prer);
/* Force 24h time format */
cr = readl_relaxed(rtc->base + STM32_RTC_CR);
cr = readl_relaxed(rtc->base + regs->cr);
cr &= ~STM32_RTC_CR_FMT;
writel_relaxed(cr, rtc->base + STM32_RTC_CR);
writel_relaxed(cr, rtc->base + regs->cr);
stm32_rtc_exit_init_mode(rtc);
@ -575,8 +696,8 @@ static int stm32_rtc_init(struct platform_device *pdev,
static int stm32_rtc_probe(struct platform_device *pdev)
{
struct stm32_rtc *rtc;
const struct stm32_rtc_registers *regs;
struct resource *res;
const struct of_device_id *match;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
@ -588,15 +709,32 @@ static int stm32_rtc_probe(struct platform_device *pdev)
if (IS_ERR(rtc->base))
return PTR_ERR(rtc->base);
rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
"st,syscfg");
if (IS_ERR(rtc->dbp)) {
dev_err(&pdev->dev, "no st,syscfg\n");
return PTR_ERR(rtc->dbp);
}
rtc->data = (struct stm32_rtc_data *)
of_device_get_match_data(&pdev->dev);
regs = &rtc->data->regs;
match = of_match_device(stm32_rtc_of_match, &pdev->dev);
rtc->data = (struct stm32_rtc_data *)match->data;
if (rtc->data->need_dbp) {
rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
"st,syscfg");
if (IS_ERR(rtc->dbp)) {
dev_err(&pdev->dev, "no st,syscfg\n");
return PTR_ERR(rtc->dbp);
}
ret = of_property_read_u32_index(pdev->dev.of_node, "st,syscfg",
1, &rtc->dbp_reg);
if (ret) {
dev_err(&pdev->dev, "can't read DBP register offset\n");
return ret;
}
ret = of_property_read_u32_index(pdev->dev.of_node, "st,syscfg",
2, &rtc->dbp_mask);
if (ret) {
dev_err(&pdev->dev, "can't read DBP register mask\n");
return ret;
}
}
if (!rtc->data->has_pclk) {
rtc->pclk = NULL;
@ -624,11 +762,13 @@ static int stm32_rtc_probe(struct platform_device *pdev)
if (ret)
goto err;
regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, PWR_CR_DBP);
if (rtc->data->need_dbp)
regmap_update_bits(rtc->dbp, rtc->dbp_reg,
rtc->dbp_mask, rtc->dbp_mask);
/*
* After a system reset, RTC_ISR.INITS flag can be read to check if
* the calendar has been initalized or not. INITS flag is reset by a
* the calendar has been initialized or not. INITS flag is reset by a
* power-on reset (no vbat, no power-supply). It is not reset if
* rtc_ck parent clock has changed (so RTC prescalers need to be
* changed). That's why we cannot rely on this flag to know if RTC
@ -645,15 +785,22 @@ static int stm32_rtc_probe(struct platform_device *pdev)
goto err;
}
ret = device_init_wakeup(&pdev->dev, true);
if (rtc->data->has_wakeirq) {
rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
if (rtc->wakeirq_alarm <= 0)
ret = rtc->wakeirq_alarm;
else
ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
rtc->wakeirq_alarm);
}
if (ret)
dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
platform_set_drvdata(pdev, rtc);
ret = device_init_wakeup(&pdev->dev, true);
if (ret)
dev_warn(&pdev->dev,
"alarm won't be able to wake up the system");
rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
&stm32_rtc_ops, THIS_MODULE);
&stm32_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
ret = PTR_ERR(rtc->rtc_dev);
dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
@ -663,8 +810,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
/* Handle RTC alarm interrupts */
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq_alarm, NULL,
stm32_rtc_alarm_irq,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
stm32_rtc_alarm_irq, IRQF_ONESHOT,
pdev->name, rtc);
if (ret) {
dev_err(&pdev->dev, "IRQ%d (alarm interrupt) already claimed\n",
@ -676,17 +822,27 @@ static int stm32_rtc_probe(struct platform_device *pdev)
* If INITS flag is reset (calendar year field set to 0x00), calendar
* must be initialized
*/
if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS))
if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
dev_warn(&pdev->dev, "Date/Time must be initialized\n");
if (regs->verr != UNDEF_REG) {
u32 ver = readl_relaxed(rtc->base + regs->verr);
dev_info(&pdev->dev, "registered rev:%d.%d\n",
(ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
(ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
}
return 0;
err:
if (rtc->data->has_pclk)
clk_disable_unprepare(rtc->pclk);
clk_disable_unprepare(rtc->rtc_ck);
regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, 0);
if (rtc->data->need_dbp)
regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
return ret;
@ -695,22 +851,25 @@ static int stm32_rtc_probe(struct platform_device *pdev)
static int stm32_rtc_remove(struct platform_device *pdev)
{
struct stm32_rtc *rtc = platform_get_drvdata(pdev);
const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int cr;
/* Disable interrupts */
stm32_rtc_wpr_unlock(rtc);
cr = readl_relaxed(rtc->base + STM32_RTC_CR);
cr = readl_relaxed(rtc->base + regs->cr);
cr &= ~STM32_RTC_CR_ALRAIE;
writel_relaxed(cr, rtc->base + STM32_RTC_CR);
writel_relaxed(cr, rtc->base + regs->cr);
stm32_rtc_wpr_lock(rtc);
clk_disable_unprepare(rtc->rtc_ck);
if (rtc->data->has_pclk)
clk_disable_unprepare(rtc->pclk);
/* Enable backup domain write protection */
regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, 0);
/* Enable backup domain write protection if needed */
if (rtc->data->need_dbp)
regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
return 0;

View File

@ -74,7 +74,7 @@
#define SUN6I_ALARM_CONFIG_WAKEUP BIT(0)
#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
@ -255,7 +255,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
&clkout_name);
rtc->ext_losc = clk_register_gate(NULL, clkout_name, rtc->hw.init->name,
0, rtc->base + SUN6I_LOSC_OUT_GATING,
SUN6I_LOSC_OUT_GATING_EN, 0,
SUN6I_LOSC_OUT_GATING_EN_OFFSET, 0,
&rtc->lock);
if (IS_ERR(rtc->ext_losc)) {
pr_crit("Couldn't register the LOSC external gate\n");

View File

@ -445,6 +445,10 @@ static int sunxi_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, chip);
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);
chip->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(chip->base))
@ -481,11 +485,12 @@ static int sunxi_rtc_probe(struct platform_device *pdev)
writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, chip->base +
SUNXI_ALRM_IRQ_STA);
chip->rtc = rtc_device_register("rtc-sunxi", &pdev->dev,
&sunxi_rtc_ops, THIS_MODULE);
if (IS_ERR(chip->rtc)) {
chip->rtc->ops = &sunxi_rtc_ops;
ret = rtc_register_device(chip->rtc);
if (ret) {
dev_err(&pdev->dev, "unable to register device\n");
return PTR_ERR(chip->rtc);
return ret;
}
dev_info(&pdev->dev, "RTC enabled\n");
@ -493,18 +498,8 @@ static int sunxi_rtc_probe(struct platform_device *pdev)
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 = {
.probe = sunxi_rtc_probe,
.remove = sunxi_rtc_remove,
.driver = {
.name = "sunxi-rtc",
.of_match_table = sunxi_rtc_dt_ids,

View File

@ -13,135 +13,139 @@
#include <linux/rtc.h>
#include <linux/platform_device.h>
static int test_mmss64;
module_param(test_mmss64, int, 0644);
MODULE_PARM_DESC(test_mmss64, "Test struct rtc_class_ops.set_mmss64().");
#define MAX_RTC_TEST 3
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 rtc_wkalrm *alrm)
struct platform_device *pdev[MAX_RTC_TEST];
static int test_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
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;
return 0;
}
static int test_rtc_set_alarm(struct device *dev,
struct rtc_wkalrm *alrm)
static int test_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
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;
}
static int test_rtc_read_time(struct device *dev,
struct rtc_time *tm)
static int test_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
rtc_time64_to_tm(ktime_get_real_seconds(), tm);
struct rtc_test_data *rtd = dev_get_drvdata(dev);
rtc_time64_to_tm(ktime_get_real_seconds() + rtd->offset, tm);
return 0;
}
static int test_rtc_set_mmss64(struct device *dev, time64_t secs)
{
dev_info(dev, "%s, secs = %lld\n", __func__, (long long)secs);
return 0;
}
struct rtc_test_data *rtd = dev_get_drvdata(dev);
static int test_rtc_set_mmss(struct device *dev, unsigned long secs)
{
dev_info(dev, "%s, secs = %lu\n", __func__, secs);
return 0;
}
static int test_rtc_proc(struct device *dev, struct seq_file *seq)
{
struct platform_device *plat_dev = to_platform_device(dev);
seq_printf(seq, "test\t\t: yes\n");
seq_printf(seq, "id\t\t: %d\n", plat_dev->id);
rtd->offset = secs - ktime_get_real_seconds();
return 0;
}
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;
}
static struct rtc_class_ops test_rtc_ops = {
.proc = test_rtc_proc,
static const struct rtc_class_ops test_rtc_ops_noalm = {
.read_time = test_rtc_read_time,
.read_alarm = test_rtc_read_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,
};
static ssize_t test_irq_show(struct device *dev,
struct device_attribute *attr, char *buf)
static const struct rtc_class_ops test_rtc_ops = {
.read_time = test_rtc_read_time,
.read_alarm = test_rtc_read_alarm,
.set_alarm = test_rtc_set_alarm,
.set_mmss64 = test_rtc_set_mmss64,
.alarm_irq_enable = test_rtc_alarm_irq_enable,
};
static void test_rtc_alarm_handler(struct timer_list *t)
{
return sprintf(buf, "%d\n", 42);
struct rtc_test_data *rtd = from_timer(rtd, t, alarm);
rtc_update_irq(rtd->rtc, 1, RTC_AF | RTC_IRQF);
}
static ssize_t test_irq_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int retval;
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;
}
static DEVICE_ATTR(irq, S_IRUGO | S_IWUSR, test_irq_show, test_irq_store);
static int test_probe(struct platform_device *plat_dev)
{
int err;
struct rtc_device *rtc;
struct rtc_test_data *rtd;
if (test_mmss64) {
test_rtc_ops.set_mmss64 = test_rtc_set_mmss64;
test_rtc_ops.set_mmss = NULL;
rtd = devm_kzalloc(&plat_dev->dev, sizeof(*rtd), GFP_KERNEL);
if (!rtd)
return -ENOMEM;
platform_set_drvdata(plat_dev, rtd);
rtd->rtc = devm_rtc_allocate_device(&plat_dev->dev);
if (IS_ERR(rtd->rtc))
return PTR_ERR(rtd->rtc);
switch (plat_dev->id) {
case 0:
rtd->rtc->ops = &test_rtc_ops_noalm;
break;
default:
rtd->rtc->ops = &test_rtc_ops;
}
rtc = devm_rtc_device_register(&plat_dev->dev, "test",
&test_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
return PTR_ERR(rtc);
}
timer_setup(&rtd->alarm, test_rtc_alarm_handler, 0);
rtd->alarm.expires = 0;
err = device_create_file(&plat_dev->dev, &dev_attr_irq);
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);
return 0;
}
static int test_remove(struct platform_device *plat_dev)
{
device_remove_file(&plat_dev->dev, &dev_attr_irq);
return 0;
return rtc_register_device(rtd->rtc);
}
static struct platform_driver test_driver = {
.probe = test_probe,
.remove = test_remove,
.driver = {
.name = "rtc-test",
},
@ -149,47 +153,45 @@ static struct platform_driver test_driver = {
static int __init test_init(void)
{
int err;
int i, err;
if ((err = platform_driver_register(&test_driver)))
return err;
if ((test0 = platform_device_alloc("rtc-test", 0)) == NULL) {
err = -ENOMEM;
goto exit_driver_unregister;
err = -ENOMEM;
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) {
err = -ENOMEM;
goto exit_put_test0;
for (i = 0; i < MAX_RTC_TEST; i++) {
err = platform_device_add(pdev[i]);
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;
exit_del_test0:
platform_device_del(test0);
exit_device_del:
for (; i > 0; i--)
platform_device_del(pdev[i - 1]);
exit_put_test1:
platform_device_put(test1);
exit_free_mem:
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);
return err;
}
static void __exit test_exit(void)
{
platform_device_unregister(test0);
platform_device_unregister(test1);
int i;
for (i = 0; i < MAX_RTC_TEST; i++)
platform_device_unregister(pdev[i]);
platform_driver_unregister(&test_driver);
}

View File

@ -58,7 +58,6 @@ struct tps6586x_rtc {
struct rtc_device *rtc;
int irq;
bool irq_en;
unsigned long long epoch_start;
};
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)
{
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
struct device *tps_dev = to_tps6586x_dev(dev);
unsigned long long ticks = 0;
unsigned long seconds;
time64_t seconds;
u8 buff[6];
int ret;
int i;
@ -88,26 +86,20 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm)
}
seconds = ticks >> 10;
seconds += rtc->epoch_start;
rtc_time_to_tm(seconds, tm);
rtc_time64_to_tm(seconds, tm);
return 0;
}
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);
unsigned long long ticks;
unsigned long seconds;
time64_t seconds;
u8 buff[5];
int ret;
rtc_tm_to_time(tm, &seconds);
if (seconds < rtc->epoch_start) {
dev_err(dev, "requested time unsupported\n");
return -EINVAL;
}
seconds -= rtc->epoch_start;
seconds = rtc_tm_to_time64(tm);
ticks = (unsigned long long)seconds << 10;
buff[0] = (ticks >> 32) & 0xff;
@ -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)
{
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
struct device *tps_dev = to_tps6586x_dev(dev);
unsigned long seconds;
time64_t seconds;
unsigned long ticks;
unsigned long rtc_current_time;
unsigned long long rticks = 0;
@ -166,12 +157,7 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
int ret;
int i;
rtc_tm_to_time(&alrm->time, &seconds);
if (alrm->enabled && (seconds < rtc->epoch_start)) {
dev_err(dev, "can't set alarm to requested time\n");
return -EINVAL;
}
seconds = rtc_tm_to_time64(&alrm->time);
ret = tps6586x_rtc_alarm_irq_enable(dev, alrm->enabled);
if (ret < 0) {
@ -179,7 +165,6 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret;
}
seconds -= rtc->epoch_start;
ret = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD,
sizeof(rbuff), rbuff);
if (ret < 0) {
@ -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)
{
struct tps6586x_rtc *rtc = dev_get_drvdata(dev);
struct device *tps_dev = to_tps6586x_dev(dev);
unsigned long ticks;
unsigned long seconds;
time64_t seconds;
u8 buff[3];
int ret;
@ -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];
seconds = ticks >> 10;
seconds += rtc->epoch_start;
rtc_time_to_tm(seconds, &alrm->time);
rtc_time64_to_tm(seconds, &alrm->time);
return 0;
}
@ -260,9 +243,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
rtc->dev = &pdev->dev;
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 */
ret = tps6586x_update(tps_dev, RTC_CTRL,
RTC_ENABLE | OSC_SRC_SEL |
@ -276,14 +256,18 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
platform_set_drvdata(pdev, rtc);
rtc->rtc = devm_rtc_device_register(&pdev->dev, dev_name(&pdev->dev),
&tps6586x_rtc_ops, THIS_MODULE);
rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_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;
}
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,
tps6586x_rtc_irq,
IRQF_ONESHOT,
@ -294,6 +278,13 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
goto fail_rtc_register;
}
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;
fail_rtc_register:

View File

@ -380,6 +380,10 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
if (!tps_rtc)
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 */
ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg);
if (ret < 0)
@ -421,10 +425,12 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
tps_rtc->irq = irq;
device_set_wakeup_capable(&pdev->dev, 1);
tps_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&tps65910_rtc_ops, THIS_MODULE);
if (IS_ERR(tps_rtc->rtc)) {
ret = PTR_ERR(tps_rtc->rtc);
tps_rtc->rtc->ops = &tps65910_rtc_ops;
tps_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
tps_rtc->rtc->range_max = RTC_TIMESTAMP_END_2099;
ret = rtc_register_device(tps_rtc->rtc);
if (ret) {
dev_err(&pdev->dev, "RTC device register: err %d\n", ret);
return ret;
}
@ -432,17 +438,6 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
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
static int tps65910_rtc_suspend(struct device *dev)
{
@ -468,7 +463,6 @@ static SIMPLE_DEV_PM_OPS(tps65910_rtc_pm_ops, tps65910_rtc_suspend,
static struct platform_driver tps65910_rtc_driver = {
.probe = tps65910_rtc_probe,
.remove = tps65910_rtc_remove,
.driver = {
.name = "tps65910-rtc",
.pm = &tps65910_rtc_pm_ops,

View File

@ -88,7 +88,7 @@ static unsigned int alarm_enabled;
static int aie_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;
@ -105,10 +105,10 @@ static inline unsigned long read_elapsed_second(void)
} while (first_low != second_low || first_mid != second_mid ||
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);
@ -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)
{
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();
rtc_time_to_tm(epoch_sec + elapsed_sec, time);
rtc_time64_to_tm(epoch_sec + elapsed_sec, time);
return 0;
}
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);
current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
epoch_sec = mktime64(epoch, 1, 1, 0, 0, 0);
current_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec);
write_elapsed_second(current_sec - epoch_sec);
@ -165,11 +165,11 @@ 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)
{
unsigned long alarm_sec;
time64_t alarm_sec;
struct rtc_time *time = &wkalrm->time;
alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec);
alarm_sec = mktime64(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec);
spin_lock_irq(&rtc_lock);
@ -292,13 +292,16 @@ static int rtc_probe(struct platform_device *pdev)
goto err_rtc1_iounmap;
}
rtc = devm_rtc_device_register(&pdev->dev, rtc_name, &vr41xx_rtc_ops,
THIS_MODULE);
rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc)) {
retval = PTR_ERR(rtc);
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;
spin_lock_irq(&rtc_lock);
@ -340,6 +343,10 @@ static int rtc_probe(struct platform_device *pdev)
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;
err_iounmap_all:

View File

@ -278,10 +278,9 @@ static int xlnx_rtc_remove(struct platform_device *pdev)
static int __maybe_unused xlnx_rtc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
if (device_may_wakeup(&pdev->dev))
if (device_may_wakeup(dev))
enable_irq_wake(xrtcdev->alarm_irq);
else
xlnx_rtc_alarm_irq_enable(dev, 0);
@ -291,10 +290,9 @@ static int __maybe_unused xlnx_rtc_suspend(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 = platform_get_drvdata(pdev);
struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
if (device_may_wakeup(&pdev->dev))
if (device_may_wakeup(dev))
disable_irq_wake(xrtcdev->alarm_irq);
else
xlnx_rtc_alarm_irq_enable(dev, 1);

View File

@ -285,7 +285,7 @@ void rtc_nvmem_unregister(struct rtc_device *rtc);
static inline int rtc_nvmem_register(struct rtc_device *rtc,
struct nvmem_config *nvmem_config)
{
return -ENODEV;
return 0;
}
static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {}
#endif