clkdev framework uses global mutex to protect clock tree, so it is not
possible to call clk_get() in interrupt context. This patch fixes this
issue and makes system reset by watchdog call working again.

Signed-off-by: Marek Szyprowski <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
---
 arch/arm/mach-exynos4/clock.c                      |    1 +
 arch/arm/mach-s3c2412/clock.c                      |    1 +
 arch/arm/mach-s3c2416/clock.c                      |    2 +-
 arch/arm/mach-s3c2443/clock.c                      |    1 +
 arch/arm/mach-s3c64xx/clock.c                      |    1 +
 arch/arm/mach-s5p64x0/cpu.c                        |    2 ++
 arch/arm/mach-s5pc100/clock.c                      |    1 +
 arch/arm/mach-s5pv210/clock.c                      |    1 +
 arch/arm/plat-s3c24xx/s3c2410-clock.c              |    1 +
 arch/arm/plat-samsung/clock.c                      |    9 +++++++++
 arch/arm/plat-samsung/include/plat/clock.h         |    2 ++
 .../arm/plat-samsung/include/plat/watchdog-reset.h |   10 +++-------
 12 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 851dea0..9dd4315 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -1211,4 +1211,5 @@ void __init exynos4_register_clocks(void)
        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
        s3c_pwmclk_init();
+       s3c_wdt_reset_init();
 }
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 140711d..1445bf6 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -752,5 +752,6 @@ int __init s3c2412_baseclk_add(void)
        }
 
        s3c_pwmclk_init();
+       s3c_wdt_reset_init();
        return 0;
 }
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
index 21a5e81..529e2a0 100644
--- a/arch/arm/mach-s3c2416/clock.c
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -139,5 +139,5 @@ void __init s3c2416_init_clocks(int xtal)
        s3c24xx_register_clock(&hsmmc0_clk);
 
        s3c_pwmclk_init();
-
+       s3c_wdt_reset_init();
 }
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index a1a7176..78ae013 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -365,4 +365,5 @@ void __init s3c2443_init_clocks(int xtal)
        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
        s3c_pwmclk_init();
+       s3c_wdt_reset_init();
 }
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 8cf39e3..86977d0 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -817,4 +817,5 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
        s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
        s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
        s3c_pwmclk_init();
+       s3c_wdt_reset_init();
 }
diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c
index a5c0095..876e0c7 100644
--- a/arch/arm/mach-s5p64x0/cpu.c
+++ b/arch/arm/mach-s5p64x0/cpu.c
@@ -136,6 +136,7 @@ void __init s5p6440_init_clocks(int xtal)
        s5p_register_clocks(xtal);
        s5p6440_register_clocks();
        s5p6440_setup_clocks();
+       s3c_wdt_reset_init();
 }
 
 void __init s5p6450_init_clocks(int xtal)
@@ -146,6 +147,7 @@ void __init s5p6450_init_clocks(int xtal)
        s5p_register_clocks(xtal);
        s5p6450_register_clocks();
        s5p6450_setup_clocks();
+       s3c_wdt_reset_init();
 }
 
 /*
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index ff5cbb3..bb60904 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -1277,4 +1277,5 @@ void __init s5pc100_register_clocks(void)
        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
        s3c_pwmclk_init();
+       s3c_wdt_reset_init();
 }
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 52a8e60..48a3963 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -1162,4 +1162,5 @@ void __init s5pv210_register_clocks(void)
        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
        s3c_pwmclk_init();
+       s3c_wdt_reset_init();
 }
diff --git a/arch/arm/plat-s3c24xx/s3c2410-clock.c 
b/arch/arm/plat-s3c24xx/s3c2410-clock.c
index def76aa..18bcf6a 100644
--- a/arch/arm/plat-s3c24xx/s3c2410-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2410-clock.c
@@ -249,5 +249,6 @@ int __init s3c2410_baseclk_add(void)
               (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
 
        s3c_pwmclk_init();
+       s3c_wdt_reset_init();
        return 0;
 }
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 302c426..141bd2e 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -64,6 +64,15 @@ static LIST_HEAD(clocks);
  */
 DEFINE_SPINLOCK(clocks_lock);
 
+/* Global watchdog clock used by arch_wtd_reset() callback */
+struct clk *s3c2410_wdtclk;
+void __init s3c_wdt_reset_init(void)
+{
+       s3c2410_wdtclk = clk_get(NULL, "watchdog");
+       if (IS_ERR(s3c2410_wdtclk))
+               printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", 
__func__);
+}
+
 /* enable and disable calls for use with the clk struct */
 
 static int clk_null_enable(struct clk *clk, int enable)
diff --git a/arch/arm/plat-samsung/include/plat/clock.h 
b/arch/arm/plat-samsung/include/plat/clock.h
index 87d5b38..5e625b4 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -81,6 +81,7 @@ extern struct clk clk_h2;
 extern struct clk clk_27m;
 extern struct clk clk_48m;
 extern struct clk clk_xusbxti;
+extern struct clk *s3c2410_wdtclk;
 
 extern int clk_default_setrate(struct clk *clk, unsigned long rate);
 extern struct clk_ops clk_ops_def_setrate;
@@ -120,4 +121,5 @@ extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
 /* Init for pwm clock code */
 
 extern void s3c_pwmclk_init(void);
+extern void __init s3c_wdt_reset_init(void);
 
diff --git a/arch/arm/plat-samsung/include/plat/watchdog-reset.h 
b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
index 54b762a..4fbbe5d 100644
--- a/arch/arm/plat-samsung/include/plat/watchdog-reset.h
+++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
@@ -12,6 +12,7 @@
 
 #include <plat/regs-watchdog.h>
 #include <mach/map.h>
+#include <plat/clock.h>
 
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -19,17 +20,12 @@
 
 static inline void arch_wdt_reset(void)
 {
-       struct clk *wdtclk;
-
        printk("arch_reset: attempting watchdog reset\n");
 
        __raw_writel(0, S3C2410_WTCON);   /* disable watchdog, to be safe  */
 
-       wdtclk = clk_get(NULL, "watchdog");
-       if (!IS_ERR(wdtclk)) {
-               clk_enable(wdtclk);
-       } else
-               printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", 
__func__);
+       if (s3c2410_wdtclk)
+               clk_enable(s3c2410_wdtclk);
 
        /* put initial values into count and data */
        __raw_writel(0x80, S3C2410_WTCNT);
-- 
1.7.1.569.g6f426

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to