11// SPDX-License-Identifier: GPL-2.0-only
2- /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
2+ /*
3+ * pm8xxx RTC driver
4+ *
5+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
6+ * Copyright (c) 2023, Linaro Limited
37 */
48#include <linux/of.h>
59#include <linux/module.h>
10+ #include <linux/nvmem-consumer.h>
611#include <linux/init.h>
712#include <linux/rtc.h>
813#include <linux/platform_device.h>
@@ -49,6 +54,8 @@ struct pm8xxx_rtc_regs {
4954 * @alarm_irq: alarm irq number
5055 * @regs: register description
5156 * @dev: device structure
57+ * @nvmem_cell: nvmem cell for offset
58+ * @offset: offset from epoch in seconds
5259 */
5360struct pm8xxx_rtc {
5461 struct rtc_device * rtc ;
@@ -57,8 +64,60 @@ struct pm8xxx_rtc {
5764 int alarm_irq ;
5865 const struct pm8xxx_rtc_regs * regs ;
5966 struct device * dev ;
67+ struct nvmem_cell * nvmem_cell ;
68+ u32 offset ;
6069};
6170
71+ static int pm8xxx_rtc_read_nvmem_offset (struct pm8xxx_rtc * rtc_dd )
72+ {
73+ size_t len ;
74+ void * buf ;
75+ int rc ;
76+
77+ buf = nvmem_cell_read (rtc_dd -> nvmem_cell , & len );
78+ if (IS_ERR (buf )) {
79+ rc = PTR_ERR (buf );
80+ dev_dbg (rtc_dd -> dev , "failed to read nvmem offset: %d\n" , rc );
81+ return rc ;
82+ }
83+
84+ if (len != sizeof (u32 )) {
85+ dev_dbg (rtc_dd -> dev , "unexpected nvmem cell size %zu\n" , len );
86+ kfree (buf );
87+ return - EINVAL ;
88+ }
89+
90+ rtc_dd -> offset = get_unaligned_le32 (buf );
91+
92+ kfree (buf );
93+
94+ return 0 ;
95+ }
96+
97+ static int pm8xxx_rtc_write_nvmem_offset (struct pm8xxx_rtc * rtc_dd , u32 offset )
98+ {
99+ u8 buf [sizeof (u32 )];
100+ int rc ;
101+
102+ put_unaligned_le32 (offset , buf );
103+
104+ rc = nvmem_cell_write (rtc_dd -> nvmem_cell , buf , sizeof (buf ));
105+ if (rc < 0 ) {
106+ dev_dbg (rtc_dd -> dev , "failed to write nvmem offset: %d\n" , rc );
107+ return rc ;
108+ }
109+
110+ return 0 ;
111+ }
112+
113+ static int pm8xxx_rtc_read_offset (struct pm8xxx_rtc * rtc_dd )
114+ {
115+ if (!rtc_dd -> nvmem_cell )
116+ return 0 ;
117+
118+ return pm8xxx_rtc_read_nvmem_offset (rtc_dd );
119+ }
120+
62121static int pm8xxx_rtc_read_raw (struct pm8xxx_rtc * rtc_dd , u32 * secs )
63122{
64123 const struct pm8xxx_rtc_regs * regs = rtc_dd -> regs ;
@@ -90,6 +149,33 @@ static int pm8xxx_rtc_read_raw(struct pm8xxx_rtc *rtc_dd, u32 *secs)
90149 return 0 ;
91150}
92151
152+ static int pm8xxx_rtc_update_offset (struct pm8xxx_rtc * rtc_dd , u32 secs )
153+ {
154+ u32 raw_secs ;
155+ u32 offset ;
156+ int rc ;
157+
158+ if (!rtc_dd -> nvmem_cell )
159+ return - ENODEV ;
160+
161+ rc = pm8xxx_rtc_read_raw (rtc_dd , & raw_secs );
162+ if (rc )
163+ return rc ;
164+
165+ offset = secs - raw_secs ;
166+
167+ if (offset == rtc_dd -> offset )
168+ return 0 ;
169+
170+ rc = pm8xxx_rtc_write_nvmem_offset (rtc_dd , offset );
171+ if (rc )
172+ return rc ;
173+
174+ rtc_dd -> offset = offset ;
175+
176+ return 0 ;
177+ }
178+
93179/*
94180 * Steps to write the RTC registers.
95181 * 1. Disable alarm if enabled.
@@ -99,23 +185,15 @@ static int pm8xxx_rtc_read_raw(struct pm8xxx_rtc *rtc_dd, u32 *secs)
99185 * 5. Enable rtc if disabled in step 2.
100186 * 6. Enable alarm if disabled in step 1.
101187 */
102- static int pm8xxx_rtc_set_time (struct device * dev , struct rtc_time * tm )
188+ static int __pm8xxx_rtc_set_time (struct pm8xxx_rtc * rtc_dd , u32 secs )
103189{
104- struct pm8xxx_rtc * rtc_dd = dev_get_drvdata (dev );
105190 const struct pm8xxx_rtc_regs * regs = rtc_dd -> regs ;
106191 u8 value [NUM_8_BIT_RTC_REGS ];
107192 bool alarm_enabled ;
108- u32 secs ;
109193 int rc ;
110194
111- if (!rtc_dd -> allow_set_time )
112- return - ENODEV ;
113-
114- secs = rtc_tm_to_time64 (tm );
115195 put_unaligned_le32 (secs , value );
116196
117- dev_dbg (dev , "set time: %ptRd %ptRt (%u)\n" , tm , tm , secs );
118-
119197 rc = regmap_update_bits_check (rtc_dd -> regmap , regs -> alarm_ctrl ,
120198 regs -> alarm_en , 0 , & alarm_enabled );
121199 if (rc )
@@ -158,6 +236,27 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
158236 return 0 ;
159237}
160238
239+ static int pm8xxx_rtc_set_time (struct device * dev , struct rtc_time * tm )
240+ {
241+ struct pm8xxx_rtc * rtc_dd = dev_get_drvdata (dev );
242+ u32 secs ;
243+ int rc ;
244+
245+ secs = rtc_tm_to_time64 (tm );
246+
247+ if (rtc_dd -> allow_set_time )
248+ rc = __pm8xxx_rtc_set_time (rtc_dd , secs );
249+ else
250+ rc = pm8xxx_rtc_update_offset (rtc_dd , secs );
251+
252+ if (rc )
253+ return rc ;
254+
255+ dev_dbg (dev , "set time: %ptRd %ptRt (%u + %u)\n" , tm , tm ,
256+ secs - rtc_dd -> offset , rtc_dd -> offset );
257+ return 0 ;
258+ }
259+
161260static int pm8xxx_rtc_read_time (struct device * dev , struct rtc_time * tm )
162261{
163262 struct pm8xxx_rtc * rtc_dd = dev_get_drvdata (dev );
@@ -168,10 +267,11 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
168267 if (rc )
169268 return rc ;
170269
270+ secs += rtc_dd -> offset ;
171271 rtc_time64_to_tm (secs , tm );
172272
173- dev_dbg (dev , "read time: %ptRd %ptRt (%u)\n" , tm , tm , secs );
174-
273+ dev_dbg (dev , "read time: %ptRd %ptRt (%u + %u )\n" , tm , tm ,
274+ secs - rtc_dd -> offset , rtc_dd -> offset );
175275 return 0 ;
176276}
177277
@@ -184,6 +284,7 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
184284 int rc ;
185285
186286 secs = rtc_tm_to_time64 (& alarm -> time );
287+ secs -= rtc_dd -> offset ;
187288 put_unaligned_le32 (secs , value );
188289
189290 rc = regmap_update_bits (rtc_dd -> regmap , regs -> alarm_ctrl ,
@@ -223,6 +324,7 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
223324 return rc ;
224325
225326 secs = get_unaligned_le32 (value );
327+ secs += rtc_dd -> offset ;
226328 rtc_time64_to_tm (secs , & alarm -> time );
227329
228330 rc = regmap_read (rtc_dd -> regmap , regs -> alarm_ctrl , & ctrl_reg );
@@ -378,9 +480,23 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
378480 rtc_dd -> allow_set_time = of_property_read_bool (pdev -> dev .of_node ,
379481 "allow-set-time" );
380482
483+ rtc_dd -> nvmem_cell = devm_nvmem_cell_get (& pdev -> dev , "offset" );
484+ if (IS_ERR (rtc_dd -> nvmem_cell )) {
485+ rc = PTR_ERR (rtc_dd -> nvmem_cell );
486+ if (rc != - ENOENT )
487+ return rc ;
488+ rtc_dd -> nvmem_cell = NULL ;
489+ }
490+
381491 rtc_dd -> regs = match -> data ;
382492 rtc_dd -> dev = & pdev -> dev ;
383493
494+ if (!rtc_dd -> allow_set_time ) {
495+ rc = pm8xxx_rtc_read_offset (rtc_dd );
496+ if (rc )
497+ return rc ;
498+ }
499+
384500 rc = pm8xxx_rtc_enable (rtc_dd );
385501 if (rc )
386502 return rc ;
@@ -435,3 +551,4 @@ MODULE_ALIAS("platform:rtc-pm8xxx");
435551MODULE_DESCRIPTION ("PMIC8xxx RTC driver" );
436552MODULE_LICENSE ("GPL v2" );
437553MODULE_AUTHOR ("Anirudh Ghayal <aghayal@codeaurora.org>" );
554+ MODULE_AUTHOR ("Johan Hovold <johan@kernel.org>" );
0 commit comments