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
43 changed files with 911 additions and 848 deletions
@@ -9,7 +9,7 @@ Optional properties:
Example: Example:
rtc: nxp,rtc-pcf2123@3 { pcf2123: rtc@3 {
compatible = "nxp,rtc-pcf2123" compatible = "nxp,rtc-pcf2123"
reg = <3> reg = <3>
spi-cs-high; spi-cs-high;
@@ -1,23 +1,29 @@
STM32 Real Time Clock STM32 Real Time Clock
Required properties: Required properties:
- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on - compatible: can be one of the following:
the device is compatible with stm32(f4/f7) or stm32h7. - "st,stm32-rtc" for devices compatible with stm32(f4/f7).
- "st,stm32h7-rtc" for devices compatible with stm32h7.
- "st,stm32mp1-rtc" for devices compatible with stm32mp1.
- reg: address range of rtc register set. - reg: address range of rtc register set.
- clocks: can use up to two clocks, depending on part used: - clocks: can use up to two clocks, depending on part used:
- "rtc_ck": RTC clock source. - "rtc_ck": RTC clock source.
It is required on stm32(f4/f7) and stm32h7.
- "pclk": RTC APB interface clock. - "pclk": RTC APB interface clock.
It is not present on stm32(f4/f7). It is not present on stm32(f4/f7).
It is required on stm32h7. It is required on stm32(h7/mp1).
- clock-names: must be "rtc_ck" and "pclk". - clock-names: must be "rtc_ck" and "pclk".
It is required only on stm32h7. It is required on stm32(h7/mp1).
- interrupt-parent: phandle for the interrupt controller. - interrupt-parent: phandle for the interrupt controller.
- interrupts: rtc alarm interrupt. It is required on stm32(f4/f7/h7).
- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain - interrupts: rtc alarm interrupt. On stm32mp1, a second interrupt is required
(RTC registers) write protection. for rtc alarm wakeup interrupt.
- st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
access control register at offset, and change the dbp (Disable Backup
Protection) bit represented by the mask, mandatory to disable/enable backup
domain (RTC registers) write protection.
It is required on stm32(f4/f7/h7).
Optional properties (to override default rtc_ck parent clock): Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
- assigned-clocks: reference to the rtc_ck clock entry. - assigned-clocks: reference to the rtc_ck clock entry.
- assigned-clock-parents: phandle of the new parent clock of rtc_ck. - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
@@ -31,7 +37,7 @@ Example:
assigned-clock-parents = <&rcc 1 CLK_LSE>; assigned-clock-parents = <&rcc 1 CLK_LSE>;
interrupt-parent = <&exti>; interrupt-parent = <&exti>;
interrupts = <17 1>; interrupts = <17 1>;
st,syscfg = <&pwrcfg>; st,syscfg = <&pwrcfg 0x00 0x100>;
}; };
rtc: rtc@58004000 { rtc: rtc@58004000 {
@@ -44,5 +50,14 @@ Example:
interrupt-parent = <&exti>; interrupt-parent = <&exti>;
interrupts = <17 1>; interrupts = <17 1>;
interrupt-names = "alarm"; interrupt-names = "alarm";
st,syscfg = <&pwrcfg>; st,syscfg = <&pwrcfg 0x00 0x100>;
};
rtc: rtc@5c004000 {
compatible = "st,stm32mp1-rtc";
reg = <0x5c004000 0x400>;
clocks = <&rcc RTCAPB>, <&rcc RTC>;
clock-names = "pclk", "rtc_ck";
interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
<&exti 19 1>;
}; };
+1 -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 If you say yes here you get support for the Ingenic JZ47xx SoCs RTC
controllers. controllers.
This driver can also be buillt as a module. If so, the module This driver can also be built as a module. If so, the module
will be called rtc-jz4740. will be called rtc-jz4740.
config RTC_DRV_LPC24XX config RTC_DRV_LPC24XX
+5
View File
@@ -441,6 +441,11 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{ {
int err; int err;
if (!rtc->ops)
return -ENODEV;
else if (!rtc->ops->set_alarm)
return -EINVAL;
err = rtc_valid_tm(&alarm->time); err = rtc_valid_tm(&alarm->time);
if (err != 0) if (err != 0)
return err; return err;
+1 -1
View File
@@ -94,7 +94,7 @@ int rtc_nvmem_register(struct rtc_device *rtc,
nvmem_config->dev = rtc->dev.parent; nvmem_config->dev = rtc->dev.parent;
nvmem_config->owner = rtc->owner; nvmem_config->owner = rtc->owner;
rtc->nvmem = nvmem_register(nvmem_config); rtc->nvmem = nvmem_register(nvmem_config);
if (IS_ERR_OR_NULL(rtc->nvmem)) if (IS_ERR(rtc->nvmem))
return PTR_ERR(rtc->nvmem); return PTR_ERR(rtc->nvmem);
/* Register the old ABI */ /* Register the old ABI */
+17 -41
View File
@@ -52,10 +52,8 @@ struct pm80x_rtc_info {
struct regmap *map; struct regmap *map;
struct rtc_device *rtc_dev; struct rtc_device *rtc_dev;
struct device *dev; struct device *dev;
struct delayed_work calib_work;
int irq; int irq;
int vrtc;
}; };
static irqreturn_t rtc_update_handler(int irq, void *data) static irqreturn_t rtc_update_handler(int irq, void *data)
@@ -100,13 +98,13 @@ static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
next->tm_min = alrm->tm_min; next->tm_min = alrm->tm_min;
next->tm_sec = alrm->tm_sec; next->tm_sec = alrm->tm_sec;
rtc_tm_to_time(now, &now_time); now_time = rtc_tm_to_time64(now);
rtc_tm_to_time(next, &next_time); next_time = rtc_tm_to_time64(next);
if (next_time < now_time) { if (next_time < now_time) {
/* Advance one day */ /* Advance one day */
next_time += 60 * 60 * 24; next_time += 60 * 60 * 24;
rtc_time_to_tm(next_time, next); rtc_time64_to_tm(next_time, next);
} }
} }
@@ -125,7 +123,7 @@ static int pm80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
ticks = base + data; ticks = base + data;
dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
base, data, ticks); base, data, ticks);
rtc_time_to_tm(ticks, tm); rtc_time64_to_tm(ticks, tm);
return 0; return 0;
} }
@@ -134,13 +132,8 @@ static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
struct pm80x_rtc_info *info = dev_get_drvdata(dev); struct pm80x_rtc_info *info = dev_get_drvdata(dev);
unsigned char buf[4]; unsigned char buf[4];
unsigned long ticks, base, data; unsigned long ticks, base, data;
if (tm->tm_year > 206) {
dev_dbg(info->dev, ticks = rtc_tm_to_time64(tm);
"Set time %d out of range. Please set time between 1970 to 2106.\n",
1900 + tm->tm_year);
return -EINVAL;
}
rtc_tm_to_time(tm, &ticks);
/* load 32-bit read-only counter */ /* load 32-bit read-only counter */
regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4); regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
@@ -174,7 +167,7 @@ static int pm80x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
base, data, ticks); base, data, ticks);
rtc_time_to_tm(ticks, &alrm->time); rtc_time64_to_tm(ticks, &alrm->time);
regmap_read(info->map, PM800_RTC_CONTROL, &ret); regmap_read(info->map, PM800_RTC_CONTROL, &ret);
alrm->enabled = (ret & PM800_ALARM1_EN) ? 1 : 0; alrm->enabled = (ret & PM800_ALARM1_EN) ? 1 : 0;
alrm->pending = (ret & (PM800_ALARM | PM800_ALARM_WAKEUP)) ? 1 : 0; alrm->pending = (ret & (PM800_ALARM | PM800_ALARM_WAKEUP)) ? 1 : 0;
@@ -202,11 +195,11 @@ static int pm80x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
base, data, ticks); base, data, ticks);
rtc_time_to_tm(ticks, &now_tm); rtc_time64_to_tm(ticks, &now_tm);
dev_dbg(info->dev, "%s, now time : %lu\n", __func__, ticks); dev_dbg(info->dev, "%s, now time : %lu\n", __func__, ticks);
rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time);
/* get new ticks for alarm in 24 hours */ /* get new ticks for alarm in 24 hours */
rtc_tm_to_time(&alarm_tm, &ticks); ticks = rtc_tm_to_time64(&alarm_tm);
dev_dbg(info->dev, "%s, alarm time: %lu\n", __func__, ticks); dev_dbg(info->dev, "%s, alarm time: %lu\n", __func__, ticks);
data = ticks - base; data = ticks - base;
@@ -254,8 +247,6 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
struct pm80x_rtc_pdata *pdata = dev_get_platdata(&pdev->dev); struct pm80x_rtc_pdata *pdata = dev_get_platdata(&pdev->dev);
struct pm80x_rtc_info *info; struct pm80x_rtc_info *info;
struct device_node *node = pdev->dev.of_node; struct device_node *node = pdev->dev.of_node;
struct rtc_time tm;
unsigned long ticks = 0;
int ret; int ret;
if (!pdata && !node) { if (!pdata && !node) {
@@ -294,6 +285,10 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
info->dev = &pdev->dev; info->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, info); dev_set_drvdata(&pdev->dev, info);
info->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(info->rtc_dev))
return PTR_ERR(info->rtc_dev);
ret = pm80x_request_irq(chip, info->irq, rtc_update_handler, ret = pm80x_request_irq(chip, info->irq, rtc_update_handler,
IRQF_ONESHOT, "rtc", info); IRQF_ONESHOT, "rtc", info);
if (ret < 0) { if (ret < 0) {
@@ -302,30 +297,11 @@ static int pm80x_rtc_probe(struct platform_device *pdev)
goto out; goto out;
} }
ret = pm80x_rtc_read_time(&pdev->dev, &tm); info->rtc_dev->ops = &pm80x_rtc_ops;
if (ret < 0) { info->rtc_dev->range_max = U32_MAX;
dev_err(&pdev->dev, "Failed to read initial time.\n");
goto out_rtc;
}
if ((tm.tm_year < 70) || (tm.tm_year > 138)) {
tm.tm_year = 70;
tm.tm_mon = 0;
tm.tm_mday = 1;
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
ret = pm80x_rtc_set_time(&pdev->dev, &tm);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to set initial time.\n");
goto out_rtc;
}
}
rtc_tm_to_time(&tm, &ticks);
info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm80x-rtc", ret = rtc_register_device(info->rtc_dev);
&pm80x_rtc_ops, THIS_MODULE); if (ret) {
if (IS_ERR(info->rtc_dev)) {
ret = PTR_ERR(info->rtc_dev);
dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
goto out_rtc; goto out_rtc;
} }
+13 -17
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]; u8 regs[ABB5ZES3_REG_RTC_SC + ABB5ZES3_RTC_SEC_LEN];
int ret; int ret;
/*
* Year register is 8-bit wide and bcd-coded, i.e records values
* between 0 and 99. tm_year is an offset from 1900 and we are
* interested in the 2000-2099 range, so any value less than 100
* is invalid.
*/
if (tm->tm_year < 100)
return -EINVAL;
regs[ABB5ZES3_REG_RTC_SC] = bin2bcd(tm->tm_sec); /* MSB=0 clears OSC */ regs[ABB5ZES3_REG_RTC_SC] = bin2bcd(tm->tm_sec); /* MSB=0 clears OSC */
regs[ABB5ZES3_REG_RTC_MN] = bin2bcd(tm->tm_min); regs[ABB5ZES3_REG_RTC_MN] = bin2bcd(tm->tm_min);
regs[ABB5ZES3_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */ regs[ABB5ZES3_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */
@@ -925,6 +916,14 @@ static int abb5zes3_probe(struct i2c_client *client,
if (ret) if (ret)
goto err; goto err;
data->rtc = devm_rtc_allocate_device(dev);
ret = PTR_ERR_OR_ZERO(data->rtc);
if (ret) {
dev_err(dev, "%s: unable to allocate RTC device (%d)\n",
__func__, ret);
goto err;
}
if (client->irq > 0) { if (client->irq > 0) {
ret = devm_request_threaded_irq(dev, client->irq, NULL, ret = devm_request_threaded_irq(dev, client->irq, NULL,
_abb5zes3_rtc_interrupt, _abb5zes3_rtc_interrupt,
@@ -942,14 +941,9 @@ static int abb5zes3_probe(struct i2c_client *client,
} }
} }
data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, data->rtc->ops = &rtc_ops;
THIS_MODULE); data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
ret = PTR_ERR_OR_ZERO(data->rtc); data->rtc->range_max = RTC_TIMESTAMP_END_2099;
if (ret) {
dev_err(dev, "%s: unable to register RTC device (%d)\n",
__func__, ret);
goto err;
}
/* Enable battery low detection interrupt if battery not already low */ /* Enable battery low detection interrupt if battery not already low */
if (!data->battery_low && data->irq) { if (!data->battery_low && data->irq) {
@@ -961,6 +955,8 @@ static int abb5zes3_probe(struct i2c_client *client,
} }
} }
ret = rtc_register_device(data->rtc);
err: err:
if (ret && data && data->irq) if (ret && data && data->irq)
device_init_wakeup(dev, false); device_init_wakeup(dev, false);
+2
View File
@@ -440,6 +440,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
rtc->ops = &at91_rtc_ops; rtc->ops = &at91_rtc_ops;
rtc->range_min = RTC_TIMESTAMP_BEGIN_1900;
rtc->range_max = RTC_TIMESTAMP_END_2099;
ret = rtc_register_device(rtc); ret = rtc_register_device(rtc);
if (ret) if (ret)
goto err_clk; goto err_clk;
+2 -4
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) static int bq4802_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct bq4802 *p = dev_get_drvdata(dev);
struct bq4802 *p = platform_get_drvdata(pdev);
unsigned long flags; unsigned long flags;
unsigned int century; unsigned int century;
u8 val; u8 val;
@@ -91,8 +90,7 @@ static int bq4802_read_time(struct device *dev, struct rtc_time *tm)
static int bq4802_set_time(struct device *dev, struct rtc_time *tm) static int bq4802_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct bq4802 *p = dev_get_drvdata(dev);
struct bq4802 *p = platform_get_drvdata(pdev);
u8 sec, min, hrs, day, mon, yrs, century, val; u8 sec, min, hrs, day, mon, yrs, century, val;
unsigned long flags; unsigned long flags;
unsigned int year; unsigned int year;
+9 -11
View File
@@ -145,9 +145,6 @@ static int brcmstb_waketmr_settime(struct device *dev,
sec = rtc_tm_to_time64(tm); sec = rtc_tm_to_time64(tm);
if (sec > U32_MAX || sec < 0)
return -EINVAL;
writel_relaxed(sec, timer->base + BRCMSTB_WKTMR_COUNTER); writel_relaxed(sec, timer->base + BRCMSTB_WKTMR_COUNTER);
return 0; return 0;
@@ -184,9 +181,6 @@ static int brcmstb_waketmr_setalarm(struct device *dev,
else else
sec = 0; sec = 0;
if (sec > U32_MAX || sec < 0)
return -EINVAL;
brcmstb_waketmr_set_alarm(timer, sec); brcmstb_waketmr_set_alarm(timer, sec);
return 0; return 0;
@@ -229,6 +223,10 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
if (IS_ERR(timer->base)) if (IS_ERR(timer->base))
return PTR_ERR(timer->base); return PTR_ERR(timer->base);
timer->rtc = devm_rtc_allocate_device(dev);
if (IS_ERR(timer->rtc))
return PTR_ERR(timer->rtc);
/* /*
* Set wakeup capability before requesting wakeup interrupt, so we can * Set wakeup capability before requesting wakeup interrupt, so we can
* process boot-time "wakeups" (e.g., from S5 soft-off) * process boot-time "wakeups" (e.g., from S5 soft-off)
@@ -261,11 +259,12 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot; timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot;
register_reboot_notifier(&timer->reboot_notifier); register_reboot_notifier(&timer->reboot_notifier);
timer->rtc = rtc_device_register("brcmstb-waketmr", dev, timer->rtc->ops = &brcmstb_waketmr_ops;
&brcmstb_waketmr_ops, THIS_MODULE); timer->rtc->range_max = U32_MAX;
if (IS_ERR(timer->rtc)) {
ret = rtc_register_device(timer->rtc);
if (ret) {
dev_err(dev, "unable to register device\n"); dev_err(dev, "unable to register device\n");
ret = PTR_ERR(timer->rtc);
goto err_notifier; goto err_notifier;
} }
@@ -288,7 +287,6 @@ static int brcmstb_waketmr_remove(struct platform_device *pdev)
struct brcmstb_waketmr *timer = dev_get_drvdata(&pdev->dev); struct brcmstb_waketmr *timer = dev_get_drvdata(&pdev->dev);
unregister_reboot_notifier(&timer->reboot_notifier); unregister_reboot_notifier(&timer->reboot_notifier);
rtc_device_unregister(timer->rtc);
return 0; return 0;
} }
+105 -12
View File
@@ -43,11 +43,24 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#ifdef CONFIG_X86 #ifdef CONFIG_X86
#include <asm/i8259.h> #include <asm/i8259.h>
#include <asm/processor.h>
#include <linux/dmi.h>
#endif #endif
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
#include <linux/mc146818rtc.h> #include <linux/mc146818rtc.h>
/*
* Use ACPI SCI to replace HPET interrupt for RTC Alarm event
*
* If cleared, ACPI SCI is only used to wake up the system from suspend
*
* If set, ACPI SCI is used to handle UIE/AIE and system wakeup
*/
static bool use_acpi_alarm;
module_param(use_acpi_alarm, bool, 0444);
struct cmos_rtc { struct cmos_rtc {
struct rtc_device *rtc; struct rtc_device *rtc;
struct device *dev; struct device *dev;
@@ -153,6 +166,12 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler)
#endif #endif
/* Don't use HPET for RTC Alarm event if ACPI Fixed event is used */
static int use_hpet_alarm(void)
{
return is_hpet_enabled() && !use_acpi_alarm;
}
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
#ifdef RTC_PORT #ifdef RTC_PORT
@@ -298,7 +317,7 @@ static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control)
*/ */
rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
if (is_hpet_enabled()) if (use_hpet_alarm())
return; return;
rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
@@ -318,8 +337,14 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)
rtc_control |= mask; rtc_control |= mask;
CMOS_WRITE(rtc_control, RTC_CONTROL); CMOS_WRITE(rtc_control, RTC_CONTROL);
if (use_hpet_alarm())
hpet_set_rtc_irq_bit(mask); hpet_set_rtc_irq_bit(mask);
if ((mask & RTC_AIE) && use_acpi_alarm) {
if (cmos->wake_on)
cmos->wake_on(cmos->dev);
}
cmos_checkintr(cmos, rtc_control); cmos_checkintr(cmos, rtc_control);
} }
@@ -330,8 +355,14 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)
rtc_control = CMOS_READ(RTC_CONTROL); rtc_control = CMOS_READ(RTC_CONTROL);
rtc_control &= ~mask; rtc_control &= ~mask;
CMOS_WRITE(rtc_control, RTC_CONTROL); CMOS_WRITE(rtc_control, RTC_CONTROL);
if (use_hpet_alarm())
hpet_mask_rtc_irq_bit(mask); hpet_mask_rtc_irq_bit(mask);
if ((mask & RTC_AIE) && use_acpi_alarm) {
if (cmos->wake_off)
cmos->wake_off(cmos->dev);
}
cmos_checkintr(cmos, rtc_control); cmos_checkintr(cmos, rtc_control);
} }
@@ -448,10 +479,14 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
CMOS_WRITE(mon, cmos->mon_alrm); CMOS_WRITE(mon, cmos->mon_alrm);
} }
/* FIXME the HPET alarm glue currently ignores day_alrm if (use_hpet_alarm()) {
/*
* FIXME the HPET alarm glue currently ignores day_alrm
* and mon_alrm ... * and mon_alrm ...
*/ */
hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec); hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min,
t->time.tm_sec);
}
if (t->enabled) if (t->enabled)
cmos_irq_enable(cmos, RTC_AIE); cmos_irq_enable(cmos, RTC_AIE);
@@ -508,7 +543,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
"batt_status\t: %s\n", "batt_status\t: %s\n",
(rtc_control & RTC_PIE) ? "yes" : "no", (rtc_control & RTC_PIE) ? "yes" : "no",
(rtc_control & RTC_UIE) ? "yes" : "no", (rtc_control & RTC_UIE) ? "yes" : "no",
is_hpet_enabled() ? "yes" : "no", use_hpet_alarm() ? "yes" : "no",
// (rtc_control & RTC_SQWE) ? "yes" : "no", // (rtc_control & RTC_SQWE) ? "yes" : "no",
(rtc_control & RTC_DM_BINARY) ? "no" : "yes", (rtc_control & RTC_DM_BINARY) ? "no" : "yes",
(rtc_control & RTC_DST_EN) ? "yes" : "no", (rtc_control & RTC_DST_EN) ? "yes" : "no",
@@ -614,7 +649,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
*/ */
irqstat = CMOS_READ(RTC_INTR_FLAGS); irqstat = CMOS_READ(RTC_INTR_FLAGS);
rtc_control = CMOS_READ(RTC_CONTROL); rtc_control = CMOS_READ(RTC_CONTROL);
if (is_hpet_enabled()) if (use_hpet_alarm())
irqstat = (unsigned long)irq & 0xF0; irqstat = (unsigned long)irq & 0xF0;
/* If we were suspended, RTC_CONTROL may not be accurate since the /* If we were suspended, RTC_CONTROL may not be accurate since the
@@ -633,6 +668,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
cmos_rtc.suspend_ctrl &= ~RTC_AIE; cmos_rtc.suspend_ctrl &= ~RTC_AIE;
rtc_control &= ~RTC_AIE; rtc_control &= ~RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL); CMOS_WRITE(rtc_control, RTC_CONTROL);
if (use_hpet_alarm())
hpet_mask_rtc_irq_bit(RTC_AIE); hpet_mask_rtc_irq_bit(RTC_AIE);
CMOS_READ(RTC_INTR_FLAGS); CMOS_READ(RTC_INTR_FLAGS);
} }
@@ -762,6 +798,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
* need to do something about other clock frequencies. * need to do something about other clock frequencies.
*/ */
cmos_rtc.rtc->irq_freq = 1024; cmos_rtc.rtc->irq_freq = 1024;
if (use_hpet_alarm())
hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq);
CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT);
} }
@@ -780,12 +817,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
goto cleanup1; goto cleanup1;
} }
if (use_hpet_alarm())
hpet_rtc_timer_init(); hpet_rtc_timer_init();
if (is_valid_irq(rtc_irq)) { if (is_valid_irq(rtc_irq)) {
irq_handler_t rtc_cmos_int_handler; irq_handler_t rtc_cmos_int_handler;
if (is_hpet_enabled()) { if (use_hpet_alarm()) {
rtc_cmos_int_handler = hpet_rtc_interrupt; rtc_cmos_int_handler = hpet_rtc_interrupt;
retval = hpet_register_irq_handler(cmos_interrupt); retval = hpet_register_irq_handler(cmos_interrupt);
if (retval) { if (retval) {
@@ -824,7 +862,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
"alarms up to one day", "alarms up to one day",
cmos_rtc.century ? ", y3k" : "", cmos_rtc.century ? ", y3k" : "",
nvmem_cfg.size, nvmem_cfg.size,
is_hpet_enabled() ? ", hpet irqs" : ""); use_hpet_alarm() ? ", hpet irqs" : "");
return 0; return 0;
@@ -858,6 +896,7 @@ static void cmos_do_remove(struct device *dev)
if (is_valid_irq(cmos->irq)) { if (is_valid_irq(cmos->irq)) {
free_irq(cmos->irq, cmos->rtc); free_irq(cmos->irq, cmos->rtc);
if (use_hpet_alarm())
hpet_unregister_irq_handler(cmos_interrupt); hpet_unregister_irq_handler(cmos_interrupt);
} }
@@ -935,13 +974,13 @@ static int cmos_suspend(struct device *dev)
mask = RTC_IRQMASK; mask = RTC_IRQMASK;
tmp &= ~mask; tmp &= ~mask;
CMOS_WRITE(tmp, RTC_CONTROL); CMOS_WRITE(tmp, RTC_CONTROL);
if (use_hpet_alarm())
hpet_mask_rtc_irq_bit(mask); hpet_mask_rtc_irq_bit(mask);
cmos_checkintr(cmos, tmp); cmos_checkintr(cmos, tmp);
} }
spin_unlock_irq(&rtc_lock); spin_unlock_irq(&rtc_lock);
if (tmp & RTC_AIE) { if ((tmp & RTC_AIE) && !use_acpi_alarm) {
cmos->enabled_wake = 1; cmos->enabled_wake = 1;
if (cmos->wake_on) if (cmos->wake_on)
cmos->wake_on(dev); cmos->wake_on(dev);
@@ -976,8 +1015,26 @@ static void cmos_check_wkalrm(struct device *dev)
{ {
struct cmos_rtc *cmos = dev_get_drvdata(dev); struct cmos_rtc *cmos = dev_get_drvdata(dev);
struct rtc_wkalrm current_alarm; struct rtc_wkalrm current_alarm;
time64_t t_now;
time64_t t_current_expires; time64_t t_current_expires;
time64_t t_saved_expires; time64_t t_saved_expires;
struct rtc_time now;
/* Check if we have RTC Alarm armed */
if (!(cmos->suspend_ctrl & RTC_AIE))
return;
cmos_read_time(dev, &now);
t_now = rtc_tm_to_time64(&now);
/*
* ACPI RTC wake event is cleared after resume from STR,
* ACK the rtc irq here
*/
if (t_now >= cmos->alarm_expires && use_acpi_alarm) {
cmos_interrupt(0, (void *)cmos->rtc);
return;
}
cmos_read_alarm(dev, &current_alarm); cmos_read_alarm(dev, &current_alarm);
t_current_expires = rtc_tm_to_time64(&current_alarm.time); t_current_expires = rtc_tm_to_time64(&current_alarm.time);
@@ -996,7 +1053,7 @@ static int __maybe_unused cmos_resume(struct device *dev)
struct cmos_rtc *cmos = dev_get_drvdata(dev); struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char tmp; unsigned char tmp;
if (cmos->enabled_wake) { if (cmos->enabled_wake && !use_acpi_alarm) {
if (cmos->wake_off) if (cmos->wake_off)
cmos->wake_off(dev); cmos->wake_off(dev);
else else
@@ -1014,16 +1071,17 @@ static int __maybe_unused cmos_resume(struct device *dev)
if (tmp & RTC_IRQMASK) { if (tmp & RTC_IRQMASK) {
unsigned char mask; unsigned char mask;
if (device_may_wakeup(dev)) if (device_may_wakeup(dev) && use_hpet_alarm())
hpet_rtc_timer_init(); hpet_rtc_timer_init();
do { do {
CMOS_WRITE(tmp, RTC_CONTROL); CMOS_WRITE(tmp, RTC_CONTROL);
if (use_hpet_alarm())
hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK); hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK);
mask = CMOS_READ(RTC_INTR_FLAGS); mask = CMOS_READ(RTC_INTR_FLAGS);
mask &= (tmp & RTC_IRQMASK) | RTC_IRQF; mask &= (tmp & RTC_IRQMASK) | RTC_IRQF;
if (!is_hpet_enabled() || !is_intr(mask)) if (!use_hpet_alarm() || !is_intr(mask))
break; break;
/* force one-shot behavior if HPET blocked /* force one-shot behavior if HPET blocked
@@ -1068,6 +1126,16 @@ static u32 rtc_handler(void *context)
unsigned char rtc_intr; unsigned char rtc_intr;
unsigned long flags; unsigned long flags;
/*
* Always update rtc irq when ACPI is used as RTC Alarm.
* Or else, ACPI SCI is enabled during suspend/resume only,
* update rtc irq in that case.
*/
if (use_acpi_alarm)
cmos_interrupt(0, (void *)cmos->rtc);
else {
/* Fix me: can we use cmos_interrupt() here as well? */
spin_lock_irqsave(&rtc_lock, flags); spin_lock_irqsave(&rtc_lock, flags);
if (cmos_rtc.suspend_ctrl) if (cmos_rtc.suspend_ctrl)
rtc_control = CMOS_READ(RTC_CONTROL); rtc_control = CMOS_READ(RTC_CONTROL);
@@ -1078,6 +1146,7 @@ static u32 rtc_handler(void *context)
rtc_update_irq(cmos->rtc, 1, rtc_intr); rtc_update_irq(cmos->rtc, 1, rtc_intr);
} }
spin_unlock_irqrestore(&rtc_lock, flags); spin_unlock_irqrestore(&rtc_lock, flags);
}
pm_wakeup_hard_event(dev); pm_wakeup_hard_event(dev);
acpi_clear_event(ACPI_EVENT_RTC); acpi_clear_event(ACPI_EVENT_RTC);
@@ -1107,6 +1176,28 @@ static void rtc_wake_off(struct device *dev)
acpi_disable_event(ACPI_EVENT_RTC, 0); acpi_disable_event(ACPI_EVENT_RTC, 0);
} }
#ifdef CONFIG_X86
/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
static void use_acpi_alarm_quirks(void)
{
int year;
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
return;
if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
return;
if (!is_hpet_enabled())
return;
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2015)
use_acpi_alarm = true;
}
#else
static inline void use_acpi_alarm_quirks(void) { }
#endif
/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find /* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
* its device node and pass extra config data. This helps its driver use * its device node and pass extra config data. This helps its driver use
* capabilities that the now-obsolete mc146818 didn't have, and informs it * capabilities that the now-obsolete mc146818 didn't have, and informs it
@@ -1119,6 +1210,8 @@ static void cmos_wake_setup(struct device *dev)
if (acpi_disabled) if (acpi_disabled)
return; return;
use_acpi_alarm_quirks();
rtc_wake_setup(dev); rtc_wake_setup(dev);
acpi_rtc_info.wake_on = rtc_wake_on; acpi_rtc_info.wake_on = rtc_wake_on;
acpi_rtc_info.wake_off = rtc_wake_off; acpi_rtc_info.wake_off = rtc_wake_off;
+6 -17
View File
@@ -1,19 +1,8 @@
/* // SPDX-License-Identifier: GPL-2.0
* RTC driver for Chrome OS Embedded Controller // RTC driver for ChromeOS Embedded Controller.
* //
* Copyright (c) 2017, Google, Inc // Copyright (C) 2017 Google, Inc.
* // Author: Stephen Barber <smbarber@chromium.org>
* Author: Stephen Barber <smbarber@chromium.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mfd/cros_ec.h> #include <linux/mfd/cros_ec.h>
@@ -409,5 +398,5 @@ module_platform_driver(cros_ec_rtc_driver);
MODULE_DESCRIPTION("RTC driver for Chrome OS ECs"); MODULE_DESCRIPTION("RTC driver for Chrome OS ECs");
MODULE_AUTHOR("Stephen Barber <smbarber@chromium.org>"); MODULE_AUTHOR("Stephen Barber <smbarber@chromium.org>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME); MODULE_ALIAS("platform:" DRV_NAME);
+2 -4
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) static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1216_priv *priv = dev_get_drvdata(dev);
struct ds1216_priv *priv = platform_get_drvdata(pdev);
struct ds1216_regs regs; struct ds1216_regs regs;
ds1216_switch_ds_to_clock(priv->ioaddr); ds1216_switch_ds_to_clock(priv->ioaddr);
@@ -104,8 +103,7 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm) static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1216_priv *priv = dev_get_drvdata(dev);
struct ds1216_priv *priv = platform_get_drvdata(pdev);
struct ds1216_regs regs; struct ds1216_regs regs;
ds1216_switch_ds_to_clock(priv->ioaddr); ds1216_switch_ds_to_clock(priv->ioaddr);
+2
View File
@@ -201,6 +201,7 @@ static const struct chip_desc chips[last_ds_type] = {
.century_reg = DS1307_REG_HOUR, .century_reg = DS1307_REG_HOUR,
.century_enable_bit = DS1340_BIT_CENTURY_EN, .century_enable_bit = DS1340_BIT_CENTURY_EN,
.century_bit = DS1340_BIT_CENTURY, .century_bit = DS1340_BIT_CENTURY,
.do_trickle_setup = &do_trickle_setup_ds1339,
.trickle_charger_reg = 0x08, .trickle_charger_reg = 0x08,
}, },
[ds_1341] = { [ds_1341] = {
@@ -1371,6 +1372,7 @@ static void ds1307_clks_register(struct ds1307 *ds1307)
static const struct regmap_config regmap_config = { static const struct regmap_config regmap_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
.max_register = 0x9,
}; };
static int ds1307_probe(struct i2c_client *client, static int ds1307_probe(struct i2c_client *client,
+3 -6
View File
@@ -314,8 +314,7 @@ ds1511_rtc_update_alarm(struct rtc_plat_data *pdata)
static int static int
ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
@@ -334,8 +333,7 @@ ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int static int
ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
@@ -373,8 +371,7 @@ ds1511_interrupt(int irq, void *dev_id)
static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
+5 -10
View File
@@ -73,8 +73,7 @@ struct rtc_plat_data {
static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm) static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
u8 century; u8 century;
@@ -98,8 +97,7 @@ static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm) static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
unsigned int year, month, day, hour, minute, second, week; unsigned int year, month, day, hour, minute, second, week;
unsigned int century; unsigned int century;
@@ -155,8 +153,7 @@ static void ds1553_rtc_update_alarm(struct rtc_plat_data *pdata)
static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
@@ -172,8 +169,7 @@ static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
@@ -208,8 +204,7 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id)
static int ds1553_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static int ds1553_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
if (pdata->irq <= 0) if (pdata->irq <= 0)
return -EINVAL; return -EINVAL;
+29 -37
View File
@@ -267,8 +267,7 @@ ds1685_rtc_get_ssn(struct ds1685_priv *rtc, u8 *ssn)
static int static int
ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm) ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrlb, century; u8 ctrlb, century;
u8 seconds, minutes, hours, wday, mday, month, years; u8 seconds, minutes, hours, wday, mday, month, years;
@@ -317,8 +316,7 @@ ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int static int
ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm) ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrlb, seconds, minutes, hours, wday, mday, month, years, century; u8 ctrlb, seconds, minutes, hours, wday, mday, month, years, century;
/* Fetch the time info from rtc_time. */ /* Fetch the time info from rtc_time. */
@@ -394,8 +392,7 @@ ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int static int
ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 seconds, minutes, hours, mday, ctrlb, ctrlc; u8 seconds, minutes, hours, mday, ctrlb, ctrlc;
int ret; int ret;
@@ -453,8 +450,7 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int static int
ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrlb, seconds, minutes, hours, mday; u8 ctrlb, seconds, minutes, hours, mday;
int ret; int ret;
@@ -1119,8 +1115,7 @@ static ssize_t
ds1685_rtc_sysfs_battery_show(struct device *dev, ds1685_rtc_sysfs_battery_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrld; u8 ctrld;
ctrld = rtc->read(rtc, RTC_CTRL_D); ctrld = rtc->read(rtc, RTC_CTRL_D);
@@ -1140,8 +1135,7 @@ static ssize_t
ds1685_rtc_sysfs_auxbatt_show(struct device *dev, ds1685_rtc_sysfs_auxbatt_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrl4a; u8 ctrl4a;
ds1685_rtc_switch_to_bank1(rtc); ds1685_rtc_switch_to_bank1(rtc);
@@ -1163,8 +1157,7 @@ static ssize_t
ds1685_rtc_sysfs_serial_show(struct device *dev, ds1685_rtc_sysfs_serial_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = dev_get_drvdata(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ssn[8]; u8 ssn[8];
ds1685_rtc_switch_to_bank1(rtc); ds1685_rtc_switch_to_bank1(rtc);
@@ -2044,6 +2037,26 @@ ds1685_rtc_probe(struct platform_device *pdev)
rtc->write(rtc, RTC_EXT_CTRL_4B, rtc->write(rtc, RTC_EXT_CTRL_4B,
(rtc->read(rtc, RTC_EXT_CTRL_4B) | RTC_CTRL_4B_KSE)); (rtc->read(rtc, RTC_EXT_CTRL_4B) | RTC_CTRL_4B_KSE));
rtc_dev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc_dev))
return PTR_ERR(rtc_dev);
rtc_dev->ops = &ds1685_rtc_ops;
/* Century bit is useless because leap year fails in 1900 and 2100 */
rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000;
rtc_dev->range_max = RTC_TIMESTAMP_END_2099;
/* Maximum periodic rate is 8192Hz (0.122070ms). */
rtc_dev->max_user_freq = RTC_MAX_USER_FREQ;
/* See if the platform doesn't support UIE. */
if (pdata->uie_unsupported)
rtc_dev->uie_unsupported = 1;
rtc->uie_unsupported = pdata->uie_unsupported;
rtc->dev = rtc_dev;
/* /*
* Fetch the IRQ and setup the interrupt handler. * Fetch the IRQ and setup the interrupt handler.
* *
@@ -2076,32 +2089,13 @@ ds1685_rtc_probe(struct platform_device *pdev)
/* Setup complete. */ /* Setup complete. */
ds1685_rtc_switch_to_bank0(rtc); ds1685_rtc_switch_to_bank0(rtc);
/* Register the device as an RTC. */
rtc_dev = rtc_device_register(pdev->name, &pdev->dev,
&ds1685_rtc_ops, THIS_MODULE);
/* Success? */
if (IS_ERR(rtc_dev))
return PTR_ERR(rtc_dev);
/* Maximum periodic rate is 8192Hz (0.122070ms). */
rtc_dev->max_user_freq = RTC_MAX_USER_FREQ;
/* See if the platform doesn't support UIE. */
if (pdata->uie_unsupported)
rtc_dev->uie_unsupported = 1;
rtc->uie_unsupported = pdata->uie_unsupported;
rtc->dev = rtc_dev;
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
ret = ds1685_rtc_sysfs_register(&pdev->dev); ret = ds1685_rtc_sysfs_register(&pdev->dev);
if (ret) if (ret)
rtc_device_unregister(rtc->dev); return ret;
#endif #endif
/* Done! */ return rtc_register_device(rtc_dev);
return ret;
} }
/** /**
@@ -2117,8 +2111,6 @@ ds1685_rtc_remove(struct platform_device *pdev)
ds1685_rtc_sysfs_unregister(&pdev->dev); ds1685_rtc_sysfs_unregister(&pdev->dev);
#endif #endif
rtc_device_unregister(rtc->dev);
/* Read Ctrl B and clear PIE/AIE/UIE. */ /* Read Ctrl B and clear PIE/AIE/UIE. */
rtc->write(rtc, RTC_CTRL_B, rtc->write(rtc, RTC_CTRL_B,
(rtc->read(rtc, RTC_CTRL_B) & (rtc->read(rtc, RTC_CTRL_B) &
+2 -6
View File
@@ -58,8 +58,7 @@ struct rtc_plat_data {
static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm) static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr_rtc; void __iomem *ioaddr = pdata->ioaddr_rtc;
u8 century; u8 century;
@@ -83,8 +82,7 @@ static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm) static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = dev_get_drvdata(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr_rtc; void __iomem *ioaddr = pdata->ioaddr_rtc;
unsigned int year, month, day, hour, minute, second, week; unsigned int year, month, day, hour, minute, second, week;
unsigned int century; unsigned int century;
@@ -154,8 +152,6 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
int ret = 0; int ret = 0;
struct nvmem_config nvmem_cfg = { struct nvmem_config nvmem_cfg = {
.name = "ds1742_nvram", .name = "ds1742_nvram",
.word_size = 1,
.stride = 1,
.reg_read = ds1742_nvram_read, .reg_read = ds1742_nvram_read,
.reg_write = ds1742_nvram_write, .reg_write = ds1742_nvram_write,
}; };
+23 -13
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); struct ftrtc010_rtc *rtc = dev_get_drvdata(dev);
unsigned int days, hour, min, sec; u32 days, hour, min, sec, offset;
unsigned long offset, time; timeu64_t time;
sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND); sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE); min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
@@ -84,7 +84,7 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
time = offset + days * 86400 + hour * 3600 + min * 60 + sec; time = offset + days * 86400 + hour * 3600 + min * 60 + sec;
rtc_time_to_tm(time, tm); rtc_time64_to_tm(time, tm);
return 0; return 0;
} }
@@ -92,13 +92,10 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int ftrtc010_rtc_set_time(struct device *dev, struct rtc_time *tm) static int ftrtc010_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct ftrtc010_rtc *rtc = dev_get_drvdata(dev); struct ftrtc010_rtc *rtc = dev_get_drvdata(dev);
unsigned int sec, min, hour, day; u32 sec, min, hour, day, offset;
unsigned long offset, time; timeu64_t time;
if (tm->tm_year >= 2148) /* EPOCH Year + 179 */ time = rtc_tm_to_time64(tm);
return -EINVAL;
rtc_tm_to_time(tm, &time);
sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND); sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE); min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
@@ -120,6 +117,7 @@ static const struct rtc_class_ops ftrtc010_rtc_ops = {
static int ftrtc010_rtc_probe(struct platform_device *pdev) static int ftrtc010_rtc_probe(struct platform_device *pdev)
{ {
u32 days, hour, min, sec;
struct ftrtc010_rtc *rtc; struct ftrtc010_rtc *rtc;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *res; struct resource *res;
@@ -166,14 +164,27 @@ static int ftrtc010_rtc_probe(struct platform_device *pdev)
if (!rtc->rtc_base) if (!rtc->rtc_base)
return -ENOMEM; return -ENOMEM;
rtc->rtc_dev = devm_rtc_allocate_device(dev);
if (IS_ERR(rtc->rtc_dev))
return PTR_ERR(rtc->rtc_dev);
rtc->rtc_dev->ops = &ftrtc010_rtc_ops;
sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
hour = readl(rtc->rtc_base + FTRTC010_RTC_HOUR);
days = readl(rtc->rtc_base + FTRTC010_RTC_DAYS);
rtc->rtc_dev->range_min = (u64)days * 86400 + hour * 3600 +
min * 60 + sec;
rtc->rtc_dev->range_max = U32_MAX + rtc->rtc_dev->range_min;
ret = devm_request_irq(dev, rtc->rtc_irq, ftrtc010_rtc_interrupt, ret = devm_request_irq(dev, rtc->rtc_irq, ftrtc010_rtc_interrupt,
IRQF_SHARED, pdev->name, dev); IRQF_SHARED, pdev->name, dev);
if (unlikely(ret)) if (unlikely(ret))
return ret; return ret;
rtc->rtc_dev = rtc_device_register(pdev->name, dev, return rtc_register_device(rtc->rtc_dev);
&ftrtc010_rtc_ops, THIS_MODULE);
return PTR_ERR_OR_ZERO(rtc->rtc_dev);
} }
static int ftrtc010_rtc_remove(struct platform_device *pdev) static int ftrtc010_rtc_remove(struct platform_device *pdev)
@@ -184,7 +195,6 @@ static int ftrtc010_rtc_remove(struct platform_device *pdev)
clk_disable_unprepare(rtc->extclk); clk_disable_unprepare(rtc->extclk);
if (!IS_ERR(rtc->pclk)) if (!IS_ERR(rtc->pclk))
clk_disable_unprepare(rtc->pclk); clk_disable_unprepare(rtc->pclk);
rtc_device_unregister(rtc->rtc_dev);
return 0; return 0;
} }
+6 -10
View File
@@ -294,11 +294,10 @@ static int lpc32xx_rtc_remove(struct platform_device *pdev)
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int lpc32xx_rtc_suspend(struct device *dev) static int lpc32xx_rtc_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
if (rtc->irq >= 0) { if (rtc->irq >= 0) {
if (device_may_wakeup(&pdev->dev)) if (device_may_wakeup(dev))
enable_irq_wake(rtc->irq); enable_irq_wake(rtc->irq);
else else
disable_irq_wake(rtc->irq); disable_irq_wake(rtc->irq);
@@ -309,10 +308,9 @@ static int lpc32xx_rtc_suspend(struct device *dev)
static int lpc32xx_rtc_resume(struct device *dev) static int lpc32xx_rtc_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
if (rtc->irq >= 0 && device_may_wakeup(&pdev->dev)) if (rtc->irq >= 0 && device_may_wakeup(dev))
disable_irq_wake(rtc->irq); disable_irq_wake(rtc->irq);
return 0; return 0;
@@ -321,8 +319,7 @@ static int lpc32xx_rtc_resume(struct device *dev)
/* Unconditionally disable the alarm */ /* Unconditionally disable the alarm */
static int lpc32xx_rtc_freeze(struct device *dev) static int lpc32xx_rtc_freeze(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
spin_lock_irq(&rtc->lock); spin_lock_irq(&rtc->lock);
@@ -337,8 +334,7 @@ static int lpc32xx_rtc_freeze(struct device *dev)
static int lpc32xx_rtc_thaw(struct device *dev) static int lpc32xx_rtc_thaw(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
if (rtc->alarm_enabled) { if (rtc->alarm_enabled) {
spin_lock_irq(&rtc->lock); spin_lock_irq(&rtc->lock);

Some files were not shown because too many files have changed in this diff Show More