From 8aec4b875008b98349222f3fbe8b86051d0fab4f Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Thu, 9 May 2019 04:13:55 +0200 Subject: rtc: ds2404: use hw endiannes variable Converting from hardware to host endiannes was done using reassignment to the same variable which makes sparse unhappy as it can not verify the endiannes handling properly. To allow sparse to verify endiannes handling an explicit __le32 is introduced. Note that this patch does not change the generated binary (x86_64 and ppc64 binary diff). Signed-off-by: Nicholas Mc Guire Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds2404.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c index 1e9f429ada64..9df0c44512b8 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c @@ -182,9 +182,10 @@ static void ds2404_enable_osc(struct device *dev) static int ds2404_read_time(struct device *dev, struct rtc_time *dt) { unsigned long time = 0; + __le32 hw_time = 0; - ds2404_read_memory(dev, 0x203, 4, (u8 *)&time); - time = le32_to_cpu(time); + ds2404_read_memory(dev, 0x203, 4, (u8 *)&hw_time); + time = le32_to_cpu(hw_time); rtc_time64_to_tm(time, dt); return 0; -- cgit v1.2.3-59-g8ed1b From c19623db3766c5710c3032ab0b1ff98c4935a58a Mon Sep 17 00:00:00 2001 From: Roman Stratiienko Date: Wed, 15 May 2019 17:20:22 +0300 Subject: rtc: test: enable wakeup flags Alarmtimer interface uses only the RTC with wekeup flags enabled. Allow to use rtc-test driver with alarmtimer interface. Signed-off-by: Roman Stratiienko Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-test.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index b298e9902f45..74b3a0603b73 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c @@ -133,6 +133,7 @@ static int test_probe(struct platform_device *plat_dev) break; default: rtd->rtc->ops = &test_rtc_ops; + device_init_wakeup(&plat_dev->dev, 1); } timer_setup(&rtd->alarm, test_rtc_alarm_handler, 0); -- cgit v1.2.3-59-g8ed1b From a86bd9044b33ae60571de2759b3803f530bccb68 Mon Sep 17 00:00:00 2001 From: Richard Leitner Date: Thu, 23 May 2019 13:54:48 +0200 Subject: rtc: s35390a: clarify INT2 pin output modes Fix the INT2 mode mask to not include the "TEST" flag. Furthermore remove the not needed reversion of bits when parsing the INT2 modes. Instead reverse the INT2_MODE defines to match the bit order from the datasheet. Additionally mention the flag names from the datasheet for the different modes in the comments. Signed-off-by: Richard Leitner Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 3c64dbb08109..fb795c454077 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -45,12 +45,13 @@ /* flag for STATUS2 */ #define S35390A_FLAG_TEST 0x01 -#define S35390A_INT2_MODE_MASK 0xF0 - +/* INT2 pin output mode */ +#define S35390A_INT2_MODE_MASK 0x0E #define S35390A_INT2_MODE_NOINTR 0x00 -#define S35390A_INT2_MODE_FREQ 0x10 -#define S35390A_INT2_MODE_ALARM 0x40 -#define S35390A_INT2_MODE_PMIN_EDG 0x20 +#define S35390A_INT2_MODE_ALARM BIT(1) /* INT2AE */ +#define S35390A_INT2_MODE_PMIN_EDG BIT(2) /* INT2ME */ +#define S35390A_INT2_MODE_FREQ BIT(3) /* INT2FE */ +#define S35390A_INT2_MODE_PMIN (BIT(3) | BIT(2)) /* INT2FE | INT2ME */ static const struct i2c_device_id s35390a_id[] = { { "s35390a", 0 }, @@ -303,9 +304,6 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) else sts = S35390A_INT2_MODE_NOINTR; - /* This chip expects the bits of each byte to be in reverse order */ - sts = bitrev8(sts); - /* set interupt mode*/ err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); if (err < 0) @@ -343,7 +341,7 @@ static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) if (err < 0) return err; - if ((bitrev8(sts) & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) { + if ((sts & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) { /* * When the alarm isn't enabled, the register to configure * the alarm time isn't accessible. -- cgit v1.2.3-59-g8ed1b From c0e12848be091e8410fb427f080f2e0149123443 Mon Sep 17 00:00:00 2001 From: Richard Leitner Date: Thu, 23 May 2019 13:54:49 +0200 Subject: rtc: s35390a: set uie_unsupported Alarms are only supported on a per minute basis. This is why uie_unsupported is set. Furthermore issue a warning when a second based alarm is requested. Signed-off-by: Richard Leitner Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index fb795c454077..4ca37f281ed9 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -289,6 +289,9 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday, alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday); + if (alm->time.tm_sec != 0) + dev_warn(&client->dev, "Alarms are only supported on a per minute basis!\n"); + /* disable interrupt (which deasserts the irq line) */ err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); if (err < 0) @@ -500,6 +503,9 @@ static int s35390a_probe(struct i2c_client *client, goto exit_dummy; } + /* supports per-minute alarms only, therefore set uie_unsupported */ + s35390a->rtc->uie_unsupported = 1; + if (status1 & S35390A_FLAG_INT2) rtc_update_irq(s35390a->rtc, 1, RTC_AF); -- cgit v1.2.3-59-g8ed1b From 0327963440926094731571562f6089bfa5a13610 Mon Sep 17 00:00:00 2001 From: Richard Leitner Date: Thu, 23 May 2019 13:54:50 +0200 Subject: rtc: s35390a: introduce struct device in probe To simplify access and shorten code introduce a struct device pointer in the s35390a probe function. Signed-off-by: Richard Leitner Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 4ca37f281ed9..7293dcdea692 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -436,14 +436,14 @@ static int s35390a_probe(struct i2c_client *client, unsigned int i; struct s35390a *s35390a; char buf, status1; + struct device *dev = &client->dev; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { err = -ENODEV; goto exit; } - s35390a = devm_kzalloc(&client->dev, sizeof(struct s35390a), - GFP_KERNEL); + s35390a = devm_kzalloc(dev, sizeof(struct s35390a), GFP_KERNEL); if (!s35390a) { err = -ENOMEM; goto exit; @@ -457,8 +457,8 @@ static int s35390a_probe(struct i2c_client *client, s35390a->client[i] = i2c_new_dummy(client->adapter, client->addr + i); if (!s35390a->client[i]) { - dev_err(&client->dev, "Address %02x unavailable\n", - client->addr + i); + dev_err(dev, "Address %02x unavailable\n", + client->addr + i); err = -EBUSY; goto exit_dummy; } @@ -467,7 +467,7 @@ static int s35390a_probe(struct i2c_client *client, err_read = s35390a_read_status(s35390a, &status1); if (err_read < 0) { err = err_read; - dev_err(&client->dev, "error resetting chip\n"); + dev_err(dev, "error resetting chip\n"); goto exit_dummy; } @@ -481,22 +481,21 @@ static int s35390a_probe(struct i2c_client *client, buf = 0; err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1); if (err < 0) { - dev_err(&client->dev, "error disabling alarm"); + dev_err(dev, "error disabling alarm"); goto exit_dummy; } } else { err = s35390a_disable_test_mode(s35390a); if (err < 0) { - dev_err(&client->dev, "error disabling test mode\n"); + dev_err(dev, "error disabling test mode\n"); goto exit_dummy; } } - device_set_wakeup_capable(&client->dev, 1); + device_set_wakeup_capable(dev, 1); - s35390a->rtc = devm_rtc_device_register(&client->dev, - s35390a_driver.driver.name, - &s35390a_rtc_ops, THIS_MODULE); + s35390a->rtc = devm_rtc_device_register(dev, s35390a_driver.driver.name, + &s35390a_rtc_ops, THIS_MODULE); if (IS_ERR(s35390a->rtc)) { err = PTR_ERR(s35390a->rtc); -- cgit v1.2.3-59-g8ed1b From 097aa24b5db09a852516c467f2cd62e8adfd6bba Mon Sep 17 00:00:00 2001 From: Richard Leitner Date: Thu, 23 May 2019 13:54:51 +0200 Subject: rtc: s35390a: change FLAG defines to use BIT macro To be consistent change the S35390A_FLAG defines to use the BIT macro (like the S35390A_INT2_MODE defines). Signed-off-by: Richard Leitner Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 7293dcdea692..b18ce5610a94 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -36,14 +36,14 @@ #define S35390A_ALRM_BYTE_MINS 2 /* flags for STATUS1 */ -#define S35390A_FLAG_POC 0x01 -#define S35390A_FLAG_BLD 0x02 -#define S35390A_FLAG_INT2 0x04 -#define S35390A_FLAG_24H 0x40 -#define S35390A_FLAG_RESET 0x80 +#define S35390A_FLAG_POC BIT(0) +#define S35390A_FLAG_BLD BIT(1) +#define S35390A_FLAG_INT2 BIT(2) +#define S35390A_FLAG_24H BIT(6) +#define S35390A_FLAG_RESET BIT(7) /* flag for STATUS2 */ -#define S35390A_FLAG_TEST 0x01 +#define S35390A_FLAG_TEST BIT(0) /* INT2 pin output mode */ #define S35390A_INT2_MODE_MASK 0x0E -- cgit v1.2.3-59-g8ed1b From b3a50169762b14102a296a410d785f9ec1132ae1 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 11 Apr 2019 00:16:29 +0200 Subject: rtc: ds1307: properly handle oscillator failure flags Stop enabling the oscillator and removing the oscillator failure flags in probe. Instead, return -EINVAL in .read_time when the oscillaotr is not start or when it failed at some point. The oscillator gets enabled on the first .set_time after failure and the failure flags are cleared. This also removes the possibility of an infinite loop at probe where a failing RTC will make the goto read_rtc to be taken every time. Tested on mcp79411. Reported-by: Mastro Gippo Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 129 +++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 71 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 07530fe1da2a..7f8b236c935c 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -225,6 +225,45 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) return -EINVAL; } + tmp = regs[DS1307_REG_SECS]; + switch (ds1307->type) { + case ds_1307: + case m41t0: + case m41t00: + case m41t11: + if (tmp & DS1307_BIT_CH) + return -EINVAL; + break; + case ds_1308: + case ds_1338: + if (tmp & DS1307_BIT_CH) + return -EINVAL; + + ret = regmap_read(ds1307->regmap, DS1307_REG_CONTROL, &tmp); + if (ret) + return ret; + if (tmp & DS1338_BIT_OSF) + return -EINVAL; + break; + case ds_1340: + if (tmp & DS1340_BIT_nEOSC) + return -EINVAL; + + ret = regmap_read(ds1307->regmap, DS1340_REG_FLAG, &tmp); + if (ret) + return ret; + if (tmp & DS1340_BIT_OSF) + return -EINVAL; + break; + case mcp794xx: + if (!(tmp & MCP794XX_BIT_ST)) + return -EINVAL; + + break; + default: + break; + } + t->tm_sec = bcd2bin(regs[DS1307_REG_SECS] & 0x7f); t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f); tmp = regs[DS1307_REG_HOUR] & 0x3f; @@ -289,7 +328,17 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) if (t->tm_year > 199 && chip->century_bit) regs[chip->century_reg] |= chip->century_bit; - if (ds1307->type == mcp794xx) { + switch (ds1307->type) { + case ds_1308: + case ds_1338: + regmap_update_bits(ds1307->regmap, DS1307_REG_CONTROL, + DS1338_BIT_OSF, 0); + break; + case ds_1340: + regmap_update_bits(ds1307->regmap, DS1340_REG_FLAG, + DS1340_BIT_OSF, 0); + break; + case mcp794xx: /* * these bits were cleared when preparing the date/time * values and need to be set again before writing the @@ -297,6 +346,9 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) */ regs[DS1307_REG_SECS] |= MCP794XX_BIT_ST; regs[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN; + break; + default: + break; } dev_dbg(dev, "%s: %7ph\n", "write", regs); @@ -1705,7 +1757,6 @@ static int ds1307_probe(struct i2c_client *client, break; } -read_rtc: /* read RTC registers */ err = regmap_bulk_read(ds1307->regmap, chip->offset, regs, sizeof(regs)); @@ -1714,75 +1765,11 @@ read_rtc: goto exit; } - /* - * minimal sanity checking; some chips (like DS1340) don't - * specify the extra bits as must-be-zero, but there are - * still a few values that are clearly out-of-range. - */ - tmp = regs[DS1307_REG_SECS]; - switch (ds1307->type) { - case ds_1307: - case m41t0: - case m41t00: - case m41t11: - /* clock halted? turn it on, so clock can tick. */ - if (tmp & DS1307_BIT_CH) { - regmap_write(ds1307->regmap, DS1307_REG_SECS, 0); - dev_warn(ds1307->dev, "SET TIME!\n"); - goto read_rtc; - } - break; - case ds_1308: - case ds_1338: - /* clock halted? turn it on, so clock can tick. */ - if (tmp & DS1307_BIT_CH) - regmap_write(ds1307->regmap, DS1307_REG_SECS, 0); - - /* oscillator fault? clear flag, and warn */ - if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) { - regmap_write(ds1307->regmap, DS1307_REG_CONTROL, - regs[DS1307_REG_CONTROL] & - ~DS1338_BIT_OSF); - dev_warn(ds1307->dev, "SET TIME!\n"); - goto read_rtc; - } - break; - case ds_1340: - /* clock halted? turn it on, so clock can tick. */ - if (tmp & DS1340_BIT_nEOSC) - regmap_write(ds1307->regmap, DS1307_REG_SECS, 0); - - err = regmap_read(ds1307->regmap, DS1340_REG_FLAG, &tmp); - if (err) { - dev_dbg(ds1307->dev, "read error %d\n", err); - goto exit; - } - - /* oscillator fault? clear flag, and warn */ - if (tmp & DS1340_BIT_OSF) { - regmap_write(ds1307->regmap, DS1340_REG_FLAG, 0); - dev_warn(ds1307->dev, "SET TIME!\n"); - } - break; - case mcp794xx: - /* make sure that the backup battery is enabled */ - if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) { - regmap_write(ds1307->regmap, DS1307_REG_WDAY, - regs[DS1307_REG_WDAY] | - MCP794XX_BIT_VBATEN); - } - - /* clock halted? turn it on, so clock can tick. */ - if (!(tmp & MCP794XX_BIT_ST)) { - regmap_write(ds1307->regmap, DS1307_REG_SECS, - MCP794XX_BIT_ST); - dev_warn(ds1307->dev, "SET TIME!\n"); - goto read_rtc; - } - - break; - default: - break; + if (ds1307->type == mcp794xx && + !(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) { + regmap_write(ds1307->regmap, DS1307_REG_WDAY, + regs[DS1307_REG_WDAY] | + MCP794XX_BIT_VBATEN); } tmp = regs[DS1307_REG_HOUR]; -- cgit v1.2.3-59-g8ed1b From d2bc4cece13967e3e654a872a8f081ae4bf75911 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 30 Apr 2019 22:18:34 +0200 Subject: rtc: st-lpc: remove unnecessary check The RTC core already ensures the alarm is set to a time in the future, it is not necessary to check again in the driver. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-st-lpc.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c index bee75ca7ff79..ce2dae6e2a24 100644 --- a/drivers/rtc/rtc-st-lpc.c +++ b/drivers/rtc/rtc-st-lpc.c @@ -166,10 +166,6 @@ static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) now_secs = rtc_tm_to_time64(&now); alarm_secs = rtc_tm_to_time64(&t->time); - /* Invalid alarm time */ - if (now_secs > alarm_secs) - return -EINVAL; - memcpy(&rtc->alarm, t, sizeof(struct rtc_wkalrm)); /* Now many secs to fire */ -- cgit v1.2.3-59-g8ed1b From a2d29238bc6005511d5bef0b9c9ddd935b18251b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 27 May 2019 12:13:57 +0200 Subject: rtc: tegra: checkpatch and miscellaneous cleanups This set of changes fixes some checkpatch warnings as well as a number of punctuation and padding inconsistencies. Signed-off-by: Thierry Reding Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tegra.c | 154 +++++++++++++++++++++++++----------------------- 1 file changed, 79 insertions(+), 75 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index f0ce76865434..a67c9d8be4f6 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -18,10 +18,10 @@ #include #include -/* set to 1 = busy every eight 32kHz clocks during copy of sec+msec to AHB */ +/* Set to 1 = busy every eight 32 kHz clocks during copy of sec+msec to AHB. */ #define TEGRA_RTC_REG_BUSY 0x004 #define TEGRA_RTC_REG_SECONDS 0x008 -/* when msec is read, the seconds are buffered into shadow seconds. */ +/* When msec is read, the seconds are buffered into shadow seconds. */ #define TEGRA_RTC_REG_SHADOW_SECONDS 0x00c #define TEGRA_RTC_REG_MILLI_SECONDS 0x010 #define TEGRA_RTC_REG_SECONDS_ALARM0 0x014 @@ -46,44 +46,48 @@ #define TEGRA_RTC_INTR_STATUS_SEC_ALARM0 (1<<0) struct tegra_rtc_info { - struct platform_device *pdev; - struct rtc_device *rtc_dev; - void __iomem *rtc_base; /* NULL if not initialized. */ - struct clk *clk; - int tegra_rtc_irq; /* alarm and periodic irq */ - spinlock_t tegra_rtc_lock; + struct platform_device *pdev; + struct rtc_device *rtc_dev; + void __iomem *rtc_base; /* NULL if not initialized */ + struct clk *clk; + int tegra_rtc_irq; /* alarm and periodic IRQ */ + spinlock_t tegra_rtc_lock; }; -/* RTC hardware is busy when it is updating its values over AHB once - * every eight 32kHz clocks (~250uS). - * outside of these updates the CPU is free to write. - * CPU is always free to read. +/* + * RTC hardware is busy when it is updating its values over AHB once every + * eight 32 kHz clocks (~250 us). Outside of these updates the CPU is free to + * write. CPU is always free to read. */ static inline u32 tegra_rtc_check_busy(struct tegra_rtc_info *info) { return readl(info->rtc_base + TEGRA_RTC_REG_BUSY) & 1; } -/* Wait for hardware to be ready for writing. - * This function tries to maximize the amount of time before the next update. - * It does this by waiting for the RTC to become busy with its periodic update, - * then returning once the RTC first becomes not busy. +/* + * Wait for hardware to be ready for writing. This function tries to maximize + * the amount of time before the next update. It does this by waiting for the + * RTC to become busy with its periodic update, then returning once the RTC + * first becomes not busy. + * * This periodic update (where the seconds and milliseconds are copied to the - * AHB side) occurs every eight 32kHz clocks (~250uS). - * The behavior of this function allows us to make some assumptions without - * introducing a race, because 250uS is plenty of time to read/write a value. + * AHB side) occurs every eight 32 kHz clocks (~250 us). The behavior of this + * function allows us to make some assumptions without introducing a race, + * because 250 us is plenty of time to read/write a value. */ static int tegra_rtc_wait_while_busy(struct device *dev) { struct tegra_rtc_info *info = dev_get_drvdata(dev); + int retries = 500; /* ~490 us is the worst case, ~250 us is best */ - int retries = 500; /* ~490 us is the worst case, ~250 us is best. */ - - /* first wait for the RTC to become busy. this is when it - * posts its updated seconds+msec registers to AHB side. */ + /* + * First wait for the RTC to become busy. This is when it posts its + * updated seconds+msec registers to AHB side. + */ while (tegra_rtc_check_busy(info)) { if (!retries--) goto retry_failed; + udelay(1); } @@ -91,7 +95,7 @@ static int tegra_rtc_wait_while_busy(struct device *dev) return 0; retry_failed: - dev_err(dev, "write failed:retry count exceeded.\n"); + dev_err(dev, "write failed: retry count exceeded\n"); return -ETIMEDOUT; } @@ -101,8 +105,10 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm) unsigned long sec, msec; unsigned long sl_irq_flags; - /* RTC hardware copies seconds to shadow seconds when a read - * of milliseconds occurs. use a lock to keep other threads out. */ + /* + * RTC hardware copies seconds to shadow seconds when a read of + * milliseconds occurs. use a lock to keep other threads out. + */ spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags); msec = readl(info->rtc_base + TEGRA_RTC_REG_MILLI_SECONDS); @@ -112,7 +118,7 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm) rtc_time64_to_tm(sec, tm); - dev_vdbg(dev, "time read as %lu. %ptR\n", sec, tm); + dev_vdbg(dev, "time read as %u, %ptR\n", sec, tm); return 0; } @@ -123,18 +129,18 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) unsigned long sec; int ret; - /* convert tm to seconds. */ + /* convert tm to seconds */ sec = rtc_tm_to_time64(tm); - dev_vdbg(dev, "time set to %lu. %ptR\n", sec, tm); + dev_vdbg(dev, "time set to %u, %ptR\n", sec, tm); - /* seconds only written if wait succeeded. */ + /* seconds only written if wait succeeded */ ret = tegra_rtc_wait_while_busy(dev); if (!ret) writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS); dev_vdbg(dev, "time read back as %d\n", - readl(info->rtc_base + TEGRA_RTC_REG_SECONDS)); + readl(info->rtc_base + TEGRA_RTC_REG_SECONDS)); return ret; } @@ -143,15 +149,15 @@ static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct tegra_rtc_info *info = dev_get_drvdata(dev); unsigned long sec; - unsigned tmp; + unsigned int tmp; sec = readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0); if (sec == 0) { - /* alarm is disabled. */ + /* alarm is disabled */ alarm->enabled = 0; } else { - /* alarm is enabled. */ + /* alarm is enabled */ alarm->enabled = 1; rtc_time64_to_tm(sec, &alarm->time); } @@ -165,13 +171,13 @@ static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int tegra_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct tegra_rtc_info *info = dev_get_drvdata(dev); - unsigned status; unsigned long sl_irq_flags; + unsigned int status; tegra_rtc_wait_while_busy(dev); spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags); - /* read the original value, and OR in the flag. */ + /* read the original value, and OR in the flag */ status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_MASK); if (enabled) status |= TEGRA_RTC_INTR_MASK_SEC_ALARM0; /* set it */ @@ -198,14 +204,14 @@ static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) tegra_rtc_wait_while_busy(dev); writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0); dev_vdbg(dev, "alarm read back as %d\n", - readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0)); + readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0)); /* if successfully written and alarm is enabled ... */ if (sec) { tegra_rtc_alarm_irq_enable(dev, 1); - dev_vdbg(dev, "alarm set as %lu. %ptR\n", sec, &alarm->time); + dev_vdbg(dev, "alarm set as %u, %ptR\n", sec, &alarm->time); } else { - /* disable alarm if 0 or write error. */ + /* disable alarm if 0 or write error */ dev_vdbg(dev, "alarm disabled\n"); tegra_rtc_alarm_irq_enable(dev, 0); } @@ -228,25 +234,26 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data) struct device *dev = data; struct tegra_rtc_info *info = dev_get_drvdata(dev); unsigned long events = 0; - unsigned status; unsigned long sl_irq_flags; + unsigned int status; status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); if (status) { - /* clear the interrupt masks and status on any irq. */ + /* clear the interrupt masks and status on any IRQ */ tegra_rtc_wait_while_busy(dev); + spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags); writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK); writel(status, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags); } - /* check if Alarm */ - if ((status & TEGRA_RTC_INTR_STATUS_SEC_ALARM0)) + /* check if alarm */ + if (status & TEGRA_RTC_INTR_STATUS_SEC_ALARM0) events |= RTC_IRQF | RTC_AF; - /* check if Periodic */ - if ((status & TEGRA_RTC_INTR_STATUS_SEC_CDN_ALARM)) + /* check if periodic */ + if (status & TEGRA_RTC_INTR_STATUS_SEC_CDN_ALARM) events |= RTC_IRQF | RTC_PF; rtc_update_irq(info->rtc_dev, 1, events); @@ -255,11 +262,11 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data) } static const struct rtc_class_ops tegra_rtc_ops = { - .read_time = tegra_rtc_read_time, - .set_time = tegra_rtc_set_time, - .read_alarm = tegra_rtc_read_alarm, - .set_alarm = tegra_rtc_set_alarm, - .proc = tegra_rtc_proc, + .read_time = tegra_rtc_read_time, + .set_time = tegra_rtc_set_time, + .read_alarm = tegra_rtc_read_alarm, + .set_alarm = tegra_rtc_set_alarm, + .proc = tegra_rtc_proc, .alarm_irq_enable = tegra_rtc_alarm_irq_enable, }; @@ -275,8 +282,7 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) struct resource *res; int ret; - info = devm_kzalloc(&pdev->dev, sizeof(struct tegra_rtc_info), - GFP_KERNEL); + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; @@ -308,13 +314,13 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) if (ret < 0) return ret; - /* set context info. */ + /* set context info */ info->pdev = pdev; spin_lock_init(&info->tegra_rtc_lock); platform_set_drvdata(pdev, info); - /* clear out the hardware. */ + /* clear out the hardware */ writel(0, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0); writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK); @@ -322,19 +328,16 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq, - tegra_rtc_irq_handler, IRQF_TRIGGER_HIGH, - dev_name(&pdev->dev), &pdev->dev); + tegra_rtc_irq_handler, IRQF_TRIGGER_HIGH, + dev_name(&pdev->dev), &pdev->dev); if (ret) { - dev_err(&pdev->dev, - "Unable to request interrupt for device (err=%d).\n", - ret); + dev_err(&pdev->dev, "failed to request interrupt: %d\n", ret); goto disable_clk; } ret = rtc_register_device(info->rtc_dev); if (ret) { - dev_err(&pdev->dev, "Unable to register device (err=%d).\n", - ret); + dev_err(&pdev->dev, "failed to register device: %d\n", ret); goto disable_clk; } @@ -363,18 +366,18 @@ static int tegra_rtc_suspend(struct device *dev) tegra_rtc_wait_while_busy(dev); - /* only use ALARM0 as a wake source. */ + /* only use ALARM0 as a wake source */ writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); writel(TEGRA_RTC_INTR_STATUS_SEC_ALARM0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK); dev_vdbg(dev, "alarm sec = %d\n", - readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0)); + readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0)); - dev_vdbg(dev, "Suspend (device_may_wakeup=%d) irq:%d\n", - device_may_wakeup(dev), info->tegra_rtc_irq); + dev_vdbg(dev, "Suspend (device_may_wakeup=%d) IRQ:%d\n", + device_may_wakeup(dev), info->tegra_rtc_irq); - /* leave the alarms on as a wake source. */ + /* leave the alarms on as a wake source */ if (device_may_wakeup(dev)) enable_irq_wake(info->tegra_rtc_irq); @@ -386,8 +389,9 @@ static int tegra_rtc_resume(struct device *dev) struct tegra_rtc_info *info = dev_get_drvdata(dev); dev_vdbg(dev, "Resume (device_may_wakeup=%d)\n", - device_may_wakeup(dev)); - /* alarms were left on as a wake source, turn them off. */ + device_may_wakeup(dev)); + + /* alarms were left on as a wake source, turn them off */ if (device_may_wakeup(dev)) disable_irq_wake(info->tegra_rtc_irq); @@ -399,18 +403,17 @@ static SIMPLE_DEV_PM_OPS(tegra_rtc_pm_ops, tegra_rtc_suspend, tegra_rtc_resume); static void tegra_rtc_shutdown(struct platform_device *pdev) { - dev_vdbg(&pdev->dev, "disabling interrupts.\n"); + dev_vdbg(&pdev->dev, "disabling interrupts\n"); tegra_rtc_alarm_irq_enable(&pdev->dev, 0); } -MODULE_ALIAS("platform:tegra_rtc"); static struct platform_driver tegra_rtc_driver = { - .remove = tegra_rtc_remove, - .shutdown = tegra_rtc_shutdown, - .driver = { - .name = "tegra_rtc", + .remove = tegra_rtc_remove, + .shutdown = tegra_rtc_shutdown, + .driver = { + .name = "tegra_rtc", .of_match_table = tegra_rtc_dt_match, - .pm = &tegra_rtc_pm_ops, + .pm = &tegra_rtc_pm_ops, }, }; @@ -418,4 +421,5 @@ module_platform_driver_probe(tegra_rtc_driver, tegra_rtc_probe); MODULE_AUTHOR("Jon Mayo "); MODULE_DESCRIPTION("driver for Tegra internal RTC"); +MODULE_ALIAS("platform:tegra_rtc"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From c6af561a4ad0971c79faee397fa02fa085018fa3 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 27 May 2019 12:13:58 +0200 Subject: rtc: tegra: Use consistent variable names and types Many of the variables have redundant prefixes or suffixes. Drop all of them where not necessary for context. Also make sure to use data types consistently. For instance, values read from 32-bit register accessors should be stored in u32. Signed-off-by: Thierry Reding Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tegra.c | 118 ++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 60 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index a67c9d8be4f6..b68ba2dd1d36 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -47,11 +47,11 @@ struct tegra_rtc_info { struct platform_device *pdev; - struct rtc_device *rtc_dev; - void __iomem *rtc_base; /* NULL if not initialized */ + struct rtc_device *rtc; + void __iomem *base; /* NULL if not initialized */ struct clk *clk; - int tegra_rtc_irq; /* alarm and periodic IRQ */ - spinlock_t tegra_rtc_lock; + int irq; /* alarm and periodic IRQ */ + spinlock_t lock; }; /* @@ -61,7 +61,7 @@ struct tegra_rtc_info { */ static inline u32 tegra_rtc_check_busy(struct tegra_rtc_info *info) { - return readl(info->rtc_base + TEGRA_RTC_REG_BUSY) & 1; + return readl(info->base + TEGRA_RTC_REG_BUSY) & 1; } /* @@ -102,19 +102,19 @@ retry_failed: static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct tegra_rtc_info *info = dev_get_drvdata(dev); - unsigned long sec, msec; - unsigned long sl_irq_flags; + unsigned long flags; + u32 sec, msec; /* * RTC hardware copies seconds to shadow seconds when a read of * milliseconds occurs. use a lock to keep other threads out. */ - spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags); + spin_lock_irqsave(&info->lock, flags); - msec = readl(info->rtc_base + TEGRA_RTC_REG_MILLI_SECONDS); - sec = readl(info->rtc_base + TEGRA_RTC_REG_SHADOW_SECONDS); + msec = readl(info->base + TEGRA_RTC_REG_MILLI_SECONDS); + sec = readl(info->base + TEGRA_RTC_REG_SHADOW_SECONDS); - spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags); + spin_unlock_irqrestore(&info->lock, flags); rtc_time64_to_tm(sec, tm); @@ -126,7 +126,7 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm) static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct tegra_rtc_info *info = dev_get_drvdata(dev); - unsigned long sec; + u32 sec; int ret; /* convert tm to seconds */ @@ -137,10 +137,10 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) /* seconds only written if wait succeeded */ ret = tegra_rtc_wait_while_busy(dev); if (!ret) - writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS); + writel(sec, info->base + TEGRA_RTC_REG_SECONDS); dev_vdbg(dev, "time read back as %d\n", - readl(info->rtc_base + TEGRA_RTC_REG_SECONDS)); + readl(info->base + TEGRA_RTC_REG_SECONDS)); return ret; } @@ -148,10 +148,9 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct tegra_rtc_info *info = dev_get_drvdata(dev); - unsigned long sec; - unsigned int tmp; + u32 sec, value; - sec = readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0); + sec = readl(info->base + TEGRA_RTC_REG_SECONDS_ALARM0); if (sec == 0) { /* alarm is disabled */ @@ -162,8 +161,8 @@ static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) rtc_time64_to_tm(sec, &alarm->time); } - tmp = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); - alarm->pending = (tmp & TEGRA_RTC_INTR_STATUS_SEC_ALARM0) != 0; + value = readl(info->base + TEGRA_RTC_REG_INTR_STATUS); + alarm->pending = (value & TEGRA_RTC_INTR_STATUS_SEC_ALARM0) != 0; return 0; } @@ -171,22 +170,22 @@ static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int tegra_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct tegra_rtc_info *info = dev_get_drvdata(dev); - unsigned long sl_irq_flags; - unsigned int status; + unsigned long flags; + u32 status; tegra_rtc_wait_while_busy(dev); - spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags); + spin_lock_irqsave(&info->lock, flags); /* read the original value, and OR in the flag */ - status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_MASK); + status = readl(info->base + TEGRA_RTC_REG_INTR_MASK); if (enabled) status |= TEGRA_RTC_INTR_MASK_SEC_ALARM0; /* set it */ else status &= ~TEGRA_RTC_INTR_MASK_SEC_ALARM0; /* clear it */ - writel(status, info->rtc_base + TEGRA_RTC_REG_INTR_MASK); + writel(status, info->base + TEGRA_RTC_REG_INTR_MASK); - spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags); + spin_unlock_irqrestore(&info->lock, flags); return 0; } @@ -194,7 +193,7 @@ static int tegra_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct tegra_rtc_info *info = dev_get_drvdata(dev); - unsigned long sec; + u32 sec; if (alarm->enabled) sec = rtc_tm_to_time64(&alarm->time); @@ -202,9 +201,9 @@ static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) sec = 0; tegra_rtc_wait_while_busy(dev); - writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0); + writel(sec, info->base + TEGRA_RTC_REG_SECONDS_ALARM0); dev_vdbg(dev, "alarm read back as %d\n", - readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0)); + readl(info->base + TEGRA_RTC_REG_SECONDS_ALARM0)); /* if successfully written and alarm is enabled ... */ if (sec) { @@ -233,19 +232,18 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data) { struct device *dev = data; struct tegra_rtc_info *info = dev_get_drvdata(dev); - unsigned long events = 0; - unsigned long sl_irq_flags; - unsigned int status; + unsigned long events = 0, flags; + u32 status; - status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); + status = readl(info->base + TEGRA_RTC_REG_INTR_STATUS); if (status) { /* clear the interrupt masks and status on any IRQ */ tegra_rtc_wait_while_busy(dev); - spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags); - writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK); - writel(status, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); - spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags); + spin_lock_irqsave(&info->lock, flags); + writel(0, info->base + TEGRA_RTC_REG_INTR_MASK); + writel(status, info->base + TEGRA_RTC_REG_INTR_STATUS); + spin_unlock_irqrestore(&info->lock, flags); } /* check if alarm */ @@ -256,7 +254,7 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data) if (status & TEGRA_RTC_INTR_STATUS_SEC_CDN_ALARM) events |= RTC_IRQF | RTC_PF; - rtc_update_irq(info->rtc_dev, 1, events); + rtc_update_irq(info->rtc, 1, events); return IRQ_HANDLED; } @@ -287,9 +285,9 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - info->rtc_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(info->rtc_base)) - return PTR_ERR(info->rtc_base); + info->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(info->base)) + return PTR_ERR(info->base); ret = platform_get_irq(pdev, 0); if (ret <= 0) { @@ -297,14 +295,14 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) return ret; } - info->tegra_rtc_irq = ret; + info->irq = ret; - info->rtc_dev = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(info->rtc_dev)) - return PTR_ERR(info->rtc_dev); + info->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(info->rtc)) + return PTR_ERR(info->rtc); - info->rtc_dev->ops = &tegra_rtc_ops; - info->rtc_dev->range_max = U32_MAX; + info->rtc->ops = &tegra_rtc_ops; + info->rtc->range_max = U32_MAX; info->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(info->clk)) @@ -316,26 +314,26 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) /* set context info */ info->pdev = pdev; - spin_lock_init(&info->tegra_rtc_lock); + spin_lock_init(&info->lock); platform_set_drvdata(pdev, info); /* clear out the hardware */ - writel(0, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0); - writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); - writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK); + writel(0, info->base + TEGRA_RTC_REG_SECONDS_ALARM0); + writel(0xffffffff, info->base + TEGRA_RTC_REG_INTR_STATUS); + writel(0, info->base + TEGRA_RTC_REG_INTR_MASK); device_init_wakeup(&pdev->dev, 1); - ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq, - tegra_rtc_irq_handler, IRQF_TRIGGER_HIGH, - dev_name(&pdev->dev), &pdev->dev); + ret = devm_request_irq(&pdev->dev, info->irq, tegra_rtc_irq_handler, + IRQF_TRIGGER_HIGH, dev_name(&pdev->dev), + &pdev->dev); if (ret) { dev_err(&pdev->dev, "failed to request interrupt: %d\n", ret); goto disable_clk; } - ret = rtc_register_device(info->rtc_dev); + ret = rtc_register_device(info->rtc); if (ret) { dev_err(&pdev->dev, "failed to register device: %d\n", ret); goto disable_clk; @@ -367,19 +365,19 @@ static int tegra_rtc_suspend(struct device *dev) tegra_rtc_wait_while_busy(dev); /* only use ALARM0 as a wake source */ - writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); + writel(0xffffffff, info->base + TEGRA_RTC_REG_INTR_STATUS); writel(TEGRA_RTC_INTR_STATUS_SEC_ALARM0, - info->rtc_base + TEGRA_RTC_REG_INTR_MASK); + info->base + TEGRA_RTC_REG_INTR_MASK); dev_vdbg(dev, "alarm sec = %d\n", - readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0)); + readl(info->base + TEGRA_RTC_REG_SECONDS_ALARM0)); dev_vdbg(dev, "Suspend (device_may_wakeup=%d) IRQ:%d\n", - device_may_wakeup(dev), info->tegra_rtc_irq); + device_may_wakeup(dev), info->irq); /* leave the alarms on as a wake source */ if (device_may_wakeup(dev)) - enable_irq_wake(info->tegra_rtc_irq); + enable_irq_wake(info->irq); return 0; } @@ -393,7 +391,7 @@ static int tegra_rtc_resume(struct device *dev) /* alarms were left on as a wake source, turn them off */ if (device_may_wakeup(dev)) - disable_irq_wake(info->tegra_rtc_irq); + disable_irq_wake(info->irq); return 0; } -- cgit v1.2.3-59-g8ed1b From 3e483e59c79601ea682aa67f9805da79716efab0 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 27 May 2019 12:13:59 +0200 Subject: rtc: tegra: Turn into regular driver Drivers registered with module_platform_driver_probe() are considered non-hotpluggable, which among other things means that they don't support deferred probe. However, recent changes in how the ARM SMMU works have required the BPMP (which is the clock provider on Tegra186 and later) be bound to the SMMU, which in turn means that the BPMP driver can defer probe and hence clocks become available much later than they used to. For most other drivers this is not a problem because they already properly support deferred probe, but rtc-tegra is the odd one out that now fails to probe and will therefore never be registered. Fix this by making the driver a regular driver that supports unloading and deferred probe. Signed-off-by: Thierry Reding Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tegra.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index b68ba2dd1d36..8bbaea24926e 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -2,7 +2,7 @@ /* * An RTC driver for the NVIDIA Tegra 200 series internal RTC. * - * Copyright (c) 2010, NVIDIA Corporation. + * Copyright (c) 2010-2019, NVIDIA Corporation. */ #include @@ -274,7 +274,7 @@ static const struct of_device_id tegra_rtc_dt_match[] = { }; MODULE_DEVICE_TABLE(of, tegra_rtc_dt_match); -static int __init tegra_rtc_probe(struct platform_device *pdev) +static int tegra_rtc_probe(struct platform_device *pdev) { struct tegra_rtc_info *info; struct resource *res; @@ -406,6 +406,7 @@ static void tegra_rtc_shutdown(struct platform_device *pdev) } static struct platform_driver tegra_rtc_driver = { + .probe = tegra_rtc_probe, .remove = tegra_rtc_remove, .shutdown = tegra_rtc_shutdown, .driver = { @@ -414,8 +415,7 @@ static struct platform_driver tegra_rtc_driver = { .pm = &tegra_rtc_pm_ops, }, }; - -module_platform_driver_probe(tegra_rtc_driver, tegra_rtc_probe); +module_platform_driver(tegra_rtc_driver); MODULE_AUTHOR("Jon Mayo "); MODULE_DESCRIPTION("driver for Tegra internal RTC"); -- cgit v1.2.3-59-g8ed1b From 9c3f0795e42513bff1cc1ab55a893d1c3dbf60b4 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Sat, 25 May 2019 11:12:51 +0200 Subject: rtc: tps65910: remove superfluous Kconfig dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TPS65910 entry is already under 'if RTC_CLASS' - remove superfluous dependency. Signed-off-by: Michał Mirosław Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 7b8e156dbf38..03b60d5c2330 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -553,7 +553,7 @@ config RTC_DRV_TPS6586X config RTC_DRV_TPS65910 tristate "TI TPS65910 RTC driver" - depends on RTC_CLASS && MFD_TPS65910 + depends on MFD_TPS65910 help If you say yes here you get support for the RTC on the TPS65910 chips. -- cgit v1.2.3-59-g8ed1b From 42ca37ca476249ef01186a7c69a6b6c860e72c29 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Sat, 25 May 2019 11:12:55 +0200 Subject: rtc: tps65910: fix typo in register name in read_alarm() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix an obvious typo: in read_alarm() call we should read alarm setting (starting at ALARM_SECONDS register) and not current time. Signed-off-by: Michał Mirosław Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tps65910.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index a9bbd022aeef..cba70509fd92 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c @@ -147,7 +147,7 @@ static int tps65910_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) struct tps65910 *tps = dev_get_drvdata(dev->parent); int ret; - ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, alarm_data, + ret = regmap_bulk_read(tps->regmap, TPS65910_ALARM_SECONDS, alarm_data, NUM_TIME_REGS); if (ret < 0) { dev_err(dev, "rtc_read_alarm error %d\n", ret); -- cgit v1.2.3-59-g8ed1b From a3094fc1a15eff0f69f6fdc335b1b21081b27a74 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 9 Apr 2019 05:00:07 +0000 Subject: rtc: imx-sc: add rtc alarm support Add i.MX system controller RTC alarm support, the RTC alarm is implemented via SIP(silicon provider) runtime service call and ARM-Trusted-Firmware will communicate with system controller via MU(message unit) IPC to set RTC alarm. When RTC alarm fires, system controller will generate a common MU irq event and notify system controller RTC driver to handle the irq event. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-imx-sc.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-imx-sc.c b/drivers/rtc/rtc-imx-sc.c index 19642bfd913a..c933045fe04b 100644 --- a/drivers/rtc/rtc-imx-sc.c +++ b/drivers/rtc/rtc-imx-sc.c @@ -3,6 +3,7 @@ * Copyright 2018 NXP. */ +#include #include #include #include @@ -11,11 +12,15 @@ #include #define IMX_SC_TIMER_FUNC_GET_RTC_SEC1970 9 +#define IMX_SC_TIMER_FUNC_SET_RTC_ALARM 8 #define IMX_SC_TIMER_FUNC_SET_RTC_TIME 6 #define IMX_SIP_SRTC 0xC2000002 #define IMX_SIP_SRTC_SET_TIME 0x0 +#define SC_IRQ_GROUP_RTC 2 +#define SC_IRQ_RTC 1 + static struct imx_sc_ipc *rtc_ipc_handle; static struct rtc_device *imx_sc_rtc; @@ -24,6 +29,16 @@ struct imx_sc_msg_timer_get_rtc_time { u32 time; } __packed; +struct imx_sc_msg_timer_rtc_set_alarm { + struct imx_sc_rpc_msg hdr; + u16 year; + u8 mon; + u8 day; + u8 hour; + u8 min; + u8 sec; +} __packed; + static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct imx_sc_msg_timer_get_rtc_time msg; @@ -60,9 +75,77 @@ static int imx_sc_rtc_set_time(struct device *dev, struct rtc_time *tm) return res.a0; } +static int imx_sc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) +{ + return imx_scu_irq_group_enable(SC_IRQ_GROUP_RTC, SC_IRQ_RTC, enable); +} + +static int imx_sc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + /* + * SCU firmware does NOT provide read alarm API, but .read_alarm + * callback is required by RTC framework to support alarm function, + * so just return here. + */ + return 0; +} + +static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct imx_sc_msg_timer_rtc_set_alarm msg; + struct imx_sc_rpc_msg *hdr = &msg.hdr; + int ret; + struct rtc_time *alrm_tm = &alrm->time; + + hdr->ver = IMX_SC_RPC_VERSION; + hdr->svc = IMX_SC_RPC_SVC_TIMER; + hdr->func = IMX_SC_TIMER_FUNC_SET_RTC_ALARM; + hdr->size = 3; + + msg.year = alrm_tm->tm_year + 1900; + msg.mon = alrm_tm->tm_mon + 1; + msg.day = alrm_tm->tm_mday; + msg.hour = alrm_tm->tm_hour; + msg.min = alrm_tm->tm_min; + msg.sec = alrm_tm->tm_sec; + + ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true); + if (ret) { + dev_err(dev, "set rtc alarm failed, ret %d\n", ret); + return ret; + } + + ret = imx_sc_rtc_alarm_irq_enable(dev, alrm->enabled); + if (ret) { + dev_err(dev, "enable rtc alarm failed, ret %d\n", ret); + return ret; + } + + return 0; +} + static const struct rtc_class_ops imx_sc_rtc_ops = { .read_time = imx_sc_rtc_read_time, .set_time = imx_sc_rtc_set_time, + .read_alarm = imx_sc_rtc_read_alarm, + .set_alarm = imx_sc_rtc_set_alarm, + .alarm_irq_enable = imx_sc_rtc_alarm_irq_enable, +}; + +static int imx_sc_rtc_alarm_notify(struct notifier_block *nb, + unsigned long event, void *group) +{ + /* ignore non-rtc irq */ + if (!((event & SC_IRQ_RTC) && (*(u8 *)group == SC_IRQ_GROUP_RTC))) + return 0; + + rtc_update_irq(imx_sc_rtc, 1, RTC_IRQF | RTC_AF); + + return 0; +} + +static struct notifier_block imx_sc_rtc_alarm_sc_notifier = { + .notifier_call = imx_sc_rtc_alarm_notify, }; static int imx_sc_rtc_probe(struct platform_device *pdev) @@ -73,6 +156,8 @@ static int imx_sc_rtc_probe(struct platform_device *pdev) if (ret) return ret; + device_init_wakeup(&pdev->dev, true); + imx_sc_rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(imx_sc_rtc)) return PTR_ERR(imx_sc_rtc); @@ -87,6 +172,8 @@ static int imx_sc_rtc_probe(struct platform_device *pdev) return ret; } + imx_scu_irq_register_notifier(&imx_sc_rtc_alarm_sc_notifier); + return 0; } -- cgit v1.2.3-59-g8ed1b From d6624cc7502127c0e8e7c86bcf151850f1765bd3 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 28 May 2019 22:30:36 +0200 Subject: rtc: sun6i: Add R40 compatible The R40 has a quite different RTC, with only a single interrupt line, but two clock outputs. Let's add a compatible. Acked-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sun6i.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 11f56de52179..9fab8ed856f4 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -681,6 +681,7 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = { { .compatible = "allwinner,sun6i-a31-rtc" }, { .compatible = "allwinner,sun8i-a23-rtc" }, { .compatible = "allwinner,sun8i-h3-rtc" }, + { .compatible = "allwinner,sun8i-r40-rtc" }, { .compatible = "allwinner,sun8i-v3-rtc" }, { .compatible = "allwinner,sun50i-h5-rtc" }, { /* sentinel */ }, -- cgit v1.2.3-59-g8ed1b From 59ab3f4060fc90e4196c6ea4813a8b7512bf200b Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Wed, 5 Jun 2019 15:26:13 +0300 Subject: rtc: tegra: Drop MODULE_ALIAS RTC driver was converted to OF driver long time ago. The MODULE_ALIAS macro has no effect for the OF drivers since the alias is overridden by the drivers core to follow the OF naming convention of the driver's alias, which is based on the device-tree matching name. $ cat /sys/devices/soc0/7000e000.rtc/modalias of:NrtcT(null)Cnvidia,tegra20-rtc Signed-off-by: Dmitry Osipenko Acked-by: Thierry Reding Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tegra.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index 8bbaea24926e..8fa1b3febf69 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -419,5 +419,4 @@ module_platform_driver(tegra_rtc_driver); MODULE_AUTHOR("Jon Mayo "); MODULE_DESCRIPTION("driver for Tegra internal RTC"); -MODULE_ALIAS("platform:tegra_rtc"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From 55c24316223ba43361dd4be5321a8cd103402e30 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 8 Jun 2019 12:56:05 +0200 Subject: rtc: fm3130: simplify getting the adapter of a client We have a dedicated pointer for that, so use it. Much easier to read and less computation involved. Signed-off-by: Wolfram Sang Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-fm3130.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index e1137670d4d2..015cf639166e 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -107,8 +107,7 @@ static int fm3130_get_time(struct device *dev, struct rtc_time *t) fm3130_rtc_mode(dev, FM3130_MODE_READ); /* read the RTC date and time registers all at once */ - tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), - fm3130->msg, 2); + tmp = i2c_transfer(fm3130->client->adapter, fm3130->msg, 2); if (tmp != 2) { dev_err(dev, "%s error %d\n", "read", tmp); return -EIO; @@ -200,8 +199,7 @@ static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) } /* read the RTC alarm registers all at once */ - tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), - &fm3130->msg[2], 2); + tmp = i2c_transfer(fm3130->client->adapter, &fm3130->msg[2], 2); if (tmp != 2) { dev_err(dev, "%s error %d\n", "read", tmp); return -EIO; @@ -351,7 +349,7 @@ static int fm3130_probe(struct i2c_client *client, struct fm3130 *fm3130; int err = -ENODEV; int tmp; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct i2c_adapter *adapter = client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) -- cgit v1.2.3-59-g8ed1b From e5108df402f7729381538720de41da4f178eae3b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 8 Jun 2019 12:56:06 +0200 Subject: rtc: m41t80: simplify getting the adapter of a client We have a dedicated pointer for that, so use it. Much easier to read and less computation involved. Signed-off-by: Wolfram Sang Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index dd5a8991f75b..e55179d74377 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -876,7 +876,7 @@ static struct notifier_block wdt_notifier = { static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct i2c_adapter *adapter = client->adapter; int rc = 0; struct rtc_time tm; struct m41t80_data *m41t80_data = NULL; -- cgit v1.2.3-59-g8ed1b From 5cb172694a010c9ec786f6ecc2290369f7271108 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 8 Jun 2019 12:56:07 +0200 Subject: rtc: rv8803: simplify getting the adapter of a client We have a dedicated pointer for that, so use it. Much easier to read and less computation involved. Signed-off-by: Wolfram Sang Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv8803.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index 0b102c3cf5a4..fc5243400108 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c @@ -517,7 +517,7 @@ static int rx8900_trickle_charger_init(struct rv8803_data *rv8803) static int rv8803_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct i2c_adapter *adapter = client->adapter; struct rv8803_data *rv8803; int err, flags; struct nvmem_config nvmem_cfg = { -- cgit v1.2.3-59-g8ed1b From 9d085c54202dec9abcf401eb77013ea8603f5188 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 8 Jun 2019 12:56:08 +0200 Subject: rtc: rx8010: simplify getting the adapter of a client We have a dedicated pointer for that, so use it. Much easier to read and less computation involved. Signed-off-by: Wolfram Sang Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rx8010.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index 7ddc22eb5b0f..2b58b9b683a9 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c @@ -437,7 +437,7 @@ static struct rtc_class_ops rx8010_rtc_ops = { static int rx8010_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct i2c_adapter *adapter = client->adapter; struct rx8010_data *rx8010; int err = 0; -- cgit v1.2.3-59-g8ed1b From 110036b4f4db61f59cc478ecb9c34e2503b60c34 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 8 Jun 2019 12:56:09 +0200 Subject: rtc: rx8025: simplify getting the adapter of a client We have a dedicated pointer for that, so use it. Much easier to read and less computation involved. Signed-off-by: Wolfram Sang Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rx8025.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index fddc996cb38d..781fa992afab 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -504,7 +504,7 @@ static void rx8025_sysfs_unregister(struct device *dev) static int rx8025_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct i2c_adapter *adapter = client->adapter; struct rx8025_data *rx8025; int err = 0; -- cgit v1.2.3-59-g8ed1b From 2372a7d32b694e39bfac54d7f4dd7c0edb02d19e Mon Sep 17 00:00:00 2001 From: Dylan Howey Date: Fri, 3 May 2019 19:52:08 +0000 Subject: rtc: pcf2123: remove sysfs register view Use regmap debugfs register view instead. Signed-off-by: Dylan Howey Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf2123.c | 90 +---------------------------------------------- 1 file changed, 1 insertion(+), 89 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 39da8b214275..fb5cb81f2161 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -44,7 +44,6 @@ #include #include #include -#include /* REGISTERS */ #define PCF2123_REG_CTRL1 (0x00) /* Control Register 1 */ @@ -107,14 +106,8 @@ static struct spi_driver pcf2123_driver; -struct pcf2123_sysfs_reg { - struct device_attribute attr; - char name[2]; -}; - struct pcf2123_plat_data { struct rtc_device *rtc; - struct pcf2123_sysfs_reg regs[16]; }; /* @@ -160,52 +153,6 @@ static int pcf2123_write_reg(struct device *dev, u8 reg, u8 val) return pcf2123_write(dev, txbuf, sizeof(txbuf)); } -static ssize_t pcf2123_show(struct device *dev, struct device_attribute *attr, - char *buffer) -{ - struct pcf2123_sysfs_reg *r; - u8 rxbuf[1]; - unsigned long reg; - int ret; - - r = container_of(attr, struct pcf2123_sysfs_reg, attr); - - ret = kstrtoul(r->name, 16, ®); - if (ret) - return ret; - - ret = pcf2123_read(dev, reg, rxbuf, 1); - if (ret < 0) - return -EIO; - - return sprintf(buffer, "0x%x\n", rxbuf[0]); -} - -static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr, - const char *buffer, size_t count) -{ - struct pcf2123_sysfs_reg *r; - unsigned long reg; - unsigned long val; - - int ret; - - r = container_of(attr, struct pcf2123_sysfs_reg, attr); - - ret = kstrtoul(r->name, 16, ®); - if (ret) - return ret; - - ret = kstrtoul(buffer, 10, &val); - if (ret) - return ret; - - ret = pcf2123_write_reg(dev, reg, val); - if (ret < 0) - return -EIO; - return count; -} - static int pcf2123_read_offset(struct device *dev, long *offset) { int ret; @@ -377,7 +324,7 @@ static int pcf2123_probe(struct spi_device *spi) struct rtc_device *rtc; struct rtc_time tm; struct pcf2123_plat_data *pdata; - int ret, i; + int ret; pdata = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_plat_data), GFP_KERNEL); @@ -409,47 +356,13 @@ static int pcf2123_probe(struct spi_device *spi) pdata->rtc = rtc; - for (i = 0; i < 16; i++) { - sysfs_attr_init(&pdata->regs[i].attr.attr); - sprintf(pdata->regs[i].name, "%1x", i); - pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR; - pdata->regs[i].attr.attr.name = pdata->regs[i].name; - pdata->regs[i].attr.show = pcf2123_show; - pdata->regs[i].attr.store = pcf2123_store; - ret = device_create_file(&spi->dev, &pdata->regs[i].attr); - if (ret) { - dev_err(&spi->dev, "Unable to create sysfs %s\n", - pdata->regs[i].name); - goto sysfs_exit; - } - } - return 0; -sysfs_exit: - for (i--; i >= 0; i--) - device_remove_file(&spi->dev, &pdata->regs[i].attr); - kfree_exit: spi->dev.platform_data = NULL; return ret; } -static int pcf2123_remove(struct spi_device *spi) -{ - struct pcf2123_plat_data *pdata = dev_get_platdata(&spi->dev); - int i; - - if (pdata) { - for (i = 0; i < 16; i++) - if (pdata->regs[i].name[0]) - device_remove_file(&spi->dev, - &pdata->regs[i].attr); - } - - return 0; -} - #ifdef CONFIG_OF static const struct of_device_id pcf2123_dt_ids[] = { { .compatible = "nxp,rtc-pcf2123", }, @@ -465,7 +378,6 @@ static struct spi_driver pcf2123_driver = { .of_match_table = of_match_ptr(pcf2123_dt_ids), }, .probe = pcf2123_probe, - .remove = pcf2123_remove, }; module_spi_driver(pcf2123_driver); -- cgit v1.2.3-59-g8ed1b From 790d033933b8a1d6bd537bdd6c08d9af745d9b78 Mon Sep 17 00:00:00 2001 From: Dylan Howey Date: Fri, 3 May 2019 19:52:10 +0000 Subject: rtc: pcf2123: port to regmap Also remove pcf2123_delay_trec. This claimed to add a 30ns delay to SPI writes, but I could not see any reference to this requirement in the datasheet. Closest thing I could find to a requirement are timings for the SPI chip enable line, which cannot be controlled by this driver (the ndelay came after the call to spi_write_then_read, which means it would sleep after CE has already gone inactive). Things seem to work fine without it. Signed-off-by: Dylan Howey Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf2123.c | 142 ++++++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 81 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index fb5cb81f2161..32bfed7eefd4 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -44,6 +44,7 @@ #include #include #include +#include /* REGISTERS */ #define PCF2123_REG_CTRL1 (0x00) /* Control Register 1 */ @@ -98,6 +99,7 @@ #define OFFSET_SIGN_BIT 6 /* 2's complement sign bit */ #define OFFSET_COARSE BIT(7) /* Coarse mode offset */ #define OFFSET_STEP (2170) /* Offset step in parts per billion */ +#define OFFSET_MASK GENMASK(6, 0) /* Offset value */ /* READ/WRITE ADDRESS BITS */ #define PCF2123_WRITE BIT(4) @@ -108,66 +110,33 @@ static struct spi_driver pcf2123_driver; struct pcf2123_plat_data { struct rtc_device *rtc; + struct regmap *map; }; -/* - * Causes a 30 nanosecond delay to ensure that the PCF2123 chip select - * is released properly after an SPI write. This function should be - * called after EVERY read/write call over SPI. - */ -static inline void pcf2123_delay_trec(void) -{ - ndelay(30); -} - -static int pcf2123_read(struct device *dev, u8 reg, u8 *rxbuf, size_t size) -{ - struct spi_device *spi = to_spi_device(dev); - int ret; - - reg |= PCF2123_READ; - ret = spi_write_then_read(spi, ®, 1, rxbuf, size); - pcf2123_delay_trec(); - - return ret; -} - -static int pcf2123_write(struct device *dev, u8 *txbuf, size_t size) -{ - struct spi_device *spi = to_spi_device(dev); - int ret; - - txbuf[0] |= PCF2123_WRITE; - ret = spi_write(spi, txbuf, size); - pcf2123_delay_trec(); - - return ret; -} - -static int pcf2123_write_reg(struct device *dev, u8 reg, u8 val) -{ - u8 txbuf[2]; - - txbuf[0] = reg; - txbuf[1] = val; - return pcf2123_write(dev, txbuf, sizeof(txbuf)); -} +static const struct regmap_config pcf2123_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .read_flag_mask = PCF2123_READ, + .write_flag_mask = PCF2123_WRITE, + .max_register = PCF2123_REG_CTDWN_TMR, +}; static int pcf2123_read_offset(struct device *dev, long *offset) { - int ret; - s8 reg; + struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + int ret, val; + unsigned int reg; - ret = pcf2123_read(dev, PCF2123_REG_OFFSET, ®, 1); - if (ret < 0) + ret = regmap_read(pdata->map, PCF2123_REG_OFFSET, ®); + if (ret) return ret; + val = sign_extend32((reg & OFFSET_MASK), OFFSET_SIGN_BIT); + if (reg & OFFSET_COARSE) - reg <<= 1; /* multiply by 2 and sign extend */ - else - reg = sign_extend32(reg, OFFSET_SIGN_BIT); + val *= 2; - *offset = ((long)reg) * OFFSET_STEP; + *offset = ((long)val) * OFFSET_STEP; return 0; } @@ -184,6 +153,7 @@ static int pcf2123_read_offset(struct device *dev, long *offset) */ static int pcf2123_set_offset(struct device *dev, long offset) { + struct pcf2123_plat_data *pdata = dev_get_platdata(dev); s8 reg; if (offset > OFFSET_STEP * 127) @@ -203,16 +173,18 @@ static int pcf2123_set_offset(struct device *dev, long offset) reg |= OFFSET_COARSE; } - return pcf2123_write_reg(dev, PCF2123_REG_OFFSET, reg); + return regmap_write(pdata->map, PCF2123_REG_OFFSET, (unsigned int)reg); } static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm) { + struct pcf2123_plat_data *pdata = dev_get_platdata(dev); u8 rxbuf[7]; int ret; - ret = pcf2123_read(dev, PCF2123_REG_SC, rxbuf, sizeof(rxbuf)); - if (ret < 0) + ret = regmap_bulk_read(pdata->map, PCF2123_REG_SC, rxbuf, + sizeof(rxbuf)); + if (ret) return ret; if (rxbuf[0] & OSC_HAS_STOPPED) { @@ -241,7 +213,8 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm) static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) { - u8 txbuf[8]; + struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + u8 txbuf[7]; int ret; dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " @@ -251,27 +224,27 @@ static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); /* Stop the counter first */ - ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_STOP); - if (ret < 0) + ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP); + if (ret) return ret; /* Set the new time */ - txbuf[0] = PCF2123_REG_SC; - txbuf[1] = bin2bcd(tm->tm_sec & 0x7F); - txbuf[2] = bin2bcd(tm->tm_min & 0x7F); - txbuf[3] = bin2bcd(tm->tm_hour & 0x3F); - txbuf[4] = bin2bcd(tm->tm_mday & 0x3F); - txbuf[5] = tm->tm_wday & 0x07; - txbuf[6] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */ - txbuf[7] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100); - - ret = pcf2123_write(dev, txbuf, sizeof(txbuf)); - if (ret < 0) + txbuf[0] = bin2bcd(tm->tm_sec & 0x7F); + txbuf[1] = bin2bcd(tm->tm_min & 0x7F); + txbuf[2] = bin2bcd(tm->tm_hour & 0x3F); + txbuf[3] = bin2bcd(tm->tm_mday & 0x3F); + txbuf[4] = tm->tm_wday & 0x07; + txbuf[5] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */ + txbuf[6] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100); + + ret = regmap_bulk_write(pdata->map, PCF2123_REG_SC, txbuf, + sizeof(txbuf)); + if (ret) return ret; /* Start the counter */ - ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_CLEAR); - if (ret < 0) + ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR); + if (ret) return ret; return 0; @@ -279,33 +252,33 @@ static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) static int pcf2123_reset(struct device *dev) { + struct pcf2123_plat_data *pdata = dev_get_platdata(dev); int ret; - u8 rxbuf[2]; + unsigned int val = 0; - ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_SW_RESET); - if (ret < 0) + ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_SW_RESET); + if (ret) return ret; /* Stop the counter */ dev_dbg(dev, "stopping RTC\n"); - ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_STOP); - if (ret < 0) + ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP); + if (ret) return ret; /* See if the counter was actually stopped */ dev_dbg(dev, "checking for presence of RTC\n"); - ret = pcf2123_read(dev, PCF2123_REG_CTRL1, rxbuf, sizeof(rxbuf)); - if (ret < 0) + ret = regmap_read(pdata->map, PCF2123_REG_CTRL1, &val); + if (ret) return ret; - dev_dbg(dev, "received data from RTC (0x%02X 0x%02X)\n", - rxbuf[0], rxbuf[1]); - if (!(rxbuf[0] & CTRL1_STOP)) + dev_dbg(dev, "received data from RTC (0x%08X)\n", val); + if (!(val & CTRL1_STOP)) return -ENODEV; /* Start the counter */ - ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_CLEAR); - if (ret < 0) + ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR); + if (ret) return ret; return 0; @@ -332,6 +305,13 @@ static int pcf2123_probe(struct spi_device *spi) return -ENOMEM; spi->dev.platform_data = pdata; + pdata->map = devm_regmap_init_spi(spi, &pcf2123_regmap_config); + + if (IS_ERR(pdata->map)) { + dev_err(&spi->dev, "regmap init failed.\n"); + goto kfree_exit; + } + ret = pcf2123_rtc_read_time(&spi->dev, &tm); if (ret < 0) { ret = pcf2123_reset(&spi->dev); -- cgit v1.2.3-59-g8ed1b From c33850bbc6c9f2276d1065b0faee2186260cb664 Mon Sep 17 00:00:00 2001 From: Dylan Howey Date: Fri, 3 May 2019 19:52:12 +0000 Subject: rtc: pcf2123: use %ptR Use %ptR to print date in human readable format. Signed-off-by: Dylan Howey Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf2123.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 32bfed7eefd4..2f87da47bc9a 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -202,11 +202,7 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm) if (tm->tm_year < 70) tm->tm_year += 100; /* assume we are in 1970...2069 */ - dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __func__, - tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); + dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm); return 0; } @@ -217,11 +213,7 @@ static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) u8 txbuf[7]; int ret; - dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __func__, - tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); + dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm); /* Stop the counter first */ ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP); -- cgit v1.2.3-59-g8ed1b From e32e60a2d5ecd8affc79f7da02d3479b4116579f Mon Sep 17 00:00:00 2001 From: Dylan Howey Date: Fri, 3 May 2019 19:52:12 +0000 Subject: rtc: pcf2123: add alarm support Allows alarm to be controlled using, e.g., the RTC_WKALM_SET ioctl. Signed-off-by: Dylan Howey Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf2123.c | 116 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 2f87da47bc9a..3b314ce991e5 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -242,6 +242,99 @@ static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) return 0; } +static int pcf2123_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + u8 rxbuf[4]; + int ret; + unsigned int val = 0; + + ret = regmap_bulk_read(pdata->map, PCF2123_REG_ALRM_MN, rxbuf, + sizeof(rxbuf)); + if (ret) + return ret; + + alm->time.tm_min = bcd2bin(rxbuf[0] & 0x7F); + alm->time.tm_hour = bcd2bin(rxbuf[1] & 0x3F); + alm->time.tm_mday = bcd2bin(rxbuf[2] & 0x3F); + alm->time.tm_wday = bcd2bin(rxbuf[3] & 0x07); + + dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time); + + ret = regmap_read(pdata->map, PCF2123_REG_CTRL2, &val); + if (ret) + return ret; + + alm->enabled = !!(val & CTRL2_AIE); + + return 0; +} + +static int pcf2123_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + u8 txbuf[4]; + int ret; + + dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time); + + /* Ensure alarm flag is clear */ + ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AF, 0); + if (ret) + return ret; + + /* Disable alarm interrupt */ + ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AIE, 0); + if (ret) + return ret; + + /* Set new alarm */ + txbuf[0] = bin2bcd(alm->time.tm_min & 0x7F); + txbuf[1] = bin2bcd(alm->time.tm_hour & 0x3F); + txbuf[2] = bin2bcd(alm->time.tm_mday & 0x3F); + txbuf[3] = bin2bcd(alm->time.tm_wday & 0x07); + + ret = regmap_bulk_write(pdata->map, PCF2123_REG_ALRM_MN, txbuf, + sizeof(txbuf)); + if (ret) + return ret; + + /* Enable alarm interrupt */ + if (alm->enabled) { + ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, + CTRL2_AIE, CTRL2_AIE); + if (ret) + return ret; + } + + return 0; +} + +static irqreturn_t pcf2123_rtc_irq(int irq, void *dev) +{ + struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + struct mutex *lock = &pdata->rtc->ops_lock; + unsigned int val = 0; + int ret = IRQ_NONE; + + mutex_lock(lock); + regmap_read(pdata->map, PCF2123_REG_CTRL2, &val); + + /* Alarm? */ + if (val & CTRL2_AF) { + ret = IRQ_HANDLED; + + /* Clear alarm flag */ + regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AF, 0); + + rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF); + } + + mutex_unlock(lock); + + return ret; +} + static int pcf2123_reset(struct device *dev) { struct pcf2123_plat_data *pdata = dev_get_platdata(dev); @@ -281,7 +374,8 @@ static const struct rtc_class_ops pcf2123_rtc_ops = { .set_time = pcf2123_rtc_set_time, .read_offset = pcf2123_read_offset, .set_offset = pcf2123_set_offset, - + .read_alarm = pcf2123_rtc_read_alarm, + .set_alarm = pcf2123_rtc_set_alarm, }; static int pcf2123_probe(struct spi_device *spi) @@ -289,7 +383,7 @@ static int pcf2123_probe(struct spi_device *spi) struct rtc_device *rtc; struct rtc_time tm; struct pcf2123_plat_data *pdata; - int ret; + int ret = 0; pdata = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_plat_data), GFP_KERNEL); @@ -328,6 +422,24 @@ static int pcf2123_probe(struct spi_device *spi) pdata->rtc = rtc; + /* Register alarm irq */ + if (spi->irq > 0) { + ret = devm_request_threaded_irq(&spi->dev, spi->irq, NULL, + pcf2123_rtc_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + pcf2123_driver.driver.name, &spi->dev); + if (!ret) + device_init_wakeup(&spi->dev, true); + else + dev_err(&spi->dev, "could not request irq.\n"); + } + + /* The PCF2123's alarm only has minute accuracy. Must add timer + * support to this driver to generate interrupts more than once + * per minute. + */ + pdata->rtc->uie_unsupported = 1; + return 0; kfree_exit: -- cgit v1.2.3-59-g8ed1b From fedc459a3da35ecf171a1d6dd9f7f51fb452baf8 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 19 Jun 2019 15:17:53 +0200 Subject: rtc: pcf2123: fix negative offset rounding Using result = (value + divisor/2) / divisor is rounding values up and only works well for positive values. Instead use DIV_ROUND_CLOSEST which does the correct thing. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf2123.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 3b314ce991e5..e8100af789ef 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -161,7 +161,7 @@ static int pcf2123_set_offset(struct device *dev, long offset) else if (offset < OFFSET_STEP * -128) reg = -128; else - reg = (s8)((offset + (OFFSET_STEP >> 1)) / OFFSET_STEP); + reg = DIV_ROUND_CLOSEST(offset, OFFSET_STEP); /* choose fine offset only for odd values in the normal range */ if (reg & 1 && reg <= 63 && reg >= -64) { -- cgit v1.2.3-59-g8ed1b From 65f662cbf829834fa4d94190eb7691e5a9cb92d8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 4 Jun 2019 12:23:35 +0800 Subject: rtc: pcf8563: Fix interrupt trigger method The PCF8563 datasheet says the interrupt line is active low and stays active until the events are cleared, i.e. a level trigger interrupt. Fix the flags used to request the interrupt. Fixes: ede3e9d47cca ("drivers/rtc/rtc-pcf8563.c: add alarm support") Signed-off-by: Chen-Yu Tsai Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf8563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 3efc86c25d27..e358313466f1 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -605,7 +605,7 @@ static int pcf8563_probe(struct i2c_client *client, if (client->irq > 0) { err = devm_request_threaded_irq(&client->dev, client->irq, NULL, pcf8563_irq, - IRQF_SHARED|IRQF_ONESHOT|IRQF_TRIGGER_FALLING, + IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW, pcf8563_driver.driver.name, client); if (err) { dev_err(&client->dev, "unable to request IRQ %d\n", -- cgit v1.2.3-59-g8ed1b From 3572e8aea3bf925dac1dbf86127657c39fe5c254 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 4 Jun 2019 12:23:36 +0800 Subject: rtc: pcf8563: Clear event flags and disable interrupts before requesting irq Besides the alarm, the PCF8563 also has a timer triggered interrupt. In cases where the previous system left the timer and interrupts on, or somehow the bits got enabled, the interrupt would keep triggering as the kernel doesn't know about it. Clear both the alarm and timer event flags, and disable the interrupts, before requesting the interrupt line. Fixes: ede3e9d47cca ("drivers/rtc/rtc-pcf8563.c: add alarm support") Fixes: a45d528aab8b ("rtc: pcf8563: clear expired alarm at boot time") Signed-off-by: Chen-Yu Tsai Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf8563.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index e358313466f1..d8adf69b6697 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -563,7 +563,6 @@ static int pcf8563_probe(struct i2c_client *client, struct pcf8563 *pcf8563; int err; unsigned char buf; - unsigned char alm_pending; dev_dbg(&client->dev, "%s\n", __func__); @@ -587,13 +586,13 @@ static int pcf8563_probe(struct i2c_client *client, return err; } - err = pcf8563_get_alarm_mode(client, NULL, &alm_pending); - if (err) { - dev_err(&client->dev, "%s: read error\n", __func__); + /* Clear flags and disable interrupts */ + buf = 0; + err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, &buf); + if (err < 0) { + dev_err(&client->dev, "%s: write error\n", __func__); return err; } - if (alm_pending) - pcf8563_set_alarm_mode(client, 0); pcf8563->rtc = devm_rtc_device_register(&client->dev, pcf8563_driver.driver.name, -- cgit v1.2.3-59-g8ed1b From 3126790d1fd3f0dff11240c1bdb04a6f020a5a03 Mon Sep 17 00:00:00 2001 From: Puranjay Mohan Date: Tue, 18 Jun 2019 09:53:51 +0530 Subject: rtc: interface: Change type of 'count' from int to u64 Callers of hrtimer_forward_now() should save the return value in u64. function rtc_pie_update_irq() stores it in variable 'count' of type int change type of count from unsigned long to u64 to solve the issue. Signed-off-by: Puranjay Mohan Link: https://lore.kernel.org/r/20190618042351.9692-1-puranjay12@gmail.com Signed-off-by: Alexandre Belloni --- drivers/rtc/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 4124f4dd376b..72b7ddc43116 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -633,7 +633,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) { struct rtc_device *rtc; ktime_t period; - int count; + u64 count; rtc = container_of(timer, struct rtc_device, pie_timer); -- cgit v1.2.3-59-g8ed1b From f2f5cb6a73b9f056ae3f8e6b4c61f57d6f3ab1ec Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 4 Jul 2019 16:55:42 +0800 Subject: rtc: pcf2123: Fix build error If REGMAP_SPI is m and RTC_DRV_PCF2123 is y, drivers/rtc/rtc-pcf2123.o: In function `pcf2123_probe': rtc-pcf2123.c:(.text+0xb2b): undefined reference to `__devm_regmap_init_spi' Select REGMAP_SPI as RTC_DRV_DS1347 driver does. Reported-by: Hulk Robot Fixes: 790d033933b8 ("rtc: pcf2123: port to regmap") Signed-off-by: YueHaibing Link: https://lore.kernel.org/r/20190704085542.48180-1-yuehaibing@huawei.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/rtc') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 03b60d5c2330..75e0a22a2fa2 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -811,6 +811,7 @@ config RTC_DRV_MAX6902 config RTC_DRV_PCF2123 tristate "NXP PCF2123" + select REGMAP_SPI help If you say yes here you get support for the NXP PCF2123 RTC chip. -- cgit v1.2.3-59-g8ed1b From fe63604c630acfc51797d5896ff01cd59c684572 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 8 Jul 2019 10:26:47 +0200 Subject: rtc: stm32: remove one condition check in stm32_rtc_set_alarm() A condition check was repeated in this function implementation despite of a corresponding check in the stm32_rtc_alarm_irq_enable() function. Thus delete redundant source code here. This issue was detected by using the Coccinelle software. Suggested-by: Russell King Signed-off-by: Markus Elfring Reviewed-by: Amelie Delaunay Link: https://lore.kernel.org/r/4da614a4-83c6-548c-a112-033b846c561b@web.de Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-stm32.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 8e6c9b3bcc29..773a1990b93f 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -519,11 +519,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) /* Write to Alarm register */ writel_relaxed(alrmar, rtc->base + regs->alrmar); - if (alrm->enabled) - stm32_rtc_alarm_irq_enable(dev, 1); - else - stm32_rtc_alarm_irq_enable(dev, 0); - + stm32_rtc_alarm_irq_enable(dev, alrm->enabled); end: stm32_rtc_wpr_lock(rtc); -- cgit v1.2.3-59-g8ed1b From f0162d21cc8025c828fafe56ee25801f770f41da Mon Sep 17 00:00:00 2001 From: Hariprasad Kelam Date: Thu, 11 Jul 2019 23:26:15 +0530 Subject: rtc: wm831x: Add IRQF_ONESHOT flag fix below issue reported by coccicheck drivers/rtc/rtc-wm831x.c:436:7-32: ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT Signed-off-by: Hariprasad Kelam Acked-by: Charles Keepax Link: https://lore.kernel.org/r/20190711175615.GA13651@hari-Inspiron-1545 Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-wm831x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/rtc') diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index d2e8b21c90c4..ccef887d2690 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c @@ -435,7 +435,8 @@ static int wm831x_rtc_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL, wm831x_alm_irq, - IRQF_TRIGGER_RISING, "RTC alarm", + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "RTC alarm", wm831x_rtc); if (ret != 0) { dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", -- cgit v1.2.3-59-g8ed1b