diff options
author | Heiko Stuebner <heiko@sntech.de> | 2015-12-18 11:51:55 -0500 |
---|---|---|
committer | Heiko Stuebner <heiko@sntech.de> | 2015-12-20 20:01:19 -0500 |
commit | dfff24bde7fb8d57482e907d5dfb0be3a9e28119 (patch) | |
tree | cc1a03e1a6db0fc471f9581a03625d1cc69cf0c8 | |
parent | 2abc02fc494fa4c920a08a1d0beecabafbcb2104 (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.c | 2 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-rk3188.c | 2 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-rk3228.c | 2 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-rk3288.c | 4 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-rk3368.c | 2 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk.c | 7 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk.h | 2 |
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 | } |
478 | CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init); | 478 | CLK_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 | ||
756 | static void __init rk3066a_clk_init(struct device_node *np) | 756 | static 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 | } |
678 | CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init); | 678 | CLK_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) | |||
848 | static struct syscore_ops rk3288_clk_syscore_ops = { | 848 | static 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 | ||
854 | static void __init rk3288_clk_init(struct device_node *np) | 853 | static 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 | } |
912 | CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); | 912 | CLK_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 | } |
894 | CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init); | 894 | CLK_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 | ||
343 | static unsigned int reg_restart; | 343 | static unsigned int reg_restart; |
344 | static void (*cb_restart)(void); | ||
344 | static int rockchip_restart_notify(struct notifier_block *this, | 345 | static 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 | ||
356 | void __init rockchip_register_restart_notifier(unsigned int reg) | 360 | void __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); |
505 | void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); | 505 | void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); |
506 | void rockchip_register_restart_notifier(unsigned int reg); | 506 | void 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 | ||