Messages in this thread Patch in this message | | | Date | Sun, 12 Sep 2010 18:26:28 +0200 | From | Ole Henrik Jahren <> | Subject | [PATCH] avr32: fix deadlock when reading clock list in debugfs |
| |
From: Ole Henrik Jahren <olehenja@alumni.ntnu.no>
clk_show() already has clk_list_lock. Make a version of clk_get(), clk_get_locked(), that does not attempt to take the lock a second time.
Signed-off-by: Ole Henrik Jahren <olehenja@alumni.ntnu.no> Cc: Haavard Skinnemoen <hskinnemoen@atmel.com> --- arch/avr32/mach-at32ap/clock.c | 27 ++++++++++++++++++++------- 1 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c index 442f08c..3951993 100644 --- a/arch/avr32/mach-at32ap/clock.c +++ b/arch/avr32/mach-at32ap/clock.c @@ -35,22 +35,30 @@ void at32_clk_register(struct clk *clk) spin_unlock(&clk_list_lock); } -struct clk *clk_get(struct device *dev, const char *id) +static struct clk *__clk_get(struct device *dev, const char *id, int locked) { struct clk *clk; - spin_lock(&clk_list_lock); + if (!locked) + spin_lock(&clk_list_lock); list_for_each_entry(clk, &at32_clock_list, list) { if (clk->dev == dev && strcmp(id, clk->name) == 0) { - spin_unlock(&clk_list_lock); + if (!locked) + spin_unlock(&clk_list_lock); return clk; } } - spin_unlock(&clk_list_lock); + if (!locked) + spin_unlock(&clk_list_lock); return ERR_PTR(-ENOENT); } + +struct clk *clk_get(struct device *dev, const char *id) +{ + return __clk_get(dev, id, 0); +} EXPORT_SYMBOL(clk_get); void clk_put(struct clk *clk) @@ -227,6 +235,11 @@ dump_clock(struct clk *parent, struct clkinf *r) r->nest = nest; } +static struct clk *clk_get_locked(struct device *dev, const char *id) +{ + return __clk_get(dev, id, 1); +} + static int clk_show(struct seq_file *s, void *unused) { struct clkinf r; @@ -257,15 +270,15 @@ static int clk_show(struct seq_file *s, void *unused) spin_lock(&clk_list_lock); /* show clock tree as derived from the three oscillators */ - clk = clk_get(NULL, "osc32k"); + clk = clk_get_locked(NULL, "osc32k"); dump_clock(clk, &r); clk_put(clk); - clk = clk_get(NULL, "osc0"); + clk = clk_get_locked(NULL, "osc0"); dump_clock(clk, &r); clk_put(clk); - clk = clk_get(NULL, "osc1"); + clk = clk_get_locked(NULL, "osc1"); dump_clock(clk, &r); clk_put(clk); -- 1.7.2.2
| |