From: David Brownell <[email protected]>

Fix the following bug, which was reported after a command line "reboot":

 WARNING: at kernel/lockdep.c:2280 lockdep_trace_alloc+0x40/0x50()
 Modules linked in:
 [<c002d910>] (unwind_backtrace+0x0/0xdc) from [<c003bba8>] 
(warn_slowpath+0x68/0x8c)
 [<c003bba8>] (warn_slowpath+0x68/0x8c) from [<c005ecf0>] 
(lockdep_trace_alloc+0x40/0x50)
 [<c005ecf0>] (lockdep_trace_alloc+0x40/0x50) from [<c0091e14>] 
(__kmalloc+0x58/0x110)
 [<c0091e14>] (__kmalloc+0x58/0x110) from [<c0165044>] (kvasprintf+0x38/0x58)
 [<c0165044>] (kvasprintf+0x38/0x58) from [<c015e794>] 
(kobject_set_name_vargs+0x14/0x54)
 [<c015e794>] (kobject_set_name_vargs+0x14/0x54) from [<c019b9ac>] 
(dev_set_name+0x20/0x2c)
 [<c019b9ac>] (dev_set_name+0x20/0x2c) from [<c0031804>] 
(davinci_watchdog_reset+0x1c/0xb0)
 [<c0031804>] (davinci_watchdog_reset+0x1c/0xb0) from [<c0029304>] 
(arm_machine_restart+0x24/0x50)
 [<c0029304>] (arm_machine_restart+0x24/0x50) from [<c0028d84>] 
(machine_restart+0x18/0x20)
 [<c0028d84>] (machine_restart+0x18/0x20) from [<c004ba80>] 
(sys_reboot+0xe0/0x1c4)
 [<c004ba80>] (sys_reboot+0xe0/0x1c4) from [<c0027d40>] 
(ret_fast_syscall+0x0/0x2c)

The issue is that dev_set_name() may no longer be called with IRQs disabled.
Trivial fix:  don't cons up a fake watchdog device, just use the real one.

Signed-off-by: David Brownell <[email protected]>
---
 arch/arm/mach-davinci/clock.h   |    3 +++
 arch/arm/mach-davinci/devices.c |    2 +-
 arch/arm/mach-davinci/time.c    |    8 ++++----
 3 files changed, 8 insertions(+), 5 deletions(-)

--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -96,4 +96,7 @@ int davinci_clk_associate(struct device 
                          const char *physical_clockname);
 
 int davinci_clk_init(struct davinci_clk *clocks);
+
+extern struct platform_device davinci_wdt_device;
+
 #endif
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -228,7 +228,7 @@ static struct resource wdt_resources[] =
        },
 };
 
-static struct platform_device davinci_wdt_device = {
+struct platform_device davinci_wdt_device = {
        .name           = "watchdog",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(wdt_resources),
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <mach/hardware.h>
 #include <asm/system.h>
@@ -403,15 +404,14 @@ struct sys_timer davinci_timer = {
 
 
 /* reset board using watchdog timer */
-void davinci_watchdog_reset(void) {
+void davinci_watchdog_reset(void)
+{
        u32 tgcr, wdtcr;
        struct davinci_soc_info *soc_info = davinci_get_soc_info();
        void __iomem *base = soc_info->wdt_base;
-       struct device dev;
        struct clk *wd_clk;
 
-       dev_set_name(&dev, "watchdog");
-       wd_clk = clk_get(&dev, NULL);
+       wd_clk = clk_get(&davinci_wdt_device.dev, NULL);
        if (WARN_ON(IS_ERR(wd_clk)))
                return;
        clk_enable(wd_clk);


_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to