aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Stuebner <heiko@sntech.de>2015-12-18 11:51:55 -0500
committerHeiko Stuebner <heiko@sntech.de>2015-12-20 20:01:19 -0500
commitdfff24bde7fb8d57482e907d5dfb0be3a9e28119 (patch)
treecc1a03e1a6db0fc471f9581a03625d1cc69cf0c8
parent2abc02fc494fa4c920a08a1d0beecabafbcb2104 (diff)
clk: rockchip: only enter pll slow-mode directly before reboots on rk3288
As commit 1d33929e2a2b ("clk: rockchip: switch PLLs to slow mode before reboot for rk3288") states, switching the PLLs to slow-mode is only necessary when rebooting using the soft-reset done through the CRU. The dwc2 controllers used create really big number of interrupts in special constellations involving usb-hubs and their number is so high, it can even overwhelm the interrupt handler if the cpu-speed os to low. Right now the PLLs are put into slow-mode in a shutdown syscore_ops callback which means it happens on all reboots (not only the soft-reset ones) and even on poweroff actions. This can result in the system not powering off and getting stuck instead, so we should move the slow-mode change nearer to the actual reboot action. For this we introduce the possiblity to also set a callback that gets called from the restart-handler directly prior to restarting the system and move the shutdown-callback to this new option. With this the slow-mode switch is done only on the necessary reboots and also has a smaller possibility of causing artifacts. Fixes: 1d33929e2a2b ("clk: rockchip: switch PLLs to slow mode before reboot for rk3288") Signed-off-by: Heiko Stuebner <heiko.stuebner@collabora.com> Reviewed-by: Douglas Anderson <dianders@chromium.org>
-rw-r--r--drivers/clk/rockchip/clk-rk3036.c2
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c2
-rw-r--r--drivers/clk/rockchip/clk-rk3228.c2
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c4
-rw-r--r--drivers/clk/rockchip/clk-rk3368.c2
-rw-r--r--drivers/clk/rockchip/clk.c7
-rw-r--r--drivers/clk/rockchip/clk.h2
7 files changed, 13 insertions, 8 deletions
diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c
index 77a9d757ff85..7333b05342ff 100644
--- a/drivers/clk/rockchip/clk-rk3036.c
+++ b/drivers/clk/rockchip/clk-rk3036.c
@@ -473,6 +473,6 @@ static void __init rk3036_clk_init(struct device_node *np)
473 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 473 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
474 ROCKCHIP_SOFTRST_HIWORD_MASK); 474 ROCKCHIP_SOFTRST_HIWORD_MASK);
475 475
476 rockchip_register_restart_notifier(RK2928_GLB_SRST_FST); 476 rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
477} 477}
478CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init); 478CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index abb47608713b..c2c35d4cdda8 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -750,7 +750,7 @@ static void __init rk3188_common_clk_init(struct device_node *np)
750 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 750 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
751 ROCKCHIP_SOFTRST_HIWORD_MASK); 751 ROCKCHIP_SOFTRST_HIWORD_MASK);
752 752
753 rockchip_register_restart_notifier(RK2928_GLB_SRST_FST); 753 rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
754} 754}
755 755
756static void __init rk3066a_clk_init(struct device_node *np) 756static void __init rk3066a_clk_init(struct device_node *np)
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
index 87a7e5930f64..981a50205339 100644
--- a/drivers/clk/rockchip/clk-rk3228.c
+++ b/drivers/clk/rockchip/clk-rk3228.c
@@ -673,6 +673,6 @@ static void __init rk3228_clk_init(struct device_node *np)
673 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 673 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
674 ROCKCHIP_SOFTRST_HIWORD_MASK); 674 ROCKCHIP_SOFTRST_HIWORD_MASK);
675 675
676 rockchip_register_restart_notifier(RK3228_GLB_SRST_FST); 676 rockchip_register_restart_notifier(RK3228_GLB_SRST_FST, NULL);
677} 677}
678CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init); 678CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 66d954e20cbf..11b40fbc4a53 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -848,7 +848,6 @@ static void rk3288_clk_shutdown(void)
848static struct syscore_ops rk3288_clk_syscore_ops = { 848static struct syscore_ops rk3288_clk_syscore_ops = {
849 .suspend = rk3288_clk_suspend, 849 .suspend = rk3288_clk_suspend,
850 .resume = rk3288_clk_resume, 850 .resume = rk3288_clk_resume,
851 .shutdown = rk3288_clk_shutdown,
852}; 851};
853 852
854static void __init rk3288_clk_init(struct device_node *np) 853static void __init rk3288_clk_init(struct device_node *np)
@@ -906,7 +905,8 @@ static void __init rk3288_clk_init(struct device_node *np)
906 rk3288_cru_base + RK3288_SOFTRST_CON(0), 905 rk3288_cru_base + RK3288_SOFTRST_CON(0),
907 ROCKCHIP_SOFTRST_HIWORD_MASK); 906 ROCKCHIP_SOFTRST_HIWORD_MASK);
908 907
909 rockchip_register_restart_notifier(RK3288_GLB_SRST_FST); 908 rockchip_register_restart_notifier(RK3288_GLB_SRST_FST,
909 rk3288_clk_shutdown);
910 register_syscore_ops(&rk3288_clk_syscore_ops); 910 register_syscore_ops(&rk3288_clk_syscore_ops);
911} 911}
912CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); 912CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c
index 1faf1602a3fc..be0ede522269 100644
--- a/drivers/clk/rockchip/clk-rk3368.c
+++ b/drivers/clk/rockchip/clk-rk3368.c
@@ -889,6 +889,6 @@ static void __init rk3368_clk_init(struct device_node *np)
889 rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0), 889 rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0),
890 ROCKCHIP_SOFTRST_HIWORD_MASK); 890 ROCKCHIP_SOFTRST_HIWORD_MASK);
891 891
892 rockchip_register_restart_notifier(RK3368_GLB_SRST_FST); 892 rockchip_register_restart_notifier(RK3368_GLB_SRST_FST, NULL);
893} 893}
894CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init); 894CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index be6c7fd8315d..443d6f07acad 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -341,9 +341,13 @@ void __init rockchip_clk_protect_critical(const char *const clocks[],
341} 341}
342 342
343static unsigned int reg_restart; 343static unsigned int reg_restart;
344static void (*cb_restart)(void);
344static int rockchip_restart_notify(struct notifier_block *this, 345static int rockchip_restart_notify(struct notifier_block *this,
345 unsigned long mode, void *cmd) 346 unsigned long mode, void *cmd)
346{ 347{
348 if (cb_restart)
349 cb_restart();
350
347 writel(0xfdb9, reg_base + reg_restart); 351 writel(0xfdb9, reg_base + reg_restart);
348 return NOTIFY_DONE; 352 return NOTIFY_DONE;
349} 353}
@@ -353,11 +357,12 @@ static struct notifier_block rockchip_restart_handler = {
353 .priority = 128, 357 .priority = 128,
354}; 358};
355 359
356void __init rockchip_register_restart_notifier(unsigned int reg) 360void __init rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void))
357{ 361{
358 int ret; 362 int ret;
359 363
360 reg_restart = reg; 364 reg_restart = reg;
365 cb_restart = cb;
361 ret = register_restart_handler(&rockchip_restart_handler); 366 ret = register_restart_handler(&rockchip_restart_handler);
362 if (ret) 367 if (ret)
363 pr_err("%s: cannot register restart handler, %d\n", 368 pr_err("%s: cannot register restart handler, %d\n",
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 01bc372bb048..809ef81cf63b 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -503,7 +503,7 @@ void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
503 const struct rockchip_cpuclk_rate_table *rates, 503 const struct rockchip_cpuclk_rate_table *rates,
504 int nrates); 504 int nrates);
505void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); 505void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
506void rockchip_register_restart_notifier(unsigned int reg); 506void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void));
507 507
508#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 508#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0)
509 509