clk: rockchip: only enter pll slow-mode directly before reboots on rk3288
authorHeiko Stuebner <heiko@sntech.de>
Fri, 18 Dec 2015 16:51:55 +0000 (17:51 +0100)
committerHeiko Stuebner <heiko@sntech.de>
Mon, 21 Dec 2015 01:01:19 +0000 (02:01 +0100)
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>
drivers/clk/rockchip/clk-rk3036.c
drivers/clk/rockchip/clk-rk3188.c
drivers/clk/rockchip/clk-rk3228.c
drivers/clk/rockchip/clk-rk3288.c
drivers/clk/rockchip/clk-rk3368.c
drivers/clk/rockchip/clk.c
drivers/clk/rockchip/clk.h

index 77a9d757ff85baf08cb15488f59914bc1f49f7ab..7333b05342ff52d2dd52786557578ed702d318d3 100644 (file)
@@ -473,6 +473,6 @@ static void __init rk3036_clk_init(struct device_node *np)
        rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK2928_GLB_SRST_FST);
+       rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
 }
 CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
index abb47608713bc39a8fddbdf915f29955b10a497f..c2c35d4cdda8e0a9b3688674299b378e9d396e5c 100644 (file)
@@ -750,7 +750,7 @@ static void __init rk3188_common_clk_init(struct device_node *np)
        rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK2928_GLB_SRST_FST);
+       rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
 }
 
 static void __init rk3066a_clk_init(struct device_node *np)
index 87a7e5930f6428f8e39247827f2966d0b593f96a..981a50205339609617c271556c9d3227c0b3bd2c 100644 (file)
@@ -673,6 +673,6 @@ static void __init rk3228_clk_init(struct device_node *np)
        rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK3228_GLB_SRST_FST);
+       rockchip_register_restart_notifier(RK3228_GLB_SRST_FST, NULL);
 }
 CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);
index 66d954e20cbf2d0417f322c47746945341c34c0b..11b40fbc4a53ae351d740104e028c85657b6c7f9 100644 (file)
@@ -848,7 +848,6 @@ static void rk3288_clk_shutdown(void)
 static struct syscore_ops rk3288_clk_syscore_ops = {
        .suspend = rk3288_clk_suspend,
        .resume = rk3288_clk_resume,
-       .shutdown = rk3288_clk_shutdown,
 };
 
 static void __init rk3288_clk_init(struct device_node *np)
@@ -906,7 +905,8 @@ static void __init rk3288_clk_init(struct device_node *np)
                                  rk3288_cru_base + RK3288_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK3288_GLB_SRST_FST);
+       rockchip_register_restart_notifier(RK3288_GLB_SRST_FST,
+                                          rk3288_clk_shutdown);
        register_syscore_ops(&rk3288_clk_syscore_ops);
 }
 CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
index 1faf1602a3fca0db2aae452618087a5cb143b33d..be0ede52226994a0ae7248c8098285e0ebfd4a86 100644 (file)
@@ -889,6 +889,6 @@ static void __init rk3368_clk_init(struct device_node *np)
        rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK3368_GLB_SRST_FST);
+       rockchip_register_restart_notifier(RK3368_GLB_SRST_FST, NULL);
 }
 CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init);
index be6c7fd8315df99de06c81ce66118761326a9290..443d6f07acad6fe07150ea02c42d218760a235f3 100644 (file)
@@ -341,9 +341,13 @@ void __init rockchip_clk_protect_critical(const char *const clocks[],
 }
 
 static unsigned int reg_restart;
+static void (*cb_restart)(void);
 static int rockchip_restart_notify(struct notifier_block *this,
                                   unsigned long mode, void *cmd)
 {
+       if (cb_restart)
+               cb_restart();
+
        writel(0xfdb9, reg_base + reg_restart);
        return NOTIFY_DONE;
 }
@@ -353,11 +357,12 @@ static struct notifier_block rockchip_restart_handler = {
        .priority = 128,
 };
 
-void __init rockchip_register_restart_notifier(unsigned int reg)
+void __init rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void))
 {
        int ret;
 
        reg_restart = reg;
+       cb_restart = cb;
        ret = register_restart_handler(&rockchip_restart_handler);
        if (ret)
                pr_err("%s: cannot register restart handler, %d\n",
index 01bc372bb0482c7081c122aa11e6cee65e9e3cc8..809ef81cf63b7d9d97ff3fee58b98f88f89bf6fc 100644 (file)
@@ -503,7 +503,7 @@ void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
                        const struct rockchip_cpuclk_rate_table *rates,
                        int nrates);
 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
-void rockchip_register_restart_notifier(unsigned int reg);
+void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void));
 
 #define ROCKCHIP_SOFTRST_HIWORD_MASK   BIT(0)