From 9852023d204b97324e7fa84f50f28a9d602b79fb Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 20 Mar 2019 12:30:08 +0100 Subject: rtc: sh: stop resetting time to epoch There is no point in resetting the time to epoch as this means that userspace will never get the valuable information that time is actually invalid. Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven [Anders Roxell : remove unused variable r] Signed-off-by: Anders Roxell Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sh.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/rtc/rtc-sh.c') diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index d417b203cbc5..7fffe6da9478 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -276,6 +276,9 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) struct sh_rtc *rtc = dev_get_drvdata(dev); unsigned int sec128, sec2, yr, yr100, cf_bit; + if (!(readb(rtc->regbase + RCR2) & RCR2_RTCEN)) + return -EINVAL; + do { unsigned int tmp; @@ -466,7 +469,6 @@ static int __init sh_rtc_probe(struct platform_device *pdev) { struct sh_rtc *rtc; struct resource *res; - struct rtc_time r; char clk_name[6]; int clk_id, ret; @@ -600,12 +602,6 @@ static int __init sh_rtc_probe(struct platform_device *pdev) rtc->rtc_dev->max_user_freq = 256; - /* reset rtc to epoch 0 if time is invalid */ - if (rtc_read_time(rtc->rtc_dev, &r) < 0) { - rtc_time_to_tm(0, &r); - rtc_set_time(rtc->rtc_dev, &r); - } - device_init_wakeup(&pdev->dev, 1); return 0; -- cgit From 1097998d27da39578542e79ff865b4d74e755cd0 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 20 Mar 2019 12:30:09 +0100 Subject: rtc: sh: fix possible race condition The IRQ is requested before the struct rtc is allocated and registered, but this struct is used in the IRQ handler. This may lead to a NULL pointer dereference. Switch to devm_rtc_allocate_device/rtc_register_device to allocate the rtc struct before requesting the IRQ. Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sh.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/rtc/rtc-sh.c') diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 7fffe6da9478..d9e67ca4b7b9 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -530,6 +530,10 @@ static int __init sh_rtc_probe(struct platform_device *pdev) rtc->clk = NULL; } + rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); + clk_enable(rtc->clk); rtc->capabilities = RTC_DEF_CAPABILITIES; @@ -593,15 +597,13 @@ static int __init sh_rtc_probe(struct platform_device *pdev) sh_rtc_setaie(&pdev->dev, 0); sh_rtc_setcie(&pdev->dev, 0); - rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, "sh", - &sh_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc->rtc_dev)) { - ret = PTR_ERR(rtc->rtc_dev); - goto err_unmap; - } - + rtc->rtc_dev->ops = &sh_rtc_ops; rtc->rtc_dev->max_user_freq = 256; + ret = rtc_register_device(rtc->rtc_dev); + if (ret) + goto err_unmap; + device_init_wakeup(&pdev->dev, 1); return 0; -- cgit From beee05dfbead2331a3183dee8ddcf10066278355 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 20 Mar 2019 12:30:10 +0100 Subject: rtc: sh: set range The SH RTC is a BCD RTC with some version having 4 digits for the year. The range for the RTCs with only 2 digits for the year was unfortunately shifted to handle 1999 to 2098. Reviewed-by: Geert Uytterhoeven Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sh.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/rtc/rtc-sh.c') diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index d9e67ca4b7b9..4cca54aa6e24 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -600,6 +600,14 @@ static int __init sh_rtc_probe(struct platform_device *pdev) rtc->rtc_dev->ops = &sh_rtc_ops; rtc->rtc_dev->max_user_freq = 256; + if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { + rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900; + rtc->rtc_dev->range_max = RTC_TIMESTAMP_END_9999; + } else { + rtc->rtc_dev->range_min = mktime64(1999, 1, 1, 0, 0, 0); + rtc->rtc_dev->range_max = mktime64(2098, 12, 31, 23, 59, 59); + } + ret = rtc_register_device(rtc->rtc_dev); if (ret) goto err_unmap; -- cgit