]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blobdiff - drivers/rtc/rtc-sc27xx.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[mirror_ubuntu-eoan-kernel.git] / drivers / rtc / rtc-sc27xx.c
index 00d87d138984b230623bd16cf31184e33d178ee9..deea5c3726adb5af514664473f3ec99caf6014df 100644 (file)
@@ -35,6 +35,8 @@
 #define SPRD_RTC_DAY_ALM_VALUE         0x4c
 #define SPRD_RTC_SPG_VALUE             0x50
 #define SPRD_RTC_SPG_UPD               0x54
+#define SPRD_RTC_PWR_CTRL              0x58
+#define SPRD_RTC_PWR_STS               0x5c
 #define SPRD_RTC_SEC_AUXALM_UPD                0x60
 #define SPRD_RTC_MIN_AUXALM_UPD                0x64
 #define SPRD_RTC_HOUR_AUXALM_UPD       0x68
 
 /* SPG values definition for SPRD_RTC_SPG_UPD register */
 #define SPRD_RTC_POWEROFF_ALM_FLAG     BIT(8)
-#define SPRD_RTC_POWER_RESET_FLAG      BIT(9)
+
+/* power control/status definition */
+#define SPRD_RTC_POWER_RESET_VALUE     0x96
+#define SPRD_RTC_POWER_STS_CLEAR       GENMASK(7, 0)
+#define SPRD_RTC_POWER_STS_SHIFT       8
+#define SPRD_RTC_POWER_STS_VALID       \
+       (~SPRD_RTC_POWER_RESET_VALUE << SPRD_RTC_POWER_STS_SHIFT)
 
 /* timeout of synchronizing time and alarm registers (us) */
 #define SPRD_RTC_POLL_TIMEOUT          200000
@@ -383,7 +391,6 @@ static int sprd_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
        struct sprd_rtc *rtc = dev_get_drvdata(dev);
        time64_t secs = rtc_tm_to_time64(tm);
-       u32 val;
        int ret;
 
        ret = sprd_rtc_set_secs(rtc, SPRD_RTC_TIME, secs);
@@ -391,27 +398,20 @@ static int sprd_rtc_set_time(struct device *dev, struct rtc_time *tm)
                return ret;
 
        if (!rtc->valid) {
-               /*
-                * Set SPRD_RTC_POWER_RESET_FLAG to indicate now RTC has valid
-                * time values.
-                */
-               ret = regmap_update_bits(rtc->regmap,
-                                        rtc->base + SPRD_RTC_SPG_UPD,
-                                        SPRD_RTC_POWER_RESET_FLAG,
-                                        SPRD_RTC_POWER_RESET_FLAG);
+               /* Clear RTC power status firstly */
+               ret = regmap_write(rtc->regmap, rtc->base + SPRD_RTC_PWR_CTRL,
+                                  SPRD_RTC_POWER_STS_CLEAR);
                if (ret)
                        return ret;
 
-               ret = regmap_read_poll_timeout(rtc->regmap,
-                                              rtc->base + SPRD_RTC_INT_RAW_STS,
-                                              val, (val & SPRD_RTC_SPG_UPD_EN),
-                                              SPRD_RTC_POLL_DELAY_US,
-                                              SPRD_RTC_POLL_TIMEOUT);
-               if (ret) {
-                       dev_err(rtc->dev, "failed to update SPG value:%d\n",
-                               ret);
+               /*
+                * Set RTC power status to indicate now RTC has valid time
+                * values.
+                */
+               ret = regmap_write(rtc->regmap, rtc->base + SPRD_RTC_PWR_CTRL,
+                                  SPRD_RTC_POWER_STS_VALID);
+               if (ret)
                        return ret;
-               }
 
                rtc->valid = true;
        }
@@ -562,15 +562,16 @@ static int sprd_rtc_check_power_down(struct sprd_rtc *rtc)
        u32 val;
        int ret;
 
-       ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_SPG_VALUE, &val);
+       ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_PWR_STS, &val);
        if (ret)
                return ret;
 
        /*
-        * If the SPRD_RTC_POWER_RESET_FLAG was not set, which means the RTC has
-        * been powered down, so the RTC time values are invalid.
+        * If the RTC power status value is SPRD_RTC_POWER_RESET_VALUE, which
+        * means the RTC has been powered down, so the RTC time values are
+        * invalid.
         */
-       rtc->valid = (val & SPRD_RTC_POWER_RESET_FLAG) ? true : false;
+       rtc->valid = val == SPRD_RTC_POWER_RESET_VALUE ? false : true;
        return 0;
 }
 
@@ -600,6 +601,10 @@ static int sprd_rtc_probe(struct platform_device *pdev)
                return rtc->irq;
        }
 
+       rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
+       if (IS_ERR(rtc->rtc))
+               return PTR_ERR(rtc->rtc);
+
        rtc->dev = &pdev->dev;
        platform_set_drvdata(pdev, rtc);
 
@@ -626,10 +631,14 @@ static int sprd_rtc_probe(struct platform_device *pdev)
                return ret;
        }
 
-       rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
-                                           &sprd_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc->rtc))
-               return PTR_ERR(rtc->rtc);
+       rtc->rtc->ops = &sprd_rtc_ops;
+       rtc->rtc->range_min = 0;
+       rtc->rtc->range_max = 5662310399LL;
+       ret = rtc_register_device(rtc->rtc);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register rtc device\n");
+               return ret;
+       }
 
        device_init_wakeup(&pdev->dev, 1);
        return 0;