[PATCH v2] ARM: Samsung: fix watchdog reset issue with clk_get()

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

 



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 <m.szyprowski@xxxxxxxxxxx>
Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SoC Development]     [Linux Rockchip Development]     [Linux USB Development]     [Video for Linux]     [Linux Audio Users]     [Linux SCSI]     [Yosemite News]

  Powered by Linux