diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-27 09:24:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-27 09:24:24 -0700 |
commit | c7b7eefa57ae3c8802fdec7d07ac4df6c49d1e7a (patch) | |
tree | 7aac7dee4d94113648b210fe9dc4ba181dfc1ccf /drivers/rtc/rtc-ab8500.c | |
parent | e5585453498907080c456ec5b51131867ed6d095 (diff) | |
parent | 3822d1bb0df18aa28930f19bc46e0704aea1be0f (diff) | |
download | lwn-c7b7eefa57ae3c8802fdec7d07ac4df6c49d1e7a.tar.gz lwn-c7b7eefa57ae3c8802fdec7d07ac4df6c49d1e7a.zip |
Merge tag 'rtc-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni:
"This cycle, there were mostly non urgent fixes in drivers. I also
finally unexported the non managed registration.
Subsystem:
- non devm managed registration is now removed from the driver API
- all the unnecessary rtc_valid_tm() calls have been removed
Drivers:
- abx80X: watchdog support
- cmos: fix non ACPI support
- sc27xx: fix alarm support
- Remove a possible sysfs race condition for ab8500, ds1307, ds1685,
isl1208
- Fix a possible race condition where an irq handler may be called
before the rtc_device struct is allocated for mt6397, pl030,
menelaus, armada38x"
* tag 'rtc-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (54 commits)
rtc: sc27xx: Always read normal alarm when registering RTC device
rtc: sc27xx: Add check to see if need to enable the alarm interrupt
rtc: sc27xx: Remove interrupts disable and clear in probe()
rtc: sc27xx: Clear SPG value update interrupt status
rtc: sc27xx: Set wakeup capability before registering rtc device
rtc: s35390a: Change buf's type to u8 in s35390a_init
rtc: ds1307: fix ds1339 wakealarm support
rtc: ds1685: simplify getting .driver_data
rtc: m41t80: mark expected switch fall-through
rtc: tegra: Propagate errors from platform_get_irq()
rtc: cmos: Remove the `use_acpi_alarm' module parameter for !ACPI
rtc: cmos: Fix non-ACPI undefined reference to `hpet_rtc_interrupt'
rtc: mv: let the core handle invalid alarms
rtc: vr41xx: switch to rtc_time64_to_tm/rtc_tm_to_time64
rtc: ab8500: remove useless check
rtc: ab8500: let the core handle range
rtc: ab8500: use rtc_add_group
rtc: rs5c348: report error when time is invalid
rtc: rs5c348: remove forward declaration
rtc: rs5c348: remove useless label
...
Diffstat (limited to 'drivers/rtc/rtc-ab8500.c')
-rw-r--r-- | drivers/rtc/rtc-ab8500.c | 96 |
1 files changed, 22 insertions, 74 deletions
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index e28f4401fd35..1f0cbd51ba06 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -46,7 +46,6 @@ #define RTC_STATUS_DATA 0x01 #define COUNTS_PER_SEC (0xF000 / 60) -#define AB8500_RTC_EPOCH 2000 static const u8 ab8500_rtc_time_regs[] = { AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG, @@ -59,23 +58,6 @@ static const u8 ab8500_rtc_alarm_regs[] = { AB8500_RTC_ALRM_MIN_LOW_REG }; -/* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */ -static unsigned long get_elapsed_seconds(int year) -{ - unsigned long secs; - struct rtc_time tm = { - .tm_year = year - 1900, - .tm_mday = 1, - }; - - /* - * This function calculates secs from 1970 and not from - * 1900, even if we supply the offset from year 1900. - */ - rtc_tm_to_time(&tm, &secs); - return secs; -} - static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) { unsigned long timeout = jiffies + HZ; @@ -118,9 +100,6 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) secs = secs / COUNTS_PER_SEC; secs = secs + (mins * 60); - /* Add back the initially subtracted number of seconds */ - secs += get_elapsed_seconds(AB8500_RTC_EPOCH); - rtc_time_to_tm(secs, tm); return 0; } @@ -131,21 +110,8 @@ static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; unsigned long no_secs, no_mins, secs = 0; - if (tm->tm_year < (AB8500_RTC_EPOCH - 1900)) { - dev_dbg(dev, "year should be equal to or greater than %d\n", - AB8500_RTC_EPOCH); - return -EINVAL; - } - - /* Get the number of seconds since 1970 */ rtc_tm_to_time(tm, &secs); - /* - * Convert it to the number of seconds since 01-01-2000 00:00:00, since - * we only have a small counter in the RTC. - */ - secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); - no_mins = secs / 60; no_secs = secs % 60; @@ -202,12 +168,9 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); secs = mins * 60; - /* Add back the initially subtracted number of seconds */ - secs += get_elapsed_seconds(AB8500_RTC_EPOCH); - rtc_time_to_tm(secs, &alarm->time); - return rtc_valid_tm(&alarm->time); + return 0; } static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled) @@ -224,12 +187,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) unsigned long mins, secs = 0, cursec = 0; struct rtc_time curtm; - if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) { - dev_dbg(dev, "year should be equal to or greater than %d\n", - AB8500_RTC_EPOCH); - return -EINVAL; - } - /* Get the number of seconds since 1970 */ rtc_tm_to_time(&alarm->time, &secs); @@ -245,12 +202,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) return -EINVAL; } - /* - * Convert it to the number of seconds since 01-01-2000 00:00:00, since - * we only have a small counter in the RTC. - */ - secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); - mins = secs / 60; buf[2] = mins & 0xFF; @@ -360,15 +311,14 @@ static DEVICE_ATTR(rtc_calibration, S_IRUGO | S_IWUSR, ab8500_sysfs_show_rtc_calibration, ab8500_sysfs_store_rtc_calibration); -static int ab8500_sysfs_rtc_register(struct device *dev) -{ - return device_create_file(dev, &dev_attr_rtc_calibration); -} +static struct attribute *ab8500_rtc_attrs[] = { + &dev_attr_rtc_calibration.attr, + NULL +}; -static void ab8500_sysfs_rtc_unregister(struct device *dev) -{ - device_remove_file(dev, &dev_attr_rtc_calibration); -} +static const struct attribute_group ab8500_rtc_sysfs_files = { + .attrs = ab8500_rtc_attrs, +}; static irqreturn_t rtc_alarm_handler(int irq, void *data) { @@ -429,14 +379,11 @@ static int ab8500_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, true); - rtc = devm_rtc_device_register(&pdev->dev, "ab8500-rtc", - (struct rtc_class_ops *)platid->driver_data, - THIS_MODULE); - if (IS_ERR(rtc)) { - dev_err(&pdev->dev, "Registration failed\n"); - err = PTR_ERR(rtc); - return err; - } + rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + rtc->ops = (struct rtc_class_ops *)platid->driver_data; err = devm_request_threaded_irq(&pdev->dev, irq, NULL, rtc_alarm_handler, IRQF_ONESHOT, @@ -447,22 +394,23 @@ static int ab8500_rtc_probe(struct platform_device *pdev) dev_pm_set_wake_irq(&pdev->dev, irq); platform_set_drvdata(pdev, rtc); - err = ab8500_sysfs_rtc_register(&pdev->dev); - if (err) { - dev_err(&pdev->dev, "sysfs RTC failed to register\n"); - return err; - } - rtc->uie_unsupported = 1; - return 0; + rtc->range_max = (1ULL << 24) * 60 - 1; // 24-bit minutes + 59 secs + rtc->start_secs = RTC_TIMESTAMP_BEGIN_2000; + rtc->set_start_time = true; + + err = rtc_add_group(rtc, &ab8500_rtc_sysfs_files); + if (err) + return err; + + return rtc_register_device(rtc); } static int ab8500_rtc_remove(struct platform_device *pdev) { dev_pm_clear_wake_irq(&pdev->dev); device_init_wakeup(&pdev->dev, false); - ab8500_sysfs_rtc_unregister(&pdev->dev); return 0; } |