You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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:
@@ -9,7 +9,7 @@ Optional properties:
|
||||
|
||||
Example:
|
||||
|
||||
rtc: nxp,rtc-pcf2123@3 {
|
||||
pcf2123: rtc@3 {
|
||||
compatible = "nxp,rtc-pcf2123"
|
||||
reg = <3>
|
||||
spi-cs-high;
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
+1
-1
@@ -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 */
|
||||
|
||||
+17
-41
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+105
-12
@@ -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,8 +337,14 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)
|
||||
|
||||
rtc_control |= mask;
|
||||
CMOS_WRITE(rtc_control, RTC_CONTROL);
|
||||
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,8 +355,14 @@ 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);
|
||||
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
|
||||
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);
|
||||
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,6 +668,7 @@ 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);
|
||||
if (use_hpet_alarm())
|
||||
hpet_mask_rtc_irq_bit(RTC_AIE);
|
||||
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.
|
||||
*/
|
||||
cmos_rtc.rtc->irq_freq = 1024;
|
||||
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;
|
||||
}
|
||||
|
||||
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,6 +896,7 @@ static void cmos_do_remove(struct device *dev)
|
||||
|
||||
if (is_valid_irq(cmos->irq)) {
|
||||
free_irq(cmos->irq, cmos->rtc);
|
||||
if (use_hpet_alarm())
|
||||
hpet_unregister_irq_handler(cmos_interrupt);
|
||||
}
|
||||
|
||||
@@ -935,13 +974,13 @@ static int cmos_suspend(struct device *dev)
|
||||
mask = RTC_IRQMASK;
|
||||
tmp &= ~mask;
|
||||
CMOS_WRITE(tmp, RTC_CONTROL);
|
||||
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, ¤t_alarm);
|
||||
t_current_expires = rtc_tm_to_time64(¤t_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);
|
||||
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,6 +1126,16 @@ static u32 rtc_handler(void *context)
|
||||
unsigned char rtc_intr;
|
||||
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);
|
||||
if (cmos_rtc.suspend_ctrl)
|
||||
rtc_control = CMOS_READ(RTC_CONTROL);
|
||||
@@ -1078,6 +1146,7 @@ static u32 rtc_handler(void *context)
|
||||
rtc_update_irq(cmos->rtc, 1, rtc_intr);
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+29
-37
@@ -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) &
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
+23
-13
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user