]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ARM: shmobile: R-Car: Break infinite loop
authorGeert Uytterhoeven <geert+renesas@glider.be>
Thu, 4 Jun 2015 18:22:29 +0000 (20:22 +0200)
committerSimon Horman <horms+renesas@verge.net.au>
Mon, 6 Jul 2015 00:35:18 +0000 (09:35 +0900)
rcar_sysc_update() loops (with interrupts disabled and while holding a
spinlock) until submitting a power shutoff or resume request fails, or
until the submitted request was accepted.
If none of these conditions becomes true, this forms an infinite loop.

Put a limit on the maximum number of loop iterations, and add a small
delay to each iteration, to fix this.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
arch/arm/mach-shmobile/pm-rcar.c

index 56ea82a851cb96f72e83a99aef1c82bd3bdc907e..a5e4c3a88ec4f1274d2a88c5a78f6e06941dcb3a 100644 (file)
@@ -42,6 +42,9 @@
 #define SYSCSR_RETRIES         100
 #define SYSCSR_DELAY_US                1
 
+#define PWRER_RETRIES          100
+#define PWRER_DELAY_US         1
+
 #define SYSCISR_RETRIES                1000
 #define SYSCISR_DELAY_US       1
 
@@ -95,14 +98,23 @@ static int rcar_sysc_update(struct rcar_sysc_ch *sysc_ch,
        iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
 
        /* Submit power shutoff or resume request until it was accepted */
-       do {
+       for (k = 0; k < PWRER_RETRIES; k++) {
                ret = on_off_fn(sysc_ch);
                if (ret)
                        goto out;
 
                status = ioread32(rcar_sysc_base +
                                  sysc_ch->chan_offs + PWRER_OFFS);
-       } while (status & chan_mask);
+               if (!(status & chan_mask))
+                       break;
+
+               udelay(PWRER_DELAY_US);
+       }
+
+       if (k == PWRER_RETRIES) {
+               ret = -EIO;
+               goto out;
+       }
 
        /* Wait until the power shutoff or resume request has completed * */
        for (k = 0; k < SYSCISR_RETRIES; k++) {