OMAP: omap_hwmod: reset timeout logic

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

checking some patches thru www.kernel.org
I noticed something iffy in

/arch/arm/mach-omap2/omap_hwmod.c

in function

static int _reset(struct omap_hwmod *oh)
...
       c = 0;
       while (c < MAX_MODULE_RESET_WAIT &&
              !(omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
                SYSS_RESETDONE_MASK)) {
               udelay(1);
               c++;
       }

       if (c == MAX_MODULE_RESET_WAIT)
               WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n",
                    oh->name, MAX_MODULE_RESET_WAIT);
       else
               pr_debug("omap_hwmod: %s: reset in %d usec\n", oh->name, c);

       /*
        * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
        * _wait_target_ready() or _reset()
        */

       return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0;
...

Let's assume MAX_MODULE_RESET_WAIT==1,
and let's look what happens with the "reset" while loop,
in case where we exit the loop at the last possible
moment.
c==0, and rest not done so udelay(1), c=1.
We do not loop another time because c==MAX_MODULE_RESET_WAIT.
So we give a warning and return -ETIMEDOUT.
Hmmm, we did not check if reset was done while udelay?
Still we warn that "failed to reset in 1 usec"!

Simple correction could be something like
.....
       c = 0;
-      while (c < MAX_MODULE_RESET_WAIT &&
-             !(omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
-               SYSS_RESETDONE_MASK)) {
-              udelay(1);
-              c++;
-      }
+      while (!(omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
+               SYSS_RESETDONE_MASK) &&
+               (c++ < MAX_MODULE_RESET_WAIT))
+                      udelay(1);

-      if (c == MAX_MODULE_RESET_WAIT)
+      if (c > MAX_MODULE_RESET_WAIT)
               WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n",
<SNIP>
-      return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0;
+      return (c > MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0;
.....

Now we do max MAX_MODULE_RESET_WAIT udelay(1)'s and
always check after udelay(1) if resetdone.

Signed-off-by: "Juha Leppanen" <juha_motorsportcom@xxxxxxxxxx>

No reply needed to me,
my spam filter will probably eat your reply.

Reported-by: "Juha Leppanen" <juha_motorsportcom@xxxxxxxxxx>
tag would be nice in kernel.org :)
Not so many kernel hackers give credit these days :(

Happy hacking,

Mr. Juha Leppanen
Kuopio, Finland


....................................................................
Luukku Plus -paketilla pääset eroon tila- ja turvallisuusongelmista.
Hanki Luukku Plus ja helpotat elämääsi. http://www.mtv3.fi/luukku
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux