hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/rtc/rtc-omap.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * TI OMAP Real Time Clock interface for Linux
34 *
....@@ -6,14 +7,8 @@
67 *
78 * Copyright (C) 2006 David Brownell (new RTC framework)
89 * Copyright (C) 2014 Johan Hovold <johan@kernel.org>
9
- *
10
- * This program is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU General Public License
12
- * as published by the Free Software Foundation; either version
13
- * 2 of the License, or (at your option) any later version.
1410 */
1511
16
-#include <dt-bindings/gpio/gpio.h>
1712 #include <linux/bcd.h>
1813 #include <linux/clk.h>
1914 #include <linux/delay.h>
....@@ -30,6 +25,7 @@
3025 #include <linux/platform_device.h>
3126 #include <linux/pm_runtime.h>
3227 #include <linux/rtc.h>
28
+#include <linux/rtc/rtc-omap.h>
3329
3430 /*
3531 * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock
....@@ -271,7 +267,7 @@
271267 }
272268
273269 /* this hardware doesn't support "don't care" alarm fields */
274
-static int tm2bcd(struct rtc_time *tm)
270
+static void tm2bcd(struct rtc_time *tm)
275271 {
276272 tm->tm_sec = bin2bcd(tm->tm_sec);
277273 tm->tm_min = bin2bcd(tm->tm_min);
....@@ -279,13 +275,7 @@
279275 tm->tm_mday = bin2bcd(tm->tm_mday);
280276
281277 tm->tm_mon = bin2bcd(tm->tm_mon + 1);
282
-
283
- /* epoch == 1900 */
284
- if (tm->tm_year < 100 || tm->tm_year > 199)
285
- return -EINVAL;
286278 tm->tm_year = bin2bcd(tm->tm_year - 100);
287
-
288
- return 0;
289279 }
290280
291281 static void bcd2tm(struct rtc_time *tm)
....@@ -328,8 +318,7 @@
328318 {
329319 struct omap_rtc *rtc = dev_get_drvdata(dev);
330320
331
- if (tm2bcd(tm) < 0)
332
- return -EINVAL;
321
+ tm2bcd(tm);
333322
334323 local_irq_disable();
335324 rtc_wait_not_busy(rtc);
....@@ -378,8 +367,7 @@
378367 struct omap_rtc *rtc = dev_get_drvdata(dev);
379368 u8 reg, irqwake_reg = 0;
380369
381
- if (tm2bcd(&alm->time) < 0)
382
- return -EINVAL;
370
+ tm2bcd(&alm->time);
383371
384372 local_irq_disable();
385373 rtc_wait_not_busy(rtc);
....@@ -415,25 +403,17 @@
415403
416404 static struct omap_rtc *omap_rtc_power_off_rtc;
417405
418
-/*
419
- * omap_rtc_poweroff: RTC-controlled power off
420
- *
421
- * The RTC can be used to control an external PMIC via the pmic_power_en pin,
422
- * which can be configured to transition to OFF on ALARM2 events.
423
- *
424
- * Notes:
425
- * The two-second alarm offset is the shortest offset possible as the alarm
426
- * registers must be set before the next timer update and the offset
427
- * calculation is too heavy for everything to be done within a single access
428
- * period (~15 us).
429
- *
430
- * Called with local interrupts disabled.
406
+/**
407
+ * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
408
+ * generates pmic_pwr_enable control, which can be used to control an external
409
+ * PMIC.
431410 */
432
-static void omap_rtc_power_off(void)
411
+int omap_rtc_power_off_program(struct device *dev)
433412 {
434413 struct omap_rtc *rtc = omap_rtc_power_off_rtc;
435414 struct rtc_time tm;
436415 unsigned long now;
416
+ int seconds;
437417 u32 val;
438418
439419 rtc->type->unlock(rtc);
....@@ -441,17 +421,18 @@
441421 val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
442422 rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
443423
444
- /* set alarm two seconds from now */
445
- omap_rtc_read_time_raw(rtc, &tm);
446
- bcd2tm(&tm);
447
- rtc_tm_to_time(&tm, &now);
448
- rtc_time_to_tm(now + 2, &tm);
424
+again:
425
+ /* Clear any existing ALARM2 event */
426
+ rtc_writel(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM2);
449427
450
- if (tm2bcd(&tm) < 0) {
451
- dev_err(&rtc->rtc->dev, "power off failed\n");
452
- rtc->type->lock(rtc);
453
- return;
454
- }
428
+ /* set alarm one second from now */
429
+ omap_rtc_read_time_raw(rtc, &tm);
430
+ seconds = tm.tm_sec;
431
+ bcd2tm(&tm);
432
+ now = rtc_tm_to_time64(&tm);
433
+ rtc_time64_to_tm(now + 1, &tm);
434
+
435
+ tm2bcd(&tm);
455436
456437 rtc_wait_not_busy(rtc);
457438
....@@ -470,14 +451,55 @@
470451 val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
471452 rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
472453 val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
454
+
455
+ /* Retry in case roll over happened before alarm was armed. */
456
+ if (rtc_read(rtc, OMAP_RTC_SECONDS_REG) != seconds) {
457
+ val = rtc_read(rtc, OMAP_RTC_STATUS_REG);
458
+ if (!(val & OMAP_RTC_STATUS_ALARM2))
459
+ goto again;
460
+ }
461
+
473462 rtc->type->lock(rtc);
474463
464
+ return 0;
465
+}
466
+EXPORT_SYMBOL(omap_rtc_power_off_program);
467
+
468
+/*
469
+ * omap_rtc_poweroff: RTC-controlled power off
470
+ *
471
+ * The RTC can be used to control an external PMIC via the pmic_power_en pin,
472
+ * which can be configured to transition to OFF on ALARM2 events.
473
+ *
474
+ * Notes:
475
+ * The one-second alarm offset is the shortest offset possible as the alarm
476
+ * registers must be set before the next timer update and the offset
477
+ * calculation is too heavy for everything to be done within a single access
478
+ * period (~15 us).
479
+ *
480
+ * Called with local interrupts disabled.
481
+ */
482
+static void omap_rtc_power_off(void)
483
+{
484
+ struct rtc_device *rtc = omap_rtc_power_off_rtc->rtc;
485
+ u32 val;
486
+
487
+ omap_rtc_power_off_program(rtc->dev.parent);
488
+
489
+ /* Set PMIC power enable and EXT_WAKEUP in case PB power on is used */
490
+ omap_rtc_power_off_rtc->type->unlock(omap_rtc_power_off_rtc);
491
+ val = rtc_readl(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG);
492
+ val |= OMAP_RTC_PMIC_POWER_EN_EN | OMAP_RTC_PMIC_EXT_WKUP_POL(0) |
493
+ OMAP_RTC_PMIC_EXT_WKUP_EN(0);
494
+ rtc_writel(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG, val);
495
+ omap_rtc_power_off_rtc->type->lock(omap_rtc_power_off_rtc);
496
+
475497 /*
476
- * Wait for alarm to trigger (within two seconds) and external PMIC to
498
+ * Wait for alarm to trigger (within one second) and external PMIC to
477499 * power off the system. Add a 500 ms margin for external latencies
478500 * (e.g. debounce circuits).
479501 */
480
- mdelay(2500);
502
+ mdelay(1500);
481503 }
482504
483505 static const struct rtc_class_ops omap_rtc_ops = {
....@@ -594,7 +616,7 @@
594616 break;
595617 default:
596618 return -ENOTSUPP;
597
- };
619
+ }
598620
599621 *config = pinconf_to_config_packed(param, arg);
600622
....@@ -705,7 +727,6 @@
705727 static int omap_rtc_probe(struct platform_device *pdev)
706728 {
707729 struct omap_rtc *rtc;
708
- struct resource *res;
709730 u8 reg, mask, new_ctrl;
710731 const struct platform_device_id *id_entry;
711732 const struct of_device_id *of_id;
....@@ -719,8 +740,7 @@
719740 if (of_id) {
720741 rtc->type = of_id->data;
721742 rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
722
- of_property_read_bool(pdev->dev.of_node,
723
- "system-power-controller");
743
+ of_device_is_system_power_controller(pdev->dev.of_node);
724744 } else {
725745 id_entry = platform_get_device_id(pdev);
726746 rtc->type = (void *)id_entry->driver_data;
....@@ -743,8 +763,7 @@
743763 if (!IS_ERR(rtc->clk))
744764 clk_prepare_enable(rtc->clk);
745765
746
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
747
- rtc->base = devm_ioremap_resource(&pdev->dev, res);
766
+ rtc->base = devm_platform_ioremap_resource(pdev, 0);
748767 if (IS_ERR(rtc->base)) {
749768 clk_disable_unprepare(rtc->clk);
750769 return PTR_ERR(rtc->base);
....@@ -841,6 +860,8 @@
841860 }
842861
843862 rtc->rtc->ops = &omap_rtc_ops;
863
+ rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
864
+ rtc->rtc->range_max = RTC_TIMESTAMP_END_2099;
844865 omap_rtc_nvmem_config.priv = rtc;
845866
846867 /* handle periodic and alarm irqs */