From d25a5ed37d5fdd25f3cfbffc2f9a0f62e58f884c Mon Sep 17 00:00:00 2001 From: Sergey Yanovich Date: Tue, 23 Feb 2016 13:54:57 +0300 Subject: [PATCH 01/40] rtc: ds1302: rewrite using SPI DS1302 is an half-duplex SPI device. The driver respects this fact now. Pin configurations should be implemented using SPI subsystem. Signed-off-by: Sergei Ianovich Acked-by: Rob Herring Signed-off-by: Alexandre Belloni --- .../devicetree/bindings/rtc/maxim-ds1302.txt | 46 +++ drivers/rtc/Kconfig | 15 +- drivers/rtc/rtc-ds1302.c | 348 ++++++++---------- 3 files changed, 212 insertions(+), 197 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/maxim-ds1302.txt diff --git a/Documentation/devicetree/bindings/rtc/maxim-ds1302.txt b/Documentation/devicetree/bindings/rtc/maxim-ds1302.txt new file mode 100644 index 000000000000..ba470c56cdec --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/maxim-ds1302.txt @@ -0,0 +1,46 @@ +* Maxim/Dallas Semiconductor DS-1302 RTC + +Simple device which could be used to store date/time between reboots. + +The device uses the standard MicroWire half-duplex transfer timing. +Master output is set on low clock and sensed by the RTC on the rising +edge. Master input is set by the RTC on the trailing edge and is sensed +by the master on low clock. + +Required properties: + +- compatible : Should be "maxim,ds1302" + +Required SPI properties: + +- reg : Should be address of the device chip select within + the controller. + +- spi-max-frequency : DS-1302 has 500 kHz if powered at 2.2V, + and 2MHz if powered at 5V. + +- spi-3wire : The device has a shared signal IN/OUT line. + +- spi-lsb-first : DS-1302 requires least significant bit first + transfers. + +- spi-cs-high: DS-1302 has active high chip select line. This is + required unless inverted in hardware. + +Example: + +spi@901c { + #address-cells = <1>; + #size-cells = <0>; + compatible = "icpdas,lp8841-spi-rtc"; + reg = <0x901c 0x1>; + + rtc@0 { + compatible = "maxim,ds1302"; + reg = <0>; + spi-max-frequency = <500000>; + spi-3wire; + spi-lsb-first; + spi-cs-high; + }; +}; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 3e84315c6f12..f1e1f502be5d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -634,6 +634,15 @@ config RTC_DRV_M41T94 This driver can also be built as a module. If so, the module will be called rtc-m41t94. +config RTC_DRV_DS1302 + tristate "Dallas/Maxim DS1302" + depends on SPI + help + If you say yes here you get support for the Dallas DS1302 RTC chips. + + This driver can also be built as a module. If so, the module + will be called rtc-ds1302. + config RTC_DRV_DS1305 tristate "Dallas/Maxim DS1305/DS1306" help @@ -834,12 +843,6 @@ config RTC_DRV_DS1286 help If you say yes here you get support for the Dallas DS1286 RTC chips. -config RTC_DRV_DS1302 - tristate "Dallas DS1302" - depends on SH_SECUREEDGE5410 - help - If you say yes here you get support for the Dallas DS1302 RTC chips. - config RTC_DRV_DS1511 tristate "Dallas DS1511" depends on HAS_IOMEM diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 6bef7a5233c4..5cdc0f201b34 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -9,16 +9,17 @@ * this archive for more details. */ -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include #define DRV_NAME "rtc-ds1302" -#define DRV_VERSION "0.1.1" +#define DRV_VERSION "1.0.0" #define RTC_CMD_READ 0x81 /* Read command */ #define RTC_CMD_WRITE 0x80 /* Write command */ @@ -28,6 +29,8 @@ #define RTC_ADDR_RAM0 0x20 /* Address of RAM0 */ #define RTC_ADDR_TCR 0x08 /* Address of trickle charge register */ +#define RTC_CLCK_BURST 0x1F /* Address of clock burst */ +#define RTC_CLCK_LEN 0x08 /* Size of clock burst */ #define RTC_ADDR_CTRL 0x07 /* Address of control register */ #define RTC_ADDR_YEAR 0x06 /* Address of year register */ #define RTC_ADDR_DAY 0x05 /* Address of day of week register */ @@ -37,217 +40,180 @@ #define RTC_ADDR_MIN 0x01 /* Address of minute register */ #define RTC_ADDR_SEC 0x00 /* Address of second register */ -#ifdef CONFIG_SH_SECUREEDGE5410 -#include -#include - -#define RTC_RESET 0x1000 -#define RTC_IODATA 0x0800 -#define RTC_SCLK 0x0400 - -#define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) -#define get_dp() SECUREEDGE_READ_IOPORT() -#define ds1302_set_tx() -#define ds1302_set_rx() - -static inline int ds1302_hw_init(void) +static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *time) { - return 0; + struct spi_device *spi = dev_get_drvdata(dev); + u8 buf[1 + RTC_CLCK_LEN]; + u8 *bp = buf; + int status; + + /* Enable writing */ + bp = buf; + *bp++ = RTC_ADDR_CTRL << 1 | RTC_CMD_WRITE; + *bp++ = RTC_CMD_WRITE_ENABLE; + + status = spi_write_then_read(spi, buf, 2, + NULL, 0); + if (!status) + return status; + + /* Write registers starting at the first time/date address. */ + bp = buf; + *bp++ = RTC_CLCK_BURST << 1 | RTC_CMD_WRITE; + + *bp++ = bin2bcd(time->tm_sec); + *bp++ = bin2bcd(time->tm_min); + *bp++ = bin2bcd(time->tm_hour); + *bp++ = bin2bcd(time->tm_mday); + *bp++ = bin2bcd(time->tm_mon + 1); + *bp++ = time->tm_wday; + *bp++ = bin2bcd(time->tm_year % 100); + *bp++ = RTC_CMD_WRITE_DISABLE; + + /* use write-then-read since dma from stack is nonportable */ + return spi_write_then_read(spi, buf, sizeof(buf), + NULL, 0); } -static inline void ds1302_reset(void) +static int ds1302_rtc_get_time(struct device *dev, struct rtc_time *time) { - set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); -} + struct spi_device *spi = dev_get_drvdata(dev); + u8 addr = RTC_CLCK_BURST << 1 | RTC_CMD_READ; + u8 buf[RTC_CLCK_LEN - 1]; + int status; -static inline void ds1302_clock(void) -{ - set_dp(get_dp() | RTC_SCLK); /* clock high */ - set_dp(get_dp() & ~RTC_SCLK); /* clock low */ -} + /* Use write-then-read to get all the date/time registers + * since dma from stack is nonportable + */ + status = spi_write_then_read(spi, &addr, sizeof(addr), + buf, sizeof(buf)); + if (status < 0) + return status; -static inline void ds1302_start(void) -{ - set_dp(get_dp() | RTC_RESET); -} + /* Decode the registers */ + time->tm_sec = bcd2bin(buf[RTC_ADDR_SEC]); + time->tm_min = bcd2bin(buf[RTC_ADDR_MIN]); + time->tm_hour = bcd2bin(buf[RTC_ADDR_HOUR]); + time->tm_wday = buf[RTC_ADDR_DAY] - 1; + time->tm_mday = bcd2bin(buf[RTC_ADDR_DATE]); + time->tm_mon = bcd2bin(buf[RTC_ADDR_MON]) - 1; + time->tm_year = bcd2bin(buf[RTC_ADDR_YEAR]) + 100; -static inline void ds1302_stop(void) -{ - set_dp(get_dp() & ~RTC_RESET); -} - -static inline void ds1302_txbit(int bit) -{ - set_dp((get_dp() & ~RTC_IODATA) | (bit ? RTC_IODATA : 0)); -} - -static inline int ds1302_rxbit(void) -{ - return !!(get_dp() & RTC_IODATA); -} - -#else -#error "Add support for your platform" -#endif - -static void ds1302_sendbits(unsigned int val) -{ - int i; - - ds1302_set_tx(); - - for (i = 8; (i); i--, val >>= 1) { - ds1302_txbit(val & 0x1); - ds1302_clock(); - } -} - -static unsigned int ds1302_recvbits(void) -{ - unsigned int val; - int i; - - ds1302_set_rx(); - - for (i = 0, val = 0; (i < 8); i++) { - val |= (ds1302_rxbit() << i); - ds1302_clock(); - } - - return val; -} - -static unsigned int ds1302_readbyte(unsigned int addr) -{ - unsigned int val; - - ds1302_reset(); - - ds1302_start(); - ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); - val = ds1302_recvbits(); - ds1302_stop(); - - return val; -} - -static void ds1302_writebyte(unsigned int addr, unsigned int val) -{ - ds1302_reset(); - - ds1302_start(); - ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); - ds1302_sendbits(val); - ds1302_stop(); -} - -static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - tm->tm_sec = bcd2bin(ds1302_readbyte(RTC_ADDR_SEC)); - tm->tm_min = bcd2bin(ds1302_readbyte(RTC_ADDR_MIN)); - tm->tm_hour = bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR)); - tm->tm_wday = bcd2bin(ds1302_readbyte(RTC_ADDR_DAY)); - tm->tm_mday = bcd2bin(ds1302_readbyte(RTC_ADDR_DATE)); - tm->tm_mon = bcd2bin(ds1302_readbyte(RTC_ADDR_MON)) - 1; - tm->tm_year = bcd2bin(ds1302_readbyte(RTC_ADDR_YEAR)); - - if (tm->tm_year < 70) - tm->tm_year += 100; - - 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 + 1, tm->tm_year, tm->tm_wday); - - return rtc_valid_tm(tm); -} - -static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_ENABLE); - /* Stop RTC */ - ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); - - ds1302_writebyte(RTC_ADDR_SEC, bin2bcd(tm->tm_sec)); - ds1302_writebyte(RTC_ADDR_MIN, bin2bcd(tm->tm_min)); - ds1302_writebyte(RTC_ADDR_HOUR, bin2bcd(tm->tm_hour)); - ds1302_writebyte(RTC_ADDR_DAY, bin2bcd(tm->tm_wday)); - ds1302_writebyte(RTC_ADDR_DATE, bin2bcd(tm->tm_mday)); - ds1302_writebyte(RTC_ADDR_MON, bin2bcd(tm->tm_mon + 1)); - ds1302_writebyte(RTC_ADDR_YEAR, bin2bcd(tm->tm_year % 100)); - - /* Start RTC */ - ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); - - ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_DISABLE); - - return 0; -} - -static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - switch (cmd) { -#ifdef RTC_SET_CHARGE - case RTC_SET_CHARGE: - { - int tcs_val; - - if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int))) - return -EFAULT; - - ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf)); - return 0; - } -#endif - } - - return -ENOIOCTLCMD; + /* Time may not be set */ + return rtc_valid_tm(time); } static struct rtc_class_ops ds1302_rtc_ops = { - .read_time = ds1302_rtc_read_time, + .read_time = ds1302_rtc_get_time, .set_time = ds1302_rtc_set_time, - .ioctl = ds1302_rtc_ioctl, }; -static int __init ds1302_rtc_probe(struct platform_device *pdev) +static int ds1302_probe(struct spi_device *spi) { - struct rtc_device *rtc; + struct rtc_device *rtc; + u8 addr; + u8 buf[4]; + u8 *bp = buf; + int status; - if (ds1302_hw_init()) { - dev_err(&pdev->dev, "Failed to init communication channel"); + /* Sanity check board setup data. This may be hooked up + * in 3wire mode, but we don't care. Note that unless + * there's an inverter in place, this needs SPI_CS_HIGH! + */ + if (spi->bits_per_word && (spi->bits_per_word != 8)) { + dev_err(&spi->dev, "bad word length\n"); + return -EINVAL; + } else if (spi->max_speed_hz > 2000000) { + dev_err(&spi->dev, "speed is too high\n"); + return -EINVAL; + } else if (spi->mode & SPI_CPHA) { + dev_err(&spi->dev, "bad mode\n"); return -EINVAL; } - /* Reset */ - ds1302_reset(); - - /* Write a magic value to the DS1302 RAM, and see if it sticks. */ - ds1302_writebyte(RTC_ADDR_RAM0, 0x42); - if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) { - dev_err(&pdev->dev, "Failed to probe"); - return -ENODEV; + addr = RTC_ADDR_CTRL << 1 | RTC_CMD_READ; + status = spi_write_then_read(spi, &addr, sizeof(addr), buf, 1); + if (status < 0) { + dev_err(&spi->dev, "control register read error %d\n", + status); + return status; } - rtc = devm_rtc_device_register(&pdev->dev, "ds1302", - &ds1302_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + if ((buf[0] & ~RTC_CMD_WRITE_DISABLE) != 0) { + status = spi_write_then_read(spi, &addr, sizeof(addr), buf, 1); + if (status < 0) { + dev_err(&spi->dev, "control register read error %d\n", + status); + return status; + } - platform_set_drvdata(pdev, rtc); + if ((buf[0] & ~RTC_CMD_WRITE_DISABLE) != 0) { + dev_err(&spi->dev, "junk in control register\n"); + return -ENODEV; + } + } + if (buf[0] == 0) { + bp = buf; + *bp++ = RTC_ADDR_CTRL << 1 | RTC_CMD_WRITE; + *bp++ = RTC_CMD_WRITE_DISABLE; + + status = spi_write_then_read(spi, buf, 2, NULL, 0); + if (status < 0) { + dev_err(&spi->dev, "control register write error %d\n", + status); + return status; + } + + addr = RTC_ADDR_CTRL << 1 | RTC_CMD_READ; + status = spi_write_then_read(spi, &addr, sizeof(addr), buf, 1); + if (status < 0) { + dev_err(&spi->dev, + "error %d reading control register\n", + status); + return status; + } + + if (buf[0] != RTC_CMD_WRITE_DISABLE) { + dev_err(&spi->dev, "failed to detect chip\n"); + return -ENODEV; + } + } + + spi_set_drvdata(spi, spi); + + rtc = devm_rtc_device_register(&spi->dev, "ds1302", + &ds1302_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc)) { + status = PTR_ERR(rtc); + dev_err(&spi->dev, "error %d registering rtc\n", status); + return status; + } return 0; } -static struct platform_driver ds1302_platform_driver = { - .driver = { - .name = DRV_NAME, - }, +static int ds1302_remove(struct spi_device *spi) +{ + spi_set_drvdata(spi, NULL); + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id ds1302_dt_ids[] = { + { .compatible = "maxim,ds1302", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ds1302_dt_ids); +#endif + +static struct spi_driver ds1302_driver = { + .driver.name = "rtc-ds1302", + .driver.of_match_table = of_match_ptr(ds1302_dt_ids), + .probe = ds1302_probe, + .remove = ds1302_remove, }; -module_platform_driver_probe(ds1302_platform_driver, ds1302_rtc_probe); +module_spi_driver(ds1302_driver); MODULE_DESCRIPTION("Dallas DS1302 RTC driver"); MODULE_VERSION(DRV_VERSION); From df2d741f0e00669b94d675564f92949752a5d241 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 28 Mar 2016 12:24:00 +0100 Subject: [PATCH 02/40] rtc: at91sam9: remove duplicate assignment of variable mr mr is written twice with the same value, remove one of the redundant assignments to mr. Signed-off-by: Colin Ian King Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-at91sam9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 7206e2fa4383..99732e6f8c3b 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -268,7 +268,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static int at91_rtc_proc(struct device *dev, struct seq_file *seq) { struct sam9_rtc *rtc = dev_get_drvdata(dev); - u32 mr = mr = rtt_readl(rtc, MR); + u32 mr = rtt_readl(rtc, MR); seq_printf(seq, "update_IRQ\t: %s\n", (mr & AT91_RTT_RTTINCIEN) ? "yes" : "no"); From fa5691131a87a36ee2d535aa3e8886e4e4f1e9f3 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 31 Mar 2016 15:07:26 +0200 Subject: [PATCH 03/40] rtc: remove useless DRV_VERSION Many drivers are defining a DRV_VERSION. This is often only used for MODULE_VERSION and sometimes to print an info message at probe time. This is kind of pointless as they are all versionned with the kernel anyway. Also the core will print a message when a new rtc is found. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1216.c | 3 --- drivers/rtc/rtc-ds1286.c | 3 --- drivers/rtc/rtc-ds1302.c | 2 -- drivers/rtc/rtc-ds1343.c | 2 -- drivers/rtc/rtc-ds1511.c | 3 --- drivers/rtc/rtc-ds1553.c | 3 --- drivers/rtc/rtc-ds1672.c | 5 ----- drivers/rtc/rtc-ds1685.c | 3 --- drivers/rtc/rtc-ds1742.c | 3 --- drivers/rtc/rtc-ep93xx.c | 3 --- drivers/rtc/rtc-gemini.c | 1 - drivers/rtc/rtc-isl12022.c | 5 ----- drivers/rtc/rtc-isl1208.c | 6 ------ drivers/rtc/rtc-m48t35.c | 3 --- drivers/rtc/rtc-m48t86.c | 4 ---- drivers/rtc/rtc-max6900.c | 5 ----- drivers/rtc/rtc-pcf2123.c | 4 ---- drivers/rtc/rtc-pcf8563.c | 5 ----- drivers/rtc/rtc-rs5c313.c | 2 -- drivers/rtc/rtc-rs5c348.c | 4 ---- drivers/rtc/rtc-rs5c372.c | 6 +----- drivers/rtc/rtc-rx8581.c | 5 ----- drivers/rtc/rtc-sh.c | 2 -- drivers/rtc/rtc-stk17ta8.c | 3 --- drivers/rtc/rtc-x1205.c | 5 ----- 25 files changed, 1 insertion(+), 89 deletions(-) diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c index 12dbd70859ae..9c82b1da2d45 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c @@ -11,8 +11,6 @@ #include #include -#define DRV_VERSION "0.2" - struct ds1216_regs { u8 tsec; u8 sec; @@ -176,5 +174,4 @@ module_platform_driver_probe(ds1216_rtc_platform_driver, ds1216_rtc_probe); MODULE_AUTHOR("Thomas Bogendoerfer "); MODULE_DESCRIPTION("DS1216 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:rtc-ds1216"); diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index 8247a29a4eb4..756e509f6ed2 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c @@ -20,8 +20,6 @@ #include #include -#define DRV_VERSION "1.0" - struct ds1286_priv { struct rtc_device *rtc; u32 __iomem *rtcregs; @@ -363,5 +361,4 @@ module_platform_driver(ds1286_platform_driver); MODULE_AUTHOR("Thomas Bogendoerfer "); MODULE_DESCRIPTION("DS1286 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:rtc-ds1286"); diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 5cdc0f201b34..7811b357ed70 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -19,7 +19,6 @@ #include #define DRV_NAME "rtc-ds1302" -#define DRV_VERSION "1.0.0" #define RTC_CMD_READ 0x81 /* Read command */ #define RTC_CMD_WRITE 0x80 /* Write command */ @@ -216,6 +215,5 @@ static struct spi_driver ds1302_driver = { module_spi_driver(ds1302_driver); MODULE_DESCRIPTION("Dallas DS1302 RTC driver"); -MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR("Paul Mundt, David McCullough"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index 3d389bd8a289..23fa9f0cb5e3 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c @@ -24,7 +24,6 @@ #include #include -#define DS1343_DRV_VERSION "01.00" #define DALLAS_MAXIM_DS1343 0 #define DALLAS_MAXIM_DS1344 1 @@ -747,4 +746,3 @@ MODULE_DESCRIPTION("DS1343 RTC SPI Driver"); MODULE_AUTHOR("Raghavendra Chandra Ganiga ," "Ankur Srivastava "); MODULE_LICENSE("GPL v2"); -MODULE_VERSION(DS1343_DRV_VERSION); diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index da3d04ce83bd..1b2dcb58c0ab 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -25,8 +25,6 @@ #include #include -#define DRV_VERSION "0.6" - enum ds1511reg { DS1511_SEC = 0x0, DS1511_MIN = 0x1, @@ -537,4 +535,3 @@ module_platform_driver(ds1511_rtc_driver); MODULE_AUTHOR("Andrew Sharp "); MODULE_DESCRIPTION("Dallas DS1511 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 38422ab4ec5a..9961ec646fd2 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -20,8 +20,6 @@ #include #include -#define DRV_VERSION "0.3" - #define RTC_REG_SIZE 0x2000 #define RTC_OFFSET 0x1ff0 @@ -359,4 +357,3 @@ module_platform_driver(ds1553_rtc_driver); MODULE_AUTHOR("Atsushi Nemoto "); MODULE_DESCRIPTION("Dallas DS1553 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 92b1cbf2c4a7..5c18ac7394c4 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -13,8 +13,6 @@ #include #include -#define DRV_VERSION "0.4" - /* Registers */ #define DS1672_REG_CNT_BASE 0 @@ -165,8 +163,6 @@ static int ds1672_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - rtc = devm_rtc_device_register(&client->dev, ds1672_driver.driver.name, &ds1672_rtc_ops, THIS_MODULE); @@ -213,4 +209,3 @@ module_i2c_driver(ds1672_driver); MODULE_AUTHOR("Alessandro Zummo "); MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 1e6cfc84b1f6..2698d8ffe4fd 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -32,8 +32,6 @@ #include #endif -#define DRV_VERSION "0.42.0" - /* ----------------------------------------------------------------------- */ /* Standard read/write functions if platform does not provide overrides */ @@ -2224,5 +2222,4 @@ MODULE_AUTHOR("Joshua Kinard "); MODULE_AUTHOR("Matthias Fuchs "); MODULE_DESCRIPTION("Dallas/Maxim DS1685/DS1687-series RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:rtc-ds1685"); diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index c5168b3bcf1a..3abf1cbfb8ce 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -24,8 +24,6 @@ #include #include -#define DRV_VERSION "0.4" - #define RTC_SIZE 8 #define RTC_CONTROL 0 @@ -239,5 +237,4 @@ module_platform_driver(ds1742_rtc_driver); MODULE_AUTHOR("Atsushi Nemoto "); MODULE_DESCRIPTION("Dallas DS1742 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:rtc-ds1742"); diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index a1628adf9f52..694038208745 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c @@ -28,8 +28,6 @@ #define EP93XX_RTC_SWCOMP_INT_MASK 0x0000ffff #define EP93XX_RTC_SWCOMP_INT_SHIFT 0 -#define DRV_VERSION "0.3" - /* * struct device dev.platform_data is used to store our private data * because struct rtc_device does not have a variable to hold it. @@ -184,5 +182,4 @@ module_platform_driver(ep93xx_rtc_driver); MODULE_AUTHOR("Alessandro Zummo "); MODULE_DESCRIPTION("EP93XX RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:ep93xx-rtc"); diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c index f46b6d46a51b..b57505efadbc 100644 --- a/drivers/rtc/rtc-gemini.c +++ b/drivers/rtc/rtc-gemini.c @@ -28,7 +28,6 @@ #include #define DRV_NAME "rtc-gemini" -#define DRV_VERSION "0.2" MODULE_AUTHOR("Hans Ulli Kroll "); MODULE_DESCRIPTION("RTC driver for Gemini SoC"); diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 839d1fd63cd7..38586a024ee8 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -20,8 +20,6 @@ #include #include -#define DRV_VERSION "0.1" - /* ISL register offsets */ #define ISL12022_REG_SC 0x00 #define ISL12022_REG_MN 0x01 @@ -258,8 +256,6 @@ static int isl12022_probe(struct i2c_client *client, if (!isl12022) return -ENOMEM; - dev_dbg(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - i2c_set_clientdata(client, isl12022); isl12022->rtc = devm_rtc_device_register(&client->dev, @@ -299,4 +295,3 @@ module_i2c_driver(isl12022_driver); MODULE_AUTHOR("roman.fietze@telemotive.de"); MODULE_DESCRIPTION("ISL 12022 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index b57a304ff62c..2893785f0eba 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -15,8 +15,6 @@ #include #include -#define DRV_VERSION "0.3" - /* Register map */ /* rtc section */ #define ISL1208_REG_SC 0x00 @@ -632,9 +630,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) if (isl1208_i2c_validate_client(client) < 0) return -ENODEV; - dev_info(&client->dev, - "chip found, driver version " DRV_VERSION "\n"); - if (client->irq > 0) { rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, isl1208_rtc_interrupt, @@ -706,4 +701,3 @@ module_i2c_driver(isl1208_driver); MODULE_AUTHOR("Herbert Valerio Riedel "); MODULE_DESCRIPTION("Intersil ISL1208 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c index c62b51217ecf..810f4ea481e4 100644 --- a/drivers/rtc/rtc-m48t35.c +++ b/drivers/rtc/rtc-m48t35.c @@ -22,8 +22,6 @@ #include #include -#define DRV_VERSION "1.0" - struct m48t35_rtc { u8 pad[0x7ff8]; /* starts at 0x7ff8 */ u8 control; @@ -190,5 +188,4 @@ module_platform_driver(m48t35_platform_driver); MODULE_AUTHOR("Thomas Bogendoerfer "); MODULE_DESCRIPTION("M48T35 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:rtc-m48t35"); diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index a17b7a3ceece..f72b91f2501f 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c @@ -39,9 +39,6 @@ #define M48T86_REG_B_SET (1 << 7) #define M48T86_REG_D_VRT (1 << 7) -#define DRV_VERSION "0.1" - - static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm) { unsigned char reg; @@ -178,5 +175,4 @@ module_platform_driver(m48t86_rtc_platform_driver); MODULE_AUTHOR("Alessandro Zummo "); MODULE_DESCRIPTION("M48T86 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:rtc-m48t86"); diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index b2a76077bbfa..48b6b411f8b2 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c @@ -17,8 +17,6 @@ #include #include -#define DRV_VERSION "0.2" - /* * register indices */ @@ -218,8 +216,6 @@ max6900_probe(struct i2c_client *client, const struct i2c_device_id *id) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - rtc = devm_rtc_device_register(&client->dev, max6900_driver.driver.name, &max6900_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) @@ -249,4 +245,3 @@ module_i2c_driver(max6900_driver); MODULE_DESCRIPTION("Maxim MAX6900 RTC driver"); MODULE_AUTHOR("Dale Farnsworth "); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index da27738b1242..f22e060709e5 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -46,8 +46,6 @@ #include #include -#define DRV_VERSION "0.6" - /* REGISTERS */ #define PCF2123_REG_CTRL1 (0x00) /* Control Register 1 */ #define PCF2123_REG_CTRL2 (0x01) /* Control Register 2 */ @@ -395,7 +393,6 @@ static int pcf2123_probe(struct spi_device *spi) } } - dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n"); dev_info(&spi->dev, "spiclk %u KHz.\n", (spi->max_speed_hz + 500) / 1000); @@ -474,4 +471,3 @@ module_spi_driver(pcf2123_driver); MODULE_AUTHOR("Chris Verges "); MODULE_DESCRIPTION("NXP PCF2123 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index c8f95b8e463a..d5e6ed96b748 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -23,8 +23,6 @@ #include #include -#define DRV_VERSION "0.4.4" - #define PCF8563_REG_ST1 0x00 /* status */ #define PCF8563_REG_ST2 0x01 #define PCF8563_BIT_AIE (1 << 1) @@ -580,8 +578,6 @@ static int pcf8563_probe(struct i2c_client *client, if (!pcf8563) return -ENOMEM; - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - i2c_set_clientdata(client, pcf8563); pcf8563->client = client; device_set_wakeup_capable(&client->dev, 1); @@ -662,4 +658,3 @@ module_i2c_driver(pcf8563_driver); MODULE_AUTHOR("Alessandro Zummo "); MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c index 5f48167c802a..89f38e3e917d 100644 --- a/drivers/rtc/rtc-rs5c313.c +++ b/drivers/rtc/rtc-rs5c313.c @@ -50,7 +50,6 @@ #include #define DRV_NAME "rs5c313" -#define DRV_VERSION "1.13" #ifdef CONFIG_SH_LANDISK /*****************************************************/ @@ -407,7 +406,6 @@ static void __exit rs5c313_rtc_exit(void) module_init(rs5c313_rtc_init); module_exit(rs5c313_rtc_exit); -MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu "); MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 1162fecab8cf..9a306983aaba 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c @@ -25,8 +25,6 @@ #include #include -#define DRV_VERSION "0.2" - #define RS5C348_REG_SECS 0 #define RS5C348_REG_MINS 1 #define RS5C348_REG_HOURS 2 @@ -171,7 +169,6 @@ static int rs5c348_probe(struct spi_device *spi) goto kfree_exit; } - dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n"); dev_info(&spi->dev, "spiclk %u KHz.\n", (spi->max_speed_hz + 500) / 1000); @@ -230,5 +227,4 @@ module_spi_driver(rs5c348_driver); MODULE_AUTHOR("Atsushi Nemoto "); MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("spi:rtc-rs5c348"); diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 28871cd7e3b5..12270c789088 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -16,9 +16,6 @@ #include #include -#define DRV_VERSION "0.6" - - /* * Ricoh has a family of I2C based RTCs, which differ only slightly from * each other. Differences center on pinout (e.g. how many interrupts, @@ -640,7 +637,7 @@ static int rs5c372_probe(struct i2c_client *client, if (rs5c372_get_datetime(client, &tm) < 0) dev_warn(&client->dev, "clock needs to be set\n"); - dev_info(&client->dev, "%s found, %s, driver version " DRV_VERSION "\n", + dev_info(&client->dev, "%s found, %s\n", ({ char *s; switch (rs5c372->type) { case rtc_r2025sd: s = "r2025sd"; break; case rtc_r2221tl: s = "r2221tl"; break; @@ -696,4 +693,3 @@ MODULE_AUTHOR( "Paul Mundt "); MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index 161e25d016c3..0c362a3d1f17 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c @@ -18,8 +18,6 @@ #include #include -#define DRV_VERSION "0.1" - #define RX8581_REG_SC 0x00 /* Second in BCD */ #define RX8581_REG_MN 0x01 /* Minute in BCD */ #define RX8581_REG_HR 0x02 /* Hour in BCD */ @@ -292,8 +290,6 @@ static int rx8581_probe(struct i2c_client *client, rx8581->write_block_data = rx8581_write_block_data; } - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - rx8581->rtc = devm_rtc_device_register(&client->dev, rx8581_driver.driver.name, &rx8581_rtc_ops, THIS_MODULE); @@ -325,4 +321,3 @@ module_i2c_driver(rx8581_driver); MODULE_AUTHOR("Martyn Welch "); MODULE_DESCRIPTION("Epson RX-8581 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 2b81dd4baf17..a45845a571e5 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -30,7 +30,6 @@ #include #define DRV_NAME "sh-rtc" -#define DRV_VERSION "0.2.3" #define RTC_REG(r) ((r) * rtc_reg_size) @@ -790,7 +789,6 @@ static struct platform_driver sh_rtc_platform_driver = { module_platform_driver_probe(sh_rtc_platform_driver, sh_rtc_probe); MODULE_DESCRIPTION("SuperH on-chip RTC driver"); -MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR("Paul Mundt , " "Jamie Lenehan , " "Angelo Castello "); diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index ba6a83b5b5c9..a456cb6177ea 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -23,8 +23,6 @@ #include #include -#define DRV_VERSION "0.1" - #define RTC_REG_SIZE 0x20000 #define RTC_OFFSET 0x1fff0 @@ -366,4 +364,3 @@ module_platform_driver(stk17ta8_rtc_driver); MODULE_AUTHOR("Thomas Hommel "); MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 5638b7ba8b06..f08f18e4fcdf 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -24,8 +24,6 @@ #include #include -#define DRV_VERSION "1.0.8" - /* offsets into CCR area */ #define CCR_SEC 0 @@ -634,8 +632,6 @@ static int x1205_probe(struct i2c_client *client, if (x1205_validate_client(client) < 0) return -ENODEV; - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); - rtc = devm_rtc_device_register(&client->dev, x1205_driver.driver.name, &x1205_rtc_ops, THIS_MODULE); @@ -693,4 +689,3 @@ MODULE_AUTHOR( "Alessandro Zummo "); MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); From ef6b3125ca6f4319e760dc27617025b8af58d9d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 29 Mar 2016 08:55:58 +0200 Subject: [PATCH 04/40] rtc: m41t80: update sysfs entries export MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver used an old sysfs entry export. Update it to use the DEVICE_ATTR_XX macro and remove the unnecessary CONFIG_RTC_INTF_SYSFS macro. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 56 +++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index d107a8e72a7d..27217898abe1 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -230,9 +230,8 @@ static struct rtc_class_ops m41t80_rtc_ops = { .proc = m41t80_rtc_proc, }; -#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) -static ssize_t m41t80_sysfs_show_flags(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t flags_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); int val; @@ -242,10 +241,10 @@ static ssize_t m41t80_sysfs_show_flags(struct device *dev, return val; return sprintf(buf, "%#x\n", val); } -static DEVICE_ATTR(flags, S_IRUGO, m41t80_sysfs_show_flags, NULL); +static DEVICE_ATTR_RO(flags); -static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t sqwfreq_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct m41t80_data *clientdata = i2c_get_clientdata(client); @@ -272,9 +271,10 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev, } return sprintf(buf, "%d\n", val); } -static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) + +static ssize_t sqwfreq_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct m41t80_data *clientdata = i2c_get_clientdata(client); @@ -324,8 +324,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev, } return count; } -static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR, - m41t80_sysfs_show_sqwfreq, m41t80_sysfs_set_sqwfreq); +static DEVICE_ATTR_RW(sqwfreq); static struct attribute *attrs[] = { &dev_attr_flags.attr, @@ -336,17 +335,6 @@ static struct attribute_group attr_group = { .attrs = attrs, }; -static int m41t80_sysfs_register(struct device *dev) -{ - return sysfs_create_group(&dev->kobj, &attr_group); -} -#else -static int m41t80_sysfs_register(struct device *dev) -{ - return 0; -} -#endif - #ifdef CONFIG_RTC_DRV_M41T80_WDT /* ***************************************************************************** @@ -636,6 +624,14 @@ static struct notifier_block wdt_notifier = { * ***************************************************************************** */ + +static void m41t80_remove_sysfs_group(void *_dev) +{ + struct device *dev = _dev; + + sysfs_remove_group(&dev->kobj, &attr_group); +} + static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -697,9 +693,21 @@ static int m41t80_probe(struct i2c_client *client, return rc; } - rc = m41t80_sysfs_register(&client->dev); - if (rc) + /* Export sysfs entries */ + rc = sysfs_create_group(&(&client->dev)->kobj, &attr_group); + if (rc) { + dev_err(&client->dev, "Failed to create sysfs group: %d\n", rc); return rc; + } + + rc = devm_add_action(&client->dev, m41t80_remove_sysfs_group, + &client->dev); + if (rc) { + m41t80_remove_sysfs_group(&client->dev); + dev_err(&client->dev, + "Failed to add sysfs cleanup action: %d\n", rc); + return rc; + } #ifdef CONFIG_RTC_DRV_M41T80_WDT if (clientdata->features & M41T80_FEATURE_HT) { From ca91607fe76cc34b54957f5963f7102b37b861dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 29 Mar 2016 08:55:59 +0200 Subject: [PATCH 05/40] rtc: m41t80: remove proc macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the CONFIG_RTC_INTF_PROC and CONFIG_RTC_INTF_PROC_MODULE macro which is not necessary anymore. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 27217898abe1..cc8b93d2edf5 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -192,7 +192,6 @@ static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) return 0; } -#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq) { struct i2c_client *client = to_i2c_client(dev); @@ -206,9 +205,6 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq) } return 0; } -#else -#define m41t80_rtc_proc NULL -#endif static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm) { From f2b84ee88d367dd563c25b6900da279ab2ffa3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 29 Mar 2016 08:56:00 +0200 Subject: [PATCH 06/40] rtc: m41t80: replace i2c functions for smbus ones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver used i2c_transfer methods to read and set date/time. The smbus methods should be used. This commit replaces i2c_transfer functions by i2c_smbus_XX_i2c_block_data for reading and setting the datetime. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 136 +++++++++++++-------------------------- 1 file changed, 45 insertions(+), 91 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index cc8b93d2edf5..1a769275ab9d 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -32,21 +32,21 @@ #include #endif -#define M41T80_REG_SSEC 0 -#define M41T80_REG_SEC 1 -#define M41T80_REG_MIN 2 -#define M41T80_REG_HOUR 3 -#define M41T80_REG_WDAY 4 -#define M41T80_REG_DAY 5 -#define M41T80_REG_MON 6 -#define M41T80_REG_YEAR 7 -#define M41T80_REG_ALARM_MON 0xa -#define M41T80_REG_ALARM_DAY 0xb -#define M41T80_REG_ALARM_HOUR 0xc -#define M41T80_REG_ALARM_MIN 0xd -#define M41T80_REG_ALARM_SEC 0xe -#define M41T80_REG_FLAGS 0xf -#define M41T80_REG_SQW 0x13 +#define M41T80_REG_SSEC 0x00 +#define M41T80_REG_SEC 0x01 +#define M41T80_REG_MIN 0x02 +#define M41T80_REG_HOUR 0x03 +#define M41T80_REG_WDAY 0x04 +#define M41T80_REG_DAY 0x05 +#define M41T80_REG_MON 0x06 +#define M41T80_REG_YEAR 0x07 +#define M41T80_REG_ALARM_MON 0x0a +#define M41T80_REG_ALARM_DAY 0x0b +#define M41T80_REG_ALARM_HOUR 0x0c +#define M41T80_REG_ALARM_MIN 0x0d +#define M41T80_REG_ALARM_SEC 0x0e +#define M41T80_REG_FLAGS 0x0f +#define M41T80_REG_SQW 0x13 #define M41T80_DATETIME_REG_SIZE (M41T80_REG_YEAR + 1) #define M41T80_ALARM_REG_SIZE \ @@ -93,24 +93,13 @@ struct m41t80_data { static int m41t80_get_datetime(struct i2c_client *client, struct rtc_time *tm) { - u8 buf[M41T80_DATETIME_REG_SIZE], dt_addr[1] = { M41T80_REG_SEC }; - struct i2c_msg msgs[] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = dt_addr, - }, - { - .addr = client->addr, - .flags = I2C_M_RD, - .len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC, - .buf = buf + M41T80_REG_SEC, - }, - }; + unsigned char buf[8]; + int err; - if (i2c_transfer(client->adapter, msgs, 2) < 0) { - dev_err(&client->dev, "read error\n"); + err = i2c_smbus_read_i2c_block_data(client, M41T80_REG_SSEC, + sizeof(buf), buf); + if (err < 0) { + dev_err(&client->dev, "Unable to read date\n"); return -EIO; } @@ -129,67 +118,29 @@ static int m41t80_get_datetime(struct i2c_client *client, /* Sets the given date and time to the real time clock. */ static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) { - u8 wbuf[1 + M41T80_DATETIME_REG_SIZE]; - u8 *buf = &wbuf[1]; - u8 dt_addr[1] = { M41T80_REG_SEC }; - struct i2c_msg msgs_in[] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = dt_addr, - }, - { - .addr = client->addr, - .flags = I2C_M_RD, - .len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC, - .buf = buf + M41T80_REG_SEC, - }, - }; - struct i2c_msg msgs[] = { - { - .addr = client->addr, - .flags = 0, - .len = 1 + M41T80_DATETIME_REG_SIZE, - .buf = wbuf, - }, - }; + unsigned char buf[8]; + int err; - /* Read current reg values into buf[1..7] */ - if (i2c_transfer(client->adapter, msgs_in, 2) < 0) { - dev_err(&client->dev, "read error\n"); - return -EIO; - } - - wbuf[0] = 0; /* offset into rtc's regs */ - /* Merge time-data and register flags into buf[0..7] */ - buf[M41T80_REG_SSEC] = 0; - buf[M41T80_REG_SEC] = - bin2bcd(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f); - buf[M41T80_REG_MIN] = - bin2bcd(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f); - buf[M41T80_REG_HOUR] = - bin2bcd(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f); - buf[M41T80_REG_WDAY] = - (tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07); - buf[M41T80_REG_DAY] = - bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f); - buf[M41T80_REG_MON] = - bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f); - - /* assume 20YY not 19YY */ - if (tm->tm_year < 100 || tm->tm_year > 199) { - dev_err(&client->dev, "Year must be between 2000 and 2099. It's %d.\n", - tm->tm_year + 1900); + if (tm->tm_year < 100 || tm->tm_year > 199) return -EINVAL; - } - buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100); - if (i2c_transfer(client->adapter, msgs, 1) != 1) { - dev_err(&client->dev, "write error\n"); - return -EIO; + buf[M41T80_REG_SSEC] = 0; + buf[M41T80_REG_SEC] = bin2bcd(tm->tm_sec); + buf[M41T80_REG_MIN] = bin2bcd(tm->tm_min); + buf[M41T80_REG_HOUR] = bin2bcd(tm->tm_hour); + buf[M41T80_REG_DAY] = bin2bcd(tm->tm_mday); + buf[M41T80_REG_MON] = bin2bcd(tm->tm_mon + 1); + buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year - 100); + buf[M41T80_REG_WDAY] = tm->tm_wday; + + err = i2c_smbus_write_i2c_block_data(client, M41T80_REG_SSEC, + sizeof(buf), buf); + if (err < 0) { + dev_err(&client->dev, "Unable to write to date registers\n"); + return err; } - return 0; + + return err; } static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq) @@ -631,14 +582,17 @@ static void m41t80_remove_sysfs_group(void *_dev) static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int rc = 0; struct rtc_device *rtc = NULL; struct rtc_time tm; struct m41t80_data *clientdata = NULL; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C - | I2C_FUNC_SMBUS_BYTE_DATA)) + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK | + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n"); return -ENODEV; + } clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata), GFP_KERNEL); From 54339f3b311f1b2cbef7b84d6794e00e7ecb2184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 29 Mar 2016 08:56:01 +0200 Subject: [PATCH 07/40] rtc: m41t80: add the use of 'BIT' macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace bit shifts by BIT macro. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 1a769275ab9d..f991433bbe8b 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -52,21 +52,21 @@ #define M41T80_ALARM_REG_SIZE \ (M41T80_REG_ALARM_SEC + 1 - M41T80_REG_ALARM_MON) -#define M41T80_SEC_ST (1 << 7) /* ST: Stop Bit */ -#define M41T80_ALMON_AFE (1 << 7) /* AFE: AF Enable Bit */ -#define M41T80_ALMON_SQWE (1 << 6) /* SQWE: SQW Enable Bit */ -#define M41T80_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */ -#define M41T80_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */ -#define M41T80_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */ -#define M41T80_WATCHDOG_RB2 (1 << 7) /* RB: Watchdog resolution */ -#define M41T80_WATCHDOG_RB1 (1 << 1) /* RB: Watchdog resolution */ -#define M41T80_WATCHDOG_RB0 (1 << 0) /* RB: Watchdog resolution */ +#define M41T80_SEC_ST BIT(7) /* ST: Stop Bit */ +#define M41T80_ALMON_AFE BIT(7) /* AFE: AF Enable Bit */ +#define M41T80_ALMON_SQWE BIT(6) /* SQWE: SQW Enable Bit */ +#define M41T80_ALHOUR_HT BIT(6) /* HT: Halt Update Bit */ +#define M41T80_FLAGS_AF BIT(6) /* AF: Alarm Flag Bit */ +#define M41T80_FLAGS_BATT_LOW BIT(4) /* BL: Battery Low Bit */ +#define M41T80_WATCHDOG_RB2 BIT(7) /* RB: Watchdog resolution */ +#define M41T80_WATCHDOG_RB1 BIT(1) /* RB: Watchdog resolution */ +#define M41T80_WATCHDOG_RB0 BIT(0) /* RB: Watchdog resolution */ -#define M41T80_FEATURE_HT (1 << 0) /* Halt feature */ -#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */ -#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */ -#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */ -#define M41T80_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */ +#define M41T80_FEATURE_HT BIT(0) /* Halt feature */ +#define M41T80_FEATURE_BL BIT(1) /* Battery low indicator */ +#define M41T80_FEATURE_SQ BIT(2) /* Squarewave feature */ +#define M41T80_FEATURE_WD BIT(3) /* Extra watchdog resolution */ +#define M41T80_FEATURE_SQ_ALT BIT(4) /* RSx bits are in reg 4 */ static DEFINE_MUTEX(m41t80_rtc_mutex); static const struct i2c_device_id m41t80_id[] = { From fc99b90154e519dd6cd21cb11d013f36017a1b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 29 Mar 2016 08:56:02 +0200 Subject: [PATCH 08/40] rtc: m41t80: remove warnings and replace obsolete function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the obsolete "simple_strtoul" function to "kstrtoul". Remove some checkpatch's errors, warnings and checks : - alignment with open parenthesis - spaces around '<' and '<<' - blank line after structure - quoted string split across lines Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index f991433bbe8b..1575b08f8908 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -226,7 +226,11 @@ static ssize_t sqwfreq_store(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct m41t80_data *clientdata = i2c_get_clientdata(client); int almon, sqw, reg_sqw, rc; - int val = simple_strtoul(buf, NULL, 0); + unsigned long val; + + rc = kstrtoul(buf, 0, &val); + if (rc < 0) + return rc; if (!(clientdata->features & M41T80_FEATURE_SQ)) return -EINVAL; @@ -255,7 +259,7 @@ static ssize_t sqwfreq_store(struct device *dev, sqw = (sqw & 0x0f) | (val << 4); rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, - almon & ~M41T80_ALMON_SQWE); + almon & ~M41T80_ALMON_SQWE); if (rc < 0) return rc; @@ -265,8 +269,8 @@ static ssize_t sqwfreq_store(struct device *dev, return rc; rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, - almon | M41T80_ALMON_SQWE); - if (rc <0) + almon | M41T80_ALMON_SQWE); + if (rc < 0) return rc; } return count; @@ -278,6 +282,7 @@ static struct attribute *attrs[] = { &dev_attr_sqwfreq.attr, NULL, }; + static struct attribute_group attr_group = { .attrs = attrs, }; @@ -329,7 +334,7 @@ static void wdt_ping(void) /* * WDS = 1 (0x80), mulitplier = WD_TIMO, resolution = 1s (0x02) */ - i2c_data[1] = wdt_margin<<2 | 0x82; + i2c_data[1] = wdt_margin << 2 | 0x82; /* * M41T65 has three bits for watchdog resolution. Don't set bit 7, as @@ -595,7 +600,7 @@ static int m41t80_probe(struct i2c_client *client, } clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata), - GFP_KERNEL); + GFP_KERNEL); if (!clientdata) return -ENOMEM; @@ -603,7 +608,7 @@ static int m41t80_probe(struct i2c_client *client, i2c_set_clientdata(client, clientdata); rtc = devm_rtc_device_register(&client->dev, client->name, - &m41t80_rtc_ops, THIS_MODULE); + &m41t80_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) return PTR_ERR(rtc); @@ -617,14 +622,13 @@ static int m41t80_probe(struct i2c_client *client, m41t80_get_datetime(client, &tm); dev_info(&client->dev, "HT bit was set!\n"); dev_info(&client->dev, - "Power Down at " - "%04i-%02i-%02i %02i:%02i:%02i\n", + "Power Down at %04i-%02i-%02i %02i:%02i:%02i\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); } rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR, - rc & ~M41T80_ALHOUR_HT); + rc & ~M41T80_ALHOUR_HT); } if (rc < 0) { @@ -637,7 +641,7 @@ static int m41t80_probe(struct i2c_client *client, if (rc >= 0 && rc & M41T80_SEC_ST) rc = i2c_smbus_write_byte_data(client, M41T80_REG_SEC, - rc & ~M41T80_SEC_ST); + rc & ~M41T80_SEC_ST); if (rc < 0) { dev_err(&client->dev, "Can't clear ST bit\n"); return rc; From 9c6dfed92c3e86d6f84780625c0595ba56d03986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 29 Mar 2016 11:04:13 +0200 Subject: [PATCH 09/40] rtc: m41t80: add alarm functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous 'commit c3b79770e51a ("Expire alarms after the time is set")' and 'commit 48e9766726eb ("remove disabled alarm functionality")' removed the alarm support because the alarm irq was not functional. Add the alarm IRQ functionality with newer functions than previous code. Tested with 'rtctest' and the alarm is functional. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 180 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 167 insertions(+), 13 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 1575b08f8908..c72473864418 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -90,6 +90,46 @@ struct m41t80_data { struct rtc_device *rtc; }; +static irqreturn_t m41t80_handle_irq(int irq, void *dev_id) +{ + struct i2c_client *client = dev_id; + struct m41t80_data *m41t80 = i2c_get_clientdata(client); + struct mutex *lock = &m41t80->rtc->ops_lock; + unsigned long events = 0; + int flags, flags_afe; + + mutex_lock(lock); + + flags_afe = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); + if (flags_afe < 0) { + mutex_unlock(lock); + return IRQ_NONE; + } + + flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); + if (flags <= 0) { + mutex_unlock(lock); + return IRQ_NONE; + } + + if (flags & M41T80_FLAGS_AF) { + flags &= ~M41T80_FLAGS_AF; + flags_afe &= ~M41T80_ALMON_AFE; + events |= RTC_AF; + } + + if (events) { + rtc_update_irq(m41t80->rtc, 1, events); + i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, flags); + i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, + flags_afe); + } + + mutex_unlock(lock); + + return IRQ_HANDLED; +} + static int m41t80_get_datetime(struct i2c_client *client, struct rtc_time *tm) { @@ -167,10 +207,109 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) return m41t80_set_datetime(to_i2c_client(dev), tm); } -/* - * XXX - m41t80 alarm functionality is reported broken. - * until it is fixed, don't register alarm functions. - */ +static int m41t80_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct i2c_client *client = to_i2c_client(dev); + int flags, retval; + + flags = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); + if (flags < 0) + return flags; + + if (enabled) + flags |= M41T80_ALMON_AFE; + else + flags &= ~M41T80_ALMON_AFE; + + retval = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, flags); + if (retval < 0) { + dev_info(dev, "Unable to enable alarm IRQ %d\n", retval); + return retval; + } + return 0; +} + +static int m41t80_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 alarmvals[5]; + int ret, err; + + alarmvals[0] = bin2bcd(alrm->time.tm_mon + 1); + alarmvals[1] = bin2bcd(alrm->time.tm_mday); + alarmvals[2] = bin2bcd(alrm->time.tm_hour); + alarmvals[3] = bin2bcd(alrm->time.tm_min); + alarmvals[4] = bin2bcd(alrm->time.tm_sec); + + /* Clear AF and AFE flags */ + ret = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); + if (ret < 0) + return ret; + err = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, + ret & ~(M41T80_ALMON_AFE)); + if (err < 0) { + dev_err(dev, "Unable to clear AFE bit\n"); + return err; + } + + ret = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); + if (ret < 0) + return ret; + + err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, + ret & ~(M41T80_FLAGS_AF)); + if (err < 0) { + dev_err(dev, "Unable to clear AF bit\n"); + return err; + } + + /* Write the alarm */ + err = i2c_smbus_write_i2c_block_data(client, M41T80_REG_ALARM_MON, + 5, alarmvals); + if (err) + return err; + + /* Enable the alarm interrupt */ + if (alrm->enabled) { + alarmvals[0] |= M41T80_ALMON_AFE; + err = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, + alarmvals[0]); + if (err) + return err; + } + + return 0; +} + +static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 alarmvals[5]; + int flags, ret; + + ret = i2c_smbus_read_i2c_block_data(client, M41T80_REG_ALARM_MON, + 5, alarmvals); + if (ret != 5) + return ret < 0 ? ret : -EIO; + + flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); + if (flags < 0) + return flags; + + alrm->time.tm_sec = bcd2bin(alarmvals[4] & 0x7f); + alrm->time.tm_min = bcd2bin(alarmvals[3] & 0x7f); + alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f); + alrm->time.tm_wday = -1; + alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f); + alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f); + alrm->time.tm_year = -1; + + alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE); + alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled; + + return 0; +} + static struct rtc_class_ops m41t80_rtc_ops = { .read_time = m41t80_rtc_read_time, .set_time = m41t80_rtc_set_time, @@ -591,7 +730,7 @@ static int m41t80_probe(struct i2c_client *client, int rc = 0; struct rtc_device *rtc = NULL; struct rtc_time tm; - struct m41t80_data *clientdata = NULL; + struct m41t80_data *m41t80_data = NULL; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_BYTE_DATA)) { @@ -599,26 +738,41 @@ static int m41t80_probe(struct i2c_client *client, return -ENODEV; } - clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata), - GFP_KERNEL); - if (!clientdata) + m41t80_data = devm_kzalloc(&client->dev, sizeof(*m41t80_data), + GFP_KERNEL); + if (!m41t80_data) return -ENOMEM; - clientdata->features = id->driver_data; - i2c_set_clientdata(client, clientdata); + m41t80_data->features = id->driver_data; + i2c_set_clientdata(client, m41t80_data); + + if (client->irq > 0) { + rc = devm_request_threaded_irq(&client->dev, client->irq, + NULL, m41t80_handle_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "m41t80", client); + if (rc) { + dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); + client->irq = 0; + } else { + m41t80_rtc_ops.read_alarm = m41t80_read_alarm; + m41t80_rtc_ops.set_alarm = m41t80_set_alarm; + m41t80_rtc_ops.alarm_irq_enable = m41t80_alarm_irq_enable; + } + } rtc = devm_rtc_device_register(&client->dev, client->name, &m41t80_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) return PTR_ERR(rtc); - clientdata->rtc = rtc; + m41t80_data->rtc = rtc; /* Make sure HT (Halt Update) bit is cleared */ rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR); if (rc >= 0 && rc & M41T80_ALHOUR_HT) { - if (clientdata->features & M41T80_FEATURE_HT) { + if (m41t80_data->features & M41T80_FEATURE_HT) { m41t80_get_datetime(client, &tm); dev_info(&client->dev, "HT bit was set!\n"); dev_info(&client->dev, @@ -664,7 +818,7 @@ static int m41t80_probe(struct i2c_client *client, } #ifdef CONFIG_RTC_DRV_M41T80_WDT - if (clientdata->features & M41T80_FEATURE_HT) { + if (m41t80_data->features & M41T80_FEATURE_HT) { save_client = client; rc = misc_register(&wdt_dev); if (rc) From 3726a21833c9c96255735bddb5dacc8eacbff3ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 29 Mar 2016 08:56:04 +0200 Subject: [PATCH 10/40] rtc: m41t80: add wakealarm functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To enable the wakealarm, the device must be able to wakeup. This is done by setting the device wakeup capability to true with 'device_init_wakeup' function. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index c72473864418..5706e99853a3 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -758,6 +758,8 @@ static int m41t80_probe(struct i2c_client *client, m41t80_rtc_ops.read_alarm = m41t80_read_alarm; m41t80_rtc_ops.set_alarm = m41t80_set_alarm; m41t80_rtc_ops.alarm_irq_enable = m41t80_alarm_irq_enable; + /* Enable the wakealarm */ + device_init_wakeup(&client->dev, true); } } From 05a7f27a889f1635b7b7d5b051b17cacb25267fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 29 Mar 2016 08:56:05 +0200 Subject: [PATCH 11/40] rtc: m41t80: handle oscillator failure bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle the Oscillator Failure (OF) bit on each read of date-time. If the OF is set, an error is returned (-EINVAL) instead of the date-time. The OF bit is cleared each time the date is set. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 5706e99853a3..d1bf93a87200 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -56,6 +56,7 @@ #define M41T80_ALMON_AFE BIT(7) /* AFE: AF Enable Bit */ #define M41T80_ALMON_SQWE BIT(6) /* SQWE: SQW Enable Bit */ #define M41T80_ALHOUR_HT BIT(6) /* HT: Halt Update Bit */ +#define M41T80_FLAGS_OF BIT(2) /* OF: Oscillator Failure Bit */ #define M41T80_FLAGS_AF BIT(6) /* AF: Alarm Flag Bit */ #define M41T80_FLAGS_BATT_LOW BIT(4) /* BL: Battery Low Bit */ #define M41T80_WATCHDOG_RB2 BIT(7) /* RB: Watchdog resolution */ @@ -134,7 +135,16 @@ static int m41t80_get_datetime(struct i2c_client *client, struct rtc_time *tm) { unsigned char buf[8]; - int err; + int err, flags; + + flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); + if (flags < 0) + return flags; + + if (flags & M41T80_FLAGS_OF) { + dev_err(&client->dev, "Oscillator failure, data is invalid.\n"); + return -EINVAL; + } err = i2c_smbus_read_i2c_block_data(client, M41T80_REG_SSEC, sizeof(buf), buf); @@ -159,7 +169,7 @@ static int m41t80_get_datetime(struct i2c_client *client, static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) { unsigned char buf[8]; - int err; + int err, flags; if (tm->tm_year < 100 || tm->tm_year > 199) return -EINVAL; @@ -180,6 +190,17 @@ static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) return err; } + /* Clear the OF bit of Flags Register */ + flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); + if (flags < 0) + return flags; + + if (i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, + flags & ~M41T80_FLAGS_OF)) { + dev_err(&client->dev, "Unable to write flags register\n"); + return -EIO; + } + return err; } From bc83a141b8351f6d4458dd13eca5a66f2c0f3323 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 10 Apr 2016 23:59:23 +0900 Subject: [PATCH 12/40] rtc: ds1302: fix error check in set_time The set_time callback for rtc-ds1302 doesn't write clock registers because the error check for the return value from spi_write_then_read() is not correct. spi_write_then_read() which returns zero on success. Signed-off-by: Akinobu Mita Cc: Sergey Yanovich Cc: Alessandro Zummo Cc: Alexandre Belloni Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1302.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 7811b357ed70..283e653fa189 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -53,7 +53,7 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *time) status = spi_write_then_read(spi, buf, 2, NULL, 0); - if (!status) + if (status) return status; /* Write registers starting at the first time/date address. */ From ef50f86e15f2516658f0badd7890292d7a685106 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 10 Apr 2016 23:59:24 +0900 Subject: [PATCH 13/40] rtc: ds1302: fix write value for day of week register The valid range of day of week register for DS1302 is 1 to 7. But the set_time callback for rtc-ds1302 attempts to write the value of tm->tm_wday which is in the range 0 to 6. While the get_time callback correctly decodes the register. Signed-off-by: Akinobu Mita Cc: Sergey Yanovich Cc: Alessandro Zummo Cc: Alexandre Belloni Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1302.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 283e653fa189..f5dd09fe5add 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -65,7 +65,7 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *time) *bp++ = bin2bcd(time->tm_hour); *bp++ = bin2bcd(time->tm_mday); *bp++ = bin2bcd(time->tm_mon + 1); - *bp++ = time->tm_wday; + *bp++ = time->tm_wday + 1; *bp++ = bin2bcd(time->tm_year % 100); *bp++ = RTC_CMD_WRITE_DISABLE; From 1d87951c398e35118a0fb67b287022f008513f42 Mon Sep 17 00:00:00 2001 From: Nicolas Boullis Date: Sun, 3 Apr 2016 00:10:37 +0200 Subject: [PATCH 14/40] rtc: ds1307: fix ds1307_native_smbus_read_block_data function The i2c_smbus_read_i2c_block_data function returns 0 on success, not the number of bytes written. Hence, when there are 32 bytes or less to send, the ds1307_native_smbus_write_block_data function returns 0 on success, while it returns the number of bytes when there are more than 32. The ds1307_write_block_data always returns the number of bytes on success. Signed-off-by: Nicolas Boullis Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index ecb7dbae9be9..eed5c06bf624 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -275,9 +275,13 @@ static s32 ds1307_native_smbus_write_block_data(const struct i2c_client *client, { u8 suboffset = 0; - if (length <= I2C_SMBUS_BLOCK_MAX) - return i2c_smbus_write_i2c_block_data(client, + if (length <= I2C_SMBUS_BLOCK_MAX) { + s32 retval = i2c_smbus_write_i2c_block_data(client, command, length, values); + if (retval < 0) + return retval; + return length; + } while (suboffset < length) { s32 retval = i2c_smbus_write_i2c_block_data(client, From 5919fb97dd85e7ee200ab60151244cca62f61368 Mon Sep 17 00:00:00 2001 From: Nicolas Boullis Date: Sun, 10 Apr 2016 13:23:05 +0200 Subject: [PATCH 15/40] rtc: ds1307: ensure that any pending alarm is cleared before a new alarm is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a previously-set alarm was disabled and then triggered, it may still be pending when a new alarm is configured. Then, if the alarm is enabled before the pending alarm is cleared, then an interrupt is immediately raised. Unfortunately, when the alarm is cleared and enabled during the same I²C block write, the chip (at least the DS1339 I have) considers that the alarm is enabled before it is cleared, and raises an interrupt. This patch ensures that the pending alarm is cleared before the alarm is enabled. Signed-off-by: Nicolas Boullis Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index eed5c06bf624..f027a95a943f 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -542,12 +542,8 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) buf[5] = 0; buf[6] = 0; - /* optionally enable ALARM1 */ + /* disable alarms */ buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE); - if (t->enabled) { - dev_dbg(dev, "alarm IRQ armed\n"); - buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */ - } buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); ret = ds1307->write_block_data(client, @@ -557,6 +553,13 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) return ret; } + /* optionally enable ALARM1 */ + if (t->enabled) { + dev_dbg(dev, "alarm IRQ armed\n"); + buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */ + i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, buf[7]); + } + return 0; } From 6406d96e74a59ae98cf3197a9f9498e14d2df562 Mon Sep 17 00:00:00 2001 From: Steve Twiss Date: Thu, 14 Apr 2016 12:04:54 +0100 Subject: [PATCH 16/40] rtc: da9053: fix access ordering error during RTC interrupt at system power on This fix alters the ordering of the IRQ and device registrations in the RTC driver probe function. This change will apply to the RTC driver that supports both DA9052 and DA9053 PMICs. A problem could occur with the existing RTC driver if: A system is started from a cold boot using the PMIC RTC IRQ to initiate a power on operation. For instance, if an RTC alarm is used to start a platform from power off. The existing driver IRQ is requested before the device has been properly registered. i.e. ret = da9052_request_irq() comes before rtc->rtc = devm_rtc_device_register(); In this case, an interrupt exists before the device has been registered and the IRQ handler can be called immediately: this can happen be before the memory for rtc->rtc has been allocated. The IRQ handler da9052_rtc_irq() contains the function call: rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); which in turn tries to access the unavailable rtc->rtc. The fix is to reorder the functions inside the RTC probe. The IRQ is requested after the RTC device resource has been registered so that da9052_request_irq() is the last thing to happen. Signed-off-by: Steve Twiss Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-da9052.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 1ba4371cbc2d..a20bcf0e33cd 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -302,6 +302,13 @@ static int da9052_rtc_probe(struct platform_device *pdev) if (ret != 0) rtc_err(rtc, "Failed to disable TICKS: %d\n", ret); + device_init_wakeup(&pdev->dev, true); + rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, + &da9052_rtc_ops, THIS_MODULE); + + if (IS_ERR(rtc->rtc)) + return PTR_ERR(rtc->rtc); + ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM", da9052_rtc_irq, rtc); if (ret != 0) { @@ -309,11 +316,7 @@ static int da9052_rtc_probe(struct platform_device *pdev) return ret; } - device_init_wakeup(&pdev->dev, true); - - rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &da9052_rtc_ops, THIS_MODULE); - return PTR_ERR_OR_ZERO(rtc->rtc); + return 0; } static struct platform_driver da9052_rtc_driver = { From 19105f424b803f32757abab5fb13eaac22b6481f Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 15 Apr 2016 09:21:10 -0500 Subject: [PATCH 17/40] rtc: ds1685: actually spin forever in poweroff path objtool reports the following warning: drivers/rtc/rtc-ds1685.o: warning: objtool: ds1685_rtc_poweroff() falls through to next function ds1685_rtc_work_queue() Similar to commit 361c6ed6b153 ("rtc: ds1685: actually spin forever in poweroff error path"), there's another unreachable() annotation which is actually reachable, which we missed the first time. Actually spin forever to be consistent with the comment and to make the unreachable() annotation guaranteed to be unreachable. Reported-by: kbuild test robot Signed-off-by: Josh Poimboeuf Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1685.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 2698d8ffe4fd..b3ce3c652fcd 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -2211,6 +2211,7 @@ ds1685_rtc_poweroff(struct platform_device *pdev) (ctrl4a | RTC_CTRL_4A_PAB)); /* Spin ... we do not switch back to bank0. */ + while(1); unreachable(); } } From 9092984f1a8440ea52bf53c2d53bf8f5953a5126 Mon Sep 17 00:00:00 2001 From: Anurag Kumar Vulisha Date: Tue, 12 Apr 2016 17:45:44 +0530 Subject: [PATCH 18/40] rtc: zynqmp: Enable RTC switching to battery power when VCC_PSAUX is N/A In order to conserve battery energy, during the PS operation, it is expected that the supply for the battery-powered domain to be switched from the battery (VCC_PSBATT) to (VCC_PSAUX) and automatically be switched back to battery when VCC_PSAUX voltage drops below a limit, doing so prevents the logic within the battery-powered domain from functioning incorrectly. Signed-off-by: Anurag Kumar Vulisha Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index 8b28762f06df..6adb603f29bc 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -45,6 +45,7 @@ #define RTC_INT_SEC BIT(0) #define RTC_INT_ALRM BIT(1) #define RTC_OSC_EN BIT(24) +#define RTC_BATT_EN BIT(31) #define RTC_CALIB_DEF 0x198233 #define RTC_CALIB_MASK 0x1FFFFF @@ -122,6 +123,13 @@ static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval) { + u32 rtc_ctrl; + + /* Enable RTC switch to battery when VCC_PSAUX is not available */ + rtc_ctrl = readl(xrtcdev->reg_base + RTC_CTRL); + rtc_ctrl |= RTC_BATT_EN; + writel(rtc_ctrl, xrtcdev->reg_base + RTC_CTRL); + /* * Based on crystal freq of 33.330 KHz * set the seconds counter and enable, set fractions counter From 58c4ed3ba2e0c97e33affd237dc05738fa55a725 Mon Sep 17 00:00:00 2001 From: Anurag Kumar Vulisha Date: Tue, 12 Apr 2016 17:45:45 +0530 Subject: [PATCH 19/40] rtc: zynqmp: Write Calibration value before setting time It is suggested to program CALIB_WRITE register with the calibration value before updating the SET_TIME_WRITE register, doing so will clear the Tick Counter and force the next second to be signaled exactly in 1 second. Signed-off-by: Anurag Kumar Vulisha Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index 6adb603f29bc..f87f971a72c2 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -56,6 +56,7 @@ struct xlnx_rtc_dev { void __iomem *reg_base; int alarm_irq; int sec_irq; + int calibval; }; static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm) @@ -68,6 +69,13 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm) if (new_time > RTC_SEC_MAX_VAL) return -EINVAL; + /* + * Writing into calibration register will clear the Tick Counter and + * force the next second to be signaled exactly in 1 second period + */ + xrtcdev->calibval &= RTC_CALIB_MASK; + writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); + writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR); return 0; @@ -121,7 +129,7 @@ static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) return 0; } -static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval) +static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev) { u32 rtc_ctrl; @@ -136,8 +144,8 @@ static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval) * to default value suggested as per design spec * to correct RTC delay in frequency over period of time. */ - calibval &= RTC_CALIB_MASK; - writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); + xrtcdev->calibval &= RTC_CALIB_MASK; + writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); } static const struct rtc_class_ops xlnx_rtc_ops = { @@ -174,7 +182,6 @@ static int xlnx_rtc_probe(struct platform_device *pdev) struct xlnx_rtc_dev *xrtcdev; struct resource *res; int ret; - unsigned int calibvalue; xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL); if (!xrtcdev) @@ -215,11 +222,11 @@ static int xlnx_rtc_probe(struct platform_device *pdev) } ret = of_property_read_u32(pdev->dev.of_node, "calibration", - &calibvalue); + &xrtcdev->calibval); if (ret) - calibvalue = RTC_CALIB_DEF; + xrtcdev->calibval = RTC_CALIB_DEF; - xlnx_init_rtc(xrtcdev, calibvalue); + xlnx_init_rtc(xrtcdev); device_init_wakeup(&pdev->dev, 1); From 74e1af3246dfb9840d99a18363dec4dc66ac9731 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 19 Apr 2016 18:12:19 -0700 Subject: [PATCH 20/40] rtc: pcf8563: Remove CLK_IS_ROOT This flag is a no-op now (see commit 47b0eeb3dc8a "clk: Deprecate CLK_IS_ROOT", 2016-02-02) so remove it. Cc: Heiko Schocher Signed-off-by: Stephen Boyd Acked-by: Heiko Schocher Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf8563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index d5e6ed96b748..b9ddbb001283 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -533,7 +533,7 @@ static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563) init.name = "pcf8563-clkout"; init.ops = &pcf8563_clkout_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.parent_names = NULL; init.num_parents = 0; pcf8563->clkout_hw.init = &init; From bdcaace5ef99eeb112decfa739b4b16e709a677b Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 19 Apr 2016 18:13:58 -0700 Subject: [PATCH 21/40] rtc: hym8563: Remove CLK_IS_ROOT This flag is a no-op now (see commit 47b0eeb3dc8a "clk: Deprecate CLK_IS_ROOT", 2016-02-02) so remove it. Cc: Heiko Stuebner Signed-off-by: Stephen Boyd Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-hym8563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index b1b4746a0eab..207270376b55 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -413,7 +413,7 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563) init.name = "hym8563-clkout"; init.ops = &hym8563_clkout_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.parent_names = NULL; init.num_parents = 0; hym8563->clkout_hw.init = &init; From 7457d5f588dfc038cef66e4645abbe9c06481504 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 19 Apr 2016 18:15:48 -0700 Subject: [PATCH 22/40] rtc: ds1307: Remove CLK_IS_ROOT This flag is a no-op now (see commit 47b0eeb3dc8a "clk: Deprecate CLK_IS_ROOT", 2016-02-02) so remove it. Cc: Akinobu Mita Cc: Michael Tatarinov Signed-off-by: Stephen Boyd Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index f027a95a943f..821d9c089cdb 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1151,12 +1151,10 @@ static struct clk_init_data ds3231_clks_init[] = { [DS3231_CLK_SQW] = { .name = "ds3231_clk_sqw", .ops = &ds3231_clk_sqw_ops, - .flags = CLK_IS_ROOT, }, [DS3231_CLK_32KHZ] = { .name = "ds3231_clk_32khz", .ops = &ds3231_clk_32khz_ops, - .flags = CLK_IS_ROOT, }, }; From 1726982f20ebb90f9b2fcdda6686e244f6af83e2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 4 May 2011 17:31:28 +0200 Subject: [PATCH 23/40] rtc: mxc: remove UIE signaling The RTC core handles it since 6610e08 (RTC: Rework RTC code to use timerqueue for events). Signed-off-by: Wolfram Sang Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mxc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 7bd89d90048f..359876a88ac8 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -240,9 +240,6 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) mxc_rtc_irq_enable(&pdev->dev, RTC_ALM_BIT, 0); } - if (status & RTC_1HZ_BIT) - events |= (RTC_UF | RTC_IRQF); - if (status & PIT_ALL_ON) events |= (RTC_PF | RTC_IRQF); From 5333a4044d7b4af8bb01e031d0ee619e9ab86601 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 4 May 2011 17:31:26 +0200 Subject: [PATCH 24/40] rtc: mc13xxx: remove UIE signaling The RTC core handles it since 6610e08 (RTC: Rework RTC code to use timerqueue for events). So far, only the callbacks to the RTC core have been removed, but not the handlers. Do this now. Signed-off-by: Wolfram Sang Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mc13xxx.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index a65868065743..30b8ef6a3676 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -250,18 +250,6 @@ static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev) return IRQ_HANDLED; } -static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev) -{ - struct mc13xxx_rtc *priv = dev; - struct mc13xxx *mc13xxx = priv->mc13xxx; - - rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF); - - mc13xxx_irq_ack(mc13xxx, irq); - - return IRQ_HANDLED; -} - static const struct rtc_class_ops mc13xxx_rtc_ops = { .read_time = mc13xxx_rtc_read_time, .set_mmss64 = mc13xxx_rtc_set_mmss, @@ -307,11 +295,6 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) if (ret) goto err_irq_request; - ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_1HZ, - mc13xxx_rtc_update_handler, DRIVER_NAME, priv); - if (ret) - goto err_irq_request; - ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA, mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv); if (ret) @@ -326,7 +309,6 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) err_irq_request: mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv); - mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv); mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv); mc13xxx_unlock(mc13xxx); @@ -341,7 +323,6 @@ static int mc13xxx_rtc_remove(struct platform_device *pdev) mc13xxx_lock(priv->mc13xxx); mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv); - mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_1HZ, priv); mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv); mc13xxx_unlock(priv->mc13xxx); From 01dc6992b3e888e7bf17691e4e86c9cc33e8f8b5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 20 Apr 2016 17:32:18 +0200 Subject: [PATCH 25/40] rtc: sa1100: DT spelling s/interrupt-name/interrupt-names/ Fix typo in interrupt-names Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/sa1100-rtc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/rtc/sa1100-rtc.txt b/Documentation/devicetree/bindings/rtc/sa1100-rtc.txt index 0cda19ad4859..968ac820254b 100644 --- a/Documentation/devicetree/bindings/rtc/sa1100-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/sa1100-rtc.txt @@ -13,5 +13,5 @@ Example: compatible = "mrvl,mmp-rtc"; reg = <0xd4010000 0x1000>; interrupts = <5>, <6>; - interrupt-name = "rtc 1Hz", "rtc alarm"; + interrupt-names = "rtc 1Hz", "rtc alarm"; }; From b62c3a1158c0abc98e03c68934fa7ee6ca10dd49 Mon Sep 17 00:00:00 2001 From: Anurag Kumar Vulisha Date: Wed, 20 Apr 2016 21:17:35 +0530 Subject: [PATCH 26/40] rtc: zynqmp: Update seconds time programming logic We program RTC time using SET_TIME_WRITE register and read the RTC current time using CURRENT_TIME register. When we set the time by writing into SET_TIME_WRITE Register and immediately try to read the rtc time from CURRENT_TIME register, the previous old value is returned instead of the new loaded time. This is because RTC takes nearly 1 sec to update the new loaded value into the CURRENT_TIME register. This behaviour is expected in our RTC IP. This patch updates the driver to read the current time from SET_TIME_WRITE register instead of CURRENT_TIME when rtc time is requested within an 1sec period after setting the RTC time. Doing so will ensure the correct time is given to the user. Since there is a delay of 1sec in updating the CURRENT_TIME we are loading set time +1sec while programming the SET_TIME_WRITE register, doing this will give correct time without any delay when read from CURRENT_TIME. Signed-off-by: Anurag Kumar Vulisha Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 45 ++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index f87f971a72c2..da18a8ae3c1d 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -64,7 +64,12 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm) struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); unsigned long new_time; - new_time = rtc_tm_to_time64(tm); + /* + * The value written will be updated after 1 sec into the + * seconds read register, so we need to program time +1 sec + * to get the correct time on read. + */ + new_time = rtc_tm_to_time64(tm) + 1; if (new_time > RTC_SEC_MAX_VAL) return -EINVAL; @@ -78,14 +83,44 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm) writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR); + /* + * Clear the rtc interrupt status register after setting the + * time. During a read_time function, the code should read the + * RTC_INT_STATUS register and if bit 0 is still 0, it means + * that one second has not elapsed yet since RTC was set and + * the current time should be read from SET_TIME_READ register; + * otherwise, CURRENT_TIME register is read to report the time + */ + writel(RTC_INT_SEC, xrtcdev->reg_base + RTC_INT_STS); + return 0; } static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm) { + u32 status; + unsigned long read_time; struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); - rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm); + status = readl(xrtcdev->reg_base + RTC_INT_STS); + + if (status & RTC_INT_SEC) { + /* + * RTC has updated the CURRENT_TIME with the time written into + * SET_TIME_WRITE register. + */ + rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm); + } else { + /* + * Time written in SET_TIME_WRITE has not yet updated into + * the seconds read register, so read the time from the + * SET_TIME_WRITE instead of CURRENT_TIME register. + * Since we add +1 sec while writing, we need to -1 sec while + * reading. + */ + read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1; + rtc_time64_to_tm(read_time, tm); + } return rtc_valid_tm(tm); } @@ -166,11 +201,9 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id) if (!(status & (RTC_INT_SEC | RTC_INT_ALRM))) return IRQ_NONE; - /* Clear interrupt */ - writel(status, xrtcdev->reg_base + RTC_INT_STS); + /* Clear RTC_INT_ALRM interrupt only */ + writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS); - if (status & RTC_INT_SEC) - rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF); if (status & RTC_INT_ALRM) rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF); From a350259da4b0556fcf276c506a14f406d608c2b3 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 20 Apr 2016 16:09:57 -0700 Subject: [PATCH 27/40] rtc: snvs: return error in case enable_irq_wake fails If enable_irq_wake fails, we should return that error code so that entering suspend fails. Otherwise we will get a WARNING along with the hint of a unbalanced wake disable: Unbalanced IRQ 37 wake disable Signed-off-by: Stefan Agner Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-snvs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index 950c5d0b6dca..0f11c2a228e3 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -322,7 +322,7 @@ static int snvs_rtc_suspend(struct device *dev) struct snvs_rtc_data *data = dev_get_drvdata(dev); if (device_may_wakeup(dev)) - enable_irq_wake(data->irq); + return enable_irq_wake(data->irq); return 0; } From b4b77f3c280e38cec178f81d7a4d7e65f4045913 Mon Sep 17 00:00:00 2001 From: Qianyu Gong Date: Thu, 21 Apr 2016 14:55:40 +0800 Subject: [PATCH 28/40] rtc: ds3232: fix call trace when rtc->ops_lock is used as NULL The rtc->ops_lock would be accessed in ds3232_irq() without being initialized as rtc_device_register() is called too late. So move devm_rtc_device_register() just before registering irq handler to initialize rtc->ops_lock earlier. Signed-off-by: Gong Qianyu Reviewed-by: Akinobu Mita Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds3232.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 7edc889729c5..04fbd7fffd0d 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -369,6 +369,11 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq, if (ret) return ret; + ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops, + THIS_MODULE); + if (IS_ERR(ds3232->rtc)) + return PTR_ERR(ds3232->rtc); + if (ds3232->irq > 0) { ret = devm_request_threaded_irq(dev, ds3232->irq, NULL, ds3232_irq, @@ -380,10 +385,8 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq, } else device_init_wakeup(dev, 1); } - ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops, - THIS_MODULE); - return PTR_ERR_OR_ZERO(ds3232->rtc); + return 0; } #ifdef CONFIG_PM_SLEEP From 6fca3fc51632685635cb7143065ae74d44673871 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 26 Apr 2016 18:17:35 -0400 Subject: [PATCH 29/40] rtc: Use IS_ENABLED() instead of checking for built-in or module The IS_ENABLED() macro checks if a Kconfig symbol has been enabled either built-in or as a module, use that macro instead of open coding the same. Signed-off-by: Javier Martinez Canillas Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cmos.c | 2 +- drivers/rtc/rtc-mrst.c | 2 +- drivers/rtc/rtc-rs5c372.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 84fb541038be..fbe9c72438e1 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -401,7 +401,7 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) +#if IS_ENABLED(CONFIG_RTC_INTF_PROC) static int cmos_procfs(struct device *dev, struct seq_file *seq) { diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index 548ea6f6f384..0094d9bdd1e6 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -266,7 +266,7 @@ static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) } -#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) +#if IS_ENABLED(CONFIG_RTC_INTF_PROC) static int mrst_procfs(struct device *dev, struct seq_file *seq) { diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 12270c789088..aaebe10876e8 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -237,11 +237,11 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) return 0; } -#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) +#if IS_ENABLED(CONFIG_RTC_INTF_PROC) #define NEED_TRIM #endif -#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) +#if IS_ENABLED(CONFIG_RTC_INTF_SYSFS) #define NEED_TRIM #endif @@ -409,7 +409,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) return 0; } -#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) +#if IS_ENABLED(CONFIG_RTC_INTF_PROC) static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq) { @@ -438,7 +438,7 @@ static const struct rtc_class_ops rs5c372_rtc_ops = { .alarm_irq_enable = rs5c_rtc_alarm_irq_enable, }; -#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) +#if IS_ENABLED(CONFIG_RTC_INTF_SYSFS) static ssize_t rs5c372_sysfs_show_trim(struct device *dev, struct device_attribute *attr, char *buf) From 3497610a45d15bd33d1993ddd84951ad21b35ded Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Sat, 30 Apr 2016 20:11:30 +0100 Subject: [PATCH 30/40] rtc: stmp3xxx: print message on error stmp3xxx_wdt_register() can fail as platform_device_alloc() or platform_device_add() can fail. But when it fails it failed silently. Lets print out an error message on failure so that user will atlest know that there was some error. Signed-off-by: Sudip Mukherjee Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-stmp3xxx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index ca54d039da31..e6aaaa52e7fe 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -107,14 +107,19 @@ static struct stmp3xxx_wdt_pdata wdt_pdata = { static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) { + int rc = -1; struct platform_device *wdt_pdev = platform_device_alloc("stmp3xxx_rtc_wdt", rtc_pdev->id); if (wdt_pdev) { wdt_pdev->dev.parent = &rtc_pdev->dev; wdt_pdev->dev.platform_data = &wdt_pdata; - platform_device_add(wdt_pdev); + rc = platform_device_add(wdt_pdev); } + + if (rc) + dev_err(&rtc_pdev->dev, + "failed to register stmp3xxx_rtc_wdt\n"); } #else static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) From 4e7f1a6051d7d5a62021fde0c9ed7005a1a82307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 3 May 2016 11:54:32 +0200 Subject: [PATCH 31/40] rtc: rv3029: remove 'i2c' in functions names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To prepare the use of regmap to add the support of RV-3049, all the 'i2c' in functions's names are removed. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv3029c2.c | 132 ++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 75 deletions(-) diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index d0cbf08040cd..091be483e3e9 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -116,9 +116,8 @@ #define RV3029_USR2_RAM_PAGE 0x3C #define RV3029_USR2_SECTION_LEN 0x04 -static int -rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf, - unsigned len) +static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf, + unsigned len) { int ret; @@ -134,9 +133,8 @@ rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf, return 0; } -static int -rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], - unsigned len) +static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], + unsigned len) { if ((reg > RV3029_USR1_RAM_PAGE + 7) || (reg + len > RV3029_USR1_RAM_PAGE + 8)) @@ -145,28 +143,27 @@ rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], return i2c_smbus_write_i2c_block_data(client, reg, len, buf); } -static int -rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set) +static int rv3029_update_bits(struct i2c_client *client, u8 reg, u8 mask, + u8 set) { u8 buf; int ret; - ret = rv3029_i2c_read_regs(client, reg, &buf, 1); + ret = rv3029_read_regs(client, reg, &buf, 1); if (ret < 0) return ret; buf &= ~mask; buf |= set & mask; - ret = rv3029_i2c_write_regs(client, reg, &buf, 1); + ret = rv3029_write_regs(client, reg, &buf, 1); if (ret < 0) return ret; return 0; } -static int -rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf) +static int rv3029_get_sr(struct i2c_client *client, u8 *buf) { - int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1); + int ret = rv3029_read_regs(client, RV3029_STATUS, buf, 1); if (ret < 0) return -EIO; @@ -174,14 +171,13 @@ rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf) return 0; } -static int -rv3029_i2c_set_sr(struct i2c_client *client, u8 val) +static int rv3029_set_sr(struct i2c_client *client, u8 val) { u8 buf[1]; int sr; buf[0] = val; - sr = rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1); + sr = rv3029_write_regs(client, RV3029_STATUS, buf, 1); dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]); if (sr < 0) return -EIO; @@ -194,7 +190,7 @@ static int rv3029_eeprom_busywait(struct i2c_client *client) u8 sr; for (i = 100; i > 0; i--) { - ret = rv3029_i2c_get_sr(client, &sr); + ret = rv3029_get_sr(client, &sr); if (ret < 0) break; if (!(sr & RV3029_STATUS_EEBUSY)) @@ -212,9 +208,9 @@ static int rv3029_eeprom_busywait(struct i2c_client *client) static int rv3029_eeprom_exit(struct i2c_client *client) { /* Re-enable eeprom refresh */ - return rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL, - RV3029_ONOFF_CTRL_EERE, - RV3029_ONOFF_CTRL_EERE); + return rv3029_update_bits(client, RV3029_ONOFF_CTRL, + RV3029_ONOFF_CTRL_EERE, + RV3029_ONOFF_CTRL_EERE); } static int rv3029_eeprom_enter(struct i2c_client *client) @@ -223,7 +219,7 @@ static int rv3029_eeprom_enter(struct i2c_client *client) u8 sr; /* Check whether we are in the allowed voltage range. */ - ret = rv3029_i2c_get_sr(client, &sr); + ret = rv3029_get_sr(client, &sr); if (ret < 0) return ret; if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) { @@ -232,11 +228,11 @@ static int rv3029_eeprom_enter(struct i2c_client *client) */ sr &= ~RV3029_STATUS_VLOW1; sr &= ~RV3029_STATUS_VLOW2; - ret = rv3029_i2c_set_sr(client, sr); + ret = rv3029_set_sr(client, sr); if (ret < 0) return ret; usleep_range(1000, 10000); - ret = rv3029_i2c_get_sr(client, &sr); + ret = rv3029_get_sr(client, &sr); if (ret < 0) return ret; if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) { @@ -247,8 +243,8 @@ static int rv3029_eeprom_enter(struct i2c_client *client) } /* Disable eeprom refresh. */ - ret = rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL, - RV3029_ONOFF_CTRL_EERE, 0); + ret = rv3029_update_bits(client, RV3029_ONOFF_CTRL, + RV3029_ONOFF_CTRL_EERE, 0); if (ret < 0) return ret; @@ -269,7 +265,7 @@ static int rv3029_eeprom_read(struct i2c_client *client, u8 reg, if (err < 0) return err; - ret = rv3029_i2c_read_regs(client, reg, buf, len); + ret = rv3029_read_regs(client, reg, buf, len); err = rv3029_eeprom_exit(client); if (err < 0) @@ -290,11 +286,11 @@ static int rv3029_eeprom_write(struct i2c_client *client, u8 reg, return err; for (i = 0; i < len; i++, reg++) { - ret = rv3029_i2c_read_regs(client, reg, &tmp, 1); + ret = rv3029_read_regs(client, reg, &tmp, 1); if (ret < 0) break; if (tmp != buf[i]) { - ret = rv3029_i2c_write_regs(client, reg, &buf[i], 1); + ret = rv3029_write_regs(client, reg, &buf[i], 1); if (ret < 0) break; } @@ -328,21 +324,20 @@ static int rv3029_eeprom_update_bits(struct i2c_client *client, return 0; } -static int -rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) +static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm) { u8 buf[1]; int ret; u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, }; - ret = rv3029_i2c_get_sr(client, buf); + ret = rv3029_get_sr(client, buf); if (ret < 0) { dev_err(&client->dev, "%s: reading SR failed\n", __func__); return -EIO; } - ret = rv3029_i2c_read_regs(client, RV3029_W_SEC, regs, - RV3029_WATCH_SECTION_LEN); + ret = rv3029_read_regs(client, RV3029_W_SEC, regs, + RV3029_WATCH_SECTION_LEN); if (ret < 0) { dev_err(&client->dev, "%s: reading RTC section failed\n", __func__); @@ -375,24 +370,24 @@ rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm) { - return rv3029_i2c_read_time(to_i2c_client(dev), tm); + return rv3029_read_time(to_i2c_client(dev), tm); } -static int -rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) +static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { + struct i2c_client *client = to_i2c_client(dev); struct rtc_time *const tm = &alarm->time; int ret; u8 regs[8]; - ret = rv3029_i2c_get_sr(client, regs); + ret = rv3029_get_sr(client, regs); if (ret < 0) { dev_err(&client->dev, "%s: reading SR failed\n", __func__); return -EIO; } - ret = rv3029_i2c_read_regs(client, RV3029_A_SC, regs, - RV3029_ALARM_SECTION_LEN); + ret = rv3029_read_regs(client, RV3029_A_SC, regs, + RV3029_ALARM_SECTION_LEN); if (ret < 0) { dev_err(&client->dev, "%s: reading alarm section failed\n", @@ -411,21 +406,14 @@ rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) return 0; } -static int -rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm); -} - -static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client, - int enable) +static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable) { int ret; /* enable/disable AIE irq */ - ret = rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL, - RV3029_IRQ_CTRL_AIE, - (enable ? RV3029_IRQ_CTRL_AIE : 0)); + ret = rv3029_update_bits(client, RV3029_IRQ_CTRL, + RV3029_IRQ_CTRL_AIE, + (enable ? RV3029_IRQ_CTRL_AIE : 0)); if (ret < 0) { dev_err(&client->dev, "can't update INT reg\n"); return ret; @@ -434,9 +422,9 @@ static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client, return 0; } -static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client, - struct rtc_wkalrm *alarm) +static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { + struct i2c_client *client = to_i2c_client(dev); struct rtc_time *const tm = &alarm->time; int ret; u8 regs[8]; @@ -449,7 +437,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client, if (tm->tm_year < 100) return -EINVAL; - ret = rv3029_i2c_get_sr(client, regs); + ret = rv3029_get_sr(client, regs); if (ret < 0) { dev_err(&client->dev, "%s: reading SR failed\n", __func__); return -EIO; @@ -462,28 +450,28 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client, regs[RV3029_A_DW-RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1); regs[RV3029_A_YR-RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100); - ret = rv3029_i2c_write_regs(client, RV3029_A_SC, regs, - RV3029_ALARM_SECTION_LEN); + ret = rv3029_write_regs(client, RV3029_A_SC, regs, + RV3029_ALARM_SECTION_LEN); if (ret < 0) return ret; if (alarm->enabled) { /* clear AF flag */ - ret = rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS, - RV3029_IRQ_FLAGS_AF, 0); + ret = rv3029_update_bits(client, RV3029_IRQ_FLAGS, + RV3029_IRQ_FLAGS_AF, 0); if (ret < 0) { dev_err(&client->dev, "can't clear alarm flag\n"); return ret; } /* enable AIE irq */ - ret = rv3029_rtc_i2c_alarm_set_irq(client, 1); + ret = rv3029_rtc_alarm_set_irq(client, 1); if (ret) return ret; dev_dbg(&client->dev, "alarm IRQ armed\n"); } else { /* disable AIE irq */ - ret = rv3029_rtc_i2c_alarm_set_irq(client, 0); + ret = rv3029_rtc_alarm_set_irq(client, 0); if (ret) return ret; @@ -493,13 +481,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client, return 0; } -static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm); -} - -static int -rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) +static int rv3029_set_time(struct i2c_client *client, struct rtc_time const *tm) { u8 regs[8]; int ret; @@ -520,18 +502,18 @@ rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) regs[RV3029_W_DAYS-RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7)+1); regs[RV3029_W_YEARS-RV3029_W_SEC] = bin2bcd(tm->tm_year - 100); - ret = rv3029_i2c_write_regs(client, RV3029_W_SEC, regs, - RV3029_WATCH_SECTION_LEN); + ret = rv3029_write_regs(client, RV3029_W_SEC, regs, + RV3029_WATCH_SECTION_LEN); if (ret < 0) return ret; - ret = rv3029_i2c_get_sr(client, regs); + ret = rv3029_get_sr(client, regs); if (ret < 0) { dev_err(&client->dev, "%s: reading SR failed\n", __func__); return ret; } /* clear PON bit */ - ret = rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON)); + ret = rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON)); if (ret < 0) { dev_err(&client->dev, "%s: reading SR failed\n", __func__); return ret; @@ -542,7 +524,7 @@ rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm) { - return rv3029_i2c_set_time(to_i2c_client(dev), tm); + return rv3029_set_time(to_i2c_client(dev), tm); } static const struct rv3029_trickle_tab_elem { @@ -646,7 +628,7 @@ static int rv3029_read_temp(struct i2c_client *client, int *temp_mC) int ret; u8 temp; - ret = rv3029_i2c_read_regs(client, RV3029_TEMP_PAGE, &temp, 1); + ret = rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1); if (ret < 0) return ret; @@ -743,8 +725,8 @@ static void rv3029_hwmon_register(struct i2c_client *client) &client->dev, client->name, client, rv3029_hwmon_groups); if (IS_ERR(hwmon_dev)) { dev_warn(&client->dev, - "unable to register hwmon device %ld\n", - PTR_ERR(hwmon_dev)); + "unable to register hwmon device %ld\n", + PTR_ERR(hwmon_dev)); } } @@ -780,7 +762,7 @@ static int rv3029_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL)) return -ENODEV; - rc = rv3029_i2c_get_sr(client, buf); + rc = rv3029_get_sr(client, buf); if (rc < 0) { dev_err(&client->dev, "reading status failed\n"); return rc; From e6e380821236b628a1379db97d777da3e36b8240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 3 May 2016 11:54:33 +0200 Subject: [PATCH 32/40] rtc: rv3029: convert to use regmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To add support of rv3049, the current driver is converted to use regmap. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv3029c2.c | 275 +++++++++++++++++++------------------ 1 file changed, 142 insertions(+), 133 deletions(-) diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 091be483e3e9..96dd1665220c 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -20,7 +20,7 @@ #include #include #include - +#include /* Register map */ /* control section */ @@ -116,81 +116,84 @@ #define RV3029_USR2_RAM_PAGE 0x3C #define RV3029_USR2_SECTION_LEN 0x04 -static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf, +struct rv3029_data { + struct device *dev; + struct rtc_device *rtc; + struct regmap *regmap; + int irq; +}; + +static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf, unsigned len) { - int ret; + struct rv3029_data *rv3029 = dev_get_drvdata(dev); if ((reg > RV3029_USR1_RAM_PAGE + 7) || (reg + len > RV3029_USR1_RAM_PAGE + 8)) return -EINVAL; - ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf); - if (ret < 0) - return ret; - if (ret < len) - return -EIO; - return 0; + return regmap_bulk_read(rv3029->regmap, reg, buf, len); } -static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], +static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[], unsigned len) { + struct rv3029_data *rv3029 = dev_get_drvdata(dev); + if ((reg > RV3029_USR1_RAM_PAGE + 7) || (reg + len > RV3029_USR1_RAM_PAGE + 8)) return -EINVAL; - return i2c_smbus_write_i2c_block_data(client, reg, len, buf); + return regmap_bulk_write(rv3029->regmap, reg, buf, len); } -static int rv3029_update_bits(struct i2c_client *client, u8 reg, u8 mask, - u8 set) +static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set) { u8 buf; int ret; - ret = rv3029_read_regs(client, reg, &buf, 1); + ret = rv3029_read_regs(dev, reg, &buf, 1); if (ret < 0) return ret; buf &= ~mask; buf |= set & mask; - ret = rv3029_write_regs(client, reg, &buf, 1); + ret = rv3029_write_regs(dev, reg, &buf, 1); if (ret < 0) return ret; return 0; } -static int rv3029_get_sr(struct i2c_client *client, u8 *buf) +static int rv3029_get_sr(struct device *dev, u8 *buf) { - int ret = rv3029_read_regs(client, RV3029_STATUS, buf, 1); + int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1); if (ret < 0) return -EIO; - dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]); + dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]); return 0; } -static int rv3029_set_sr(struct i2c_client *client, u8 val) +static int rv3029_set_sr(struct device *dev, u8 val) { u8 buf[1]; int sr; buf[0] = val; - sr = rv3029_write_regs(client, RV3029_STATUS, buf, 1); - dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]); + sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1); + dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]); if (sr < 0) return -EIO; return 0; } -static int rv3029_eeprom_busywait(struct i2c_client *client) +static int rv3029_eeprom_busywait(struct device *dev) { int i, ret; u8 sr; for (i = 100; i > 0; i--) { - ret = rv3029_get_sr(client, &sr); + ret = rv3029_get_sr(dev, &sr); if (ret < 0) break; if (!(sr & RV3029_STATUS_EEBUSY)) @@ -198,28 +201,28 @@ static int rv3029_eeprom_busywait(struct i2c_client *client) usleep_range(1000, 10000); } if (i <= 0) { - dev_err(&client->dev, "EEPROM busy wait timeout.\n"); + dev_err(dev, "EEPROM busy wait timeout.\n"); return -ETIMEDOUT; } return ret; } -static int rv3029_eeprom_exit(struct i2c_client *client) +static int rv3029_eeprom_exit(struct device *dev) { /* Re-enable eeprom refresh */ - return rv3029_update_bits(client, RV3029_ONOFF_CTRL, + return rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE, RV3029_ONOFF_CTRL_EERE); } -static int rv3029_eeprom_enter(struct i2c_client *client) +static int rv3029_eeprom_enter(struct device *dev) { int ret; u8 sr; /* Check whether we are in the allowed voltage range. */ - ret = rv3029_get_sr(client, &sr); + ret = rv3029_get_sr(dev, &sr); if (ret < 0) return ret; if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) { @@ -228,119 +231,118 @@ static int rv3029_eeprom_enter(struct i2c_client *client) */ sr &= ~RV3029_STATUS_VLOW1; sr &= ~RV3029_STATUS_VLOW2; - ret = rv3029_set_sr(client, sr); + ret = rv3029_set_sr(dev, sr); if (ret < 0) return ret; usleep_range(1000, 10000); - ret = rv3029_get_sr(client, &sr); + ret = rv3029_get_sr(dev, &sr); if (ret < 0) return ret; if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) { - dev_err(&client->dev, + dev_err(dev, "Supply voltage is too low to safely access the EEPROM.\n"); return -ENODEV; } } /* Disable eeprom refresh. */ - ret = rv3029_update_bits(client, RV3029_ONOFF_CTRL, - RV3029_ONOFF_CTRL_EERE, 0); + ret = rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE, + 0); if (ret < 0) return ret; /* Wait for any previous eeprom accesses to finish. */ - ret = rv3029_eeprom_busywait(client); + ret = rv3029_eeprom_busywait(dev); if (ret < 0) - rv3029_eeprom_exit(client); + rv3029_eeprom_exit(dev); return ret; } -static int rv3029_eeprom_read(struct i2c_client *client, u8 reg, +static int rv3029_eeprom_read(struct device *dev, u8 reg, u8 buf[], size_t len) { int ret, err; - err = rv3029_eeprom_enter(client); + err = rv3029_eeprom_enter(dev); if (err < 0) return err; - ret = rv3029_read_regs(client, reg, buf, len); + ret = rv3029_read_regs(dev, reg, buf, len); - err = rv3029_eeprom_exit(client); + err = rv3029_eeprom_exit(dev); if (err < 0) return err; return ret; } -static int rv3029_eeprom_write(struct i2c_client *client, u8 reg, +static int rv3029_eeprom_write(struct device *dev, u8 reg, u8 const buf[], size_t len) { int ret, err; size_t i; u8 tmp; - err = rv3029_eeprom_enter(client); + err = rv3029_eeprom_enter(dev); if (err < 0) return err; for (i = 0; i < len; i++, reg++) { - ret = rv3029_read_regs(client, reg, &tmp, 1); + ret = rv3029_read_regs(dev, reg, &tmp, 1); if (ret < 0) break; if (tmp != buf[i]) { - ret = rv3029_write_regs(client, reg, &buf[i], 1); + ret = rv3029_write_regs(dev, reg, &buf[i], 1); if (ret < 0) break; } - ret = rv3029_eeprom_busywait(client); + ret = rv3029_eeprom_busywait(dev); if (ret < 0) break; } - err = rv3029_eeprom_exit(client); + err = rv3029_eeprom_exit(dev); if (err < 0) return err; return ret; } -static int rv3029_eeprom_update_bits(struct i2c_client *client, +static int rv3029_eeprom_update_bits(struct device *dev, u8 reg, u8 mask, u8 set) { u8 buf; int ret; - ret = rv3029_eeprom_read(client, reg, &buf, 1); + ret = rv3029_eeprom_read(dev, reg, &buf, 1); if (ret < 0) return ret; buf &= ~mask; buf |= set & mask; - ret = rv3029_eeprom_write(client, reg, &buf, 1); + ret = rv3029_eeprom_write(dev, reg, &buf, 1); if (ret < 0) return ret; return 0; } -static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm) +static int rv3029_read_time(struct device *dev, struct rtc_time *tm) { u8 buf[1]; int ret; u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, }; - ret = rv3029_get_sr(client, buf); + ret = rv3029_get_sr(dev, buf); if (ret < 0) { - dev_err(&client->dev, "%s: reading SR failed\n", __func__); + dev_err(dev, "%s: reading SR failed\n", __func__); return -EIO; } - ret = rv3029_read_regs(client, RV3029_W_SEC, regs, + ret = rv3029_read_regs(dev, RV3029_W_SEC, regs, RV3029_WATCH_SECTION_LEN); if (ret < 0) { - dev_err(&client->dev, "%s: reading RTC section failed\n", - __func__); + dev_err(dev, "%s: reading RTC section failed\n", __func__); return ret; } @@ -368,30 +370,23 @@ static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm) return 0; } -static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm) +static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { - return rv3029_read_time(to_i2c_client(dev), tm); -} - -static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - struct i2c_client *client = to_i2c_client(dev); struct rtc_time *const tm = &alarm->time; int ret; u8 regs[8]; - ret = rv3029_get_sr(client, regs); + ret = rv3029_get_sr(dev, regs); if (ret < 0) { - dev_err(&client->dev, "%s: reading SR failed\n", __func__); + dev_err(dev, "%s: reading SR failed\n", __func__); return -EIO; } - ret = rv3029_read_regs(client, RV3029_A_SC, regs, + ret = rv3029_read_regs(dev, RV3029_A_SC, regs, RV3029_ALARM_SECTION_LEN); if (ret < 0) { - dev_err(&client->dev, "%s: reading alarm section failed\n", - __func__); + dev_err(dev, "%s: reading alarm section failed\n", __func__); return ret; } @@ -406,25 +401,23 @@ static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) return 0; } -static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable) +static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable) { int ret; /* enable/disable AIE irq */ - ret = rv3029_update_bits(client, RV3029_IRQ_CTRL, - RV3029_IRQ_CTRL_AIE, + ret = rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE, (enable ? RV3029_IRQ_CTRL_AIE : 0)); if (ret < 0) { - dev_err(&client->dev, "can't update INT reg\n"); + dev_err(dev, "can't update INT reg\n"); return ret; } return 0; } -static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { - struct i2c_client *client = to_i2c_client(dev); struct rtc_time *const tm = &alarm->time; int ret; u8 regs[8]; @@ -437,9 +430,9 @@ static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) if (tm->tm_year < 100) return -EINVAL; - ret = rv3029_get_sr(client, regs); + ret = rv3029_get_sr(dev, regs); if (ret < 0) { - dev_err(&client->dev, "%s: reading SR failed\n", __func__); + dev_err(dev, "%s: reading SR failed\n", __func__); return -EIO; } regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f); @@ -450,38 +443,38 @@ static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) regs[RV3029_A_DW-RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1); regs[RV3029_A_YR-RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100); - ret = rv3029_write_regs(client, RV3029_A_SC, regs, + ret = rv3029_write_regs(dev, RV3029_A_SC, regs, RV3029_ALARM_SECTION_LEN); if (ret < 0) return ret; if (alarm->enabled) { /* clear AF flag */ - ret = rv3029_update_bits(client, RV3029_IRQ_FLAGS, + ret = rv3029_update_bits(dev, RV3029_IRQ_FLAGS, RV3029_IRQ_FLAGS_AF, 0); if (ret < 0) { - dev_err(&client->dev, "can't clear alarm flag\n"); + dev_err(dev, "can't clear alarm flag\n"); return ret; } /* enable AIE irq */ - ret = rv3029_rtc_alarm_set_irq(client, 1); + ret = rv3029_rtc_alarm_set_irq(dev, 1); if (ret) return ret; - dev_dbg(&client->dev, "alarm IRQ armed\n"); + dev_dbg(dev, "alarm IRQ armed\n"); } else { /* disable AIE irq */ - ret = rv3029_rtc_alarm_set_irq(client, 0); + ret = rv3029_rtc_alarm_set_irq(dev, 0); if (ret) return ret; - dev_dbg(&client->dev, "alarm IRQ disabled\n"); + dev_dbg(dev, "alarm IRQ disabled\n"); } return 0; } -static int rv3029_set_time(struct i2c_client *client, struct rtc_time const *tm) +static int rv3029_set_time(struct device *dev, struct rtc_time *tm) { u8 regs[8]; int ret; @@ -502,31 +495,25 @@ static int rv3029_set_time(struct i2c_client *client, struct rtc_time const *tm) regs[RV3029_W_DAYS-RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7)+1); regs[RV3029_W_YEARS-RV3029_W_SEC] = bin2bcd(tm->tm_year - 100); - ret = rv3029_write_regs(client, RV3029_W_SEC, regs, + ret = rv3029_write_regs(dev, RV3029_W_SEC, regs, RV3029_WATCH_SECTION_LEN); if (ret < 0) return ret; - ret = rv3029_get_sr(client, regs); + ret = rv3029_get_sr(dev, regs); if (ret < 0) { - dev_err(&client->dev, "%s: reading SR failed\n", __func__); + dev_err(dev, "%s: reading SR failed\n", __func__); return ret; } /* clear PON bit */ - ret = rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON)); + ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON)); if (ret < 0) { - dev_err(&client->dev, "%s: reading SR failed\n", __func__); + dev_err(dev, "%s: reading SR failed\n", __func__); return ret; } return 0; } - -static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return rv3029_set_time(to_i2c_client(dev), tm); -} - static const struct rv3029_trickle_tab_elem { u32 r; /* resistance in ohms */ u8 conf; /* trickle config bits */ @@ -584,9 +571,9 @@ static const struct rv3029_trickle_tab_elem { }, }; -static void rv3029_trickle_config(struct i2c_client *client) +static void rv3029_trickle_config(struct device *dev) { - struct device_node *of_node = client->dev.of_node; + struct device_node *of_node = dev->of_node; const struct rv3029_trickle_tab_elem *elem; int i, err; u32 ohms; @@ -608,27 +595,26 @@ static void rv3029_trickle_config(struct i2c_client *client) break; } trickle_set_bits = elem->conf; - dev_info(&client->dev, + dev_info(dev, "Trickle charger enabled at %d ohms resistance.\n", elem->r); } - err = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL, + err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL, RV3029_TRICKLE_MASK, trickle_set_bits); if (err < 0) { - dev_err(&client->dev, - "Failed to update trickle charger config\n"); + dev_err(dev, "Failed to update trickle charger config\n"); } } #ifdef CONFIG_RTC_DRV_RV3029_HWMON -static int rv3029_read_temp(struct i2c_client *client, int *temp_mC) +static int rv3029_read_temp(struct device *dev, int *temp_mC) { int ret; u8 temp; - ret = rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1); + ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1); if (ret < 0) return ret; @@ -641,10 +627,9 @@ static ssize_t rv3029_hwmon_show_temp(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = dev_get_drvdata(dev); int ret, temp_mC; - ret = rv3029_read_temp(client, &temp_mC); + ret = rv3029_read_temp(dev, &temp_mC); if (ret < 0) return ret; @@ -656,7 +641,6 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev, const char *buf, size_t count) { - struct i2c_client *client = dev_get_drvdata(dev); unsigned long interval_ms; int ret; u8 th_set_bits = 0; @@ -670,7 +654,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev, if (interval_ms >= 16000) th_set_bits |= RV3029_EECTRL_THP; } - ret = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL, + ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL, RV3029_EECTRL_THE | RV3029_EECTRL_THP, th_set_bits); if (ret < 0) @@ -683,11 +667,10 @@ static ssize_t rv3029_hwmon_show_update_interval(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = dev_get_drvdata(dev); int ret, interval_ms; u8 eectrl; - ret = rv3029_eeprom_read(client, RV3029_CONTROL_E2P_EECTRL, + ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL, &eectrl, 1); if (ret < 0) return ret; @@ -717,32 +700,32 @@ static struct attribute *rv3029_hwmon_attrs[] = { }; ATTRIBUTE_GROUPS(rv3029_hwmon); -static void rv3029_hwmon_register(struct i2c_client *client) +static void rv3029_hwmon_register(struct device *dev, const char *name) { + struct rv3029_data *rv3029 = dev_get_drvdata(dev); struct device *hwmon_dev; - hwmon_dev = devm_hwmon_device_register_with_groups( - &client->dev, client->name, client, rv3029_hwmon_groups); + hwmon_dev = devm_hwmon_device_register_with_groups(dev, name, rv3029, + rv3029_hwmon_groups); if (IS_ERR(hwmon_dev)) { - dev_warn(&client->dev, - "unable to register hwmon device %ld\n", + dev_warn(dev, "unable to register hwmon device %ld\n", PTR_ERR(hwmon_dev)); } } #else /* CONFIG_RTC_DRV_RV3029_HWMON */ -static void rv3029_hwmon_register(struct i2c_client *client) +static void rv3029_hwmon_register(struct device *dev, const char *name) { } #endif /* CONFIG_RTC_DRV_RV3029_HWMON */ static const struct rtc_class_ops rv3029_rtc_ops = { - .read_time = rv3029_rtc_read_time, - .set_time = rv3029_rtc_set_time, - .read_alarm = rv3029_rtc_read_alarm, - .set_alarm = rv3029_rtc_set_alarm, + .read_time = rv3029_read_time, + .set_time = rv3029_set_time, + .read_alarm = rv3029_read_alarm, + .set_alarm = rv3029_set_alarm, }; static struct i2c_device_id rv3029_id[] = { @@ -752,41 +735,67 @@ static struct i2c_device_id rv3029_id[] = { }; MODULE_DEVICE_TABLE(i2c, rv3029_id); -static int rv3029_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq, + const char *name) { - struct rtc_device *rtc; + struct rv3029_data *rv3029; int rc = 0; u8 buf[1]; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL)) - return -ENODEV; + rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL); + if (!rv3029) + return -ENOMEM; - rc = rv3029_get_sr(client, buf); + rv3029->regmap = regmap; + rv3029->irq = irq; + rv3029->dev = dev; + dev_set_drvdata(dev, rv3029); + + rc = rv3029_get_sr(dev, buf); if (rc < 0) { - dev_err(&client->dev, "reading status failed\n"); + dev_err(dev, "reading status failed\n"); return rc; } - rv3029_trickle_config(client); - rv3029_hwmon_register(client); + rv3029_trickle_config(dev); + rv3029_hwmon_register(dev, name); - rtc = devm_rtc_device_register(&client->dev, client->name, - &rv3029_rtc_ops, THIS_MODULE); + rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops, + THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + return PTR_ERR_OR_ZERO(rv3029->rtc); +} - i2c_set_clientdata(client, rtc); +static int rv3029_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct regmap *regmap; + static const struct regmap_config config = { + .reg_bits = 8, + .val_bits = 8, + }; - return 0; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK | + I2C_FUNC_SMBUS_BYTE)) { + dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n"); + return -ENODEV; + } + + regmap = devm_regmap_init_i2c(client, &config); + if (IS_ERR(regmap)) { + dev_err(&client->dev, "%s: regmap allocation failed: %ld\n", + __func__, PTR_ERR(regmap)); + return PTR_ERR(regmap); + } + + return rv3029_probe(&client->dev, regmap, client->irq, client->name); } static struct i2c_driver rv3029_driver = { .driver = { .name = "rtc-rv3029c2", }, - .probe = rv3029_probe, + .probe = rv3029_i2c_probe, .id_table = rv3029_id, }; From c2a1c145401df063d1197ace5d3b5bd323e26f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 3 May 2016 11:54:34 +0200 Subject: [PATCH 33/40] rtc: rv3029: Add support of RV3049 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support of Microcrystal RV3049 RTC (SPI) using regmap on the RV3029 (I2C) driver. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 37 ++++++------- drivers/rtc/rtc-rv3029c2.c | 108 +++++++++++++++++++++++++++++++++++-- 2 files changed, 124 insertions(+), 21 deletions(-) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index f1e1f502be5d..18639e0cb6e2 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -573,24 +573,6 @@ config RTC_DRV_EM3027 This driver can also be built as a module. If so, the module will be called rtc-em3027. -config RTC_DRV_RV3029C2 - tristate "Micro Crystal RV3029" - help - If you say yes here you get support for the Micro Crystal - RV3029 RTC chips. - - This driver can also be built as a module. If so, the module - will be called rtc-rv3029c2. - -config RTC_DRV_RV3029_HWMON - bool "HWMON support for RV3029" - depends on RTC_DRV_RV3029C2 && HWMON - depends on !(RTC_DRV_RV3029C2=y && HWMON=m) - default y - help - Say Y here if you want to expose temperature sensor data on - rtc-rv3029. - config RTC_DRV_RV8803 tristate "Micro Crystal RV8803" help @@ -786,6 +768,25 @@ config RTC_DRV_PCF2127 This driver can also be built as a module. If so, the module will be called rtc-pcf2127. +config RTC_DRV_RV3029C2 + tristate "Micro Crystal RV3029/3049" + depends on RTC_I2C_AND_SPI + help + If you say yes here you get support for the Micro Crystal + RV3029 and RV3049 RTC chips. + + This driver can also be built as a module. If so, the module + will be called rtc-rv3029c2. + +config RTC_DRV_RV3029_HWMON + bool "HWMON support for RV3029/3049" + depends on RTC_DRV_RV3029C2 && HWMON + depends on !(RTC_DRV_RV3029C2=y && HWMON=m) + default y + help + Say Y here if you want to expose temperature sensor data on + rtc-rv3029. + comment "Platform RTC drivers" # this 'CMOS' RTC driver is arch dependent because diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 96dd1665220c..1310646a4821 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -1,5 +1,5 @@ /* - * Micro Crystal RV-3029 rtc class driver + * Micro Crystal RV-3029 / RV-3049 rtc class driver * * Author: Gregory Hermant * Michael Buesch @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -766,6 +767,8 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq, return PTR_ERR_OR_ZERO(rv3029->rtc); } +#if IS_ENABLED(CONFIG_I2C) + static int rv3029_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -799,9 +802,108 @@ static struct i2c_driver rv3029_driver = { .id_table = rv3029_id, }; -module_i2c_driver(rv3029_driver); +static int rv3029_register_driver(void) +{ + return i2c_add_driver(&rv3029_driver); +} + +static void rv3029_unregister_driver(void) +{ + i2c_del_driver(&rv3029_driver); +} + +#else + +static int rv3029_register_driver(void) +{ + return 0; +} + +static void rv3029_unregister_driver(void) +{ +} + +#endif + +#if IS_ENABLED(CONFIG_SPI_MASTER) + +static int rv3049_probe(struct spi_device *spi) +{ + static const struct regmap_config config = { + .reg_bits = 8, + .val_bits = 8, + }; + struct regmap *regmap; + + regmap = devm_regmap_init_spi(spi, &config); + if (IS_ERR(regmap)) { + dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n", + __func__, PTR_ERR(regmap)); + return PTR_ERR(regmap); + } + + return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049"); +} + +static struct spi_driver rv3049_driver = { + .driver = { + .name = "rv3049", + }, + .probe = rv3049_probe, +}; + +static int rv3049_register_driver(void) +{ + return spi_register_driver(&rv3049_driver); +} + +static void rv3049_unregister_driver(void) +{ + spi_unregister_driver(&rv3049_driver); +} + +#else + +static int rv3049_register_driver(void) +{ + return 0; +} + +static void rv3049_unregister_driver(void) +{ +} + +#endif + +static int __init rv30x9_init(void) +{ + int ret; + + ret = rv3029_register_driver(); + if (ret) { + pr_err("Failed to register rv3029 driver: %d\n", ret); + return ret; + } + + ret = rv3049_register_driver(); + if (ret) { + pr_err("Failed to register rv3049 driver: %d\n", ret); + rv3029_unregister_driver(); + } + + return ret; +} +module_init(rv30x9_init) + +static void __exit rv30x9_exit(void) +{ + rv3049_unregister_driver(); + rv3029_unregister_driver(); +} +module_exit(rv30x9_exit) MODULE_AUTHOR("Gregory Hermant "); MODULE_AUTHOR("Michael Buesch "); -MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver"); +MODULE_DESCRIPTION("Micro Crystal RV3029/RV3049 RTC driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:rv3049"); From abe2f551efc65760d61668ad6fb511bf834082dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 3 May 2016 11:54:35 +0200 Subject: [PATCH 34/40] rtc: rv3029: Remove some checks and warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove some checks from checkpatch such as spaces around arithmetic operations or prefer "unsigned int". Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv3029c2.c | 68 +++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 1310646a4821..cf8d4650e15e 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -125,24 +125,24 @@ struct rv3029_data { }; static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf, - unsigned len) + unsigned int len) { struct rv3029_data *rv3029 = dev_get_drvdata(dev); if ((reg > RV3029_USR1_RAM_PAGE + 7) || - (reg + len > RV3029_USR1_RAM_PAGE + 8)) + (reg + len > RV3029_USR1_RAM_PAGE + 8)) return -EINVAL; return regmap_bulk_read(rv3029->regmap, reg, buf, len); } static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[], - unsigned len) + unsigned int len) { struct rv3029_data *rv3029 = dev_get_drvdata(dev); if ((reg > RV3029_USR1_RAM_PAGE + 7) || - (reg + len > RV3029_USR1_RAM_PAGE + 8)) + (reg + len > RV3029_USR1_RAM_PAGE + 8)) return -EINVAL; return regmap_bulk_write(rv3029->regmap, reg, buf, len); @@ -347,12 +347,12 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm) return ret; } - tm->tm_sec = bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]); - tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES-RV3029_W_SEC]); + tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]); + tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]); /* HR field has a more complex interpretation */ { - const u8 _hr = regs[RV3029_W_HOURS-RV3029_W_SEC]; + const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC]; if (_hr & RV3029_REG_HR_12_24) { /* 12h format */ @@ -363,10 +363,10 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm) tm->tm_hour = bcd2bin(_hr & 0x3f); } - tm->tm_mday = bcd2bin(regs[RV3029_W_DATE-RV3029_W_SEC]); - tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS-RV3029_W_SEC]) - 1; - tm->tm_year = bcd2bin(regs[RV3029_W_YEARS-RV3029_W_SEC]) + 100; - tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS-RV3029_W_SEC]) - 1; + tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]); + tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1; + tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 100; + tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1; return 0; } @@ -391,13 +391,13 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) return ret; } - tm->tm_sec = bcd2bin(regs[RV3029_A_SC-RV3029_A_SC] & 0x7f); - tm->tm_min = bcd2bin(regs[RV3029_A_MN-RV3029_A_SC] & 0x7f); - tm->tm_hour = bcd2bin(regs[RV3029_A_HR-RV3029_A_SC] & 0x3f); - tm->tm_mday = bcd2bin(regs[RV3029_A_DT-RV3029_A_SC] & 0x3f); - tm->tm_mon = bcd2bin(regs[RV3029_A_MO-RV3029_A_SC] & 0x1f) - 1; - tm->tm_year = bcd2bin(regs[RV3029_A_YR-RV3029_A_SC] & 0x7f) + 100; - tm->tm_wday = bcd2bin(regs[RV3029_A_DW-RV3029_A_SC] & 0x07) - 1; + tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f); + tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f); + tm->tm_hour = bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f); + tm->tm_mday = bcd2bin(regs[RV3029_A_DT - RV3029_A_SC] & 0x3f); + tm->tm_mon = bcd2bin(regs[RV3029_A_MO - RV3029_A_SC] & 0x1f) - 1; + tm->tm_year = bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100; + tm->tm_wday = bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1; return 0; } @@ -436,13 +436,13 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) dev_err(dev, "%s: reading SR failed\n", __func__); return -EIO; } - regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f); - regs[RV3029_A_MN-RV3029_A_SC] = bin2bcd(tm->tm_min & 0x7f); - regs[RV3029_A_HR-RV3029_A_SC] = bin2bcd(tm->tm_hour & 0x3f); - regs[RV3029_A_DT-RV3029_A_SC] = bin2bcd(tm->tm_mday & 0x3f); - regs[RV3029_A_MO-RV3029_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1); - regs[RV3029_A_DW-RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1); - regs[RV3029_A_YR-RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100); + regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f); + regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min & 0x7f); + regs[RV3029_A_HR - RV3029_A_SC] = bin2bcd(tm->tm_hour & 0x3f); + regs[RV3029_A_DT - RV3029_A_SC] = bin2bcd(tm->tm_mday & 0x3f); + regs[RV3029_A_MO - RV3029_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1); + regs[RV3029_A_DW - RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1); + regs[RV3029_A_YR - RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100); ret = rv3029_write_regs(dev, RV3029_A_SC, regs, RV3029_ALARM_SECTION_LEN); @@ -488,13 +488,13 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm) if (tm->tm_year < 100) return -EINVAL; - regs[RV3029_W_SEC-RV3029_W_SEC] = bin2bcd(tm->tm_sec); - regs[RV3029_W_MINUTES-RV3029_W_SEC] = bin2bcd(tm->tm_min); - regs[RV3029_W_HOURS-RV3029_W_SEC] = bin2bcd(tm->tm_hour); - regs[RV3029_W_DATE-RV3029_W_SEC] = bin2bcd(tm->tm_mday); - regs[RV3029_W_MONTHS-RV3029_W_SEC] = bin2bcd(tm->tm_mon+1); - regs[RV3029_W_DAYS-RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7)+1); - regs[RV3029_W_YEARS-RV3029_W_SEC] = bin2bcd(tm->tm_year - 100); + regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec); + regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min); + regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour); + regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday); + regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1); + regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7) + 1); + regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100); ret = rv3029_write_regs(dev, RV3029_W_SEC, regs, RV3029_WATCH_SECTION_LEN); @@ -515,6 +515,7 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm) return 0; } + static const struct rv3029_trickle_tab_elem { u32 r; /* resistance in ohms */ u8 conf; /* trickle config bits */ @@ -603,9 +604,8 @@ static void rv3029_trickle_config(struct device *dev) err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL, RV3029_TRICKLE_MASK, trickle_set_bits); - if (err < 0) { + if (err < 0) dev_err(dev, "Failed to update trickle charger config\n"); - } } #ifdef CONFIG_RTC_DRV_RV3029_HWMON From dc492e866a997b3df2a551fa772d6887a19e53b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 3 May 2016 11:54:36 +0200 Subject: [PATCH 35/40] rtc: rv3029: fix alarm support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The RTC RV3029 handles different types of alarms : seconds, minutes, ... These alarms can be enabled or disabled individually using an AE_x bit which is the last bit (BIT(7)) on each alarm registers. To prepare the alarm IRQ support, the current code enables all the alarm types by setting each AE_x to 1. It also fixes others alarms issues : - month and weekday errors : it was performing -1 instead of +1. - wrong use of bit mask with bin2bcd Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv3029c2.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index cf8d4650e15e..88a0c188a6f2 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -76,6 +76,7 @@ #define RV3029_A_DW 0x14 #define RV3029_A_MO 0x15 #define RV3029_A_YR 0x16 +#define RV3029_A_AE_X BIT(7) #define RV3029_ALARM_SECTION_LEN 0x07 /* timer section */ @@ -436,14 +437,22 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) dev_err(dev, "%s: reading SR failed\n", __func__); return -EIO; } - regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f); - regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min & 0x7f); - regs[RV3029_A_HR - RV3029_A_SC] = bin2bcd(tm->tm_hour & 0x3f); - regs[RV3029_A_DT - RV3029_A_SC] = bin2bcd(tm->tm_mday & 0x3f); - regs[RV3029_A_MO - RV3029_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1); - regs[RV3029_A_DW - RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1); - regs[RV3029_A_YR - RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100); + /* Activate all the alarms with AE_x bit */ + regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X; + regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X; + regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour) & 0x3f) + | RV3029_A_AE_X; + regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday) & 0x3f) + | RV3029_A_AE_X; + regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd(tm->tm_mon + 1) & 0x1f) + | RV3029_A_AE_X; + regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd(tm->tm_wday + 1) & 0x7) + | RV3029_A_AE_X; + regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd(tm->tm_year - 100)) + | RV3029_A_AE_X; + + /* Write the alarm */ ret = rv3029_write_regs(dev, RV3029_A_SC, regs, RV3029_ALARM_SECTION_LEN); if (ret < 0) From 38201ca3c58d27ac95ee08995558c7176b4feb13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 3 May 2016 11:54:37 +0200 Subject: [PATCH 36/40] rtc: rv3029: fix set_time function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bin2bcd function in set_time is uncorrect on weekdays as the bit mask should be done at the end of arithmetic operations. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv3029c2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 88a0c188a6f2..916bbc2f57de 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -502,7 +502,7 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm) regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour); regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday); regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1); - regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7) + 1); + regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7; regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100); ret = rv3029_write_regs(dev, RV3029_W_SEC, regs, From 0ddc5b89cd12938e251c691563f45409b4d15d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Date: Tue, 3 May 2016 11:54:38 +0200 Subject: [PATCH 37/40] rtc: rv3029: add alarm IRQ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the alarm IRQ functionality. Signed-off-by: Mylène Josserand Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv3029c2.c | 114 ++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 21 deletions(-) diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 916bbc2f57de..c2ef64fb4757 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -329,6 +329,47 @@ static int rv3029_eeprom_update_bits(struct device *dev, return 0; } +static irqreturn_t rv3029_handle_irq(int irq, void *dev_id) +{ + struct device *dev = dev_id; + struct rv3029_data *rv3029 = dev_get_drvdata(dev); + struct mutex *lock = &rv3029->rtc->ops_lock; + unsigned long events = 0; + u8 flags, controls; + int ret; + + mutex_lock(lock); + + ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1); + if (ret) { + dev_warn(dev, "Read IRQ Control Register error %d\n", ret); + mutex_unlock(lock); + return IRQ_NONE; + } + + ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1); + if (ret) { + dev_warn(dev, "Read IRQ Flags Register error %d\n", ret); + mutex_unlock(lock); + return IRQ_NONE; + } + + if (flags & RV3029_IRQ_FLAGS_AF) { + flags &= ~RV3029_IRQ_FLAGS_AF; + controls &= ~RV3029_IRQ_CTRL_AIE; + events |= RTC_AF; + } + + if (events) { + rtc_update_irq(rv3029->rtc, 1, events); + rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1); + rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1); + } + mutex_unlock(lock); + + return IRQ_HANDLED; +} + static int rv3029_read_time(struct device *dev, struct rtc_time *tm) { u8 buf[1]; @@ -376,7 +417,7 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct rtc_time *const tm = &alarm->time; int ret; - u8 regs[8]; + u8 regs[8], controls, flags; ret = rv3029_get_sr(dev, regs); if (ret < 0) { @@ -392,6 +433,17 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) return ret; } + ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1); + if (ret) { + dev_err(dev, "Read IRQ Control Register error %d\n", ret); + return ret; + } + ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1); + if (ret < 0) { + dev_err(dev, "Read IRQ Flags Register error %d\n", ret); + return ret; + } + tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f); tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f); tm->tm_hour = bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f); @@ -400,16 +452,30 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) tm->tm_year = bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100; tm->tm_wday = bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1; + alarm->enabled = !!(controls & RV3029_IRQ_CTRL_AIE); + alarm->pending = (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled; + return 0; } -static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable) +static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable) { int ret; + u8 controls; + + ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1); + if (ret < 0) { + dev_warn(dev, "Read IRQ Control Register error %d\n", ret); + return ret; + } /* enable/disable AIE irq */ - ret = rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE, - (enable ? RV3029_IRQ_CTRL_AIE : 0)); + if (enable) + controls |= RV3029_IRQ_CTRL_AIE; + else + controls &= ~RV3029_IRQ_CTRL_AIE; + + ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1); if (ret < 0) { dev_err(dev, "can't update INT reg\n"); return ret; @@ -459,26 +525,15 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) return ret; if (alarm->enabled) { - /* clear AF flag */ - ret = rv3029_update_bits(dev, RV3029_IRQ_FLAGS, - RV3029_IRQ_FLAGS_AF, 0); - if (ret < 0) { - dev_err(dev, "can't clear alarm flag\n"); - return ret; - } /* enable AIE irq */ - ret = rv3029_rtc_alarm_set_irq(dev, 1); + ret = rv3029_alarm_irq_enable(dev, 1); if (ret) return ret; - - dev_dbg(dev, "alarm IRQ armed\n"); } else { /* disable AIE irq */ - ret = rv3029_rtc_alarm_set_irq(dev, 0); + ret = rv3029_alarm_irq_enable(dev, 0); if (ret) return ret; - - dev_dbg(dev, "alarm IRQ disabled\n"); } return 0; @@ -731,11 +786,9 @@ static void rv3029_hwmon_register(struct device *dev, const char *name) #endif /* CONFIG_RTC_DRV_RV3029_HWMON */ -static const struct rtc_class_ops rv3029_rtc_ops = { +static struct rtc_class_ops rv3029_rtc_ops = { .read_time = rv3029_read_time, .set_time = rv3029_set_time, - .read_alarm = rv3029_read_alarm, - .set_alarm = rv3029_set_alarm, }; static struct i2c_device_id rv3029_id[] = { @@ -772,8 +825,27 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq, rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops, THIS_MODULE); + if (IS_ERR(rv3029->rtc)) { + dev_err(dev, "unable to register the class device\n"); + return PTR_ERR(rv3029->rtc); + } - return PTR_ERR_OR_ZERO(rv3029->rtc); + if (rv3029->irq > 0) { + rc = devm_request_threaded_irq(dev, rv3029->irq, + NULL, rv3029_handle_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "rv3029", dev); + if (rc) { + dev_warn(dev, "unable to request IRQ, alarms disabled\n"); + rv3029->irq = 0; + } else { + rv3029_rtc_ops.read_alarm = rv3029_read_alarm; + rv3029_rtc_ops.set_alarm = rv3029_set_alarm; + rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable; + } + } + + return 0; } #if IS_ENABLED(CONFIG_I2C) From a9dbe558920e12ea286cd4479039df26991a95de Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Wed, 2 Jun 2010 15:53:05 +0200 Subject: [PATCH 38/40] rtc: rs5c372: r2025: fix check for 'oscillator halted' condition The R2025SD chip, according to its data sheet, sets the /XST bit to zero if the oscillator stops. Hence the check for this condition was wrong. Signed-off-by: Thomas Koeller Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rs5c372.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index aaebe10876e8..ef86229428fc 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -506,9 +506,9 @@ static int rs5c_oscillator_setup(struct rs5c372 *rs5c372) int addr, i, ret = 0; if (rs5c372->type == rtc_r2025sd) { - if (!(rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST)) + if (rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST) return ret; - rs5c372->regs[RS5C_REG_CTRL2] &= ~R2025_CTRL2_XST; + rs5c372->regs[RS5C_REG_CTRL2] |= R2025_CTRL2_XST; } else { if (!(rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP)) return ret; From 814db2bc4c4e19530eae818354dceb861ceb9fb1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 4 May 2016 11:50:02 +0200 Subject: [PATCH 39/40] rtc: rv3029: hide unused i2c device table The added support for SPI mode made it possible to configure the driver when I2C is disabled, leaving an unused device table: drivers/rtc/rtc-rv3029c2.c:794:29: error: 'rv3029_id' defined but not used [-Werror=unused-variable] This moves the table inside of the #ifdef section that has the only user, to avoid the harmless warning. Signed-off-by: Arnd Bergmann Fixes: d08f50dd0afc ("rtc: rv3029: Add support of RV3049") Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv3029c2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index c2ef64fb4757..1f9f7b4bf3fb 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -791,13 +791,6 @@ static struct rtc_class_ops rv3029_rtc_ops = { .set_time = rv3029_set_time, }; -static struct i2c_device_id rv3029_id[] = { - { "rv3029", 0 }, - { "rv3029c2", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, rv3029_id); - static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq, const char *name) { @@ -875,6 +868,13 @@ static int rv3029_i2c_probe(struct i2c_client *client, return rv3029_probe(&client->dev, regmap, client->irq, client->name); } +static struct i2c_device_id rv3029_id[] = { + { "rv3029", 0 }, + { "rv3029c2", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, rv3029_id); + static struct i2c_driver rv3029_driver = { .driver = { .name = "rtc-rv3029c2", From b9ba1eb0336877b9b83556fd30d2becda110fd8c Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Tue, 10 May 2016 12:26:42 +0200 Subject: [PATCH 40/40] rtc: tps6586x: rename so module can be autoloaded This module is loaded by the related mfd driver which has the needed MODULE_DEVICE_TABLE(i2c,...). This patch fix the modalias when the rtc driver is built as a module, so the right name is used. Everything operates correctly when this module is builtin. Fixes: esdc59ed3865 ("rtc: add RTC driver for TPS6586x") Signed-off-by: Nicolas Chauvet Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tps6586x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index e404faac6851..a3418a8a3796 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c @@ -344,7 +344,7 @@ static struct platform_driver tps6586x_rtc_driver = { }; module_platform_driver(tps6586x_rtc_driver); -MODULE_ALIAS("platform:rtc-tps6586x"); +MODULE_ALIAS("platform:tps6586x-rtc"); MODULE_DESCRIPTION("TI TPS6586x RTC driver"); MODULE_AUTHOR("Laxman dewangan "); MODULE_LICENSE("GPL v2");