]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/rtc/rtc-opal.c
UBUNTU: upstream stable to v4.14.156, v4.19.86
[mirror_ubuntu-bionic-kernel.git] / drivers / rtc / rtc-opal.c
index e2a946c0e667e150e1029728134c6d20baf4d076..60f2250fd96bec2cec1dd33f652edaac474d2182 100644 (file)
@@ -57,7 +57,8 @@ static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms)
 
 static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
 {
-       long rc = OPAL_BUSY;
+       s64 rc = OPAL_BUSY;
+       int retries = 10;
        u32 y_m_d;
        u64 h_m_s_ms;
        __be32 __y_m_d;
@@ -65,10 +66,17 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
 
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
                rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
-               if (rc == OPAL_BUSY_EVENT)
+               if (rc == OPAL_BUSY_EVENT) {
+                       msleep(OPAL_BUSY_DELAY_MS);
                        opal_poll_events(NULL);
-               else
-                       msleep(10);
+               } else if (rc == OPAL_BUSY) {
+                       msleep(OPAL_BUSY_DELAY_MS);
+               } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) {
+                       if (retries--) {
+                               msleep(10); /* Wait 10ms before retry */
+                               rc = OPAL_BUSY; /* go around again */
+                       }
+               }
        }
 
        if (rc != OPAL_SUCCESS)
@@ -83,17 +91,26 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
 
 static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm)
 {
-       long rc = OPAL_BUSY;
+       s64 rc = OPAL_BUSY;
+       int retries = 10;
        u32 y_m_d = 0;
        u64 h_m_s_ms = 0;
 
        tm_to_opal(tm, &y_m_d, &h_m_s_ms);
+
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
                rc = opal_rtc_write(y_m_d, h_m_s_ms);
-               if (rc == OPAL_BUSY_EVENT)
+               if (rc == OPAL_BUSY_EVENT) {
+                       msleep(OPAL_BUSY_DELAY_MS);
                        opal_poll_events(NULL);
-               else
-                       msleep(10);
+               } else if (rc == OPAL_BUSY) {
+                       msleep(OPAL_BUSY_DELAY_MS);
+               } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) {
+                       if (retries--) {
+                               msleep(10); /* Wait 10ms before retry */
+                               rc = OPAL_BUSY; /* go around again */
+                       }
+               }
        }
 
        return rc == OPAL_SUCCESS ? 0 : -EIO;