ARM: imx: move clk_prepare() out from mxc_restart()
It's inappropriate to call clk_prepare() in mxc_restart(), because the restart routine could be called in atomic context. Move clk_get() and clk_prepare() into mxc_arch_reset_init() and only have the atomic part clk_enable() be called in mxc_restart(). As a result, mxc_arch_reset_init() needs to be called after clk gets initialized. While there, it also changes printk(KERN_ERR ...) to pr_err() and adds __init annotation for mxc_arch_reset_init(). Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
This commit is contained in:
parent
24a83fe4b0
commit
18cb680f1a
12 changed files with 39 additions and 18 deletions
|
@ -15,10 +15,13 @@
|
|||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
#include "mx25.h"
|
||||
|
||||
static void __init imx25_dt_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,12 +16,15 @@
|
|||
#include <asm/mach/time.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
#include "mx27.h"
|
||||
|
||||
static void __init imx27_dt_init(void)
|
||||
{
|
||||
struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
|
||||
|
||||
mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
|
||||
platform_device_register_full(&devinfo);
|
||||
|
|
|
@ -16,10 +16,13 @@
|
|||
#include <asm/mach/time.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
#include "mx31.h"
|
||||
|
||||
static void __init imx31_dt_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,15 @@
|
|||
#include <asm/mach/time.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
#include "mx51.h"
|
||||
|
||||
static void __init imx51_dt_init(void)
|
||||
{
|
||||
struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
|
||||
|
||||
mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
platform_device_register_full(&devinfo);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <asm/mach/time.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
#include "mx53.h"
|
||||
|
||||
static void __init imx53_qsb_init(void)
|
||||
|
@ -38,6 +39,8 @@ static void __init imx53_qsb_init(void)
|
|||
|
||||
static void __init imx53_dt_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
|
||||
|
||||
if (of_machine_is_compatible("fsl,imx53-qsb"))
|
||||
imx53_qsb_init();
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ void __init mx1_map_io(void)
|
|||
void __init imx1_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX1);
|
||||
mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
|
||||
imx_iomuxv1_init(MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR),
|
||||
MX1_NUM_GPIO_PORT);
|
||||
}
|
||||
|
@ -51,6 +50,7 @@ void __init mx1_init_irq(void)
|
|||
|
||||
void __init imx1_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
|
||||
|
|
|
@ -66,7 +66,6 @@ void __init mx21_map_io(void)
|
|||
void __init imx21_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX21);
|
||||
mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
|
||||
imx_iomuxv1_init(MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR),
|
||||
MX21_NUM_GPIO_PORT);
|
||||
}
|
||||
|
@ -82,6 +81,7 @@ static const struct resource imx21_audmux_res[] __initconst = {
|
|||
|
||||
void __init imx21_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
|
|
|
@ -54,7 +54,6 @@ void __init imx25_init_early(void)
|
|||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX25);
|
||||
mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR));
|
||||
mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
|
||||
}
|
||||
|
||||
void __init mx25_init_irq(void)
|
||||
|
@ -89,6 +88,7 @@ static const struct resource imx25_audmux_res[] __initconst = {
|
|||
|
||||
void __init imx25_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
/* i.mx25 has the i.mx35 type gpio */
|
||||
|
|
|
@ -66,7 +66,6 @@ void __init mx27_map_io(void)
|
|||
void __init imx27_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX27);
|
||||
mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
|
||||
imx_iomuxv1_init(MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR),
|
||||
MX27_NUM_GPIO_PORT);
|
||||
}
|
||||
|
@ -82,6 +81,7 @@ static const struct resource imx27_audmux_res[] __initconst = {
|
|||
|
||||
void __init imx27_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
/* i.mx27 has the i.mx21 type gpio */
|
||||
|
|
|
@ -138,7 +138,6 @@ void __init mx31_map_io(void)
|
|||
void __init imx31_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX31);
|
||||
mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
|
||||
arch_ioremap_caller = imx3_ioremap_caller;
|
||||
arm_pm_idle = imx3_idle;
|
||||
mx3_ccm_base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
|
||||
|
@ -174,6 +173,7 @@ void __init imx31_soc_init(void)
|
|||
|
||||
imx3_init_l2x0();
|
||||
|
||||
mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
|
||||
|
@ -216,7 +216,6 @@ void __init imx35_init_early(void)
|
|||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX35);
|
||||
mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
|
||||
mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
|
||||
arm_pm_idle = imx3_idle;
|
||||
arch_ioremap_caller = imx3_ioremap_caller;
|
||||
mx3_ccm_base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
|
||||
|
@ -272,6 +271,7 @@ void __init imx35_soc_init(void)
|
|||
|
||||
imx3_init_l2x0();
|
||||
|
||||
mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
|
||||
|
|
|
@ -83,7 +83,6 @@ void __init imx51_init_early(void)
|
|||
imx51_ipu_mipi_setup();
|
||||
mxc_set_cpu_type(MXC_CPU_MX51);
|
||||
mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
|
||||
mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
|
||||
imx_src_init();
|
||||
}
|
||||
|
||||
|
@ -91,7 +90,6 @@ void __init imx53_init_early(void)
|
|||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX53);
|
||||
mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
|
||||
mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
|
||||
imx_src_init();
|
||||
}
|
||||
|
||||
|
@ -129,6 +127,7 @@ static const struct resource imx51_audmux_res[] __initconst = {
|
|||
|
||||
void __init imx51_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
/* i.mx51 has the i.mx35 type gpio */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "hardware.h"
|
||||
|
||||
static void __iomem *wdog_base;
|
||||
static struct clk *wdog_clk;
|
||||
|
||||
/*
|
||||
* Reset the system. It is called by machine_restart().
|
||||
|
@ -38,16 +39,13 @@ void mxc_restart(char mode, const char *cmd)
|
|||
{
|
||||
unsigned int wcr_enable;
|
||||
|
||||
if (cpu_is_mx1()) {
|
||||
wcr_enable = (1 << 0);
|
||||
} else {
|
||||
struct clk *clk;
|
||||
if (wdog_clk)
|
||||
clk_enable(wdog_clk);
|
||||
|
||||
clk = clk_get_sys("imx2-wdt.0", NULL);
|
||||
if (!IS_ERR(clk))
|
||||
clk_prepare_enable(clk);
|
||||
if (cpu_is_mx1())
|
||||
wcr_enable = (1 << 0);
|
||||
else
|
||||
wcr_enable = (1 << 2);
|
||||
}
|
||||
|
||||
/* Assert SRS signal */
|
||||
__raw_writew(wcr_enable, wdog_base);
|
||||
|
@ -55,7 +53,7 @@ void mxc_restart(char mode, const char *cmd)
|
|||
/* wait for reset to assert... */
|
||||
mdelay(500);
|
||||
|
||||
printk(KERN_ERR "Watchdog reset failed to assert reset\n");
|
||||
pr_err("%s: Watchdog reset failed to assert reset\n", __func__);
|
||||
|
||||
/* delay to allow the serial port to show the message */
|
||||
mdelay(50);
|
||||
|
@ -64,7 +62,16 @@ void mxc_restart(char mode, const char *cmd)
|
|||
soft_restart(0);
|
||||
}
|
||||
|
||||
void mxc_arch_reset_init(void __iomem *base)
|
||||
void __init mxc_arch_reset_init(void __iomem *base)
|
||||
{
|
||||
wdog_base = base;
|
||||
|
||||
wdog_clk = clk_get_sys("imx2-wdt.0", NULL);
|
||||
if (IS_ERR(wdog_clk)) {
|
||||
pr_warn("%s: failed to get wdog clock\n", __func__);
|
||||
wdog_clk = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
clk_prepare(wdog_clk);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue