summaryrefslogtreecommitdiff
path: root/drivers/rtc/rtc-tps6586x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-tps6586x.c')
-rw-r--r--drivers/rtc/rtc-tps6586x.c86
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");