diff options
Diffstat (limited to 'drivers/rtc/rtc-tps6586x.c')
| -rw-r--r-- | drivers/rtc/rtc-tps6586x.c | 86 |
1 files changed, 31 insertions, 55 deletions
diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 426901cef14f..54c8429b16bf 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c @@ -1,28 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * rtc-tps6586x.c: RTC driver for TI PMIC TPS6586X * * Copyright (c) 2012, NVIDIA Corporation. * * Author: Laxman Dewangan <ldewangan@nvidia.com> - * - * 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 version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, - * whether express or implied; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA */ #include <linux/device.h> #include <linux/err.h> #include <linux/init.h> +#include <linux/irq.h> #include <linux/kernel.h> #include <linux/mfd/tps6586x.h> #include <linux/module.h> @@ -58,7 +46,6 @@ struct tps6586x_rtc { struct rtc_device *rtc; int irq; bool irq_en; - unsigned long long epoch_start; }; static inline struct device *to_tps6586x_dev(struct device *dev) @@ -68,10 +55,9 @@ static inline struct device *to_tps6586x_dev(struct device *dev) static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); struct device *tps_dev = to_tps6586x_dev(dev); unsigned long long ticks = 0; - unsigned long seconds; + time64_t seconds; u8 buff[6]; int ret; int i; @@ -88,26 +74,20 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm) } seconds = ticks >> 10; - seconds += rtc->epoch_start; - rtc_time_to_tm(seconds, tm); - return rtc_valid_tm(tm); + rtc_time64_to_tm(seconds, tm); + + return 0; } static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); struct device *tps_dev = to_tps6586x_dev(dev); unsigned long long ticks; - unsigned long seconds; + time64_t seconds; u8 buff[5]; int ret; - rtc_tm_to_time(tm, &seconds); - if (seconds < rtc->epoch_start) { - dev_err(dev, "requested time unsupported\n"); - return -EINVAL; - } - seconds -= rtc->epoch_start; + seconds = rtc_tm_to_time64(tm); ticks = (unsigned long long)seconds << 10; buff[0] = (ticks >> 32) & 0xff; @@ -155,9 +135,8 @@ static int tps6586x_rtc_alarm_irq_enable(struct device *dev, static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); struct device *tps_dev = to_tps6586x_dev(dev); - unsigned long seconds; + time64_t seconds; unsigned long ticks; unsigned long rtc_current_time; unsigned long long rticks = 0; @@ -166,12 +145,7 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) int ret; int i; - rtc_tm_to_time(&alrm->time, &seconds); - - if (alrm->enabled && (seconds < rtc->epoch_start)) { - dev_err(dev, "can't set alarm to requested time\n"); - return -EINVAL; - } + seconds = rtc_tm_to_time64(&alrm->time); ret = tps6586x_rtc_alarm_irq_enable(dev, alrm->enabled); if (ret < 0) { @@ -179,7 +153,6 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; } - seconds -= rtc->epoch_start; ret = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD, sizeof(rbuff), rbuff); if (ret < 0) { @@ -210,10 +183,9 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - struct tps6586x_rtc *rtc = dev_get_drvdata(dev); struct device *tps_dev = to_tps6586x_dev(dev); unsigned long ticks; - unsigned long seconds; + time64_t seconds; u8 buff[3]; int ret; @@ -225,9 +197,8 @@ static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ticks = (buff[0] << 16) | (buff[1] << 8) | buff[2]; seconds = ticks >> 10; - seconds += rtc->epoch_start; - rtc_time_to_tm(seconds, &alrm->time); + rtc_time64_to_tm(seconds, &alrm->time); return 0; } @@ -260,9 +231,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) rtc->dev = &pdev->dev; rtc->irq = platform_get_irq(pdev, 0); - /* Set epoch start as 00:00:00:01:01:2009 */ - rtc->epoch_start = mktime(2009, 1, 1, 0, 0, 0); - /* 1 kHz tick mode, enable tick counting */ ret = tps6586x_update(tps_dev, RTC_CTRL, RTC_ENABLE | OSC_SRC_SEL | @@ -273,27 +241,37 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) return ret; } - device_init_wakeup(&pdev->dev, 1); + device_init_wakeup(&pdev->dev, true); platform_set_drvdata(pdev, rtc); - rtc->rtc = devm_rtc_device_register(&pdev->dev, dev_name(&pdev->dev), - &tps6586x_rtc_ops, THIS_MODULE); + rtc->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc->rtc)) { ret = PTR_ERR(rtc->rtc); - dev_err(&pdev->dev, "RTC device register: ret %d\n", ret); goto fail_rtc_register; } + rtc->rtc->ops = &tps6586x_rtc_ops; + rtc->rtc->range_max = (1ULL << 30) - 1; /* 30-bit seconds */ + rtc->rtc->alarm_offset_max = ALM1_VALID_RANGE_IN_SEC; + rtc->rtc->start_secs = mktime64(2009, 1, 1, 0, 0, 0); + rtc->rtc->set_start_time = true; + + irq_set_status_flags(rtc->irq, IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, tps6586x_rtc_irq, - IRQF_ONESHOT | IRQF_EARLY_RESUME, + IRQF_ONESHOT, dev_name(&pdev->dev), rtc); if (ret < 0) { dev_err(&pdev->dev, "request IRQ(%d) failed with ret %d\n", rtc->irq, ret); goto fail_rtc_register; } - disable_irq(rtc->irq); + + ret = devm_rtc_register_device(rtc->rtc); + if (ret) + goto fail_rtc_register; + return 0; fail_rtc_register: @@ -302,13 +280,12 @@ fail_rtc_register: return ret; }; -static int tps6586x_rtc_remove(struct platform_device *pdev) +static void tps6586x_rtc_remove(struct platform_device *pdev) { struct device *tps_dev = to_tps6586x_dev(&pdev->dev); tps6586x_update(tps_dev, RTC_CTRL, 0, RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -337,15 +314,14 @@ static SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_rtc_suspend, static struct platform_driver tps6586x_rtc_driver = { .driver = { .name = "tps6586x-rtc", - .owner = THIS_MODULE, .pm = &tps6586x_pm_ops, }, .probe = tps6586x_rtc_probe, - .remove = tps6586x_rtc_remove, + .remove = tps6586x_rtc_remove, }; module_platform_driver(tps6586x_rtc_driver); -MODULE_ALIAS("platform:rtc-tps6586x"); +MODULE_ALIAS("platform:tps6586x-rtc"); MODULE_DESCRIPTION("TI TPS6586x RTC driver"); MODULE_AUTHOR("Laxman dewangan <ldewangan@nvidia.com>"); MODULE_LICENSE("GPL v2"); |
