From 3180cfabf6fbf982ca6d1a6eb56334647cc1416b Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 29 Jun 2020 13:41:23 +0200 Subject: rtc: cpcap: fix range Unbreak CPCAP driver, which has one more bit in the day counter increasing the max. range from 2014 to 2058. The original commit introducing the range limit was obviously wrong, since the driver has only been written in 2017 (3 years after 14 bits would have run out). Fixes: d2377f8cc5a7 ("rtc: cpcap: set range") Reported-by: Sicelo A. Mhlongo Reported-by: Dev Null Signed-off-by: Sebastian Reichel Signed-off-by: Alexandre Belloni Tested-by: Merlijn Wajer Acked-by: Tony Lindgren Acked-by: Merlijn Wajer Link: https://lore.kernel.org/r/20200629114123.27956-1-sebastian.reichel@collabora.com --- drivers/rtc/rtc-cpcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c index a603f1f21125..800667d73a6f 100644 --- a/drivers/rtc/rtc-cpcap.c +++ b/drivers/rtc/rtc-cpcap.c @@ -261,7 +261,7 @@ static int cpcap_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc->rtc_dev); rtc->rtc_dev->ops = &cpcap_rtc_ops; - rtc->rtc_dev->range_max = (1 << 14) * SECS_PER_DAY - 1; + rtc->rtc_dev->range_max = (timeu64_t) (DAY_MASK + 1) * SECS_PER_DAY - 1; err = cpcap_get_vendor(dev, rtc->regmap, &rtc->vendor); if (err) -- cgit v1.2.3 From 05513a706b4f8f978c0ecc97b6d99793fbaaaf17 Mon Sep 17 00:00:00 2001 From: "Tales L. da Aparecida" Date: Tue, 23 Jun 2020 22:21:19 -0300 Subject: rtc: imxdi: fix trivial typos Fix typos 'pionter' -> 'pointer' and 'softwere' -> 'software' Signed-off-by: Tales L. da Aparecida Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20200624012119.54768-1-tales.aparecida@gmail.com --- drivers/rtc/rtc-imxdi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index f21dc6b16d88..8d141d8a5490 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -95,7 +95,7 @@ /** * struct imxdi_dev - private imxdi rtc data - * @pdev: pionter to platform dev + * @pdev: pointer to platform dev * @rtc: pointer to rtc struct * @ioaddr: IO registers pointer * @clk: input reference clock @@ -350,7 +350,7 @@ static int di_handle_invalid_and_failure_state(struct imxdi_dev *imxdi, u32 dsr) * the tamper register is locked. We cannot disable the * tamper detection. The TDCHL can only be reset by a * DRYICE POR, but we cannot force a DRYICE POR in - * softwere because we are still in "FAILURE STATE". + * software because we are still in "FAILURE STATE". * We need a DRYICE POR via battery power cycling.... */ /* -- cgit v1.2.3 From d8f090dbeafdcc3d30761aa0062f19d1adf9ef08 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 15 Jun 2020 18:14:55 +0200 Subject: rtc: max77686: Do not allow interrupt to fire before system resume The rtc-max77686 device shares the main interrupt line with parent MFD device (max77686 driver). During the system suspend, the parent MFD device disables this IRQ to prevent an early event happening before resuming I2C bus controller. The same should be done by rtc-max77686 driver because otherwise the interrupt handler max77686_rtc_alarm_irq() will be called before its resume function (max77686_rtc_resume()). Such issue is not fatal but disabling shared IRQ by all users ensures correct behavior. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20200615161455.4420-1-krzk@kernel.org --- drivers/rtc/rtc-max77686.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 03ebcf1c0f3d..645de5af707b 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -805,17 +805,33 @@ static int max77686_rtc_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int max77686_rtc_suspend(struct device *dev) { + struct max77686_rtc_info *info = dev_get_drvdata(dev); + int ret = 0; + if (device_may_wakeup(dev)) { struct max77686_rtc_info *info = dev_get_drvdata(dev); - return enable_irq_wake(info->virq); + ret = enable_irq_wake(info->virq); } - return 0; + /* + * Main IRQ (not virtual) must be disabled during suspend because if it + * happens while suspended it will be handled before resuming I2C. + * + * Since Main IRQ is shared, all its users should disable it to be sure + * it won't fire while one of them is still suspended. + */ + disable_irq(info->rtc_irq); + + return ret; } static int max77686_rtc_resume(struct device *dev) { + struct max77686_rtc_info *info = dev_get_drvdata(dev); + + enable_irq(info->rtc_irq); + if (device_may_wakeup(dev)) { struct max77686_rtc_info *info = dev_get_drvdata(dev); -- cgit v1.2.3 From 22f8d5a1bf230cf8567a4121fc3789babb46336d Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Sat, 20 Jun 2020 20:04:43 +0800 Subject: rtc: goldfish: Enable interrupt in set_alarm() when necessary When use goldfish rtc, the "hwclock" command fails with "select() to /dev/rtc to wait for clock tick timed out". This is because "hwclock" need the set_alarm() hook to enable interrupt when alrm->enabled is true. This operation is missing in goldfish rtc (but other rtc drivers, such as cmos rtc, enable interrupt here), so add it. Signed-off-by: Huacai Chen Signed-off-by: Jiaxun Yang Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/1592654683-31314-1-git-send-email-chenhc@lemote.com --- drivers/rtc/rtc-goldfish.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c index 27797157fcb3..6349d2cd3680 100644 --- a/drivers/rtc/rtc-goldfish.c +++ b/drivers/rtc/rtc-goldfish.c @@ -73,6 +73,7 @@ static int goldfish_rtc_set_alarm(struct device *dev, rtc_alarm64 = rtc_tm_to_time64(&alrm->time) * NSEC_PER_SEC; writel((rtc_alarm64 >> 32), base + TIMER_ALARM_HIGH); writel(rtc_alarm64, base + TIMER_ALARM_LOW); + writel(1, base + TIMER_IRQ_ENABLED); } else { /* * if this function was called with enabled=0 -- cgit v1.2.3 From 3567d3d1477289d2ee988ee007507fca69f97eb8 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 6 Jul 2020 08:27:27 +0200 Subject: rtc: Replace HTTP links with HTTPS ones Rationale: Reduces attack surface on kernel devs opening the links for MITM as HTTPS traffic is much harder to manipulate. Deterministic algorithm: For each file: If not .svg: For each line: If doesn't contain `\bxmlns\b`: For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: If both the HTTP and HTTPS versions return 200 OK and serve the same content: Replace HTTP with HTTPS. Signed-off-by: Alexander A. Klimov Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20200706062727.18481-1-grandmaster@al2klimov.de --- drivers/rtc/rtc-ab-b5ze-s3.c | 2 +- drivers/rtc/rtc-bq32k.c | 2 +- drivers/rtc/rtc-mcp795.c | 2 +- drivers/rtc/rtc-pcf85063.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index 811fe2005488..2370ac0cdb5f 100644 --- a/drivers/rtc/rtc-ab-b5ze-s3.c +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -7,7 +7,7 @@ * * Detailed datasheet of the chip is available here: * - * http://www.abracon.com/realtimeclock/AB-RTCMC-32.768kHz-B5ZE-S3-Application-Manual.pdf + * https://www.abracon.com/realtimeclock/AB-RTCMC-32.768kHz-B5ZE-S3-Application-Manual.pdf * * This work is based on ISL12057 driver (drivers/rtc/rtc-isl12057.c). * diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 4a63f0cd2321..933e4237237d 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -6,7 +6,7 @@ * Copyright (C) 2014 Pavel Machek * * You can get hardware description at - * http://www.ti.com/lit/ds/symlink/bq32000.pdf + * https://www.ti.com/lit/ds/symlink/bq32000.pdf */ #include diff --git a/drivers/rtc/rtc-mcp795.c b/drivers/rtc/rtc-mcp795.c index 1660d5e79582..21cbf7f892e8 100644 --- a/drivers/rtc/rtc-mcp795.c +++ b/drivers/rtc/rtc-mcp795.c @@ -7,7 +7,7 @@ * based on other Linux RTC drivers * * Device datasheet: - * http://ww1.microchip.com/downloads/en/DeviceDoc/22280A.pdf + * https://ww1.microchip.com/downloads/en/DeviceDoc/22280A.pdf */ #include diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index 7a87f461bec8..ca55ba975aeb 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -21,8 +21,8 @@ /* * Information for this driver was pulled from the following datasheets. * - * http://www.nxp.com/documents/data_sheet/PCF85063A.pdf - * http://www.nxp.com/documents/data_sheet/PCF85063TP.pdf + * https://www.nxp.com/documents/data_sheet/PCF85063A.pdf + * https://www.nxp.com/documents/data_sheet/PCF85063TP.pdf * * PCF85063A -- Rev. 6 — 18 November 2015 * PCF85063TP -- Rev. 4 — 6 May 2015 -- cgit v1.2.3 From d3de4beb14a887754b83843bf23b6dbe8d022764 Mon Sep 17 00:00:00 2001 From: "Johnson CH Chen (陳昭勳)" Date: Thu, 9 Jul 2020 06:34:06 +0000 Subject: rtc: ds1374: wdt: Use watchdog core for watchdog part Let ds1374 watchdog use watchdog core functions. It also includes improving watchdog timer setting and nowayout, and just uses ioctl() of watchdog core. Signed-off-by: Johnson Chen Signed-off-by: Alexandre Belloni Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/HK2PR01MB328182D5A54BFAA8A22E448AFA640@HK2PR01MB3281.apcprd01.prod.exchangelabs.com --- drivers/rtc/Kconfig | 1 + drivers/rtc/rtc-ds1374.c | 258 +++++++++++------------------------------------ 2 files changed, 62 insertions(+), 197 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b54d87d45c89..c25d51f35f0c 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -282,6 +282,7 @@ config RTC_DRV_DS1374 config RTC_DRV_DS1374_WDT bool "Dallas/Maxim DS1374 watchdog timer" depends on RTC_DRV_DS1374 + select WATCHDOG_CORE if WATCHDOG help If you say Y here you will get support for the watchdog timer in the Dallas Semiconductor DS1374 diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 9c51a12cf70f..c71065d26cd2 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -46,6 +46,7 @@ #define DS1374_REG_WDALM2 0x06 #define DS1374_REG_CR 0x07 /* Control */ #define DS1374_REG_CR_AIE 0x01 /* Alarm Int. Enable */ +#define DS1374_REG_CR_WDSTR 0x08 /* 1=INT, 0=RST */ #define DS1374_REG_CR_WDALM 0x20 /* 1=Watchdog, 0=Alarm */ #define DS1374_REG_CR_WACE 0x40 /* WD/Alarm counter enable */ #define DS1374_REG_SR 0x08 /* Status */ @@ -71,7 +72,9 @@ struct ds1374 { struct i2c_client *client; struct rtc_device *rtc; struct work_struct work; - +#ifdef CONFIG_RTC_DRV_DS1374_WDT + struct watchdog_device wdt; +#endif /* The mutex protects alarm operations, and prevents a race * between the enable_irq() in the workqueue and the free_irq() * in the remove function. @@ -369,238 +372,98 @@ static const struct rtc_class_ops ds1374_rtc_ops = { * ***************************************************************************** */ -static struct i2c_client *save_client; /* Default margin */ -#define WD_TIMO 131762 +#define TIMER_MARGIN_DEFAULT 32 +#define TIMER_MARGIN_MIN 1 +#define TIMER_MARGIN_MAX 4095 /* 24-bit value */ #define DRV_NAME "DS1374 Watchdog" -static int wdt_margin = WD_TIMO; -static unsigned long wdt_is_open; +static int wdt_margin; module_param(wdt_margin, int, 0); MODULE_PARM_DESC(wdt_margin, "Watchdog timeout in seconds (default 32s)"); +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default =" + __MODULE_STRING(WATCHDOG_NOWAYOUT)")"); + static const struct watchdog_info ds1374_wdt_info = { .identity = "DS1374 WTD", .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, }; -static int ds1374_wdt_settimeout(unsigned int timeout) +static int ds1374_wdt_settimeout(struct watchdog_device *wdt, unsigned int timeout) { - int ret = -ENOIOCTLCMD; - int cr; + struct ds1374 *ds1374 = watchdog_get_drvdata(wdt); + struct i2c_client *client = ds1374->client; + int ret, cr; - ret = cr = i2c_smbus_read_byte_data(save_client, DS1374_REG_CR); - if (ret < 0) - goto out; + wdt->timeout = timeout; + + cr = i2c_smbus_read_byte_data(client, DS1374_REG_CR); + if (cr < 0) + return cr; /* Disable any existing watchdog/alarm before setting the new one */ cr &= ~DS1374_REG_CR_WACE; - ret = i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr); + ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr); if (ret < 0) - goto out; + return ret; /* Set new watchdog time */ - ret = ds1374_write_rtc(save_client, timeout, DS1374_REG_WDALM0, 3); - if (ret) { - pr_info("couldn't set new watchdog time\n"); - goto out; - } + timeout = timeout * 4096; + ret = ds1374_write_rtc(client, timeout, DS1374_REG_WDALM0, 3); + if (ret) + return ret; /* Enable watchdog timer */ cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_WDALM; + cr &= ~DS1374_REG_CR_WDSTR;/* for RST PIN */ cr &= ~DS1374_REG_CR_AIE; - ret = i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr); + ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr); if (ret < 0) - goto out; + return ret; return 0; -out: - return ret; } - /* * Reload the watchdog timer. (ie, pat the watchdog) */ -static void ds1374_wdt_ping(void) +static int ds1374_wdt_start(struct watchdog_device *wdt) { + struct ds1374 *ds1374 = watchdog_get_drvdata(wdt); u32 val; - int ret = 0; - ret = ds1374_read_rtc(save_client, &val, DS1374_REG_WDALM0, 3); - if (ret) - pr_info("WD TICK FAIL!!!!!!!!!! %i\n", ret); + return ds1374_read_rtc(ds1374->client, &val, DS1374_REG_WDALM0, 3); } -static void ds1374_wdt_disable(void) +static int ds1374_wdt_stop(struct watchdog_device *wdt) { + struct ds1374 *ds1374 = watchdog_get_drvdata(wdt); + struct i2c_client *client = ds1374->client; int cr; - cr = i2c_smbus_read_byte_data(save_client, DS1374_REG_CR); + cr = i2c_smbus_read_byte_data(client, DS1374_REG_CR); + if (cr < 0) + return cr; + /* Disable watchdog timer */ cr &= ~DS1374_REG_CR_WACE; - i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr); -} - -/* - * Watchdog device is opened, and watchdog starts running. - */ -static int ds1374_wdt_open(struct inode *inode, struct file *file) -{ - struct ds1374 *ds1374 = i2c_get_clientdata(save_client); - - if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) { - mutex_lock(&ds1374->mutex); - if (test_and_set_bit(0, &wdt_is_open)) { - mutex_unlock(&ds1374->mutex); - return -EBUSY; - } - /* - * Activate - */ - wdt_is_open = 1; - mutex_unlock(&ds1374->mutex); - return stream_open(inode, file); - } - return -ENODEV; -} - -/* - * Close the watchdog device. - */ -static int ds1374_wdt_release(struct inode *inode, struct file *file) -{ - if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) - clear_bit(0, &wdt_is_open); - - return 0; + return i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr); } -/* - * Pat the watchdog whenever device is written to. - */ -static ssize_t ds1374_wdt_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) -{ - if (len) { - ds1374_wdt_ping(); - return 1; - } - return 0; -} - -static ssize_t ds1374_wdt_read(struct file *file, char __user *data, - size_t len, loff_t *ppos) -{ - return 0; -} - -/* - * Handle commands from user-space. - */ -static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - int new_margin, options; - - switch (cmd) { - case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info __user *)arg, - &ds1374_wdt_info, sizeof(ds1374_wdt_info)) ? -EFAULT : 0; - - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: - return put_user(0, (int __user *)arg); - case WDIOC_KEEPALIVE: - ds1374_wdt_ping(); - return 0; - case WDIOC_SETTIMEOUT: - if (get_user(new_margin, (int __user *)arg)) - return -EFAULT; - - /* the hardware's tick rate is 4096 Hz, so - * the counter value needs to be scaled accordingly - */ - new_margin <<= 12; - if (new_margin < 1 || new_margin > 16777216) - return -EINVAL; - - wdt_margin = new_margin; - ds1374_wdt_settimeout(new_margin); - ds1374_wdt_ping(); - /* fallthrough */ - case WDIOC_GETTIMEOUT: - /* when returning ... inverse is true */ - return put_user((wdt_margin >> 12), (int __user *)arg); - case WDIOC_SETOPTIONS: - if (copy_from_user(&options, (int __user *)arg, sizeof(int))) - return -EFAULT; - - if (options & WDIOS_DISABLECARD) { - pr_info("disable watchdog\n"); - ds1374_wdt_disable(); - return 0; - } - - if (options & WDIOS_ENABLECARD) { - pr_info("enable watchdog\n"); - ds1374_wdt_settimeout(wdt_margin); - ds1374_wdt_ping(); - return 0; - } - return -EINVAL; - } - return -ENOTTY; -} - -static long ds1374_wdt_unlocked_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - int ret; - struct ds1374 *ds1374 = i2c_get_clientdata(save_client); - - mutex_lock(&ds1374->mutex); - ret = ds1374_wdt_ioctl(file, cmd, arg); - mutex_unlock(&ds1374->mutex); - - return ret; -} - -static int ds1374_wdt_notify_sys(struct notifier_block *this, - unsigned long code, void *unused) -{ - if (code == SYS_DOWN || code == SYS_HALT) - /* Disable Watchdog */ - ds1374_wdt_disable(); - return NOTIFY_DONE; -} - -static const struct file_operations ds1374_wdt_fops = { - .owner = THIS_MODULE, - .read = ds1374_wdt_read, - .unlocked_ioctl = ds1374_wdt_unlocked_ioctl, - .compat_ioctl = compat_ptr_ioctl, - .write = ds1374_wdt_write, - .open = ds1374_wdt_open, - .release = ds1374_wdt_release, - .llseek = no_llseek, -}; - -static struct miscdevice ds1374_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &ds1374_wdt_fops, -}; - -static struct notifier_block ds1374_wdt_notifier = { - .notifier_call = ds1374_wdt_notify_sys, +static const struct watchdog_ops ds1374_wdt_ops = { + .owner = THIS_MODULE, + .start = ds1374_wdt_start, + .stop = ds1374_wdt_stop, + .set_timeout = ds1374_wdt_settimeout, }; - #endif /*CONFIG_RTC_DRV_DS1374_WDT*/ /* ***************************************************************************** @@ -652,16 +515,22 @@ static int ds1374_probe(struct i2c_client *client, return ret; #ifdef CONFIG_RTC_DRV_DS1374_WDT - save_client = client; - ret = misc_register(&ds1374_miscdev); + ds1374->wdt.info = &ds1374_wdt_info; + ds1374->wdt.ops = &ds1374_wdt_ops; + ds1374->wdt.timeout = TIMER_MARGIN_DEFAULT; + ds1374->wdt.min_timeout = TIMER_MARGIN_MIN; + ds1374->wdt.max_timeout = TIMER_MARGIN_MAX; + + watchdog_init_timeout(&ds1374->wdt, wdt_margin, &client->dev); + watchdog_set_nowayout(&ds1374->wdt, nowayout); + watchdog_stop_on_reboot(&ds1374->wdt); + watchdog_stop_on_unregister(&ds1374->wdt); + watchdog_set_drvdata(&ds1374->wdt, ds1374); + ds1374_wdt_settimeout(&ds1374->wdt, ds1374->wdt.timeout); + + ret = devm_watchdog_register_device(&client->dev, &ds1374->wdt); if (ret) return ret; - ret = register_reboot_notifier(&ds1374_wdt_notifier); - if (ret) { - misc_deregister(&ds1374_miscdev); - return ret; - } - ds1374_wdt_settimeout(131072); #endif return 0; @@ -670,11 +539,6 @@ static int ds1374_probe(struct i2c_client *client, static int ds1374_remove(struct i2c_client *client) { struct ds1374 *ds1374 = i2c_get_clientdata(client); -#ifdef CONFIG_RTC_DRV_DS1374_WDT - misc_deregister(&ds1374_miscdev); - ds1374_miscdev.parent = NULL; - unregister_reboot_notifier(&ds1374_wdt_notifier); -#endif if (client->irq > 0) { mutex_lock(&ds1374->mutex); -- cgit v1.2.3 From 4df2ef85f0efe44505f511ca5e4455585f53a2da Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 14 Jul 2020 13:45:56 +0100 Subject: rtc: pl031: fix set_alarm by adding back call to alarm_irq_enable Commit c8ff5841a90b ("rtc: pl031: switch to rtc_time64_to_tm/rtc_tm_to_time64") seemed to have accidentally removed the call to pl031_alarm_irq_enable from pl031_set_alarm while switching to 64-bit apis. Let us add back the same to get the set alarm functionality back. Fixes: c8ff5841a90b ("rtc: pl031: switch to rtc_time64_to_tm/rtc_tm_to_time64") Signed-off-by: Sudeep Holla Signed-off-by: Alexandre Belloni Tested-by: Valentin Schneider Cc: Linus Walleij Cc: Alexandre Belloni Link: https://lore.kernel.org/r/20200714124556.20294-1-sudeep.holla@arm.com --- drivers/rtc/rtc-pl031.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 40d7450a1ce4..c6b89273feba 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -275,6 +275,7 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) struct pl031_local *ldata = dev_get_drvdata(dev); writel(rtc_tm_to_time64(&alarm->time), ldata->base + RTC_MR); + pl031_alarm_irq_enable(dev, alarm->enabled); return 0; } -- cgit v1.2.3 From c7f3be4c94d3686ec67b7e7b4fb47e4c225a2789 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 20 Jul 2020 09:52:49 +0200 Subject: rtc: ds1374: fix RTC_DRV_DS1374_WDT dependencies It is not enough to select WATCHDOG_CORE, the watchdog part of the driver now also depends on WATCHDOG. This is currently the best we can do because alarm support and watchdog support are mutually exclusive. Reported-by: Randy Dunlap Signed-off-by: Alexandre Belloni Acked-by: Randy Dunlap # build-tested Link: https://lore.kernel.org/r/20200720075250.1019172-1-alexandre.belloni@bootlin.com --- drivers/rtc/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index c25d51f35f0c..2753e0f54cc3 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -281,8 +281,8 @@ config RTC_DRV_DS1374 config RTC_DRV_DS1374_WDT bool "Dallas/Maxim DS1374 watchdog timer" - depends on RTC_DRV_DS1374 - select WATCHDOG_CORE if WATCHDOG + depends on RTC_DRV_DS1374 && WATCHDOG + select WATCHDOG_CORE help If you say Y here you will get support for the watchdog timer in the Dallas Semiconductor DS1374 -- cgit v1.2.3 From 3d6cfb36ed719e5efdc2a6a8e8ee07f185c88da1 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 20 Jul 2020 09:52:50 +0200 Subject: rtc: ds1374: remove unused define Remove unused define and fix typo where it should have been used. Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20200720075250.1019172-2-alexandre.belloni@bootlin.com --- drivers/rtc/rtc-ds1374.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index c71065d26cd2..177d870bda0d 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -377,8 +377,6 @@ static const struct rtc_class_ops ds1374_rtc_ops = { #define TIMER_MARGIN_MIN 1 #define TIMER_MARGIN_MAX 4095 /* 24-bit value */ -#define DRV_NAME "DS1374 Watchdog" - static int wdt_margin; module_param(wdt_margin, int, 0); MODULE_PARM_DESC(wdt_margin, "Watchdog timeout in seconds (default 32s)"); @@ -389,7 +387,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default =" __MODULE_STRING(WATCHDOG_NOWAYOUT)")"); static const struct watchdog_info ds1374_wdt_info = { - .identity = "DS1374 WTD", + .identity = "DS1374 Watchdog", .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, }; -- cgit v1.2.3 From 9bf1306257589b3a5ad46175538af9922d94e26f Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Mon, 27 Jul 2020 15:46:14 +1200 Subject: rtc: ds1307: provide an indication that the watchdog has fired There's not much feedback when the ds1388 watchdog fires. Generally it yanks on the reset line and the board reboots. Capture the fact that the watchdog has fired in the past so that userspace can retrieve it via WDIOC_GETBOOTSTATUS. This should help distinguish a watchdog triggered reset from a power interruption. Signed-off-by: Chris Packham Signed-off-by: Alexandre Belloni Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20200727034615.19755-1-chris.packham@alliedtelesis.co.nz --- drivers/rtc/rtc-ds1307.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 49702942bb08..54c85cdd019d 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1668,6 +1668,8 @@ static const struct watchdog_ops ds1388_wdt_ops = { static void ds1307_wdt_register(struct ds1307 *ds1307) { struct watchdog_device *wdt; + int err; + int val; if (ds1307->type != ds_1388) return; @@ -1676,6 +1678,10 @@ static void ds1307_wdt_register(struct ds1307 *ds1307) if (!wdt) return; + err = regmap_read(ds1307->regmap, DS1388_REG_FLAG, &val); + if (!err && val & DS1388_BIT_WF) + wdt->bootstatus = WDIOF_CARDRESET; + wdt->info = &ds1388_wdt_info; wdt->ops = &ds1388_wdt_ops; wdt->timeout = 99; -- cgit v1.2.3 From 16c24801122e2961c588562f04707b98f9c84bbb Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 6 Aug 2020 13:54:31 +0100 Subject: rtc: max77686: Fix wake-ups for max77620 Following commit d8f090dbeafd ("rtc: max77686: Do not allow interrupt to fire before system resume"), RTC wake-ups stopped working on Jetson TX2 and Jetson Xavier platforms. The Jetson TX2 uses the max77620 PMIC and the Jetson Xavier uses max20024 PMIC. Both of these PMICs have the same max77620 RTC controller. For the max77620 RTC, the variable 'rtc_irq_from_platform' is defined as true in the max77686 driver and because of this the IRQ passed to the max77686 driver for RTC is the PMIC IRQ and not the parent. Hence, following commit d8f090dbeafd ("rtc: max77686: Do not allow interrupt to fire before system resume"), for the max77620 the RTC IRQ within the PMIC is now getting disabled on entry to suspend and unable to wake the system up. Fix this by only disabling interrupts on entry to suspend in the max77686 RTC driver, if the interrupt is the parent interrupt. Fixes: d8f090dbeafd ("rtc: max77686: Do not allow interrupt to fire before system resume") Signed-off-by: Jon Hunter Signed-off-by: Alexandre Belloni Tested-by: Thierry Reding Reviewed-by: Thierry Reding Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20200806125431.699339-1-jonathanh@nvidia.com --- drivers/rtc/rtc-max77686.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 645de5af707b..d51cc12114cb 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -815,13 +815,15 @@ static int max77686_rtc_suspend(struct device *dev) } /* - * Main IRQ (not virtual) must be disabled during suspend because if it - * happens while suspended it will be handled before resuming I2C. + * If the main IRQ (not virtual) is the parent IRQ, then it must be + * disabled during suspend because if it happens while suspended it + * will be handled before resuming I2C. * * Since Main IRQ is shared, all its users should disable it to be sure * it won't fire while one of them is still suspended. */ - disable_irq(info->rtc_irq); + if (!info->drv_data->rtc_irq_from_platform) + disable_irq(info->rtc_irq); return ret; } @@ -830,7 +832,8 @@ static int max77686_rtc_resume(struct device *dev) { struct max77686_rtc_info *info = dev_get_drvdata(dev); - enable_irq(info->rtc_irq); + if (!info->drv_data->rtc_irq_from_platform) + enable_irq(info->rtc_irq); if (device_may_wakeup(dev)) { struct max77686_rtc_info *info = dev_get_drvdata(dev); -- cgit v1.2.3 From 985b30dbe2cf58c27dd81da85410439ced8ce6d7 Mon Sep 17 00:00:00 2001 From: Liam Beguin Date: Mon, 29 Jun 2020 22:42:10 -0400 Subject: rtc: pcf2127: add pca2129 device id The PCA2129 is the automotive grade version of the PCF2129. add it to the list of compatibles. Signed-off-by: Liam Beguin Signed-off-by: Alexandre Belloni Reviewed-by: Bruno Thomsen Link: https://lore.kernel.org/r/20200630024211.12782-2-liambeguin@gmail.com --- Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 2 ++ drivers/rtc/rtc-pcf2127.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index 18cb456752f6..c7d14de214c4 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -52,6 +52,8 @@ properties: - nxp,pcf2127 # Real-time clock - nxp,pcf2129 + # Real-time clock + - nxp,pca2129 # Real-time Clock Module - pericom,pt7c4338 # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 9c5670776c68..4accee09bfad 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -553,6 +553,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, static const struct of_device_id pcf2127_of_match[] = { { .compatible = "nxp,pcf2127" }, { .compatible = "nxp,pcf2129" }, + { .compatible = "nxp,pca2129" }, {} }; MODULE_DEVICE_TABLE(of, pcf2127_of_match); @@ -664,6 +665,7 @@ static int pcf2127_i2c_probe(struct i2c_client *client, static const struct i2c_device_id pcf2127_i2c_id[] = { { "pcf2127", 1 }, { "pcf2129", 0 }, + { "pca2129", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id); @@ -729,6 +731,7 @@ static int pcf2127_spi_probe(struct spi_device *spi) static const struct spi_device_id pcf2127_spi_id[] = { { "pcf2127", 1 }, { "pcf2129", 0 }, + { "pca2129", 0 }, { } }; MODULE_DEVICE_TABLE(spi, pcf2127_spi_id); -- cgit v1.2.3 From 8a914bac44be33623cfcf27688b18b6f81a5c7d5 Mon Sep 17 00:00:00 2001 From: Liam Beguin Date: Mon, 29 Jun 2020 22:42:11 -0400 Subject: rtc: pcf2127: add alarm support Add alarm support for the pcf2127 RTC chip family. Tested on pca2129. Signed-off-by: Liam Beguin Signed-off-by: Alexandre Belloni Reviewed-by: Bruno Thomsen Link: https://lore.kernel.org/r/20200630024211.12782-3-liambeguin@gmail.com --- drivers/rtc/rtc-pcf2127.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 4accee09bfad..4e99c45a87d7 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -28,7 +29,9 @@ #define PCF2127_BIT_CTRL1_TSF1 BIT(4) /* Control register 2 */ #define PCF2127_REG_CTRL2 0x01 +#define PCF2127_BIT_CTRL2_AIE BIT(1) #define PCF2127_BIT_CTRL2_TSIE BIT(2) +#define PCF2127_BIT_CTRL2_AF BIT(4) #define PCF2127_BIT_CTRL2_TSF2 BIT(5) /* Control register 3 */ #define PCF2127_REG_CTRL3 0x02 @@ -46,6 +49,12 @@ #define PCF2127_REG_DW 0x07 #define PCF2127_REG_MO 0x08 #define PCF2127_REG_YR 0x09 +/* Alarm registers */ +#define PCF2127_REG_ALARM_SC 0x0A +#define PCF2127_REG_ALARM_MN 0x0B +#define PCF2127_REG_ALARM_HR 0x0C +#define PCF2127_REG_ALARM_DM 0x0D +#define PCF2127_REG_ALARM_DW 0x0E /* Watchdog registers */ #define PCF2127_REG_WD_CTL 0x10 #define PCF2127_BIT_WD_CTL_TF0 BIT(0) @@ -324,6 +333,114 @@ static const struct watchdog_ops pcf2127_watchdog_ops = { .set_timeout = pcf2127_wdt_set_timeout, }; +/* Alarm */ +static int pcf2127_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pcf2127 *pcf2127 = dev_get_drvdata(dev); + unsigned int buf[5], ctrl2; + int ret; + + ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL2, &ctrl2); + if (ret) + return ret; + + ret = pcf2127_wdt_active_ping(&pcf2127->wdd); + if (ret) + return ret; + + ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_ALARM_SC, buf, + sizeof(buf)); + if (ret) + return ret; + + alrm->enabled = ctrl2 & PCF2127_BIT_CTRL2_AIE; + alrm->pending = ctrl2 & PCF2127_BIT_CTRL2_AF; + + alrm->time.tm_sec = bcd2bin(buf[0] & 0x7F); + alrm->time.tm_min = bcd2bin(buf[1] & 0x7F); + alrm->time.tm_hour = bcd2bin(buf[2] & 0x3F); + alrm->time.tm_mday = bcd2bin(buf[3] & 0x3F); + alrm->time.tm_wday = buf[4] & 0x07; + + return 0; +} + +static int pcf2127_rtc_alarm_irq_enable(struct device *dev, u32 enable) +{ + struct pcf2127 *pcf2127 = dev_get_drvdata(dev); + int ret; + + ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2, + PCF2127_BIT_CTRL2_AIE, + enable ? PCF2127_BIT_CTRL2_AIE : 0); + if (ret) + return ret; + + return pcf2127_wdt_active_ping(&pcf2127->wdd); +} + +static int pcf2127_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pcf2127 *pcf2127 = dev_get_drvdata(dev); + uint8_t buf[5]; + int ret; + + ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2, + PCF2127_BIT_CTRL2_AF, 0); + if (ret) + return ret; + + ret = pcf2127_wdt_active_ping(&pcf2127->wdd); + if (ret) + return ret; + + buf[0] = bin2bcd(alrm->time.tm_sec); + buf[1] = bin2bcd(alrm->time.tm_min); + buf[2] = bin2bcd(alrm->time.tm_hour); + buf[3] = bin2bcd(alrm->time.tm_mday); + buf[4] = (alrm->time.tm_wday & 0x07); + + ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_ALARM_SC, buf, + sizeof(buf)); + if (ret) + return ret; + + return pcf2127_rtc_alarm_irq_enable(dev, alrm->enabled); +} + +static irqreturn_t pcf2127_rtc_irq(int irq, void *dev) +{ + struct pcf2127 *pcf2127 = dev_get_drvdata(dev); + unsigned int ctrl2 = 0; + int ret = 0; + + ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL2, &ctrl2); + if (ret) + return IRQ_NONE; + + if (ctrl2 & PCF2127_BIT_CTRL2_AF) { + regmap_write(pcf2127->regmap, PCF2127_REG_CTRL2, + ctrl2 & ~PCF2127_BIT_CTRL2_AF); + + rtc_update_irq(pcf2127->rtc, 1, RTC_IRQF | RTC_AF); + } + + ret = pcf2127_wdt_active_ping(&pcf2127->wdd); + if (ret) + return IRQ_NONE; + + return IRQ_HANDLED; +} + +static const struct rtc_class_ops pcf2127_rtc_alrm_ops = { + .ioctl = pcf2127_rtc_ioctl, + .read_time = pcf2127_rtc_read_time, + .set_time = pcf2127_rtc_set_time, + .read_alarm = pcf2127_rtc_read_alarm, + .set_alarm = pcf2127_rtc_set_alarm, + .alarm_irq_enable = pcf2127_rtc_alarm_irq_enable, +}; + /* sysfs interface */ static ssize_t timestamp0_store(struct device *dev, @@ -419,6 +536,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, const char *name, bool has_nvmem) { struct pcf2127 *pcf2127; + int alarm_irq = 0; u32 wdd_timeout; int ret = 0; @@ -441,6 +559,22 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, pcf2127->rtc->range_max = RTC_TIMESTAMP_END_2099; pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */ + alarm_irq = of_irq_get_byname(dev->of_node, "alarm"); + if (alarm_irq >= 0) { + ret = devm_request_irq(dev, alarm_irq, pcf2127_rtc_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + dev_name(dev), dev); + if (ret) { + dev_err(dev, "failed to request alarm irq\n"); + return ret; + } + } + + if (alarm_irq >= 0 || device_property_read_bool(dev, "wakeup-source")) { + device_init_wakeup(dev, true); + pcf2127->rtc->ops = &pcf2127_rtc_alrm_ops; + } + pcf2127->wdd.parent = dev; pcf2127->wdd.info = &pcf2127_wdt_info; pcf2127->wdd.ops = &pcf2127_watchdog_ops; -- cgit v1.2.3 From 27006416be16b7887fb94b3b445f32453defb3f1 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 12 Aug 2020 10:51:14 +0200 Subject: rtc: pcf2127: fix alarm handling Fix multiple issues when handling alarms: - Use threaded interrupt to avoid scheduling when atomic - Stop matching on week day as it may not be set correctly - Avoid parsing the DT interrupt and use what is provided by the i2c or spi subsystem - Avoid returning IRQ_NONE in case of error in the interrupt handler - Never write WDTF as specified in the datasheet - Set uie_unsupported, as for the pcf85063, setting alarms every seconds is not working correctly and confuses the RTC. Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20200812085114.474903-1-alexandre.belloni@bootlin.com --- drivers/rtc/rtc-pcf2127.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 4e99c45a87d7..ed6316992cbb 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -33,6 +33,7 @@ #define PCF2127_BIT_CTRL2_TSIE BIT(2) #define PCF2127_BIT_CTRL2_AF BIT(4) #define PCF2127_BIT_CTRL2_TSF2 BIT(5) +#define PCF2127_BIT_CTRL2_WDTF BIT(6) /* Control register 3 */ #define PCF2127_REG_CTRL3 0x02 #define PCF2127_BIT_CTRL3_BLIE BIT(0) @@ -55,6 +56,7 @@ #define PCF2127_REG_ALARM_HR 0x0C #define PCF2127_REG_ALARM_DM 0x0D #define PCF2127_REG_ALARM_DW 0x0E +#define PCF2127_BIT_ALARM_AE BIT(7) /* Watchdog registers */ #define PCF2127_REG_WD_CTL 0x10 #define PCF2127_BIT_WD_CTL_TF0 BIT(0) @@ -360,7 +362,6 @@ static int pcf2127_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) alrm->time.tm_min = bcd2bin(buf[1] & 0x7F); alrm->time.tm_hour = bcd2bin(buf[2] & 0x3F); alrm->time.tm_mday = bcd2bin(buf[3] & 0x3F); - alrm->time.tm_wday = buf[4] & 0x07; return 0; } @@ -398,7 +399,7 @@ static int pcf2127_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) buf[1] = bin2bcd(alrm->time.tm_min); buf[2] = bin2bcd(alrm->time.tm_hour); buf[3] = bin2bcd(alrm->time.tm_mday); - buf[4] = (alrm->time.tm_wday & 0x07); + buf[4] = PCF2127_BIT_ALARM_AE; /* Do not match on week day */ ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_ALARM_SC, buf, sizeof(buf)); @@ -418,16 +419,15 @@ static irqreturn_t pcf2127_rtc_irq(int irq, void *dev) if (ret) return IRQ_NONE; - if (ctrl2 & PCF2127_BIT_CTRL2_AF) { - regmap_write(pcf2127->regmap, PCF2127_REG_CTRL2, - ctrl2 & ~PCF2127_BIT_CTRL2_AF); + if (!(ctrl2 & PCF2127_BIT_CTRL2_AF)) + return IRQ_NONE; - rtc_update_irq(pcf2127->rtc, 1, RTC_IRQF | RTC_AF); - } + regmap_write(pcf2127->regmap, PCF2127_REG_CTRL2, + ctrl2 & ~(PCF2127_BIT_CTRL2_AF | PCF2127_BIT_CTRL2_WDTF)); - ret = pcf2127_wdt_active_ping(&pcf2127->wdd); - if (ret) - return IRQ_NONE; + rtc_update_irq(pcf2127->rtc, 1, RTC_IRQF | RTC_AF); + + pcf2127_wdt_active_ping(&pcf2127->wdd); return IRQ_HANDLED; } @@ -533,10 +533,9 @@ static const struct attribute_group pcf2127_attr_group = { }; static int pcf2127_probe(struct device *dev, struct regmap *regmap, - const char *name, bool has_nvmem) + int alarm_irq, const char *name, bool has_nvmem) { struct pcf2127 *pcf2127; - int alarm_irq = 0; u32 wdd_timeout; int ret = 0; @@ -558,12 +557,13 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, pcf2127->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; pcf2127->rtc->range_max = RTC_TIMESTAMP_END_2099; pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */ + pcf2127->rtc->uie_unsupported = 1; - alarm_irq = of_irq_get_byname(dev->of_node, "alarm"); if (alarm_irq >= 0) { - ret = devm_request_irq(dev, alarm_irq, pcf2127_rtc_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - dev_name(dev), dev); + ret = devm_request_threaded_irq(dev, alarm_irq, NULL, + pcf2127_rtc_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + dev_name(dev), dev); if (ret) { dev_err(dev, "failed to request alarm irq\n"); return ret; @@ -792,7 +792,7 @@ static int pcf2127_i2c_probe(struct i2c_client *client, return PTR_ERR(regmap); } - return pcf2127_probe(&client->dev, regmap, + return pcf2127_probe(&client->dev, regmap, client->irq, pcf2127_i2c_driver.driver.name, id->driver_data); } @@ -858,7 +858,8 @@ static int pcf2127_spi_probe(struct spi_device *spi) return PTR_ERR(regmap); } - return pcf2127_probe(&spi->dev, regmap, pcf2127_spi_driver.driver.name, + return pcf2127_probe(&spi->dev, regmap, spi->irq, + pcf2127_spi_driver.driver.name, spi_get_device_id(spi)->driver_data); } -- cgit v1.2.3