blob: 8352b6e27089221c5ccbaa2a6cda1f1c16fc44e8 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Real Time Clock driver for Marvell 88PM80x PMIC
4 *
5 * Copyright (c) 2012 Marvell International Ltd.
6 * Wenzeng Chen<wzch@marvell.com>
7 * Qiao Zhou <zhouqiao@marvell.com>
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/regmap.h>
14#include <linux/mfd/core.h>
15#include <linux/mfd/88pm80x.h>
16#include <linux/mfd/pm802.h>
17#include <linux/mfd/pm813.h>
18#include <linux/rtc.h>
19#include <linux/reboot.h>
20#include <linux/sysfs.h>
21
22#define PM800_RTC_COUNTER1 (0xD1)
23#define PM800_RTC_COUNTER2 (0xD2)
24#define PM800_RTC_COUNTER3 (0xD3)
25#define PM800_RTC_COUNTER4 (0xD4)
26#define PM800_RTC_EXPIRE1_1 (0xD5)
27#define PM800_RTC_EXPIRE1_2 (0xD6)
28#define PM800_RTC_EXPIRE1_3 (0xD7)
29#define PM800_RTC_EXPIRE1_4 (0xD8)
30#define PM800_RTC_TRIM1 (0xD9)
31#define PM800_RTC_TRIM2 (0xDA)
32#define PM800_RTC_TRIM3 (0xDB)
33#define PM800_RTC_TRIM4 (0xDC)
34#define PM800_RTC_EXPIRE2_1 (0xDD)
35#define PM800_RTC_EXPIRE2_2 (0xDE)
36#define PM800_RTC_EXPIRE2_3 (0xDF)
37#define PM800_RTC_EXPIRE2_4 (0xE0)
38
39#define PM800_POWER_DOWN_LOG1 (0xE5)
40#define PM800_POWER_DOWN_LOG2 (0xE6)
41#define PM800_CHG_WAKEUP (1 << 1)
42
43/*for save RTC offset*/
44#define PM800_USER_DATA1 (0xEA)
45#define PM800_USER_DATA2 (0xEB)
46#define PM800_USER_DATA3 (0xEC)
47#define PM800_USER_DATA4 (0xED)
48#define PM800_USER_DATA5 (0xEE)
49#define PM800_USER_DATA6 (0xEF)
50
51struct pm80x_rtc_info {
52 struct pm80x_chip *chip;
53 struct regmap *map;
54 struct rtc_device *rtc_dev;
55 struct device *dev;
56 struct delayed_work calib_work;
57
58 int irq;
59 int vrtc;
60 int (*sync) (s64 ticks);
61
62#ifdef CONFIG_RTC_DRV_SA1100
63 struct delayed_work sa1100_sync_work;
64#endif
65};
66
67#ifdef CONFIG_RTC_DRV_SA1100
68extern int sync_time_to_soc(s64 ticks);
69#endif
70
71static void deferred_restart(struct work_struct *dummy)
72{
73 kernel_restart("charger-alarm");
74 BUG();
75}
76static DECLARE_WORK(restart_work, deferred_restart);
77
78#ifdef CONFIG_RTC_DRV_SA1100
79static int pm80x_rtc_read_time(struct device *dev, struct rtc_time *tm);
80static void sa1100_sync_fn(struct work_struct *work)
81{
82 struct pm80x_rtc_info *info =
83 container_of(work, struct pm80x_rtc_info, sa1100_sync_work.work);
84 s64 ticks;
85 struct rtc_time tm;
86 int ret;
87
88 ret = pm80x_rtc_read_time(info->dev, &tm);
89 if (ret < 0) {
90 dev_err(info->dev, "Failed to read time.\n");
91 return;
92 }
93
94 ticks = rtc_tm_to_time64(&tm);
95 if (info->sync)
96 info->sync(ticks);
97}
98#endif
99
100static irqreturn_t rtc_update_handler(int irq, void *data)
101{
102 struct pm80x_rtc_info *info = (struct pm80x_rtc_info *)data;
103 int mask;
104
105 /*
106 * write 1 to clear PM800_ALARM (bit 5 of 0xd0),
107 * which indicates the alarm event has happened;
108 *
109 * write 1 to PM800_ALARM_WAKEUP (bit 4 of 0xd0),
110 * which is must for "expired-alarm powers up system",
111 * it triggers falling edge of RTC_ALARM_WU signal,
112 * while the "power down" triggers the rising edge of RTC_ALARM_WU signal;
113 *
114 * write 0 to PM800_ALARM1_EN (bit 0 0f 0xd0) to disable alarm;
115 */
116 mask = PM800_ALARM | PM800_ALARM_WAKEUP;
117 regmap_update_bits(info->map, PM800_RTC_CONTROL, mask | PM800_ALARM1_EN, mask);
118
119 rtc_update_irq(info->rtc_dev, 1, RTC_AF);
120
121 if (strstr(saved_command_line, "androidboot.mode=charger")) {
122 /*
123 * this bit indicates the system powers up because of "reboot" command
124 * in uboot, so it boots up the generic Android instead of entering
125 * power off charge feature
126 */
127 regmap_update_bits(info->map, PM800_USER_DATA6, (1 << 1), (1 << 1));
128 schedule_work(&restart_work);
129 }
130
131 return IRQ_HANDLED;
132}
133
134static int pm80x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
135{
136 struct pm80x_rtc_info *info = dev_get_drvdata(dev);
137
138 if (enabled)
139 regmap_update_bits(info->map, PM800_RTC_CONTROL,
140 PM800_ALARM1_EN, PM800_ALARM1_EN);
141 else
142 regmap_update_bits(info->map, PM800_RTC_CONTROL,
143 PM800_ALARM1_EN, 0);
144 return 0;
145}
146
147static int pm80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
148{
149 struct pm80x_rtc_info *info = dev_get_drvdata(dev);
150 unsigned char buf[5];
151 s64 ticks, data, base;
152 u32 reg;
153
154 buf[4] = 0x0;
155
156 if (info->chip->type == CHIP_PM801 || info->chip->type == CHIP_PM800)
157 reg = PM800_USER_DATA1;
158 else
159 reg = PM802_RTC_EXPIRE2_1;
160
161 if (CHIP_PM802 == info->chip->type) {
162 if (CHIP_PM802_ID_B1 == info->chip->chip_id ||
163 CHIP_PM802_ID_B0 == info->chip->chip_id) {
164 /* F1[7:4] */
165 regmap_raw_read(info->map, PM802_RTC_MISC14, &buf[4], 1);
166 buf[4] = (buf[4] >> 4) & 0xf;
167 } else {
168 /* CD[7:0] */
169 regmap_raw_read(info->map, PM802S_RTC_SPARED, &buf[4], 1);
170 }
171 } else if (CHIP_PM813 == info->chip->type) {
172 if (CHIP_PM813_ID == info->chip->chip_id) {
173 /* F6[7:0] */
174 regmap_raw_read(info->map, PM813_RTC_MISC19, &buf[4], 1);
175 } else {
176 /* CD[7:0] */
177 regmap_raw_read(info->map, PM813S_RTC_SPARED, &buf[4], 1);
178 }
179 }
180
181 regmap_raw_read(info->map, reg, buf, 4);
182 /* convert bits[3:0] to signed number */
183 base = (((s64)buf[4]) << 60) >> 28;
184 base |= (((u32)buf[3]) << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
185 dev_dbg(info->dev, "%x-%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3], buf[4]);
186
187 /* load 32-bit read-only counter */
188 regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
189 data = (((u32)buf[3]) << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
190 ticks = base + data;
191 dev_dbg(info->dev, "get base:0x%llx, RO count:0x%llx, ticks:0x%llx\n",
192 base, data, ticks);
193 rtc_time64_to_tm(ticks, tm);
194 return 0;
195}
196
197static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
198{
199 struct pm80x_rtc_info *info = dev_get_drvdata(dev);
200 unsigned char buf[5];
201 s64 ticks, data, base;
202 u32 reg;
203
204 buf[4] = 0x0;
205
206 if (info->chip->type == CHIP_PM801 || info->chip->type == CHIP_PM800)
207 reg = PM800_USER_DATA1;
208 else
209 reg = PM802_RTC_EXPIRE2_1;
210
211 if (CHIP_PM801 == info->chip->type || CHIP_PM800 == info->chip->type) {
212 if ((tm->tm_year < 100) || (tm->tm_year > 205)) {
213 dev_err(info->dev,
214 "PM801: Set time %d out of range. Please set time between 2000 to 2105.\n",
215 1900 + tm->tm_year);
216 return -EINVAL;
217 }
218 } else {
219 if ((tm->tm_year < 70) || (tm->tm_year > 300)) {
220 dev_err(info->dev,
221 "PM8XX: Set time %d out of range. Please set time between 1970 to 2200.\n",
222 1900 + tm->tm_year);
223 return -EINVAL;
224 }
225 }
226
227 ticks = rtc_tm_to_time64(tm);
228
229 /* load 32-bit read-only counter */
230 regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
231 data = (((u32)buf[3]) << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
232 base = ticks - data;
233 dev_dbg(info->dev, "set base:0x%llx, RO count:0x%llx, ticks:0x%llx\n",
234 base, data, ticks);
235 buf[0] = base & 0xFF;
236 buf[1] = (base >> 8) & 0xFF;
237 buf[2] = (base >> 16) & 0xFF;
238 buf[3] = (base >> 24) & 0xFF;
239 regmap_raw_write(info->map, reg, buf, 4);
240
241 buf[4] = (base >> 32) & 0xFF;
242 if (CHIP_PM802 == info->chip->type) {
243 if (CHIP_PM802_ID_B1 == info->chip->chip_id ||
244 CHIP_PM802_ID_B0 == info->chip->chip_id) {
245 regmap_raw_read(info->map, PM802_RTC_MISC14, buf, 1);
246 buf[0] &= 0x0f;
247 buf[0] |= ((buf[4] & 0xf) << 4);
248 /* F1[7:4] */
249 regmap_raw_write(info->map, PM802_RTC_MISC14, &buf[0], 1);
250 } else {
251 /* CD[7:0] */
252 regmap_raw_write(info->map, PM802S_RTC_SPARED, &buf[4], 1);
253 }
254 } else if (CHIP_PM813 == info->chip->type) {
255 if (CHIP_PM813_ID == info->chip->chip_id) {
256 /* F6[7:0] */
257 regmap_raw_write(info->map, PM813_RTC_MISC19, &buf[4], 1);
258 } else {
259 /* CD[7:0] */
260 regmap_raw_write(info->map, PM813S_RTC_SPARED, &buf[4], 1);
261 }
262 }
263
264 if (info->sync)
265 info->sync(ticks);
266
267 return 0;
268}
269
270static int pm80x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
271{
272 struct pm80x_rtc_info *info = dev_get_drvdata(dev);
273 unsigned char buf[5];
274 s64 ticks, base, data;
275 int ret;
276 u32 reg;
277
278 buf[4] = 0x0;
279
280 if (info->chip->type == CHIP_PM801 || info->chip->type == CHIP_PM800)
281 reg = PM800_USER_DATA1;
282 else
283 reg = PM802_RTC_EXPIRE2_1;
284
285 if (CHIP_PM802 == info->chip->type) {
286 if (CHIP_PM802_ID_B1 == info->chip->chip_id ||
287 CHIP_PM802_ID_B0 == info->chip->chip_id) {
288 /* F1[7:4] */
289 regmap_raw_read(info->map, PM802_RTC_MISC14, &buf[4], 1);
290 buf[4] = (buf[4] >> 4) & 0xf;
291 } else {
292 /* CD[7:0] */
293 regmap_raw_read(info->map, PM802S_RTC_SPARED, &buf[4], 1);
294 }
295 } else if (CHIP_PM813 == info->chip->type) {
296 if (CHIP_PM813_ID == info->chip->chip_id) {
297 /* F6[7:0] */
298 regmap_raw_read(info->map, PM813_RTC_MISC19, &buf[4], 1);
299 } else {
300 /* CD[7:0] */
301 regmap_raw_read(info->map, PM813S_RTC_SPARED, &buf[4], 1);
302 }
303 }
304
305 regmap_raw_read(info->map, reg, buf, 4);
306 base = (((s64)buf[4]) << 60) >> 28;
307 base |= (((u32)buf[3]) << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
308 dev_dbg(info->dev, "%x-%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3], buf[4]);
309
310 regmap_raw_read(info->map, PM800_RTC_EXPIRE1_1, buf, 4);
311 data = (((u32)buf[3]) << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
312 ticks = base + data;
313 dev_dbg(info->dev, "get base:0x%llx, RO count:0x%llx, ticks:0x%llx\n",
314 base, data, ticks);
315
316 rtc_time64_to_tm(ticks, &alrm->time);
317 regmap_read(info->map, PM800_RTC_CONTROL, &ret);
318 alrm->enabled = (ret & PM800_ALARM1_EN) ? 1 : 0;
319 alrm->pending = (ret & (PM800_ALARM | PM800_ALARM_WAKEUP)) ? 1 : 0;
320 return 0;
321}
322
323static int pm80x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
324{
325 struct pm80x_rtc_info *info = dev_get_drvdata(dev);
326 s64 ticks, base, data;
327 unsigned char buf[5];
328 int mask;
329 u32 reg;
330
331 buf[4] = 0x0;
332
333 if (info->chip->type == CHIP_PM801 || info->chip->type == CHIP_PM800)
334 reg = PM800_USER_DATA1;
335 else
336 reg = PM802_RTC_EXPIRE2_1;
337
338 regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_ALARM1_EN, 0);
339
340 if (CHIP_PM802 == info->chip->type) {
341 if (CHIP_PM802_ID_B1 == info->chip->chip_id ||
342 CHIP_PM802_ID_B0 == info->chip->chip_id) {
343 /* F1[7:4] */
344 regmap_raw_read(info->map, PM802_RTC_MISC14, &buf[4], 1);
345 buf[4] = (buf[4] >> 4) & 0xf;
346 } else {
347 /* CD[7:0] */
348 regmap_raw_read(info->map, PM802S_RTC_SPARED, &buf[4], 1);
349 }
350 } else if (CHIP_PM813 == info->chip->type) {
351 if (CHIP_PM813_ID == info->chip->chip_id) {
352 /* F6[7:0] */
353 regmap_raw_read(info->map, PM813_RTC_MISC19, &buf[4], 1);
354 } else {
355 /* CD[7:0] */
356 regmap_raw_read(info->map, PM813S_RTC_SPARED, &buf[4], 1);
357 }
358 }
359
360 regmap_raw_read(info->map, reg, buf, 4);
361 base = (((s64)buf[4]) << 60) >> 28;
362 base |= (((u32)buf[3]) << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
363 dev_dbg(info->dev, "%x-%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3], buf[4]);
364
365 /* get new ticks for alarm */
366 ticks = rtc_tm_to_time64(&alrm->time);
367 dev_dbg(info->dev, "%s, alarm time: %llu\n", __func__, ticks);
368 data = ticks - base;
369
370 buf[0] = data & 0xff;
371 buf[1] = (data >> 8) & 0xff;
372 buf[2] = (data >> 16) & 0xff;
373 buf[3] = (data >> 24) & 0xff;
374 regmap_raw_write(info->map, PM800_RTC_EXPIRE1_1, buf, 4);
375 if (alrm->enabled) {
376 mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN;
377 regmap_update_bits(info->map, PM800_RTC_CONTROL, mask, mask);
378 } else {
379 mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN;
380 regmap_update_bits(info->map, PM800_RTC_CONTROL, mask,
381 PM800_ALARM | PM800_ALARM_WAKEUP);
382 }
383 return 0;
384}
385
386static const struct rtc_class_ops pm80x_rtc_ops = {
387 .read_time = pm80x_rtc_read_time,
388 .set_time = pm80x_rtc_set_time,
389 .read_alarm = pm80x_rtc_read_alarm,
390 .set_alarm = pm80x_rtc_set_alarm,
391 .alarm_irq_enable = pm80x_rtc_alarm_irq_enable,
392};
393
394#ifdef CONFIG_PM_SLEEP
395static int pm80x_rtc_suspend(struct device *dev)
396{
397 return pm80x_dev_suspend(dev);
398}
399
400static int pm80x_rtc_resume(struct device *dev)
401{
402 return pm80x_dev_resume(dev);
403}
404#endif
405
406static SIMPLE_DEV_PM_OPS(pm80x_rtc_pm_ops, pm80x_rtc_suspend, pm80x_rtc_resume);
407
408static struct delayed_work sync_work;
409static unsigned int print_tstamp_delay = 30;
410static void sync_timestamp(struct work_struct *work)
411{
412 struct timespec64 ts;
413 struct rtc_time tm;
414
415 ktime_get_real_ts64(&ts);
416 rtc_time64_to_tm(ts.tv_sec - sys_tz.tz_minuteswest * 60, &tm);
417 pr_info("Timestamp is: %02d-%02d %02d:%02d:%02d.%03lu UTC\n",
418 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
419 tm.tm_sec, ts.tv_nsec);
420 /* print timestamp every 30 minutes */
421 schedule_delayed_work(&sync_work, print_tstamp_delay*60*HZ);
422}
423
424#ifdef CONFIG_SYSFS
425static ssize_t tstamp_show_delay(struct device *dev,
426 struct device_attribute *attr, char *buf)
427{
428 return snprintf(buf, PAGE_SIZE, "%u\n", print_tstamp_delay);
429}
430static ssize_t tstamp_store_delay(struct device *dev,
431 struct device_attribute *attr,
432 const char *buf, size_t size)
433{
434 char *end;
435 unsigned long new = simple_strtoul(buf, &end, 0);
436 if (end == buf)
437 return -EINVAL;
438 print_tstamp_delay = new;
439 cancel_delayed_work(&sync_work);
440 schedule_delayed_work(&sync_work, print_tstamp_delay*60*HZ);
441 return size;
442}
443static DEVICE_ATTR(tstamp_delay, 0664, tstamp_show_delay, tstamp_store_delay);
444
445static int add_tstamp_delay(struct device *dev)
446{
447 return device_create_file(dev, &dev_attr_tstamp_delay);
448}
449
450static void remove_tstamp_delay(struct device *dev)
451{
452 device_remove_file(dev, &dev_attr_tstamp_delay);
453}
454
455#else
456#define add_tstamp_delay(dev) 0
457#define remove_tstamp_delay(dev) do {} while (0)
458#endif /* CONFIG_SYSFS */
459
460static int pm80x_rtc_probe(struct platform_device *pdev)
461{
462 struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
463 struct pm80x_rtc_pdata *pdata = NULL;
464 struct pm80x_rtc_info *info;
465 struct rtc_time tm;
466 int ret;
467
468 INIT_DEFERRABLE_WORK(&sync_work, sync_timestamp);
469 schedule_delayed_work(&sync_work, 1*60*HZ);
470 add_tstamp_delay(&pdev->dev);
471
472 pdata = pdev->dev.platform_data;
473 if (IS_ENABLED(CONFIG_OF)) {
474 if (!pdata) {
475 pdata = devm_kzalloc(&pdev->dev,
476 sizeof(*pdata), GFP_KERNEL);
477 if (!pdata)
478 return -ENOMEM;
479 }
480 } else if (!pdata) {
481 return -EINVAL;
482 }
483
484 info =
485 devm_kzalloc(&pdev->dev, sizeof(struct pm80x_rtc_info), GFP_KERNEL);
486 if (!info)
487 return -ENOMEM;
488 info->irq = platform_get_irq(pdev, 0);
489 if (info->irq < 0) {
490 dev_err(&pdev->dev, "No IRQ resource!\n");
491 ret = -EINVAL;
492 goto out;
493 }
494
495 info->chip = chip;
496 info->map = chip->regmap;
497 if (!info->map) {
498 dev_err(&pdev->dev, "no regmap!\n");
499 ret = -EINVAL;
500 goto out;
501 }
502
503 info->dev = &pdev->dev;
504 dev_set_drvdata(&pdev->dev, info);
505
506 ret = pm80x_rtc_read_time(&pdev->dev, &tm);
507 if (ret < 0) {
508 dev_err(&pdev->dev, "Failed to read initial time.\n");
509 goto out;
510 }
511
512 if (CHIP_PM801 == info->chip->type || CHIP_PM800 == info->chip->type) {
513 if ((tm.tm_year < 100) || (tm.tm_year > 205)) {
514 tm.tm_year = 100;
515 tm.tm_mon = 0;
516 tm.tm_mday = 1;
517 tm.tm_hour = 0;
518 tm.tm_min = 0;
519 tm.tm_sec = 0;
520 ret = pm80x_rtc_set_time(&pdev->dev, &tm);
521 if (ret < 0) {
522 dev_err(&pdev->dev, "Failed to set initial time.\n");
523 goto out;
524 }
525 }
526 } else {
527 if ((tm.tm_year < 70) || (tm.tm_year > 1157)) {
528 tm.tm_year = 70;
529 tm.tm_mon = 0;
530 tm.tm_mday = 1;
531 tm.tm_hour = 0;
532 tm.tm_min = 0;
533 tm.tm_sec = 0;
534 ret = pm80x_rtc_set_time(&pdev->dev, &tm);
535 if (ret < 0) {
536 dev_err(&pdev->dev, "Failed to set initial time.\n");
537 goto out;
538 }
539 }
540 }
541
542 info->sync = NULL; /*initialize*/
543#ifdef CONFIG_RTC_DRV_SA1100
544 info->sync = sync_time_to_soc;
545 INIT_DELAYED_WORK(&info->sa1100_sync_work, sa1100_sync_fn);
546 schedule_delayed_work(&info->sa1100_sync_work, 2 * HZ);
547#endif
548
549 dev_info(&pdev->dev, "%d-%d-%d-->%d: %d: %d\n",
550 tm.tm_year, tm.tm_mon, tm.tm_mday,
551 tm.tm_hour, tm.tm_min, tm.tm_sec);
552
553 info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm80x-rtc",
554 &pm80x_rtc_ops, THIS_MODULE);
555 if (IS_ERR(info->rtc_dev)) {
556 ret = PTR_ERR(info->rtc_dev);
557 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
558 goto out;
559 }
560 /*
561 * enable internal XO instead of internal 3.25MHz clock since it can
562 * free running in PMIC power-down state.
563 */
564 regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_RTC1_USE_XO,
565 PM800_RTC1_USE_XO);
566
567 /* remeber whether this power up is caused by PMIC RTC or not. */
568 info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup;
569
570 ret = pm80x_request_irq(chip, info->irq, rtc_update_handler,
571 IRQF_ONESHOT | IRQF_NO_SUSPEND , "rtc", info);
572 if (ret < 0) {
573 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
574 info->irq, ret);
575 goto out;
576 }
577
578 device_init_wakeup(&pdev->dev, 1);
579
580 return 0;
581out:
582 return ret;
583}
584
585static int pm80x_rtc_remove(struct platform_device *pdev)
586{
587 struct pm80x_rtc_info *info = platform_get_drvdata(pdev);
588 platform_set_drvdata(pdev, NULL);
589 pm80x_free_irq(info->chip, info->irq, info);
590 remove_tstamp_delay(&pdev->dev);
591 return 0;
592}
593
594static void pm80x_rtc_shutdown(struct platform_device *pdev)
595{
596
597 struct timespec64 now;
598 struct rtc_time tm;
599 struct pm80x_rtc_info *info = platform_get_drvdata(pdev);
600
601 /* sync timekeeping time to pmic rtc */
602 ktime_get_real_ts64(&now);
603 if (now.tv_nsec < (NSEC_PER_SEC >> 1))
604 rtc_time64_to_tm(now.tv_sec, &tm);
605 else
606 rtc_time64_to_tm(now.tv_sec + 1, &tm);
607 pm80x_rtc_set_time(info->dev, &tm);
608
609 pm80x_free_irq(info->chip, info->irq, info);
610}
611
612static struct platform_driver pm80x_rtc_driver = {
613 .driver = {
614 .name = "88pm80x-rtc",
615 .owner = THIS_MODULE,
616 .pm = &pm80x_rtc_pm_ops,
617 },
618 .probe = pm80x_rtc_probe,
619 .remove = pm80x_rtc_remove,
620 .shutdown = pm80x_rtc_shutdown,
621};
622
623module_platform_driver(pm80x_rtc_driver);
624
625MODULE_LICENSE("GPL");
626MODULE_DESCRIPTION("Marvell 88PM80x RTC driver");
627MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
628MODULE_ALIAS("platform:88pm80x-rtc");