ARM: OMAP: dmtimers: Fix locking issue in omap_dm_timer_request*()
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Sun, 12 Aug 2012 10:45:34 +0000 (13:45 +0300)
committerTony Lindgren <tony@atomide.com>
Mon, 13 Aug 2012 13:23:16 +0000 (06:23 -0700)
Calling omap_dm_timer_prepare while the spinlock is held is not
allowed as sleeping functions are called later on during the
preparation (namely within clk_get()).

dm_timer_lock is only required for protecting the
omap_timer_list. After the timer is marked as reserved, the lock is no
longer needed and should be freed.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
Cc: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/plat-omap/dmtimer.c

index 7b6689a..938b50a 100644 (file)
@@ -189,6 +189,7 @@ struct omap_dm_timer *omap_dm_timer_request(void)
                timer->reserved = 1;
                break;
        }
+       spin_unlock_irqrestore(&dm_timer_lock, flags);
 
        if (timer) {
                ret = omap_dm_timer_prepare(timer);
@@ -197,7 +198,6 @@ struct omap_dm_timer *omap_dm_timer_request(void)
                        timer = NULL;
                }
        }
-       spin_unlock_irqrestore(&dm_timer_lock, flags);
 
        if (!timer)
                pr_debug("%s: timer request failed!\n", __func__);
@@ -220,6 +220,7 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
                        break;
                }
        }
+       spin_unlock_irqrestore(&dm_timer_lock, flags);
 
        if (timer) {
                ret = omap_dm_timer_prepare(timer);
@@ -228,7 +229,6 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
                        timer = NULL;
                }
        }
-       spin_unlock_irqrestore(&dm_timer_lock, flags);
 
        if (!timer)
                pr_debug("%s: timer%d request failed!\n", __func__, id);