From 37563e5ec4eafa48ee477ec496b60a1830be1b9f Mon Sep 17 00:00:00 2001 From: dann frazier Date: Fri, 24 Apr 2015 11:54:20 -0600 Subject: rtc: efi: Update author email address I'm no longer employed by HP. Signed-off-by: dann frazier Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index cb989cd..c5fbabb 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c @@ -3,7 +3,7 @@ * * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. * - * Author: dann frazier + * Author: dann frazier * Based on efirtc.c by Stephane Eranian * * This program is free software; you can redistribute it and/or modify it @@ -233,7 +233,7 @@ static struct platform_driver efi_rtc_driver = { module_platform_driver_probe(efi_rtc_driver, efi_rtc_probe); MODULE_ALIAS("platform:rtc-efi"); -MODULE_AUTHOR("dann frazier "); +MODULE_AUTHOR("dann frazier "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("EFI RTC driver"); MODULE_ALIAS("platform:rtc-efi"); -- cgit v0.10.2 From 9a72f4104bc821fd07798ec42141c8066874b9f9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 2 May 2015 00:44:35 +0900 Subject: rtc: ab8500: Constify platform_device_id The platform_device_id is not modified by the driver and core uses it as const. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 6856f0a..133d2e2 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -442,7 +442,7 @@ static const struct rtc_class_ops ab8540_rtc_ops = { .alarm_irq_enable = ab8500_rtc_irq_enable, }; -static struct platform_device_id ab85xx_rtc_ids[] = { +static const struct platform_device_id ab85xx_rtc_ids[] = { { "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, }, { "ab8540-rtc", (kernel_ulong_t)&ab8540_rtc_ops, }, }; -- cgit v0.10.2 From 19fd685fcb13fa3c0b1539c2f31e1add8ab63edf Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 2 May 2015 00:44:36 +0900 Subject: rtc: hid-sensor-time: Constify platform_device_id The platform_device_id is not modified by the driver and core uses it as const. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c index af4f85a..c398f74 100644 --- a/drivers/rtc/rtc-hid-sensor-time.c +++ b/drivers/rtc/rtc-hid-sensor-time.c @@ -318,7 +318,7 @@ static int hid_time_remove(struct platform_device *pdev) return 0; } -static struct platform_device_id hid_time_ids[] = { +static const struct platform_device_id hid_time_ids[] = { { /* Format: HID-SENSOR-usage_id_in_hex_lowercase */ .name = "HID-SENSOR-2000a0", -- cgit v0.10.2 From cd6ba00aaa8bb5335cf2aa4b98c0ac15ffc9000d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 2 May 2015 00:44:37 +0900 Subject: rtc: mxc: Constify platform_device_id The platform_device_id is not modified by the driver and core uses it as const. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 09d422b..5fc292c 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -84,7 +84,7 @@ struct rtc_plat_data { enum imx_rtc_type devtype; }; -static struct platform_device_id imx_rtc_devtype[] = { +static const struct platform_device_id imx_rtc_devtype[] = { { .name = "imx1-rtc", .driver_data = IMX1_RTC, -- cgit v0.10.2 From 1796dcce2daacc125f2d60afc3f631ca29e36684 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 3 May 2015 18:57:10 +0900 Subject: rtc: interface: Fix coding style violations Fix issues reported by checkpatch: ERROR: open brace '{' following struct go on the same line ERROR: "foo* bar" should be "foo *bar" Additionally adjust alignment of wrapped function arguments. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 8dcf682..b0709f8 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -101,8 +101,7 @@ struct rtc_timer { /* flags */ #define RTC_DEV_BUSY 0 -struct rtc_device -{ +struct rtc_device { struct device dev; struct module *owner; @@ -198,10 +197,10 @@ int rtc_register(rtc_task_t *task); int rtc_unregister(rtc_task_t *task); int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); -void rtc_timer_init(struct rtc_timer *timer, void (*f)(void* p), void* data); -int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer, - ktime_t expires, ktime_t period); -int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer); +void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data); +int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer, + ktime_t expires, ktime_t period); +int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer); void rtc_timer_do_work(struct work_struct *work); static inline bool is_leap_year(unsigned int year) -- cgit v0.10.2 From 73744a64aab872703b851b9678a7f488b507eb81 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 3 May 2015 18:57:11 +0900 Subject: rtc: interface: Remove unused return value from rtc_timer_cancel() The rtc_timer_cancel() always returns 0 and cannot fail (calls only other void-returning functions). Signed-off-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 166fc60..a6b14c2 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -976,14 +976,12 @@ int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer, * * Kernel interface to cancel an rtc_timer */ -int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer) +void rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer) { - int ret = 0; mutex_lock(&rtc->ops_lock); if (timer->enabled) rtc_timer_remove(rtc, timer); mutex_unlock(&rtc->ops_lock); - return ret; } diff --git a/include/linux/rtc.h b/include/linux/rtc.h index b0709f8..587017e 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -200,7 +200,7 @@ int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data); int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer, ktime_t expires, ktime_t period); -int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer); +void rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer); void rtc_timer_do_work(struct work_struct *work); static inline bool is_leap_year(unsigned int year) -- cgit v0.10.2 From a42e6eae457837d6a5925f4926f5ba05ccf44f89 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 2 May 2015 14:31:49 +0900 Subject: rtc: s3c: Integrate Exynos3250 into S3C6410 There are now no differences between RTC on Exynos3250 and S3C6410. Merge everything into one so duplicated code could be removed. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanwoo Choi Acked-by: Alexandre Belloni Reviewed-by: Javier Martinez Canillas Signed-off-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 76cbad7..a0f8323 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -772,18 +772,6 @@ static struct s3c_rtc_data const s3c6410_rtc_data = { .disable = s3c6410_rtc_disable, }; -static struct s3c_rtc_data const exynos3250_rtc_data = { - .max_user_freq = 32768, - .needs_src_clk = true, - .irq_handler = s3c6410_rtc_irq, - .set_freq = s3c6410_rtc_setfreq, - .enable_tick = s3c6410_rtc_enable_tick, - .save_tick_cnt = s3c6410_rtc_save_tick_cnt, - .restore_tick_cnt = s3c6410_rtc_restore_tick_cnt, - .enable = s3c24xx_rtc_enable, - .disable = s3c6410_rtc_disable, -}; - static const struct of_device_id s3c_rtc_dt_match[] = { { .compatible = "samsung,s3c2410-rtc", @@ -799,7 +787,7 @@ static const struct of_device_id s3c_rtc_dt_match[] = { .data = (void *)&s3c6410_rtc_data, }, { .compatible = "samsung,exynos3250-rtc", - .data = (void *)&exynos3250_rtc_data, + .data = (void *)&s3c6410_rtc_data, }, { /* sentinel */ }, }; -- cgit v0.10.2 From e30d31317bb01832379d86826cba1e3dcff78987 Mon Sep 17 00:00:00 2001 From: Juergen Borleis Date: Mon, 27 Apr 2015 15:59:47 +0200 Subject: rtc: imxdi: avoid the __raw* register access functions Be independent of the endianness of the kernel. Signed-off-by: Juergen Borleis Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index c666eab..056ef6c 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -137,8 +137,8 @@ static void di_int_enable(struct imxdi_dev *imxdi, u32 intr) unsigned long flags; spin_lock_irqsave(&imxdi->irq_lock, flags); - __raw_writel(__raw_readl(imxdi->ioaddr + DIER) | intr, - imxdi->ioaddr + DIER); + writel(readl(imxdi->ioaddr + DIER) | intr, + imxdi->ioaddr + DIER); spin_unlock_irqrestore(&imxdi->irq_lock, flags); } @@ -150,8 +150,8 @@ static void di_int_disable(struct imxdi_dev *imxdi, u32 intr) unsigned long flags; spin_lock_irqsave(&imxdi->irq_lock, flags); - __raw_writel(__raw_readl(imxdi->ioaddr + DIER) & ~intr, - imxdi->ioaddr + DIER); + writel(readl(imxdi->ioaddr + DIER) & ~intr, + imxdi->ioaddr + DIER); spin_unlock_irqrestore(&imxdi->irq_lock, flags); } @@ -169,11 +169,11 @@ static void clear_write_error(struct imxdi_dev *imxdi) dev_warn(&imxdi->pdev->dev, "WARNING: Register write error!\n"); /* clear the write error flag */ - __raw_writel(DSR_WEF, imxdi->ioaddr + DSR); + writel(DSR_WEF, imxdi->ioaddr + DSR); /* wait for it to take effect */ for (cnt = 0; cnt < 1000; cnt++) { - if ((__raw_readl(imxdi->ioaddr + DSR) & DSR_WEF) == 0) + if ((readl(imxdi->ioaddr + DSR) & DSR_WEF) == 0) return; udelay(10); } @@ -201,7 +201,7 @@ static int di_write_wait(struct imxdi_dev *imxdi, u32 val, int reg) imxdi->dsr = 0; /* do the register write */ - __raw_writel(val, imxdi->ioaddr + reg); + writel(val, imxdi->ioaddr + reg); /* wait for the write to finish */ ret = wait_event_interruptible_timeout(imxdi->write_wait, @@ -235,7 +235,7 @@ static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm) struct imxdi_dev *imxdi = dev_get_drvdata(dev); unsigned long now; - now = __raw_readl(imxdi->ioaddr + DTCMR); + now = readl(imxdi->ioaddr + DTCMR); rtc_time_to_tm(now, tm); return 0; @@ -280,17 +280,17 @@ static int dryice_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) struct imxdi_dev *imxdi = dev_get_drvdata(dev); u32 dcamr; - dcamr = __raw_readl(imxdi->ioaddr + DCAMR); + dcamr = readl(imxdi->ioaddr + DCAMR); rtc_time_to_tm(dcamr, &alarm->time); /* alarm is enabled if the interrupt is enabled */ - alarm->enabled = (__raw_readl(imxdi->ioaddr + DIER) & DIER_CAIE) != 0; + alarm->enabled = (readl(imxdi->ioaddr + DIER) & DIER_CAIE) != 0; /* don't allow the DSR read to mess up DSR_WCF */ mutex_lock(&imxdi->write_mutex); /* alarm is pending if the alarm flag is set */ - alarm->pending = (__raw_readl(imxdi->ioaddr + DSR) & DSR_CAF) != 0; + alarm->pending = (readl(imxdi->ioaddr + DSR) & DSR_CAF) != 0; mutex_unlock(&imxdi->write_mutex); @@ -312,7 +312,7 @@ static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) return rc; /* don't allow setting alarm in the past */ - now = __raw_readl(imxdi->ioaddr + DTCMR); + now = readl(imxdi->ioaddr + DTCMR); if (alarm_time < now) return -EINVAL; @@ -346,7 +346,7 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id) u32 dsr, dier; irqreturn_t rc = IRQ_NONE; - dier = __raw_readl(imxdi->ioaddr + DIER); + dier = readl(imxdi->ioaddr + DIER); /* handle write complete and write error cases */ if (dier & DIER_WCIE) { @@ -357,7 +357,7 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id) return rc; /* DSR_WCF clears itself on DSR read */ - dsr = __raw_readl(imxdi->ioaddr + DSR); + dsr = readl(imxdi->ioaddr + DSR); if (dsr & (DSR_WCF | DSR_WEF)) { /* mask the interrupt */ di_int_disable(imxdi, DIER_WCIE); @@ -373,7 +373,7 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id) /* handle the alarm case */ if (dier & DIER_CAIE) { /* DSR_WCF clears itself on DSR read */ - dsr = __raw_readl(imxdi->ioaddr + DSR); + dsr = readl(imxdi->ioaddr + DSR); if (dsr & DSR_CAF) { /* mask the interrupt */ di_int_disable(imxdi, DIER_CAIE); @@ -446,7 +446,7 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) */ /* mask all interrupts */ - __raw_writel(0, imxdi->ioaddr + DIER); + writel(0, imxdi->ioaddr + DIER); rc = devm_request_irq(&pdev->dev, imxdi->irq, dryice_norm_irq, IRQF_SHARED, pdev->name, imxdi); @@ -456,7 +456,7 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) } /* put dryice into valid state */ - if (__raw_readl(imxdi->ioaddr + DSR) & DSR_NVF) { + if (readl(imxdi->ioaddr + DSR) & DSR_NVF) { rc = di_write_wait(imxdi, DSR_NVF | DSR_SVF, DSR); if (rc) goto err; @@ -471,23 +471,23 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) goto err; /* clear alarm flag */ - if (__raw_readl(imxdi->ioaddr + DSR) & DSR_CAF) { + if (readl(imxdi->ioaddr + DSR) & DSR_CAF) { rc = di_write_wait(imxdi, DSR_CAF, DSR); if (rc) goto err; } /* the timer won't count if it has never been written to */ - if (__raw_readl(imxdi->ioaddr + DTCMR) == 0) { + if (readl(imxdi->ioaddr + DTCMR) == 0) { rc = di_write_wait(imxdi, 0, DTCMR); if (rc) goto err; } /* start keeping time */ - if (!(__raw_readl(imxdi->ioaddr + DCR) & DCR_TCE)) { + if (!(readl(imxdi->ioaddr + DCR) & DCR_TCE)) { rc = di_write_wait(imxdi, - __raw_readl(imxdi->ioaddr + DCR) | DCR_TCE, + readl(imxdi->ioaddr + DCR) | DCR_TCE, DCR); if (rc) goto err; @@ -516,7 +516,7 @@ static int __exit dryice_rtc_remove(struct platform_device *pdev) flush_work(&imxdi->work); /* mask all interrupts */ - __raw_writel(0, imxdi->ioaddr + DIER); + writel(0, imxdi->ioaddr + DIER); clk_disable_unprepare(imxdi->clk); -- cgit v0.10.2 From 3ba3fab765beecd599d8e8e00dc2ed4306518dfd Mon Sep 17 00:00:00 2001 From: Juergen Borleis Date: Mon, 27 Apr 2015 15:59:48 +0200 Subject: rtc: imxdi: add some background info about the states the machine can be in Document the i.MX DryIce machine states. Signed-off-by: Juergen Borleis Signed-off-by: Robert Schwebel [rsc: got NDA clearance from Freescale] Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 056ef6c..63ca52b 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -129,6 +129,49 @@ struct imxdi_dev { struct work_struct work; }; +/* Some background: + * + * The DryIce unit is a complex security/tamper monitor device. To be able do + * its job in a useful manner it runs a bigger statemachine to bring it into + * security/tamper failure state and once again to bring it out of this state. + * + * This unit can be in one of three states: + * + * - "NON-VALID STATE" + * always after the battery power was removed + * - "FAILURE STATE" + * if one of the enabled security events has happened + * - "VALID STATE" + * if the unit works as expected + * + * Everything stops when the unit enters the failure state including the RTC + * counter (to be able to detect the time the security event happened). + * + * The following events (when enabled) let the DryIce unit enter the failure + * state: + * + * - wire-mesh-tamper detect + * - external tamper B detect + * - external tamper A detect + * - temperature tamper detect + * - clock tamper detect + * - voltage tamper detect + * - RTC counter overflow + * - monotonic counter overflow + * - external boot + * + * If we find the DryIce unit in "FAILURE STATE" and the TDCHL cleared, we + * can only detect this state. In this case the unit is completely locked and + * must force a second "SYSTEM POR" to bring the DryIce into the + * "NON-VALID STATE" + "FAILURE STATE" where a recovery is possible. + * If the TDCHL is set in the "FAILURE STATE" we are out of luck. In this case + * a battery power cycle is required. + * + * In the "NON-VALID STATE" + "FAILURE STATE" we can clear the "FAILURE STATE" + * and recover the DryIce unit. By clearing the "NON-VALID STATE" as the last + * task, we bring back this unit into life. + */ + /* * enable a dryice interrupt */ -- cgit v0.10.2 From c7e9bbe022c7bee57d9e14b42a7c3732da8db558 Mon Sep 17 00:00:00 2001 From: Juergen Borleis Date: Mon, 27 Apr 2015 15:59:49 +0200 Subject: rtc: imxdi: add the unit recovery code This code is required to recover the unit from a security violation. Hopefully this code can recover the unit from a hardware related invalid state as well. Signed-off-by: Juergen Borleis Signed-off-by: Robert Schwebel [rsc: got NDA clearance from Freescale] Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 63ca52b..3d7f039 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -173,6 +173,281 @@ struct imxdi_dev { */ /* + * Do a write into the unit without interrupt support. + * We do not need to check the WEF here, because the only reason this kind of + * write error can happen is if we write to the unit twice within the 122 us + * interval. This cannot happen, since we are using this function only while + * setting up the unit. + */ +static void di_write_busy_wait(const struct imxdi_dev *imxdi, u32 val, + unsigned reg) +{ + /* do the register write */ + writel(val, imxdi->ioaddr + reg); + + /* + * now it takes four 32,768 kHz clock cycles to take + * the change into effect = 122 us + */ + usleep_range(130, 200); +} + +static void di_report_tamper_info(struct imxdi_dev *imxdi, u32 dsr) +{ + u32 dtcr; + + dtcr = readl(imxdi->ioaddr + DTCR); + + dev_emerg(&imxdi->pdev->dev, "DryIce tamper event detected\n"); + /* the following flags force a transition into the "FAILURE STATE" */ + if (dsr & DSR_VTD) + dev_emerg(&imxdi->pdev->dev, "%sVoltage Tamper Event\n", + dtcr & DTCR_VTE ? "" : "Spurious "); + + if (dsr & DSR_CTD) + dev_emerg(&imxdi->pdev->dev, "%s32768 Hz Clock Tamper Event\n", + dtcr & DTCR_CTE ? "" : "Spurious "); + + if (dsr & DSR_TTD) + dev_emerg(&imxdi->pdev->dev, "%sTemperature Tamper Event\n", + dtcr & DTCR_TTE ? "" : "Spurious "); + + if (dsr & DSR_SAD) + dev_emerg(&imxdi->pdev->dev, + "%sSecure Controller Alarm Event\n", + dtcr & DTCR_SAIE ? "" : "Spurious "); + + if (dsr & DSR_EBD) + dev_emerg(&imxdi->pdev->dev, "%sExternal Boot Tamper Event\n", + dtcr & DTCR_EBE ? "" : "Spurious "); + + if (dsr & DSR_ETAD) + dev_emerg(&imxdi->pdev->dev, "%sExternal Tamper A Event\n", + dtcr & DTCR_ETAE ? "" : "Spurious "); + + if (dsr & DSR_ETBD) + dev_emerg(&imxdi->pdev->dev, "%sExternal Tamper B Event\n", + dtcr & DTCR_ETBE ? "" : "Spurious "); + + if (dsr & DSR_WTD) + dev_emerg(&imxdi->pdev->dev, "%sWire-mesh Tamper Event\n", + dtcr & DTCR_WTE ? "" : "Spurious "); + + if (dsr & DSR_MCO) + dev_emerg(&imxdi->pdev->dev, + "%sMonotonic-counter Overflow Event\n", + dtcr & DTCR_MOE ? "" : "Spurious "); + + if (dsr & DSR_TCO) + dev_emerg(&imxdi->pdev->dev, "%sTimer-counter Overflow Event\n", + dtcr & DTCR_TOE ? "" : "Spurious "); +} + +static void di_what_is_to_be_done(struct imxdi_dev *imxdi, + const char *power_supply) +{ + dev_emerg(&imxdi->pdev->dev, "Please cycle the %s power supply in order to get the DryIce/RTC unit working again\n", + power_supply); +} + +static int di_handle_failure_state(struct imxdi_dev *imxdi, u32 dsr) +{ + u32 dcr; + + dev_dbg(&imxdi->pdev->dev, "DSR register reports: %08X\n", dsr); + + /* report the cause */ + di_report_tamper_info(imxdi, dsr); + + dcr = readl(imxdi->ioaddr + DCR); + + if (dcr & DCR_FSHL) { + /* we are out of luck */ + di_what_is_to_be_done(imxdi, "battery"); + return -ENODEV; + } + /* + * with the next SYSTEM POR we will transit from the "FAILURE STATE" + * into the "NON-VALID STATE" + "FAILURE STATE" + */ + di_what_is_to_be_done(imxdi, "main"); + + return -ENODEV; +} + +static int di_handle_valid_state(struct imxdi_dev *imxdi, u32 dsr) +{ + /* initialize alarm */ + di_write_busy_wait(imxdi, DCAMR_UNSET, DCAMR); + di_write_busy_wait(imxdi, 0, DCALR); + + /* clear alarm flag */ + if (dsr & DSR_CAF) + di_write_busy_wait(imxdi, DSR_CAF, DSR); + + return 0; +} + +static int di_handle_invalid_state(struct imxdi_dev *imxdi, u32 dsr) +{ + u32 dcr, sec; + + /* + * lets disable all sources which can force the DryIce unit into + * the "FAILURE STATE" for now + */ + di_write_busy_wait(imxdi, 0x00000000, DTCR); + /* and lets protect them at runtime from any change */ + di_write_busy_wait(imxdi, DCR_TDCSL, DCR); + + sec = readl(imxdi->ioaddr + DTCMR); + if (sec != 0) + dev_warn(&imxdi->pdev->dev, + "The security violation has happend at %u seconds\n", + sec); + /* + * the timer cannot be set/modified if + * - the TCHL or TCSL bit is set in DCR + */ + dcr = readl(imxdi->ioaddr + DCR); + if (!(dcr & DCR_TCE)) { + if (dcr & DCR_TCHL) { + /* we are out of luck */ + di_what_is_to_be_done(imxdi, "battery"); + return -ENODEV; + } + if (dcr & DCR_TCSL) { + di_what_is_to_be_done(imxdi, "main"); + return -ENODEV; + } + } + /* + * - the timer counter stops/is stopped if + * - its overflow flag is set (TCO in DSR) + * -> clear overflow bit to make it count again + * - NVF is set in DSR + * -> clear non-valid bit to make it count again + * - its TCE (DCR) is cleared + * -> set TCE to make it count + * - it was never set before + * -> write a time into it (required again if the NVF was set) + */ + /* state handled */ + di_write_busy_wait(imxdi, DSR_NVF, DSR); + /* clear overflow flag */ + di_write_busy_wait(imxdi, DSR_TCO, DSR); + /* enable the counter */ + di_write_busy_wait(imxdi, dcr | DCR_TCE, DCR); + /* set and trigger it to make it count */ + di_write_busy_wait(imxdi, sec, DTCMR); + + /* now prepare for the valid state */ + return di_handle_valid_state(imxdi, __raw_readl(imxdi->ioaddr + DSR)); +} + +static int di_handle_invalid_and_failure_state(struct imxdi_dev *imxdi, u32 dsr) +{ + u32 dcr; + + /* + * now we must first remove the tamper sources in order to get the + * device out of the "FAILURE STATE" + * To disable any of the following sources we need to modify the DTCR + */ + if (dsr & (DSR_WTD | DSR_ETBD | DSR_ETAD | DSR_EBD | DSR_SAD | + DSR_TTD | DSR_CTD | DSR_VTD | DSR_MCO | DSR_TCO)) { + dcr = __raw_readl(imxdi->ioaddr + DCR); + if (dcr & DCR_TDCHL) { + /* + * 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". + * We need a DRYICE POR via battery power cycling.... + */ + /* + * out of luck! + * we cannot disable them without a DRYICE POR + */ + di_what_is_to_be_done(imxdi, "battery"); + return -ENODEV; + } + if (dcr & DCR_TDCSL) { + /* a soft lock can be removed by a SYSTEM POR */ + di_what_is_to_be_done(imxdi, "main"); + return -ENODEV; + } + } + + /* disable all sources */ + di_write_busy_wait(imxdi, 0x00000000, DTCR); + + /* clear the status bits now */ + di_write_busy_wait(imxdi, dsr & (DSR_WTD | DSR_ETBD | DSR_ETAD | + DSR_EBD | DSR_SAD | DSR_TTD | DSR_CTD | DSR_VTD | + DSR_MCO | DSR_TCO), DSR); + + dsr = readl(imxdi->ioaddr + DSR); + if ((dsr & ~(DSR_NVF | DSR_SVF | DSR_WBF | DSR_WNF | + DSR_WCF | DSR_WEF)) != 0) + dev_warn(&imxdi->pdev->dev, + "There are still some sources of pain in DSR: %08x!\n", + dsr & ~(DSR_NVF | DSR_SVF | DSR_WBF | DSR_WNF | + DSR_WCF | DSR_WEF)); + + /* + * now we are trying to clear the "Security-violation flag" to + * get the DryIce out of this state + */ + di_write_busy_wait(imxdi, DSR_SVF, DSR); + + /* success? */ + dsr = readl(imxdi->ioaddr + DSR); + if (dsr & DSR_SVF) { + dev_crit(&imxdi->pdev->dev, + "Cannot clear the security violation flag. We are ending up in an endless loop!\n"); + /* last resort */ + di_what_is_to_be_done(imxdi, "battery"); + return -ENODEV; + } + + /* + * now we have left the "FAILURE STATE" and ending up in the + * "NON-VALID STATE" time to recover everything + */ + return di_handle_invalid_state(imxdi, dsr); +} + +static int di_handle_state(struct imxdi_dev *imxdi) +{ + int rc; + u32 dsr; + + dsr = readl(imxdi->ioaddr + DSR); + + switch (dsr & (DSR_NVF | DSR_SVF)) { + case DSR_NVF: + dev_warn(&imxdi->pdev->dev, "Invalid stated unit detected\n"); + rc = di_handle_invalid_state(imxdi, dsr); + break; + case DSR_SVF: + dev_warn(&imxdi->pdev->dev, "Failure stated unit detected\n"); + rc = di_handle_failure_state(imxdi, dsr); + break; + case DSR_NVF | DSR_SVF: + dev_warn(&imxdi->pdev->dev, + "Failure+Invalid stated unit detected\n"); + rc = di_handle_invalid_and_failure_state(imxdi, dsr); + break; + default: + dev_notice(&imxdi->pdev->dev, "Unlocked unit detected\n"); + rc = di_handle_valid_state(imxdi, dsr); + } + + return rc; +} + +/* * enable a dryice interrupt */ static void di_int_enable(struct imxdi_dev *imxdi, u32 intr) @@ -491,6 +766,10 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) /* mask all interrupts */ writel(0, imxdi->ioaddr + DIER); + rc = di_handle_state(imxdi); + if (rc != 0) + goto err; + rc = devm_request_irq(&pdev->dev, imxdi->irq, dryice_norm_irq, IRQF_SHARED, pdev->name, imxdi); if (rc) { @@ -498,44 +777,6 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) goto err; } - /* put dryice into valid state */ - if (readl(imxdi->ioaddr + DSR) & DSR_NVF) { - rc = di_write_wait(imxdi, DSR_NVF | DSR_SVF, DSR); - if (rc) - goto err; - } - - /* initialize alarm */ - rc = di_write_wait(imxdi, DCAMR_UNSET, DCAMR); - if (rc) - goto err; - rc = di_write_wait(imxdi, 0, DCALR); - if (rc) - goto err; - - /* clear alarm flag */ - if (readl(imxdi->ioaddr + DSR) & DSR_CAF) { - rc = di_write_wait(imxdi, DSR_CAF, DSR); - if (rc) - goto err; - } - - /* the timer won't count if it has never been written to */ - if (readl(imxdi->ioaddr + DTCMR) == 0) { - rc = di_write_wait(imxdi, 0, DTCMR); - if (rc) - goto err; - } - - /* start keeping time */ - if (!(readl(imxdi->ioaddr + DCR) & DCR_TCE)) { - rc = di_write_wait(imxdi, - readl(imxdi->ioaddr + DCR) | DCR_TCE, - DCR); - if (rc) - goto err; - } - platform_set_drvdata(pdev, imxdi); imxdi->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &dryice_rtc_ops, THIS_MODULE); -- cgit v0.10.2 From a7c535e3a8e50e625750d2aa0ed4f84591ca7bfa Mon Sep 17 00:00:00 2001 From: Juergen Borleis Date: Mon, 27 Apr 2015 15:59:50 +0200 Subject: rtc: imxdi: monitor a security violation at runtime Maybe the unit enters the hardware related state at runtime and not at system boot time (after a power cycle). Signed-off-by: Juergen Borleis Signed-off-by: Robert Schwebel [rsc: got NDA clearance from Freescale] Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 3d7f039..a08da4a 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -665,6 +665,25 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id) irqreturn_t rc = IRQ_NONE; dier = readl(imxdi->ioaddr + DIER); + dsr = readl(imxdi->ioaddr + DSR); + + /* handle the security violation event */ + if (dier & DIER_SVIE) { + if (dsr & DSR_SVF) { + /* + * Disable the interrupt when this kind of event has + * happened. + * There cannot be more than one event of this type, + * because it needs a complex state change + * including a main power cycle to get again out of + * this state. + */ + di_int_disable(imxdi, DIER_SVIE); + /* report the violation */ + di_report_tamper_info(imxdi, dsr); + rc = IRQ_HANDLED; + } + } /* handle write complete and write error cases */ if (dier & DIER_WCIE) { @@ -675,7 +694,6 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id) return rc; /* DSR_WCF clears itself on DSR read */ - dsr = readl(imxdi->ioaddr + DSR); if (dsr & (DSR_WCF | DSR_WEF)) { /* mask the interrupt */ di_int_disable(imxdi, DIER_WCIE); @@ -691,7 +709,6 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id) /* handle the alarm case */ if (dier & DIER_CAIE) { /* DSR_WCF clears itself on DSR read */ - dsr = readl(imxdi->ioaddr + DSR); if (dsr & DSR_CAF) { /* mask the interrupt */ di_int_disable(imxdi, DIER_CAIE); -- cgit v0.10.2 From 9bb698c60a12d3b5db62f99a0874565c791e998b Mon Sep 17 00:00:00 2001 From: Juergen Borleis Date: Mon, 27 Apr 2015 15:59:51 +0200 Subject: rtc: imxdi: when locked, do not fail silently If the DryICE unit is locked it is impossible to set the time. Provide an error message for this case. Signed-off-by: Juergen Borleis Signed-off-by: Robert Schwebel [rsc: got NDA clearance from Freescale] Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index a08da4a..7bffd7f 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -566,14 +566,35 @@ static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm) static int dryice_rtc_set_mmss(struct device *dev, unsigned long secs) { struct imxdi_dev *imxdi = dev_get_drvdata(dev); + u32 dcr, dsr; int rc; + dcr = readl(imxdi->ioaddr + DCR); + dsr = readl(imxdi->ioaddr + DSR); + + if (!(dcr & DCR_TCE) || (dsr & DSR_SVF)) { + if (dcr & DCR_TCHL) { + /* we are even more out of luck */ + di_what_is_to_be_done(imxdi, "battery"); + return -EPERM; + } + if ((dcr & DCR_TCSL) || (dsr & DSR_SVF)) { + /* we are out of luck for now */ + di_what_is_to_be_done(imxdi, "main"); + return -EPERM; + } + } + /* zero the fractional part first */ rc = di_write_wait(imxdi, 0, DTCLR); - if (rc == 0) - rc = di_write_wait(imxdi, secs, DTCMR); + if (rc != 0) + return rc; - return rc; + rc = di_write_wait(imxdi, secs, DTCMR); + if (rc != 0) + return rc; + + return di_write_wait(imxdi, readl(imxdi->ioaddr + DCR) | DCR_TCE, DCR); } static int dryice_rtc_alarm_irq_enable(struct device *dev, -- cgit v0.10.2 From 3090ac0abcfe65a649c49d903265e09daa1a91ea Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Tue, 28 Jun 2011 17:03:37 +0200 Subject: rtc: at32ap700x: update author email This patch updates the email address of the rtc-at32ap700x driver supported by me to an email account I will use on a more regular basis in the future. Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index d618d6c..83ac233 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c @@ -282,6 +282,6 @@ static struct platform_driver at32_rtc_driver = { module_platform_driver_probe(at32_rtc_driver, at32_rtc_probe); -MODULE_AUTHOR("Hans-Christian Egtvedt "); +MODULE_AUTHOR("Hans-Christian Egtvedt "); MODULE_DESCRIPTION("Real time clock for AVR32 AT32AP700x"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From fdf8afa188595e2f6c39f6a05ea147f48621a996 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 6 May 2015 09:24:42 +0200 Subject: rtc: xgene: Set hardware dependency The rtc-xgene driver is only useful on X-Gene SoC. Signed-off-by: Jean Delvare Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: Iyappan Subramanian Cc: Keyur Chudgar Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 0fe4ad8..b957b4f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1533,6 +1533,7 @@ config RTC_DRV_MOXART config RTC_DRV_XGENE tristate "APM X-Gene RTC" depends on HAS_IOMEM + depends on ARCH_XGENE || COMPILE_TEST help If you say yes here you get support for the APM X-Gene SoC real time clock. -- cgit v0.10.2 From a5d7ea0912cc35efb61bccb1f07432f25fce6281 Mon Sep 17 00:00:00 2001 From: Eddie Huang Date: Wed, 6 May 2015 15:23:40 +0800 Subject: mfd: provide RTC resource in MT6397 MFD Provide MT6397 RTC interrupt, base address, and register in MT6397 MFD. Signed-off-by: Eddie Huang Acked-by: Lee Jones Signed-off-by: Alexandre Belloni diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c index 09bc780..4027623 100644 --- a/drivers/mfd/mt6397-core.c +++ b/drivers/mfd/mt6397-core.c @@ -21,9 +21,27 @@ #include #include +#define MT6397_RTC_BASE 0xe000 +#define MT6397_RTC_SIZE 0x3e + +static const struct resource mt6397_rtc_resources[] = { + { + .start = MT6397_RTC_BASE, + .end = MT6397_RTC_BASE + MT6397_RTC_SIZE, + .flags = IORESOURCE_MEM, + }, + { + .start = MT6397_IRQ_RTC, + .end = MT6397_IRQ_RTC, + .flags = IORESOURCE_IRQ, + }, +}; + static const struct mfd_cell mt6397_devs[] = { { .name = "mt6397-rtc", + .num_resources = ARRAY_SIZE(mt6397_rtc_resources), + .resources = mt6397_rtc_resources, .of_compatible = "mediatek,mt6397-rtc", }, { .name = "mt6397-regulator", -- cgit v0.10.2 From fc2979118f3f5193475cb53d5df7bdaa7e358a42 Mon Sep 17 00:00:00 2001 From: Tianping Fang Date: Wed, 6 May 2015 15:23:41 +0800 Subject: rtc: mediatek: Add MT6397 RTC driver Add Mediatek MT6397 RTC driver Signed-off-by: Tianping Fang Signed-off-by: Eddie Huang Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b957b4f..20a1f35 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1530,6 +1530,16 @@ config RTC_DRV_MOXART This driver can also be built as a module. If so, the module will be called rtc-moxart +config RTC_DRV_MT6397 + tristate "Mediatek Real Time Clock driver" + depends on MFD_MT6397 || COMPILE_TEST + help + This selects the Mediatek(R) RTC driver. RTC is part of Mediatek + MT6397 PMIC. You should enable MT6397 PMIC MFD before select + Mediatek(R) RTC driver. + + If you want to use Mediatek(R) RTC interface, select Y or M here. + config RTC_DRV_XGENE tristate "APM X-Gene RTC" depends on HAS_IOMEM diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 2b82e2b..371d977 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -155,3 +155,4 @@ obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o +obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c new file mode 100644 index 0000000..8bed852 --- /dev/null +++ b/drivers/rtc/rtc-mt6397.c @@ -0,0 +1,394 @@ +/* +* Copyright (c) 2014-2015 MediaTek Inc. +* Author: Tianping.Fang +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RTC_BBPU 0x0000 +#define RTC_BBPU_CBUSY BIT(6) + +#define RTC_WRTGR 0x003c + +#define RTC_IRQ_STA 0x0002 +#define RTC_IRQ_STA_AL BIT(0) +#define RTC_IRQ_STA_LP BIT(3) + +#define RTC_IRQ_EN 0x0004 +#define RTC_IRQ_EN_AL BIT(0) +#define RTC_IRQ_EN_ONESHOT BIT(2) +#define RTC_IRQ_EN_LP BIT(3) +#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) + +#define RTC_AL_MASK 0x0008 +#define RTC_AL_MASK_DOW BIT(4) + +#define RTC_TC_SEC 0x000a +/* Min, Hour, Dom... register offset to RTC_TC_SEC */ +#define RTC_OFFSET_SEC 0 +#define RTC_OFFSET_MIN 1 +#define RTC_OFFSET_HOUR 2 +#define RTC_OFFSET_DOM 3 +#define RTC_OFFSET_DOW 4 +#define RTC_OFFSET_MTH 5 +#define RTC_OFFSET_YEAR 6 +#define RTC_OFFSET_COUNT 7 + +#define RTC_AL_SEC 0x0018 + +#define RTC_PDN2 0x002e +#define RTC_PDN2_PWRON_ALARM BIT(4) + +#define RTC_MIN_YEAR 1968 +#define RTC_BASE_YEAR 1900 +#define RTC_NUM_YEARS 128 +#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) + +struct mt6397_rtc { + struct device *dev; + struct rtc_device *rtc_dev; + struct mutex lock; + struct regmap *regmap; + int irq; + u32 addr_base; +}; + +static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) +{ + unsigned long timeout = jiffies + HZ; + int ret; + u32 data; + + ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1); + if (ret < 0) + return ret; + + while (1) { + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU, + &data); + if (ret < 0) + break; + if (!(data & RTC_BBPU_CBUSY)) + break; + if (time_after(jiffies, timeout)) { + ret = -ETIMEDOUT; + break; + } + cpu_relax(); + } + + return ret; +} + +static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data) +{ + struct mt6397_rtc *rtc = data; + u32 irqsta, irqen; + int ret; + + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_STA, &irqsta); + if ((ret >= 0) && (irqsta & RTC_IRQ_STA_AL)) { + rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); + irqen = irqsta & ~RTC_IRQ_EN_AL; + mutex_lock(&rtc->lock); + if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, + irqen) < 0) + mtk_rtc_write_trigger(rtc); + mutex_unlock(&rtc->lock); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int __mtk_rtc_read_time(struct mt6397_rtc *rtc, + struct rtc_time *tm, int *sec) +{ + int ret; + u16 data[RTC_OFFSET_COUNT]; + + mutex_lock(&rtc->lock); + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, + data, RTC_OFFSET_COUNT); + if (ret < 0) + goto exit; + + tm->tm_sec = data[RTC_OFFSET_SEC]; + tm->tm_min = data[RTC_OFFSET_MIN]; + tm->tm_hour = data[RTC_OFFSET_HOUR]; + tm->tm_mday = data[RTC_OFFSET_DOM]; + tm->tm_mon = data[RTC_OFFSET_MTH]; + tm->tm_year = data[RTC_OFFSET_YEAR]; + + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, sec); +exit: + mutex_unlock(&rtc->lock); + return ret; +} + +static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + time64_t time; + struct mt6397_rtc *rtc = dev_get_drvdata(dev); + int sec, ret; + + do { + ret = __mtk_rtc_read_time(rtc, tm, &sec); + if (ret < 0) + goto exit; + } while (sec < tm->tm_sec); + + /* HW register use 7 bits to store year data, minus + * RTC_MIN_YEAR_OFFSET before write year data to register, and plus + * RTC_MIN_YEAR_OFFSET back after read year from register + */ + tm->tm_year += RTC_MIN_YEAR_OFFSET; + + /* HW register start mon from one, but tm_mon start from zero. */ + tm->tm_mon--; + time = rtc_tm_to_time64(tm); + + /* rtc_tm_to_time64 covert Gregorian date to seconds since + * 01-01-1970 00:00:00, and this date is Thursday. + */ + tm->tm_wday = (time / 86400 + 4) % 7; + +exit: + return ret; +} + +static int mtk_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct mt6397_rtc *rtc = dev_get_drvdata(dev); + int ret; + u16 data[RTC_OFFSET_COUNT]; + + tm->tm_year -= RTC_MIN_YEAR_OFFSET; + tm->tm_mon++; + + data[RTC_OFFSET_SEC] = tm->tm_sec; + data[RTC_OFFSET_MIN] = tm->tm_min; + data[RTC_OFFSET_HOUR] = tm->tm_hour; + data[RTC_OFFSET_DOM] = tm->tm_mday; + data[RTC_OFFSET_MTH] = tm->tm_mon; + data[RTC_OFFSET_YEAR] = tm->tm_year; + + mutex_lock(&rtc->lock); + ret = regmap_bulk_write(rtc->regmap, rtc->addr_base + RTC_TC_SEC, + data, RTC_OFFSET_COUNT); + if (ret < 0) + goto exit; + + /* Time register write to hardware after call trigger function */ + ret = mtk_rtc_write_trigger(rtc); + +exit: + mutex_unlock(&rtc->lock); + return ret; +} + +static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct rtc_time *tm = &alm->time; + struct mt6397_rtc *rtc = dev_get_drvdata(dev); + u32 irqen, pdn2; + int ret; + u16 data[RTC_OFFSET_COUNT]; + + mutex_lock(&rtc->lock); + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, &irqen); + if (ret < 0) + goto err_exit; + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_PDN2, &pdn2); + if (ret < 0) + goto err_exit; + + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC, + data, RTC_OFFSET_COUNT); + if (ret < 0) + goto err_exit; + + alm->enabled = !!(irqen & RTC_IRQ_EN_AL); + alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM); + mutex_unlock(&rtc->lock); + + tm->tm_sec = data[RTC_OFFSET_SEC]; + tm->tm_min = data[RTC_OFFSET_MIN]; + tm->tm_hour = data[RTC_OFFSET_HOUR]; + tm->tm_mday = data[RTC_OFFSET_DOM]; + tm->tm_mon = data[RTC_OFFSET_MTH]; + tm->tm_year = data[RTC_OFFSET_YEAR]; + + tm->tm_year += RTC_MIN_YEAR_OFFSET; + tm->tm_mon--; + + return 0; +err_exit: + mutex_unlock(&rtc->lock); + return ret; +} + +static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct rtc_time *tm = &alm->time; + struct mt6397_rtc *rtc = dev_get_drvdata(dev); + int ret; + u16 data[RTC_OFFSET_COUNT]; + + tm->tm_year -= RTC_MIN_YEAR_OFFSET; + tm->tm_mon++; + + data[RTC_OFFSET_SEC] = tm->tm_sec; + data[RTC_OFFSET_MIN] = tm->tm_min; + data[RTC_OFFSET_HOUR] = tm->tm_hour; + data[RTC_OFFSET_DOM] = tm->tm_mday; + data[RTC_OFFSET_MTH] = tm->tm_mon; + data[RTC_OFFSET_YEAR] = tm->tm_year; + + mutex_lock(&rtc->lock); + if (alm->enabled) { + ret = regmap_bulk_write(rtc->regmap, + rtc->addr_base + RTC_AL_SEC, + data, RTC_OFFSET_COUNT); + if (ret < 0) + goto exit; + ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_AL_MASK, + RTC_AL_MASK_DOW); + if (ret < 0) + goto exit; + ret = regmap_update_bits(rtc->regmap, + rtc->addr_base + RTC_IRQ_EN, + RTC_IRQ_EN_ONESHOT_AL, + RTC_IRQ_EN_ONESHOT_AL); + if (ret < 0) + goto exit; + } else { + ret = regmap_update_bits(rtc->regmap, + rtc->addr_base + RTC_IRQ_EN, + RTC_IRQ_EN_ONESHOT_AL, 0); + if (ret < 0) + goto exit; + } + + /* All alarm time register write to hardware after calling + * mtk_rtc_write_trigger. This can avoid race condition if alarm + * occur happen during writing alarm time register. + */ + ret = mtk_rtc_write_trigger(rtc); +exit: + mutex_unlock(&rtc->lock); + return ret; +} + +static struct rtc_class_ops mtk_rtc_ops = { + .read_time = mtk_rtc_read_time, + .set_time = mtk_rtc_set_time, + .read_alarm = mtk_rtc_read_alarm, + .set_alarm = mtk_rtc_set_alarm, +}; + +static int mtk_rtc_probe(struct platform_device *pdev) +{ + struct resource *res; + struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent); + struct mt6397_rtc *rtc; + int ret; + + rtc = devm_kzalloc(&pdev->dev, sizeof(struct mt6397_rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rtc->addr_base = res->start; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + rtc->irq = irq_create_mapping(mt6397_chip->irq_domain, res->start); + if (rtc->irq <= 0) + return -EINVAL; + + rtc->regmap = mt6397_chip->regmap; + rtc->dev = &pdev->dev; + mutex_init(&rtc->lock); + + platform_set_drvdata(pdev, rtc); + + ret = request_threaded_irq(rtc->irq, NULL, + mtk_rtc_irq_handler_thread, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + "mt6397-rtc", rtc); + if (ret) { + dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", + rtc->irq, ret); + goto out_dispose_irq; + } + + rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev, + &mtk_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc->rtc_dev)) { + dev_err(&pdev->dev, "register rtc device failed\n"); + ret = PTR_ERR(rtc->rtc_dev); + goto out_free_irq; + } + + device_init_wakeup(&pdev->dev, 1); + + return 0; + +out_free_irq: + free_irq(rtc->irq, rtc->rtc_dev); +out_dispose_irq: + irq_dispose_mapping(rtc->irq); + return ret; +} + +static int mtk_rtc_remove(struct platform_device *pdev) +{ + struct mt6397_rtc *rtc = platform_get_drvdata(pdev); + + rtc_device_unregister(rtc->rtc_dev); + free_irq(rtc->irq, rtc->rtc_dev); + irq_dispose_mapping(rtc->irq); + + return 0; +} + +static const struct of_device_id mt6397_rtc_of_match[] = { + { .compatible = "mediatek,mt6397-rtc", }, + { } +}; + +static struct platform_driver mtk_rtc_driver = { + .driver = { + .name = "mt6397-rtc", + .of_match_table = mt6397_rtc_of_match, + }, + .probe = mtk_rtc_probe, + .remove = mtk_rtc_remove, +}; + +module_platform_driver(mtk_rtc_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Tianping Fang "); +MODULE_DESCRIPTION("RTC Driver for MediaTek MT6397 PMIC"); +MODULE_ALIAS("platform:mt6397-rtc"); -- cgit v0.10.2 From 607b8fc90d3bd8121ab00ac824e6bd2e1a6a2e6e Mon Sep 17 00:00:00 2001 From: Eddie Huang Date: Wed, 6 May 2015 15:23:42 +0800 Subject: MAINTAINERS: add Mediatek RTC driver Add Mediatek RTC driver to maintainer entry. Signed-off-by: Eddie Huang Signed-off-by: Alexandre Belloni diff --git a/MAINTAINERS b/MAINTAINERS index d8afd29..8fc34fa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1236,6 +1236,13 @@ W: http://www.digriz.org.uk/ts78xx/kernel S: Maintained F: arch/arm/mach-orion5x/ts78xx-* +ARM/Mediatek RTC DRIVER +M: Eddie Huang +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: drivers/rtc/rtc-mt6397.c + ARM/Mediatek SoC support M: Matthias Brugger L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -- cgit v0.10.2 From 99c14e4df6144bca12dcac657266a7b8216aaa16 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 20 Feb 2015 14:47:30 +0100 Subject: rtc: mc13xxx: fix obfuscated and wrong format string According to C99, %2.s means 'print two spaces' (a precision of . without following digits or * means 0). The kernel's printf implementation, however, treats that case as if no precision was given, but relying on that quirk is rather silly. Also, since no - (aka left-justify) flag is given, the field with of 2 would then cause the alarm->enabled case to come out as "o n". Deobfuscate it. Signed-off-by: Rasmus Villemoes Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 32df1d8..a658680 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -216,7 +216,7 @@ static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) s1970 = rtc_tm_to_time64(&alarm->time); - dev_dbg(dev, "%s: o%2.s %lld\n", __func__, alarm->enabled ? "n" : "ff", + dev_dbg(dev, "%s: %s %lld\n", __func__, alarm->enabled ? "on" : "off", (long long)s1970); ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled, -- cgit v0.10.2 From 9393996761e23280f259d706133c8f0cd139fd58 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 14 May 2015 22:39:06 +0200 Subject: rtc: mt6397: fix build on some 32bits platforms On some !ARM 32bits platforms, the following compilation error happens because of the division on a 64bits value in mtk_rtc_read_time(): drivers/built-in.o: In function `mtk_rtc_read_time': rtc-mt6397.c:(.text+0x265d13f): undefined reference to `__divdi3' rtc-mt6397.c:(.text+0x265d150): undefined reference to `__moddi3' Use div_s64() as done in rtc_time64_to_tm() to solve that. Reported-by: kbuild test robot Acked-by: Eddie Huang Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c index 8bed852..c0090b6 100644 --- a/drivers/rtc/rtc-mt6397.c +++ b/drivers/rtc/rtc-mt6397.c @@ -150,7 +150,7 @@ static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm) { time64_t time; struct mt6397_rtc *rtc = dev_get_drvdata(dev); - int sec, ret; + int days, sec, ret; do { ret = __mtk_rtc_read_time(rtc, tm, &sec); @@ -171,7 +171,8 @@ static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm) /* rtc_tm_to_time64 covert Gregorian date to seconds since * 01-01-1970 00:00:00, and this date is Thursday. */ - tm->tm_wday = (time / 86400 + 4) % 7; + days = div_s64(time, 86400); + tm->tm_wday = (days + 4) % 7; exit: return ret; -- cgit v0.10.2 From 8ad0f5b682d2db108a15f850c54b577720c11699 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 18 Apr 2011 20:16:57 +0800 Subject: rtc: ds1672, max6900, max8998: Add MODULE_DEVICE_TABLE The device table is required to load modules based on modaliases. After adding MODULE_DEVICE_TABLE, below entries will be added to modules.alias: alias i2c:ds1672 rtc_ds1672 alias i2c:max6900 rtc_max6900 alias platform:lp3974-rtc rtc_max8998 alias platform:max8998-rtc rtc_max8998 Signed-off-by: Axel Lin Cc: Alessandro Zummo Cc: Dale Farnsworth Cc: Minkyu Kang Cc: Joonyoung Shim Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index a4888db..92b1cbf 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -198,6 +198,7 @@ static struct i2c_device_id ds1672_id[] = { { "ds1672", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, ds1672_id); static struct i2c_driver ds1672_driver = { .driver = { diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 4804985..b2a7607 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c @@ -234,6 +234,7 @@ static struct i2c_device_id max6900_id[] = { { "max6900", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, max6900_id); static struct i2c_driver max6900_driver = { .driver = { diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index 5726ef7..30804b0 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c @@ -309,6 +309,7 @@ static const struct platform_device_id max8998_rtc_id[] = { { "lp3974-rtc", TYPE_LP3974 }, { } }; +MODULE_DEVICE_TABLE(platform, max8998_rtc_id); static struct platform_driver max8998_rtc_driver = { .driver = { -- cgit v0.10.2 From 2d0cca0db4134712c7a67694c5aab57a49e228f2 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 13 May 2015 17:18:01 +0200 Subject: rtc: max77686: Report platform modalias to fix module autoload If the rtc-max77686 driver is built as a module, modalias information is not filled so the module is not autoloaded. Use the MODULE_DEVICE_TABLE() macro to export the platform ID table so the module contains that data. Signed-off-by: Javier Martinez Canillas Reviewed-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 7632a87..7184a0e 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -511,6 +511,7 @@ static const struct platform_device_id rtc_id[] = { { "max77686-rtc", 0 }, {}, }; +MODULE_DEVICE_TABLE(platform, rtc_id); static struct platform_driver max77686_rtc_driver = { .driver = { -- cgit v0.10.2 From 9bde31df56bdd8950e31ae409af5276cb324058c Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 13 May 2015 17:18:02 +0200 Subject: rtc: max77802: Report platform modalias to fix module autoload If the rtc-max77802 driver is built as a module, modalias information is not filled so the module is not autoloaded. Use the MODULE_DEVICE_TABLE() macro to export the platform ID table so the module contains that data. Signed-off-by: Javier Martinez Canillas Reviewed-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-max77802.c b/drivers/rtc/rtc-max77802.c index 7f8adf8..82ffcc5 100644 --- a/drivers/rtc/rtc-max77802.c +++ b/drivers/rtc/rtc-max77802.c @@ -484,6 +484,7 @@ static const struct platform_device_id rtc_id[] = { { "max77802-rtc", 0 }, {}, }; +MODULE_DEVICE_TABLE(platform, rtc_id); static struct platform_driver max77802_rtc_driver = { .driver = { -- cgit v0.10.2 From ff32ff17a0d9c8e6e128e0be1b53756307414b2a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 21 Mar 2012 10:55:31 -0700 Subject: rtc: ep93xx: Use readl/writel for io Drivers should not be using the __raw_* io accessors. Signed-off-by: H Hartley Sweeten Cc: Alessandro Zummo Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index de325d6..a1628ad 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c @@ -45,7 +45,7 @@ static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload, struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev); unsigned long comp; - comp = __raw_readl(ep93xx_rtc->mmio_base + EP93XX_RTC_SWCOMP); + comp = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_SWCOMP); if (preload) *preload = (comp & EP93XX_RTC_SWCOMP_INT_MASK) @@ -63,7 +63,7 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev); unsigned long time; - time = __raw_readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA); + time = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA); rtc_time_to_tm(time, tm); return 0; @@ -73,7 +73,7 @@ static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs) { struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev); - __raw_writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD); + writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD); return 0; } -- cgit v0.10.2 From 6c95fa80e6f3e111b738949111a94bfac5021721 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 22 Feb 2013 11:19:15 +0900 Subject: rtc: rtc-v3020: use gpio_request_array() Using gpio_request_array()/gpio_free_array() can make the code simpler because it can set the direction and initial value in one shot and the for loop is unnecessary. Also, struct v3020_gpio is removed, because the struct v3020_gpio is replaced with struct gpio. Signed-off-by: Jingoo Han Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index bfbfa7e..f9f9709 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c @@ -49,18 +49,13 @@ struct v3020_chip_ops { #define V3020_RD 2 #define V3020_IO 3 -struct v3020_gpio { - const char *name; - unsigned int gpio; -}; - struct v3020 { /* MMIO access */ void __iomem *ioaddress; int leftshift; /* GPIO access */ - struct v3020_gpio *gpio; + struct gpio *gpio; struct v3020_chip_ops *ops; @@ -107,48 +102,34 @@ static struct v3020_chip_ops v3020_mmio_ops = { .write_bit = v3020_mmio_write_bit, }; -static struct v3020_gpio v3020_gpio[] = { - { "RTC CS", 0 }, - { "RTC WR", 0 }, - { "RTC RD", 0 }, - { "RTC IO", 0 }, +static struct gpio v3020_gpio[] = { + { 0, GPIOF_OUT_INIT_HIGH, "RTC CS"}, + { 0, GPIOF_OUT_INIT_HIGH, "RTC WR"}, + { 0, GPIOF_OUT_INIT_HIGH, "RTC RD"}, + { 0, GPIOF_OUT_INIT_HIGH, "RTC IO"}, }; static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev, struct v3020_platform_data *pdata) { - int i, err; + int err; v3020_gpio[V3020_CS].gpio = pdata->gpio_cs; v3020_gpio[V3020_WR].gpio = pdata->gpio_wr; v3020_gpio[V3020_RD].gpio = pdata->gpio_rd; v3020_gpio[V3020_IO].gpio = pdata->gpio_io; - for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++) { - err = gpio_request(v3020_gpio[i].gpio, v3020_gpio[i].name); - if (err) - goto err_request; + err = gpio_request_array(v3020_gpio, ARRAY_SIZE(v3020_gpio)); - gpio_direction_output(v3020_gpio[i].gpio, 1); - } - - chip->gpio = v3020_gpio; - - return 0; - -err_request: - while (--i >= 0) - gpio_free(v3020_gpio[i].gpio); + if (!err) + chip->gpio = v3020_gpio; return err; } static void v3020_gpio_unmap(struct v3020 *chip) { - int i; - - for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++) - gpio_free(v3020_gpio[i].gpio); + gpio_free_array(v3020_gpio, ARRAY_SIZE(v3020_gpio)); } static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit) -- cgit v0.10.2 From 119434f44c78df8c4b6d67f835448542a4bd7e91 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 21 May 2015 17:29:35 +0200 Subject: rtc: snvs: fix wakealarm by call enable_irq_wake earlier When entering suspend while an wakeup alarm is set, enable_set_wake should make sure that the RTC interrupt keep being enabled and the .irq_set_wake for the RTC interrupt get called. However, since the driver uses the suspend_noirq callback, the call to enable_irq_wake has been made after disabling the interrupts. While .irq_set_wake has been called properly, the interrupt remained disabled. Use the suspend callback to call enable_irq_wake early enough to ensure the RTC interrupt remains enabled. Fixes: 7654e9d4fd8f ("drivers/rtc/rtc-snvs: fix suspend/resume") Cc: # 3.19 Signed-off-by: Stefan Agner Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index 0479e80..d87a85c 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -322,6 +322,13 @@ static int snvs_rtc_suspend(struct device *dev) if (device_may_wakeup(dev)) enable_irq_wake(data->irq); + return 0; +} + +static int snvs_rtc_suspend_noirq(struct device *dev) +{ + struct snvs_rtc_data *data = dev_get_drvdata(dev); + if (data->clk) clk_disable_unprepare(data->clk); @@ -331,23 +338,28 @@ static int snvs_rtc_suspend(struct device *dev) static int snvs_rtc_resume(struct device *dev) { struct snvs_rtc_data *data = dev_get_drvdata(dev); - int ret; if (device_may_wakeup(dev)) - disable_irq_wake(data->irq); + return disable_irq_wake(data->irq); - if (data->clk) { - ret = clk_prepare_enable(data->clk); - if (ret) - return ret; - } + return 0; +} + +static int snvs_rtc_resume_noirq(struct device *dev) +{ + struct snvs_rtc_data *data = dev_get_drvdata(dev); + + if (data->clk) + return clk_prepare_enable(data->clk); return 0; } static const struct dev_pm_ops snvs_rtc_pm_ops = { - .suspend_noirq = snvs_rtc_suspend, - .resume_noirq = snvs_rtc_resume, + .suspend = snvs_rtc_suspend, + .suspend_noirq = snvs_rtc_suspend_noirq, + .resume = snvs_rtc_resume, + .resume_noirq = snvs_rtc_resume_noirq, }; #define SNVS_RTC_PM_OPS (&snvs_rtc_pm_ops) -- cgit v0.10.2 From 20d048ac8ba160747be5dbe00b7cbcfda762d25f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 3 May 2015 11:29:44 +0200 Subject: rtc: stmp3xxx select STMP_DEVICE rtc-stmp3xxx depends on lib/stmp_device, select it. Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 20a1f35..3eff65d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1396,6 +1396,7 @@ config RTC_DRV_COH901331 config RTC_DRV_STMP tristate "Freescale STMP3xxx/i.MX23/i.MX28 RTC" depends on ARCH_MXS + select STMP_DEVICE help If you say yes here you will get support for the onboard STMP3xxx/i.MX23/i.MX28 RTC. -- cgit v0.10.2 From 98a9bb5bf44bb6ee372f2a3b42703f597030cc48 Mon Sep 17 00:00:00 2001 From: Hans Ulli Kroll Date: Wed, 20 May 2015 17:49:31 +0200 Subject: rtc: driver for Cortina Gemini Driver for the on chip RTC found on Cortina's SoC Gemini. Signed-off-by: Hans Ulli Kroll [alexandre.belloni@free-electrons.com: use devm_request_irq() and remove useless goto] Signed-off-by: Alexandre Belloni diff --git a/MAINTAINERS b/MAINTAINERS index 8fc34fa..16df5b1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -977,6 +977,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) T: git git://github.com/ulli-kroll/linux.git S: Maintained F: arch/arm/mach-gemini/ +F: drivers/rtc/rtc-gemini.c ARM/CSR SIRFPRIMA2 MACHINE SUPPORT M: Barry Song diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 3eff65d..c94bb6a 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1372,6 +1372,17 @@ config RTC_DRV_ARMADA38X This driver can also be built as a module. If so, the module will be called armada38x-rtc. +config RTC_DRV_GEMINI + tristate "Gemini SoC RTC" + depends on ARCH_GEMINI || COMPILE_TEST + depends on HAS_IOMEM + help + If you say Y here you will get support for the + RTC found on Gemini SoC's. + + This driver can also be built as a module. If so, the module + will be called rtc-gemini. + config RTC_DRV_PS3 tristate "PS3 RTC" depends on PPC_PS3 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 371d977..7cc7cec 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o +obj-$(CONFIG_RTC_DRV_GEMINI) += rtc-gemini.o obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c new file mode 100644 index 0000000..5fc17df --- /dev/null +++ b/drivers/rtc/rtc-gemini.c @@ -0,0 +1,176 @@ +/* + * Gemini OnChip RTC + * + * Copyright (C) 2009 Janos Laube + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original code for older kernel 2.6.15 are from Stormlinksemi + * first update from Janos Laube for > 2.6.29 kernels + * + * checkpatch fixes and usage of rtc-lib code + * Hans Ulli Kroll + */ + +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "rtc-gemini" +#define DRV_VERSION "0.2" + +MODULE_AUTHOR("Hans Ulli Kroll "); +MODULE_DESCRIPTION("RTC driver for Gemini SoC"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); + +struct gemini_rtc { + struct rtc_device *rtc_dev; + void __iomem *rtc_base; + int rtc_irq; +}; + +enum gemini_rtc_offsets { + GEMINI_RTC_SECOND = 0x00, + GEMINI_RTC_MINUTE = 0x04, + GEMINI_RTC_HOUR = 0x08, + GEMINI_RTC_DAYS = 0x0C, + GEMINI_RTC_ALARM_SECOND = 0x10, + GEMINI_RTC_ALARM_MINUTE = 0x14, + GEMINI_RTC_ALARM_HOUR = 0x18, + GEMINI_RTC_RECORD = 0x1C, + GEMINI_RTC_CR = 0x20 +}; + +static irqreturn_t gemini_rtc_interrupt(int irq, void *dev) +{ + return IRQ_HANDLED; +} + +/* + * Looks like the RTC in the Gemini SoC is (totaly) broken + * We can't read/write directly the time from RTC registers. + * We must do some "offset" calculation to get the real time + * + * This FIX works pretty fine and Stormlinksemi aka Cortina-Networks does + * the same thing, without the rtc-lib.c calls. + */ + +static int gemini_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct gemini_rtc *rtc = dev_get_drvdata(dev); + + unsigned int days, hour, min, sec; + unsigned long offset, time; + + sec = readl(rtc->rtc_base + GEMINI_RTC_SECOND); + min = readl(rtc->rtc_base + GEMINI_RTC_MINUTE); + hour = readl(rtc->rtc_base + GEMINI_RTC_HOUR); + days = readl(rtc->rtc_base + GEMINI_RTC_DAYS); + offset = readl(rtc->rtc_base + GEMINI_RTC_RECORD); + + time = offset + days * 86400 + hour * 3600 + min * 60 + sec; + + rtc_time_to_tm(time, tm); + + return 0; +} + +static int gemini_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct gemini_rtc *rtc = dev_get_drvdata(dev); + unsigned int sec, min, hour, day; + unsigned long offset, time; + + if (tm->tm_year >= 2148) /* EPOCH Year + 179 */ + return -EINVAL; + + rtc_tm_to_time(tm, &time); + + sec = readl(rtc->rtc_base + GEMINI_RTC_SECOND); + min = readl(rtc->rtc_base + GEMINI_RTC_MINUTE); + hour = readl(rtc->rtc_base + GEMINI_RTC_HOUR); + day = readl(rtc->rtc_base + GEMINI_RTC_DAYS); + + offset = time - (day * 86400 + hour * 3600 + min * 60 + sec); + + writel(offset, rtc->rtc_base + GEMINI_RTC_RECORD); + writel(0x01, rtc->rtc_base + GEMINI_RTC_CR); + + return 0; +} + +static struct rtc_class_ops gemini_rtc_ops = { + .read_time = gemini_rtc_read_time, + .set_time = gemini_rtc_set_time, +}; + +static int gemini_rtc_probe(struct platform_device *pdev) +{ + struct gemini_rtc *rtc; + struct device *dev = &pdev->dev; + struct resource *res; + int ret; + + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); + if (unlikely(!rtc)) + return -ENOMEM; + platform_set_drvdata(pdev, rtc); + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) + return -ENODEV; + + rtc->rtc_irq = res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + rtc->rtc_base = devm_ioremap(dev, res->start, + res->end - res->start + 1); + + ret = devm_request_irq(dev, rtc->rtc_irq, gemini_rtc_interrupt, + IRQF_SHARED, pdev->name, dev); + if (unlikely(ret)) + return ret; + + rtc->rtc_dev = rtc_device_register(pdev->name, dev, + &gemini_rtc_ops, THIS_MODULE); + if (likely(IS_ERR(rtc->rtc_dev))) + return PTR_ERR(rtc->rtc_dev); + + return 0; +} + +static int gemini_rtc_remove(struct platform_device *pdev) +{ + struct gemini_rtc *rtc = platform_get_drvdata(pdev); + + rtc_device_unregister(rtc->rtc_dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver gemini_rtc_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = gemini_rtc_probe, + .remove = gemini_rtc_remove, +}; + +module_platform_driver_probe(gemini_rtc_driver, gemini_rtc_probe); -- cgit v0.10.2 From 538330ccb93849530f5617d1fa870237496caa60 Mon Sep 17 00:00:00 2001 From: Jan Kardell Date: Thu, 28 May 2015 08:48:45 +0200 Subject: rtc: pcf8563 fix: return -EINVAL if we read an invalid time. Return -EINVAL if the voltage low bit is set to avoid getting a bogus time at boot. There was a comment stating that util-linux hwclock refuses to set a new time if we return an error code on read, but at least the current version do set the time as expected. Remove the comment and the check for valid time, and let the rtc core check it for us. Signed-off-by: Jan Kardell Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 0ba7e59..229426d 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -22,7 +22,7 @@ #include #include -#define DRV_VERSION "0.4.3" +#define DRV_VERSION "0.4.4" #define PCF8563_REG_ST1 0x00 /* status */ #define PCF8563_REG_ST2 0x01 @@ -202,8 +202,9 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) { pcf8563->voltage_low = 1; - dev_info(&client->dev, + dev_err(&client->dev, "low voltage detected, date/time is not reliable.\n"); + return -EINVAL; } dev_dbg(&client->dev, @@ -234,12 +235,6 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - /* the clock can give out invalid datetime, but we cannot return - * -EINVAL otherwise hwclock will refuse to set the time on bootup. - */ - if (rtc_valid_tm(tm) < 0) - dev_err(&client->dev, "retrieved date/time is not valid.\n"); - return 0; } -- cgit v0.10.2 From e044253b3b4fb5a8b275202511a4d9765ac0a982 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 14 Aug 2013 11:11:21 +0200 Subject: rtc: simplify use of devm_ioremap_resource Remove unneeded error handling on the result of a call to platform_get_resource when the value is passed to devm_ioremap_resource. Move the call to platform_get_resource adjacent to the call to devm_ioremap_resource to make the connection between them more clear. A simplified version of the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression pdev,res,n,e,e1; expression ret != 0; identifier l; @@ - res = platform_get_resource(pdev, IORESOURCE_MEM, n); ... when != res - if (res == NULL) { ... \(goto l;\|return ret;\) } ... when != res + res = platform_get_resource(pdev, IORESOURCE_MEM, n); e = devm_ioremap_resource(e1, res); // Signed-off-by: Julia Lawall [viresh.kumar@linaro.org: acked rtc-spear] Acked-by: Viresh Kumar Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c index d16f550..12dbd70 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c @@ -144,15 +144,13 @@ static int __init ds1216_rtc_probe(struct platform_device *pdev) struct ds1216_priv *priv; u8 dummy[8]; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; platform_set_drvdata(pdev, priv); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->ioaddr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->ioaddr)) return PTR_ERR(priv->ioaddr); diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index 2fe537f..8247a29 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c @@ -332,13 +332,11 @@ static int ds1286_probe(struct platform_device *pdev) struct resource *res; struct ds1286_priv *priv; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; priv = devm_kzalloc(&pdev->dev, sizeof(struct ds1286_priv), GFP_KERNEL); if (!priv) return -ENOMEM; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->rtcregs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->rtcregs)) return PTR_ERR(priv->rtcregs); diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index d2cdb98..f05ef85 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c @@ -358,12 +358,6 @@ static int spear_rtc_probe(struct platform_device *pdev) int status = 0; int irq; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "no resource defined\n"); - return -EBUSY; - } - config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); if (!config) return -ENOMEM; @@ -383,6 +377,7 @@ static int spear_rtc_probe(struct platform_device *pdev) return status; } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); config->ioaddr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(config->ioaddr)) return PTR_ERR(config->ioaddr); -- cgit v0.10.2 From d200c79b1ad1fa76feb5e0991d11f3edfe9960de Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 29 May 2015 17:44:05 +0530 Subject: rtc: palmas: Initialise bb_charging flag before using it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialise the variable high_bb_charging before using it to avoid configuring wrong value and fix following compilation warning: /* rtc-palmas.c: In function ‘palmas_rtc_probe’: rtc-palmas.c:242:7: warning: ‘high_bb_charging’ may be used uninitialized in this function */ Signed-off-by: Laxman Dewangan Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-palmas.c b/drivers/rtc/rtc-palmas.c index 3b01d56..7ea2c47 100644 --- a/drivers/rtc/rtc-palmas.c +++ b/drivers/rtc/rtc-palmas.c @@ -239,7 +239,7 @@ static int palmas_rtc_probe(struct platform_device *pdev) struct palmas_rtc *palmas_rtc = NULL; int ret; bool enable_bb_charging = false; - bool high_bb_charging; + bool high_bb_charging = false; if (pdev->dev.of_node) { enable_bb_charging = of_property_read_bool(pdev->dev.of_node, -- cgit v0.10.2 From 626fea046b49490cdd8c917911437737c1f904a8 Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Fri, 12 Jun 2015 10:04:09 +0800 Subject: rtc: pcf8563: Replace deprecated rtc_time_to_tm() and rtc_tm_to_time() pcf8563_rtc_set_alarm() uses deprecated rtc_tm_to_time() and rtc_time_to_tm(), which will overflow in year 2106 on 32-bit machines. This patch solves this by: - Replacing rtc_time_to_tm() with rtc_time64_to_tm() - Replacing rtc_tm_to_time() with rtc_tm_to_time64() Acked-by: Arnd Bergmann Signed-off-by: Xunlei Pang Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 229426d..fc564d3 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -358,13 +358,13 @@ static int pcf8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm) struct i2c_client *client = to_i2c_client(dev); unsigned char buf[4]; int err; - unsigned long alarm_time; /* The alarm has no seconds, round up to nearest minute */ if (tm->time.tm_sec) { - rtc_tm_to_time(&tm->time, &alarm_time); - alarm_time += 60-tm->time.tm_sec; - rtc_time_to_tm(alarm_time, &tm->time); + time64_t alarm_time = rtc_tm_to_time64(&tm->time); + + alarm_time += 60 - tm->time.tm_sec; + rtc_time64_to_tm(alarm_time, &tm->time); } dev_dbg(dev, "%s, min=%d hour=%d wday=%d mday=%d " -- cgit v0.10.2 From 9200025724619d83f9fc366281f0bde36afe6e5a Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Fri, 12 Jun 2015 10:04:10 +0800 Subject: rtc: Introduce rtc_tm_sub() helper function There're many sites need comparing the two rtc_time variants for many rtc drivers, especially in the instances of rtc_class_ops::set_alarm(). So add this common helper function to make things easy. Suggested-by: Arnd Bergmann Signed-off-by: Xunlei Pang Signed-off-by: Alexandre Belloni diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 587017e..b361603 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -24,6 +24,14 @@ extern void rtc_time64_to_tm(time64_t time, struct rtc_time *tm); ktime_t rtc_tm_to_ktime(struct rtc_time tm); struct rtc_time rtc_ktime_to_tm(ktime_t kt); +/* + * rtc_tm_sub - Return the difference in seconds. + */ +static inline time64_t rtc_tm_sub(struct rtc_time *lhs, struct rtc_time *rhs) +{ + return rtc_tm_to_time64(lhs) - rtc_tm_to_time64(rhs); +} + /** * Deprecated. Use rtc_time64_to_tm(). */ -- cgit v0.10.2 From f118db1efdbd224b3e0dd174a8942471eee798a0 Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Fri, 12 Jun 2015 10:04:11 +0800 Subject: rtc: isl1208: Replace deprecated rtc_tm_to_time() isl1208_i2c_set_alarm() uses deprecated rtc_tm_to_time(), which will overflow in year 2106 on 32-bit machines. This patch solves this by: - Replacing rtc_tm_to_time() with rtc_tm_sub() Cc: Herbert Valerio Riedel Signed-off-by: Xunlei Pang Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index c3c549d..aa3b8f1 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -370,22 +370,15 @@ isl1208_i2c_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) struct rtc_time *alarm_tm = &alarm->time; u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, }; const int offs = ISL1208_REG_SCA; - unsigned long rtc_secs, alarm_secs; struct rtc_time rtc_tm; int err, enable; err = isl1208_i2c_read_time(client, &rtc_tm); if (err) return err; - err = rtc_tm_to_time(&rtc_tm, &rtc_secs); - if (err) - return err; - err = rtc_tm_to_time(alarm_tm, &alarm_secs); - if (err) - return err; /* If the alarm time is before the current time disable the alarm */ - if (!alarm->enabled || alarm_secs <= rtc_secs) + if (!alarm->enabled || rtc_tm_sub(alarm_tm, &rtc_tm) <= 0) enable = 0x00; else enable = 0x80; -- cgit v0.10.2 From 9033fd8ba7e96821e65fe3afc3f4077a8b66d1c9 Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Fri, 12 Jun 2015 10:04:12 +0800 Subject: rtc: sunxi: Replace deprecated rtc_tm_to_time() sunxi_rtc_setalarm() uses deprecated rtc_tm_to_time(), which will overflow in year 2106 on 32-bit machines. This patch solves this by: - Replacing rtc_tm_to_time() with rtc_tm_sub() Also remove the unnecessary initial zeroing of some local variables in sunxi_rtc_setalarm(). Cc: Carlo Caione Signed-off-by: Xunlei Pang Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c index 6e678fa..52543ae 100644 --- a/drivers/rtc/rtc-sunxi.c +++ b/drivers/rtc/rtc-sunxi.c @@ -269,14 +269,13 @@ static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); struct rtc_time *alrm_tm = &wkalrm->time; struct rtc_time tm_now; - u32 alrm = 0; - unsigned long time_now = 0; - unsigned long time_set = 0; - unsigned long time_gap = 0; - unsigned long time_gap_day = 0; - unsigned long time_gap_hour = 0; - unsigned long time_gap_min = 0; - int ret = 0; + u32 alrm; + time64_t diff; + unsigned long time_gap; + unsigned long time_gap_day; + unsigned long time_gap_hour; + unsigned long time_gap_min; + int ret; ret = sunxi_rtc_gettime(dev, &tm_now); if (ret < 0) { @@ -284,14 +283,18 @@ static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) return -EINVAL; } - rtc_tm_to_time(alrm_tm, &time_set); - rtc_tm_to_time(&tm_now, &time_now); - if (time_set <= time_now) { + diff = rtc_tm_sub(alrm_tm, &tm_now); + if (diff <= 0) { dev_err(dev, "Date to set in the past\n"); return -EINVAL; } - time_gap = time_set - time_now; + if (diff > 255 * SEC_IN_DAY) { + dev_err(dev, "Day must be in the range 0 - 255\n"); + return -EINVAL; + } + + time_gap = diff; time_gap_day = time_gap / SEC_IN_DAY; time_gap -= time_gap_day * SEC_IN_DAY; time_gap_hour = time_gap / SEC_IN_HOUR; @@ -299,11 +302,6 @@ static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) time_gap_min = time_gap / SEC_IN_MIN; time_gap -= time_gap_min * SEC_IN_MIN; - if (time_gap_day > 255) { - dev_err(dev, "Day must be in the range 0 - 255\n"); - return -EINVAL; - } - sunxi_rtc_setaie(0, chip); writel(0, chip->base + SUNXI_ALRM_DHMS); usleep_range(100, 300); -- cgit v0.10.2 From 9c5150b31b49e3d89c52df9b1c1ebcea4e665ec3 Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Fri, 12 Jun 2015 11:10:16 +0800 Subject: rtc: NTP: Add CONFIG_RTC_SYSTOHC_DEVICE for NTP synchronization Currently, CONFIG_RTC_SYSTOHC uses CONFIG_RTC_HCTOSYS_DEVICE which is originally used by CONFIG_RTC_HCTOSYS, but this rtc device has some limiations, for example, it must be battery-backed, be able to work with irq off and through system suspension, etc. So add CONFIG_RTC_SYSTOHC_DEVICE used exclusively for CONFIG_RTC_SYSTOHC, it is more lenient compared to CONFIG_RTC_HCTOSYS_DEVICE, and could be assigned any available RTC in the system. Default value is CONFIG_RTC_HCTOSYS_DEVICE which is "rtc0" by default. After this patch, NTP will sync up "rtc0" by default. Cc: Paul Bolle Signed-off-by: Xunlei Pang Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index c94bb6a..efaff36 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -25,17 +25,9 @@ config RTC_HCTOSYS the value read from a specified RTC device. This is useful to avoid unnecessary fsck runs at boot time, and to network better. -config RTC_SYSTOHC - bool "Set the RTC time based on NTP synchronization" - default y - help - If you say yes here, the system time (wall clock) will be stored - in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11 - minutes if userspace reports synchronized NTP status. - config RTC_HCTOSYS_DEVICE string "RTC used to set the system time" - depends on RTC_HCTOSYS = y || RTC_SYSTOHC = y + depends on RTC_HCTOSYS default "rtc0" help The RTC device that will be used to (re)initialize the system @@ -56,6 +48,25 @@ config RTC_HCTOSYS_DEVICE sleep states. Do not specify an RTC here unless it stays powered during all this system's supported sleep states. +config RTC_SYSTOHC + bool "Set the RTC time based on NTP synchronization" + default y + help + If you say yes here, the system time (wall clock) will be stored + in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11 + minutes if userspace reports synchronized NTP status. + +config RTC_SYSTOHC_DEVICE + string "RTC used to synchronize NTP adjustment" + depends on RTC_SYSTOHC + default RTC_HCTOSYS_DEVICE if RTC_HCTOSYS + default "rtc0" + help + The RTC device used for NTP synchronization. The main difference + between RTC_HCTOSYS_DEVICE and RTC_SYSTOHC_DEVICE is that this + one can sleep when setting time, because it runs in the workqueue + context. + config RTC_DEBUG bool "RTC debug support" help diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c index 7728d5e..b4a68ff 100644 --- a/drivers/rtc/systohc.c +++ b/drivers/rtc/systohc.c @@ -31,7 +31,7 @@ int rtc_set_ntp_time(struct timespec64 now) else rtc_time64_to_tm(now.tv_sec + 1, &tm); - rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); + rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE); if (rtc) { /* rtc_hctosys exclusively uses UTC, so we call set_time here, * not set_mmss. */ -- cgit v0.10.2 From 460ea8d70db1ffd9a5d6996c240c34458473334f Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Fri, 12 Jun 2015 11:10:17 +0800 Subject: sparc: time: Replace update_persistent_clock() with CONFIG_RTC_SYSTOHC On Sparc systems, update_persistent_clock() uses RTC drivers to do the job, it makes more sense to hand it over to CONFIG_RTC_SYSTOHC. In the long run, all the update_persistent_clock() should migrate to proper class RTC drivers if any and use CONFIG_RTC_SYSTOHC instead. Signed-off-by: Xunlei Pang Acked-by: David S. Miller Signed-off-by: Alexandre Belloni diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index e49502a..56442d2 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -25,6 +25,7 @@ config SPARC select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select RTC_CLASS select RTC_DRV_M48T59 + select RTC_SYSTOHC select HAVE_DMA_ATTRS select HAVE_DMA_API_DEBUG select HAVE_ARCH_JUMP_LABEL if SPARC64 @@ -35,7 +36,6 @@ config SPARC select HAVE_BPF_JIT select HAVE_DEBUG_BUGVERBOSE select GENERIC_SMP_IDLE_THREAD - select GENERIC_CMOS_UPDATE select GENERIC_CLOCKEVENTS select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 8caf45e..c9692f3 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -65,8 +64,6 @@ DEFINE_PER_CPU(struct clock_event_device, sparc32_clockevent); DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); -static int set_rtc_mmss(unsigned long); - unsigned long profile_pc(struct pt_regs *regs) { extern char __copy_user_begin[], __copy_user_end[]; @@ -87,11 +84,6 @@ EXPORT_SYMBOL(profile_pc); volatile u32 __iomem *master_l10_counter; -int update_persistent_clock(struct timespec now) -{ - return set_rtc_mmss(now.tv_sec); -} - irqreturn_t notrace timer_interrupt(int dummy, void *dev_id) { if (timer_cs_enabled) { @@ -362,16 +354,3 @@ void __init time_init(void) sbus_time_init(); } - -static int set_rtc_mmss(unsigned long secs) -{ - struct rtc_device *rtc = rtc_class_open("rtc0"); - int err = -1; - - if (rtc) { - err = rtc_set_mmss(rtc, secs); - rtc_class_close(rtc); - } - - return err; -} diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index edbbeb1..2e6035c 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -394,19 +393,6 @@ static struct sparc64_tick_ops hbtick_operations __read_mostly = { static unsigned long timer_ticks_per_nsec_quotient __read_mostly; -int update_persistent_clock(struct timespec now) -{ - struct rtc_device *rtc = rtc_class_open("rtc0"); - int err = -1; - - if (rtc) { - err = rtc_set_mmss(rtc, now.tv_sec); - rtc_class_close(rtc); - } - - return err; -} - unsigned long cmos_regs; EXPORT_SYMBOL(cmos_regs); -- cgit v0.10.2 From c86a6c28957a9e8e9a71582a32e96971ad411ffe Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Fri, 12 Jun 2015 11:10:18 +0800 Subject: rtc: interface: Remove rtc_set_mmss() Now rtc_set_mmss() has no users, just remove it. We still have rtc_set_time() doing similar things. Signed-off-by: Xunlei Pang Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index a6b14c2..11b6390 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -91,51 +91,6 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) } EXPORT_SYMBOL_GPL(rtc_set_time); -int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) -{ - int err; - - err = mutex_lock_interruptible(&rtc->ops_lock); - if (err) - return err; - - if (!rtc->ops) - err = -ENODEV; - else if (rtc->ops->set_mmss64) - err = rtc->ops->set_mmss64(rtc->dev.parent, secs); - else if (rtc->ops->set_mmss) - err = rtc->ops->set_mmss(rtc->dev.parent, secs); - else if (rtc->ops->read_time && rtc->ops->set_time) { - struct rtc_time new, old; - - err = rtc->ops->read_time(rtc->dev.parent, &old); - if (err == 0) { - rtc_time64_to_tm(secs, &new); - - /* - * avoid writing when we're going to change the day of - * the month. We will retry in the next minute. This - * basically means that if the RTC must not drift - * by more than 1 minute in 11 minutes. - */ - if (!((old.tm_hour == 23 && old.tm_min == 59) || - (new.tm_hour == 23 && new.tm_min == 59))) - err = rtc->ops->set_time(rtc->dev.parent, - &new); - } - } else { - err = -EINVAL; - } - - pm_stay_awake(rtc->dev.parent); - mutex_unlock(&rtc->ops_lock); - /* A timer might have just expired */ - schedule_work(&rtc->irqwork); - - return err; -} -EXPORT_SYMBOL_GPL(rtc_set_mmss); - static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm) { int err; diff --git a/include/linux/rtc.h b/include/linux/rtc.h index b361603..3359f04 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -168,7 +168,6 @@ extern void devm_rtc_device_unregister(struct device *dev, extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); -extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs); extern int rtc_set_ntp_time(struct timespec64 now); int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm); extern int rtc_read_alarm(struct rtc_device *rtc, -- cgit v0.10.2 From b2bd2370a25b78a7090ac701836d414cdb731bea Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 9 Jun 2015 11:15:35 +0200 Subject: rtc: efi: use correct EFI 'epoch' The rtc-efi driver declares that the EFI 'epoch' is 1/1/1998, but the UEFI spec does not define it at all. It does define a range of [1900, 9999] for the 'Year' member of the EFI_TIME struct, so let's use 1900 as the minimum year and not 1998. Also, move the validation of the year to the convert_from_efi_time() routine where all other EFI_TIME fields are validated as well. This prevents rtc_read_time() failures when the RTC that backs the EFI time services is set to a date before 1998, e.g., when it has lost power. This also optimizes the compute_wday() routine, by replacing the for loop with a simple arithmetic expression, and by reusing the yearday value that we need to compute anyway when populating the rtc_time::tm_yday field. Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: rtc-linux@googlegroups.com Signed-off-by: Ard Biesheuvel Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index c5fbabb..3806961 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c @@ -24,10 +24,6 @@ #include #define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT) -/* - * EFI Epoch is 1/1/1998 - */ -#define EFI_RTC_EPOCH 1998 /* * returns day of the year [0-365] @@ -38,31 +34,24 @@ compute_yday(efi_time_t *eft) /* efi_time_t.month is in the [1-12] so, we need -1 */ return rtc_year_days(eft->day, eft->month - 1, eft->year); } + /* * returns day of the week [0-6] 0=Sunday - * - * Don't try to provide a year that's before 1998, please ! */ static int -compute_wday(efi_time_t *eft) +compute_wday(efi_time_t *eft, int yday) { - int y; - int ndays = 0; - - if (eft->year < EFI_RTC_EPOCH) { - pr_err("EFI year < " __stringify(EFI_RTC_EPOCH) ", invalid date\n"); - return -1; - } - - for (y = EFI_RTC_EPOCH; y < eft->year; y++) - ndays += 365 + (is_leap_year(y) ? 1 : 0); - - ndays += compute_yday(eft); + int ndays = eft->year * (365 % 7) + + (eft->year - 1) / 4 + - (eft->year - 1) / 100 + + (eft->year - 1) / 400 + + yday; /* - * 4=1/1/1998 was a Thursday + * 1/1/0000 may or may not have been a Sunday (if it ever existed at + * all) but assuming it was makes this calculation work correctly. */ - return (ndays + 4) % 7; + return ndays % 7; } static void @@ -103,16 +92,16 @@ convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime) if (!eft->month || eft->month > 12) return false; wtime->tm_mon = eft->month - 1; - wtime->tm_year = eft->year - 1900; - /* day of the week [0-6], Sunday=0 */ - wtime->tm_wday = compute_wday(eft); - if (wtime->tm_wday < 0) + if (eft->year < 1900 || eft->year > 9999) return false; + wtime->tm_year = eft->year - 1900; /* day in the year [1-365]*/ wtime->tm_yday = compute_yday(eft); + /* day of the week [0-6], Sunday=0 */ + wtime->tm_wday = compute_wday(eft, wtime->tm_yday); switch (eft->daylight & EFI_ISDST) { case EFI_ISDST: -- cgit v0.10.2 From fe5613360102de0dd79102ec2d2e006a5eeb00d8 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 8 Jun 2015 16:16:14 +0200 Subject: rtc: mv: use BIT() Use bit instead of hand coding the shift and correct the 24 hour vs 24 hours typo. Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 4237622..7e84bb4 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,7 @@ #define RTC_MINUTES_OFFS 8 #define RTC_HOURS_OFFS 16 #define RTC_WDAY_OFFS 24 -#define RTC_HOURS_12H_MODE (1 << 22) /* 12 hours mode */ +#define RTC_HOURS_12H_MODE BIT(22) /* 12 hour mode */ #define RTC_DATE_REG_OFFS 4 #define RTC_MDAY_OFFS 0 @@ -33,7 +34,7 @@ #define RTC_ALARM_TIME_REG_OFFS 8 #define RTC_ALARM_DATE_REG_OFFS 0xc -#define RTC_ALARM_VALID (1 << 7) +#define RTC_ALARM_VALID BIT(7) #define RTC_ALARM_INTERRUPT_MASK_REG_OFFS 0x10 #define RTC_ALARM_INTERRUPT_CASUE_REG_OFFS 0x14 -- cgit v0.10.2 From 4042a1475ef5cb290f5fedd5ef8de3e1114c55cd Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 8 Jun 2015 16:16:15 +0200 Subject: rtc: mv: correct 24 hour error message The driver can't accommodate the 12 hour mode but the error message states that the 24 hour mode is not supported. Also fix the typos (hour vs hours). Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 7e84bb4..7f50d2e 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -78,7 +78,7 @@ static int mv_rtc_read_time(struct device *dev, struct rtc_time *tm) second = rtc_time & 0x7f; minute = (rtc_time >> RTC_MINUTES_OFFS) & 0x7f; - hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f; /* assume 24 hours mode */ + hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f; /* assume 24 hour mode */ wday = (rtc_time >> RTC_WDAY_OFFS) & 0x7; day = rtc_date & 0x3f; @@ -109,7 +109,7 @@ static int mv_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) second = rtc_time & 0x7f; minute = (rtc_time >> RTC_MINUTES_OFFS) & 0x7f; - hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f; /* assume 24 hours mode */ + hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f; /* assume 24 hour mode */ wday = (rtc_time >> RTC_WDAY_OFFS) & 0x7; day = rtc_date & 0x3f; @@ -240,10 +240,10 @@ static int __init mv_rtc_probe(struct platform_device *pdev) if (!IS_ERR(pdata->clk)) clk_prepare_enable(pdata->clk); - /* make sure the 24 hours mode is enabled */ + /* make sure the 24 hour mode is enabled */ rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS); if (rtc_time & RTC_HOURS_12H_MODE) { - dev_err(&pdev->dev, "24 Hours mode not supported.\n"); + dev_err(&pdev->dev, "12 Hour mode is enabled but not supported.\n"); ret = -EINVAL; goto out; } -- cgit v0.10.2 From 45b4c85b71bbe691329983c9bf9877392700edc3 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Sat, 13 Jun 2015 21:16:56 +0800 Subject: rtc: gemini: fix cocci warnings Use resource_size function on resource object instead of explicit computation. No need to set .owner here. The core will do it. Remove .owner field if calls are used which set it automatically Signed-off-by: Fengguang Wu Acked-by: Hans Ulli Kroll Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c index 5fc17df..35f4486 100644 --- a/drivers/rtc/rtc-gemini.c +++ b/drivers/rtc/rtc-gemini.c @@ -139,7 +139,7 @@ static int gemini_rtc_probe(struct platform_device *pdev) return -ENODEV; rtc->rtc_base = devm_ioremap(dev, res->start, - res->end - res->start + 1); + resource_size(res)); ret = devm_request_irq(dev, rtc->rtc_irq, gemini_rtc_interrupt, IRQF_SHARED, pdev->name, dev); @@ -167,7 +167,6 @@ static int gemini_rtc_remove(struct platform_device *pdev) static struct platform_driver gemini_rtc_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = gemini_rtc_probe, .remove = gemini_rtc_remove, -- cgit v0.10.2 From 4be1f6bbd1e968ab02653c28eababd9480dfff77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sat, 13 Jun 2015 12:34:04 +0200 Subject: rtc: hym8563: make the irq optional Sometimes the irq line is not connected to any soc-pin. This does not hinder basic timekeeping functionality of the rtc, so probe should not fail in this case. Signed-off-by: Heiko Stuebner Signed-off-by: Alexandre Belloni diff --git a/Documentation/devicetree/bindings/rtc/haoyu,hym8563.txt b/Documentation/devicetree/bindings/rtc/haoyu,hym8563.txt index 5c199ee..a8934fe 100644 --- a/Documentation/devicetree/bindings/rtc/haoyu,hym8563.txt +++ b/Documentation/devicetree/bindings/rtc/haoyu,hym8563.txt @@ -6,11 +6,11 @@ as well as a clock output of up to 32kHz. Required properties: - compatible: should be: "haoyu,hym8563" - reg: i2c address -- interrupts: rtc alarm/event interrupt - #clock-cells: the value should be 0 Optional properties: - clock-output-names: From common clock binding +- interrupts: rtc alarm/event interrupt Example: diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index 0f710e9..e9da795 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -548,14 +548,16 @@ static int hym8563_probe(struct i2c_client *client, return ret; } - ret = devm_request_threaded_irq(&client->dev, client->irq, - NULL, hym8563_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - client->name, hym8563); - if (ret < 0) { - dev_err(&client->dev, "irq %d request failed, %d\n", - client->irq, ret); - return ret; + if (client->irq > 0) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, hym8563_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + client->name, hym8563); + if (ret < 0) { + dev_err(&client->dev, "irq %d request failed, %d\n", + client->irq, ret); + return ret; + } } /* check state of calendar information */ -- cgit v0.10.2 From e3edd67141a1ea5294e54b17fee5becf1090f5d4 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 20 Apr 2015 19:51:34 -0500 Subject: rtc: ds1307: Enable the mcp794xx alarm after programming time Alarm interrupt enable register is at offset 0x7, while the time registers for the alarm follow that. When we program Alarm interrupt enable prior to programming the time, it is possible that previous time value could be close or match at the time of alarm enable resulting in interrupt trigger which is unexpected (and does not match the time we expect it to trigger). To prevent this scenario from occuring, program the ALM0_EN bit only after the alarm time is appropriately programmed. Ofcourse, I2C programming is non-atomic, so there are loopholes where the interrupt wont trigger if the time requested is in the past at the time of programming the ALM0_EN bit. However, we will not have unexpected interrupts while the time is programmed after the interrupt are enabled. Signed-off-by: Nishanth Menon Reviewed-by: Grygorii Strashko Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 4ffabb3..6e76de1 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -742,17 +742,17 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t) regs[6] &= ~MCP794XX_BIT_ALMX_IF; /* Set alarm match: second, minute, hour, day, date, month. */ regs[6] |= MCP794XX_MSK_ALMX_MATCH; - - if (t->enabled) - regs[0] |= MCP794XX_BIT_ALM0_EN; - else - regs[0] &= ~MCP794XX_BIT_ALM0_EN; + /* Disable interrupt. We will not enable until completely programmed */ + regs[0] &= ~MCP794XX_BIT_ALM0_EN; ret = ds1307->write_block_data(client, MCP794XX_REG_CONTROL, 10, regs); if (ret < 0) return ret; - return 0; + if (!t->enabled) + return 0; + regs[0] |= MCP794XX_BIT_ALM0_EN; + return i2c_smbus_write_byte_data(client, MCP794XX_REG_CONTROL, regs[0]); } static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled) -- cgit v0.10.2 From cd1420d3a90944e677987ca8c56f1cd22ecd1b51 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 12 May 2015 23:27:02 +0200 Subject: rtc: pfc8563: fix uninitialized variable warning Gcc is unable to prove that alm_pending is always initialized when it is used, so it prints a harmless warning: drivers/rtc/rtc-pcf8563.c: In function 'pcf8563_probe': drivers/rtc/rtc-pcf8563.c:449:5: warning: 'alm_pending' may be used uninitialized in this function [-Wmaybe-uninitialized] This uses the same conditional expression that is used inside of the pcf8563_get_alarm_mode() function, to help gcc figure it out and shut up that warning, and make the ARM defconfigs build again with no warnings. Signed-off-by: Arnd Bergmann Fixes: a45d528aab8b ("rtc: pcf8563: clear expired alarm at boot time") Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index fc564d3..8bba022 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -432,7 +432,7 @@ static int pcf8563_probe(struct i2c_client *client, } err = pcf8563_get_alarm_mode(client, NULL, &alm_pending); - if (err < 0) { + if (err) { dev_err(&client->dev, "%s: read error\n", __func__); return err; } -- cgit v0.10.2 From 4733f39794e33e30ac06b38bcc6f4228adbf09cc Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 26 May 2015 11:13:04 +0200 Subject: MAINTAINERS: Add RTC subsystem repository The RTC subsystem patches are available through my kernel.org repository. Signed-off-by: Alexandre Belloni diff --git a/MAINTAINERS b/MAINTAINERS index 16df5b1..5dc60b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8245,6 +8245,7 @@ M: Alessandro Zummo M: Alexandre Belloni L: rtc-linux@googlegroups.com Q: http://patchwork.ozlabs.org/project/rtc-linux/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git S: Maintained F: Documentation/rtc.txt F: drivers/rtc/ -- cgit v0.10.2 From 35cd49c11174322c3e998eff8f05acc5a55dcc9b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 9 May 2015 16:40:25 +0200 Subject: rtc: Properly sort Makefile Properly sort the Makefile by filename Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 7cc7cec..5a893dd9 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -20,8 +20,8 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o # Keep the list ordered. -obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o +obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o @@ -43,7 +43,6 @@ obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o -obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o @@ -70,9 +69,9 @@ obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o -obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o obj-$(CONFIG_RTC_DRV_ISL12057) += rtc-isl12057.o +obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o @@ -83,32 +82,35 @@ obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o -obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o -obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o -obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o -obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o -obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o +obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o +obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o +obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o +obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o -obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o +obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o +obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o +obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o +obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o +obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o -obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o +obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o obj-$(CONFIG_RTC_DRV_PALMAS) += rtc-palmas.o obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o +obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o +obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o +obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o -obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o -obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o -obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o obj-$(CONFIG_RTC_DRV_PM8XXX) += rtc-pm8xxx.o @@ -131,6 +133,7 @@ obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o obj-$(CONFIG_RTC_DRV_S5M) += rtc-s5m.o obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o +obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o @@ -142,10 +145,10 @@ obj-$(CONFIG_RTC_DRV_SUNXI) += rtc-sunxi.o obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o -obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o obj-$(CONFIG_RTC_DRV_TPS80031) += rtc-tps80031.o +obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o @@ -154,6 +157,3 @@ obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o -obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o -obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o -obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o -- cgit v0.10.2 From 98ab2c938c7f77741ed09ee8ce21e8d7770669ef Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 9 May 2015 21:21:54 +0200 Subject: rtc: whitespace fixes Some entries in the Kconfig are improperly indented with spaces instead of tabs. Also fix whitespaces in Makefile. Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index efaff36..6db0a9d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -12,7 +12,7 @@ menuconfig RTC_CLASS select RTC_LIB help Generic RTC class support. If you say yes here, you will - be allowed to plug one or more RTCs to your system. You will + be allowed to plug one or more RTCs to your system. You will probably want to enable one or more of the interfaces below. if RTC_CLASS @@ -165,10 +165,10 @@ config RTC_DRV_88PM80X will be called rtc-88pm80x. config RTC_DRV_ABB5ZES3 - depends on I2C - select REGMAP_I2C - tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3" - help + depends on I2C + select REGMAP_I2C + tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3" + help If you say yes here you get support for the Abracon AB-RTCMC-32.768kHz-B5ZE-S3 I2C RTC chip. @@ -376,10 +376,10 @@ config RTC_DRV_ISL12022 will be called rtc-isl12022. config RTC_DRV_ISL12057 - depends on I2C - select REGMAP_I2C - tristate "Intersil ISL12057" - help + depends on I2C + select REGMAP_I2C + tristate "Intersil ISL12057" + help If you say yes here you get support for the Intersil ISL12057 I2C RTC chip. @@ -614,13 +614,13 @@ comment "SPI RTC drivers" if SPI_MASTER config RTC_DRV_M41T93 - tristate "ST M41T93" - help - If you say yes here you will get support for the - ST M41T93 SPI RTC chip. + tristate "ST M41T93" + help + If you say yes here you will get support for the + ST M41T93 SPI RTC chip. - This driver can also be built as a module. If so, the module - will be called rtc-m41t93. + This driver can also be built as a module. If so, the module + will be called rtc-m41t93. config RTC_DRV_M41T94 tristate "ST M41T94" @@ -1211,7 +1211,7 @@ config RTC_DRV_SH Say Y here to enable support for the on-chip RTC found in most SuperH processors. - To compile this driver as a module, choose M here: the + To compile this driver as a module, choose M here: the module will be called rtc-sh. config RTC_DRV_VR41XX @@ -1310,14 +1310,14 @@ config RTC_DRV_GENERIC just say Y. config RTC_DRV_PXA - tristate "PXA27x/PXA3xx" - depends on ARCH_PXA - help - If you say Y here you will get access to the real time clock - built into your PXA27x or PXA3xx CPU. - - This RTC driver uses PXA RTC registers available since pxa27x - series (RDxR, RYxR) instead of legacy RCNR, RTAR. + tristate "PXA27x/PXA3xx" + depends on ARCH_PXA + help + If you say Y here you will get access to the real time clock + built into your PXA27x or PXA3xx CPU. + + This RTC driver uses PXA RTC registers available since pxa27x + series (RDxR, RYxR) instead of legacy RCNR, RTAR. config RTC_DRV_VT8500 tristate "VIA/WonderMedia 85xx SoC RTC" diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 5a893dd9..5ea5370 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -14,14 +14,14 @@ ifdef CONFIG_RTC_DRV_EFI rtc-core-y += rtc-efi-platform.o endif -rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o -rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o -rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o +rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o +rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o +rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o # Keep the list ordered. obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o -obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o +obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o @@ -57,7 +57,7 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o obj-$(CONFIG_RTC_DRV_DS1685_FAMILY) += rtc-ds1685.o obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o -obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o +obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o @@ -85,7 +85,7 @@ obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o -obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o +obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o -- cgit v0.10.2 From 3783055ef4cf096910f670f9a1a32e32db08559b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 8 Jun 2015 19:27:37 +0200 Subject: rtc: remove useless I2C dependencies Multiple options depend on I2C but are already under under if I2C. Remove those useless dependencies. Signed-off-by: Alexandre Belloni diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6db0a9d..ca3432c 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -146,7 +146,7 @@ if I2C config RTC_DRV_88PM860X tristate "Marvell 88PM860x" - depends on I2C && MFD_88PM860X + depends on MFD_88PM860X help If you say yes here you get support for RTC function in Marvell 88PM860x chips. @@ -156,7 +156,7 @@ config RTC_DRV_88PM860X config RTC_DRV_88PM80X tristate "Marvell 88PM80x" - depends on I2C && MFD_88PM800 + depends on MFD_88PM800 help If you say yes here you get support for RTC function in Marvell 88PM80x chips. @@ -165,7 +165,6 @@ config RTC_DRV_88PM80X will be called rtc-88pm80x. config RTC_DRV_ABB5ZES3 - depends on I2C select REGMAP_I2C tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3" help @@ -215,7 +214,6 @@ config RTC_DRV_DS1307 config RTC_DRV_DS1374 tristate "Dallas/Maxim DS1374" - depends on I2C help If you say yes here you get support for Dallas Semiconductor DS1374 real-time clock chips. If an interrupt is associated @@ -243,7 +241,6 @@ config RTC_DRV_DS1672 config RTC_DRV_DS3232 tristate "Dallas/Maxim DS3232" - depends on I2C help If you say yes here you get support for Dallas Semiconductor DS3232 real-time clock chips. If an interrupt is associated @@ -254,7 +251,7 @@ config RTC_DRV_DS3232 config RTC_DRV_HYM8563 tristate "Haoyu Microelectronics HYM8563" - depends on I2C && OF + depends on OF help Say Y to enable support for the HYM8563 I2C RTC chip. Apart from the usual rtc functions it provides a clock output of @@ -376,7 +373,6 @@ config RTC_DRV_ISL12022 will be called rtc-isl12022. config RTC_DRV_ISL12057 - depends on I2C select REGMAP_I2C tristate "Intersil ISL12057" help -- cgit v0.10.2