From b2a16610f2ba72468b4a7ac1e462af1e9c70bae8 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:29 +0000 Subject: power: reset: at91-reset: introduce struct at91_reset Introduce struct at91_reset intended to keep all the at91 reset controller data. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index d94e3267c3b6..2df0610e5527 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -49,7 +49,13 @@ enum reset_type { RESET_TYPE_ULP2 = 8, }; -static void __iomem *at91_ramc_base[2], *at91_rstc_base; +struct at91_reset { + void __iomem *rstc_base; +}; + +static struct at91_reset reset; + +static void __iomem *at91_ramc_base[2]; static struct clk *sclk; /* @@ -76,7 +82,7 @@ static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, "b .\n\t" : : "r" (at91_ramc_base[0]), - "r" (at91_rstc_base), + "r" (reset.rstc_base), "r" (1), "r" cpu_to_le32(AT91_SDRAMC_LPCB_POWER_DOWN), "r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)); @@ -119,7 +125,7 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, : : "r" (at91_ramc_base[0]), "r" (at91_ramc_base[1]), - "r" (at91_rstc_base), + "r" (reset.rstc_base), "r" (1), "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN), "r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST) @@ -131,8 +137,8 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, static int sama5d3_restart(struct notifier_block *this, unsigned long mode, void *cmd) { - writel(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, - at91_rstc_base); + writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST), + reset.rstc_base); return NOTIFY_DONE; } @@ -140,14 +146,16 @@ static int sama5d3_restart(struct notifier_block *this, unsigned long mode, static int samx7_restart(struct notifier_block *this, unsigned long mode, void *cmd) { - writel(AT91_RSTC_KEY | AT91_RSTC_PROCRST, at91_rstc_base); + writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PROCRST), + reset.rstc_base); + return NOTIFY_DONE; } static void __init at91_reset_status(struct platform_device *pdev) { const char *reason; - u32 reg = readl(at91_rstc_base + AT91_RSTC_SR); + u32 reg = readl(reset.rstc_base + AT91_RSTC_SR); switch ((reg & AT91_RSTC_RSTTYP) >> 8) { case RESET_TYPE_GENERAL: @@ -208,8 +216,8 @@ static int __init at91_reset_probe(struct platform_device *pdev) struct device_node *np; int ret, idx = 0; - at91_rstc_base = of_iomap(pdev->dev.of_node, 0); - if (!at91_rstc_base) { + reset.rstc_base = of_iomap(pdev->dev.of_node, 0); + if (!reset.rstc_base) { dev_err(&pdev->dev, "Could not map reset controller address\n"); return -ENODEV; } -- cgit From 4d9ce0f56aeeb46c8be0e8974646f163d3f6b72d Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:30 +0000 Subject: power: reset: at91-reset: add ramc_base[] to struct at91_reset Add ramc_base[] to struct at91_reset. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 2df0610e5527..999d3a1653d2 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -51,11 +51,11 @@ enum reset_type { struct at91_reset { void __iomem *rstc_base; + void __iomem *ramc_base[2]; }; static struct at91_reset reset; -static void __iomem *at91_ramc_base[2]; static struct clk *sclk; /* @@ -81,7 +81,7 @@ static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, "b .\n\t" : - : "r" (at91_ramc_base[0]), + : "r" (reset.ramc_base[0]), "r" (reset.rstc_base), "r" (1), "r" cpu_to_le32(AT91_SDRAMC_LPCB_POWER_DOWN), @@ -123,8 +123,8 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, " b .\n\t" : - : "r" (at91_ramc_base[0]), - "r" (at91_ramc_base[1]), + : "r" (reset.ramc_base[0]), + "r" (reset.ramc_base[1]), "r" (reset.rstc_base), "r" (1), "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN), @@ -225,8 +225,8 @@ static int __init at91_reset_probe(struct platform_device *pdev) if (!of_device_is_compatible(pdev->dev.of_node, "atmel,sama5d3-rstc")) { /* we need to shutdown the ddr controller, so get ramc base */ for_each_matching_node(np, at91_ramc_of_match) { - at91_ramc_base[idx] = of_iomap(np, 0); - if (!at91_ramc_base[idx]) { + reset.ramc_base[idx] = of_iomap(np, 0); + if (!reset.ramc_base[idx]) { dev_err(&pdev->dev, "Could not map ram controller address\n"); of_node_put(np); return -ENODEV; -- cgit From f9e6ce74cbf2a34f4d37bccbbfc7865e5b3e01dd Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:30 +0000 Subject: power: reset: at91-reset: add sclk to struct at91_reset Add sclk to struct at91_reset. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 999d3a1653d2..1bc39bfda0aa 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -52,12 +52,11 @@ enum reset_type { struct at91_reset { void __iomem *rstc_base; void __iomem *ramc_base[2]; + struct clk *sclk; }; static struct at91_reset reset; -static struct clk *sclk; - /* * unless the SDRAM is cleanly shutdown before we hit the * reset register it can be left driving the data bus and @@ -238,11 +237,11 @@ static int __init at91_reset_probe(struct platform_device *pdev) match = of_match_node(at91_reset_of_match, pdev->dev.of_node); at91_restart_nb.notifier_call = match->data; - sclk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(sclk)) - return PTR_ERR(sclk); + reset.sclk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(reset.sclk)) + return PTR_ERR(reset.sclk); - ret = clk_prepare_enable(sclk); + ret = clk_prepare_enable(reset.sclk); if (ret) { dev_err(&pdev->dev, "Could not enable slow clock\n"); return ret; @@ -250,7 +249,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) ret = register_restart_handler(&at91_restart_nb); if (ret) { - clk_disable_unprepare(sclk); + clk_disable_unprepare(reset.sclk); return ret; } @@ -262,7 +261,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) static int __exit at91_reset_remove(struct platform_device *pdev) { unregister_restart_handler(&at91_restart_nb); - clk_disable_unprepare(sclk); + clk_disable_unprepare(reset.sclk); return 0; } -- cgit From 1e3c4af9de26a0246cf00aba207c49846e80c37b Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:31 +0000 Subject: power: reset: at91-reset: add notifier block to struct at91_reset Add struct notifier_block to struct at91_reset. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 1bc39bfda0aa..e8840193620d 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -53,6 +53,7 @@ struct at91_reset { void __iomem *rstc_base; void __iomem *ramc_base[2]; struct clk *sclk; + struct notifier_block nb; }; static struct at91_reset reset; @@ -205,10 +206,6 @@ static const struct of_device_id at91_reset_of_match[] = { }; MODULE_DEVICE_TABLE(of, at91_reset_of_match); -static struct notifier_block at91_restart_nb = { - .priority = 192, -}; - static int __init at91_reset_probe(struct platform_device *pdev) { const struct of_device_id *match; @@ -235,7 +232,8 @@ static int __init at91_reset_probe(struct platform_device *pdev) } match = of_match_node(at91_reset_of_match, pdev->dev.of_node); - at91_restart_nb.notifier_call = match->data; + reset.nb.notifier_call = match->data; + reset.nb.priority = 192; reset.sclk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(reset.sclk)) @@ -247,7 +245,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) return ret; } - ret = register_restart_handler(&at91_restart_nb); + ret = register_restart_handler(&reset.nb); if (ret) { clk_disable_unprepare(reset.sclk); return ret; @@ -260,7 +258,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) static int __exit at91_reset_remove(struct platform_device *pdev) { - unregister_restart_handler(&at91_restart_nb); + unregister_restart_handler(&reset.nb); clk_disable_unprepare(reset.sclk); return 0; -- cgit From b7967b7919f0e3787d6e23424b5ad367fbb937e2 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:31 +0000 Subject: power: reset: at91-reset: convert reset in pointer to struct at91_reset Convert reset in pointer to struct at91_reset. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 50 ++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 23 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index e8840193620d..4bb5eef4b258 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -56,7 +56,7 @@ struct at91_reset { struct notifier_block nb; }; -static struct at91_reset reset; +static struct at91_reset *reset; /* * unless the SDRAM is cleanly shutdown before we hit the @@ -81,8 +81,8 @@ static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, "b .\n\t" : - : "r" (reset.ramc_base[0]), - "r" (reset.rstc_base), + : "r" (reset->ramc_base[0]), + "r" (reset->rstc_base), "r" (1), "r" cpu_to_le32(AT91_SDRAMC_LPCB_POWER_DOWN), "r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)); @@ -123,9 +123,9 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, " b .\n\t" : - : "r" (reset.ramc_base[0]), - "r" (reset.ramc_base[1]), - "r" (reset.rstc_base), + : "r" (reset->ramc_base[0]), + "r" (reset->ramc_base[1]), + "r" (reset->rstc_base), "r" (1), "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN), "r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST) @@ -138,7 +138,7 @@ static int sama5d3_restart(struct notifier_block *this, unsigned long mode, void *cmd) { writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST), - reset.rstc_base); + reset->rstc_base); return NOTIFY_DONE; } @@ -147,7 +147,7 @@ static int samx7_restart(struct notifier_block *this, unsigned long mode, void *cmd) { writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PROCRST), - reset.rstc_base); + reset->rstc_base); return NOTIFY_DONE; } @@ -155,7 +155,7 @@ static int samx7_restart(struct notifier_block *this, unsigned long mode, static void __init at91_reset_status(struct platform_device *pdev) { const char *reason; - u32 reg = readl(reset.rstc_base + AT91_RSTC_SR); + u32 reg = readl(reset->rstc_base + AT91_RSTC_SR); switch ((reg & AT91_RSTC_RSTTYP) >> 8) { case RESET_TYPE_GENERAL: @@ -212,8 +212,12 @@ static int __init at91_reset_probe(struct platform_device *pdev) struct device_node *np; int ret, idx = 0; - reset.rstc_base = of_iomap(pdev->dev.of_node, 0); - if (!reset.rstc_base) { + reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL); + if (!reset) + return -ENOMEM; + + reset->rstc_base = of_iomap(pdev->dev.of_node, 0); + if (!reset->rstc_base) { dev_err(&pdev->dev, "Could not map reset controller address\n"); return -ENODEV; } @@ -221,8 +225,8 @@ static int __init at91_reset_probe(struct platform_device *pdev) if (!of_device_is_compatible(pdev->dev.of_node, "atmel,sama5d3-rstc")) { /* we need to shutdown the ddr controller, so get ramc base */ for_each_matching_node(np, at91_ramc_of_match) { - reset.ramc_base[idx] = of_iomap(np, 0); - if (!reset.ramc_base[idx]) { + reset->ramc_base[idx] = of_iomap(np, 0); + if (!reset->ramc_base[idx]) { dev_err(&pdev->dev, "Could not map ram controller address\n"); of_node_put(np); return -ENODEV; @@ -232,22 +236,22 @@ static int __init at91_reset_probe(struct platform_device *pdev) } match = of_match_node(at91_reset_of_match, pdev->dev.of_node); - reset.nb.notifier_call = match->data; - reset.nb.priority = 192; + reset->nb.notifier_call = match->data; + reset->nb.priority = 192; - reset.sclk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(reset.sclk)) - return PTR_ERR(reset.sclk); + reset->sclk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(reset->sclk)) + return PTR_ERR(reset->sclk); - ret = clk_prepare_enable(reset.sclk); + ret = clk_prepare_enable(reset->sclk); if (ret) { dev_err(&pdev->dev, "Could not enable slow clock\n"); return ret; } - ret = register_restart_handler(&reset.nb); + ret = register_restart_handler(&reset->nb); if (ret) { - clk_disable_unprepare(reset.sclk); + clk_disable_unprepare(reset->sclk); return ret; } @@ -258,8 +262,8 @@ static int __init at91_reset_probe(struct platform_device *pdev) static int __exit at91_reset_remove(struct platform_device *pdev) { - unregister_restart_handler(&reset.nb); - clk_disable_unprepare(reset.sclk); + unregister_restart_handler(&reset->nb); + clk_disable_unprepare(reset->sclk); return 0; } -- cgit From 55f8e6fdefbe926e1729bba3a7608eed7d7f24f5 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:32 +0000 Subject: power: reset: at91-reset: pass rstc base address to at91_reset_status() Add new argument to at91_reset_status() that is the pointer to reset controller base address. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 4bb5eef4b258..bd05496c5ac7 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -152,10 +152,11 @@ static int samx7_restart(struct notifier_block *this, unsigned long mode, return NOTIFY_DONE; } -static void __init at91_reset_status(struct platform_device *pdev) +static void __init at91_reset_status(struct platform_device *pdev, + void __iomem *base) { const char *reason; - u32 reg = readl(reset->rstc_base + AT91_RSTC_SR); + u32 reg = readl(base + AT91_RSTC_SR); switch ((reg & AT91_RSTC_RSTTYP) >> 8) { case RESET_TYPE_GENERAL: @@ -255,7 +256,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) return ret; } - at91_reset_status(pdev); + at91_reset_status(pdev, reset->rstc_base); return 0; } -- cgit From 583ef884c8dc8e5ec9a7fde12d40ef7fdf18f5fb Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:32 +0000 Subject: power: reset: at91-reset: devm_kzalloc() for at91_reset data structure Allocate at91_reset data on probe and set it as platform data. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index bd05496c5ac7..7ba77555e9e1 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -56,8 +56,6 @@ struct at91_reset { struct notifier_block nb; }; -static struct at91_reset *reset; - /* * unless the SDRAM is cleanly shutdown before we hit the * reset register it can be left driving the data bus and @@ -66,6 +64,8 @@ static struct at91_reset *reset; static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, void *cmd) { + struct at91_reset *reset = container_of(this, struct at91_reset, nb); + asm volatile( /* Align to cache lines */ ".balign 32\n\t" @@ -93,6 +93,8 @@ static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, void *cmd) { + struct at91_reset *reset = container_of(this, struct at91_reset, nb); + asm volatile( /* * Test wether we have a second RAM controller to care @@ -137,6 +139,8 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, static int sama5d3_restart(struct notifier_block *this, unsigned long mode, void *cmd) { + struct at91_reset *reset = container_of(this, struct at91_reset, nb); + writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST), reset->rstc_base); @@ -146,6 +150,8 @@ static int sama5d3_restart(struct notifier_block *this, unsigned long mode, static int samx7_restart(struct notifier_block *this, unsigned long mode, void *cmd) { + struct at91_reset *reset = container_of(this, struct at91_reset, nb); + writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PROCRST), reset->rstc_base); @@ -210,6 +216,7 @@ MODULE_DEVICE_TABLE(of, at91_reset_of_match); static int __init at91_reset_probe(struct platform_device *pdev) { const struct of_device_id *match; + struct at91_reset *reset; struct device_node *np; int ret, idx = 0; @@ -250,6 +257,8 @@ static int __init at91_reset_probe(struct platform_device *pdev) return ret; } + platform_set_drvdata(pdev, reset); + ret = register_restart_handler(&reset->nb); if (ret) { clk_disable_unprepare(reset->sclk); @@ -263,6 +272,8 @@ static int __init at91_reset_probe(struct platform_device *pdev) static int __exit at91_reset_remove(struct platform_device *pdev) { + struct at91_reset *reset = platform_get_drvdata(pdev); + unregister_restart_handler(&reset->nb); clk_disable_unprepare(reset->sclk); -- cgit From a5bbad258a9ec41df4a158c828b9ef0af7955854 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:32 +0000 Subject: power: reset: at91-reset: introduce struct at91_reset_data Introduce struct at91_reset_data to be able to provide per SoC data. At the moment this being only notifier callback. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 50 +++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 7ba77555e9e1..c653bd7ac29a 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -49,6 +49,11 @@ enum reset_type { RESET_TYPE_ULP2 = 8, }; +struct at91_reset_data { + int (*notifier_call)(struct notifier_block *this, unsigned long mode, + void *cmd); +}; + struct at91_reset { void __iomem *rstc_base; void __iomem *ramc_base[2]; @@ -203,18 +208,50 @@ static const struct of_device_id at91_ramc_of_match[] = { { /* sentinel */ } }; +static const struct at91_reset_data at91sam9260_reset_data = { + .notifier_call = at91sam9260_restart, +}; + +static const struct at91_reset_data at91sam9g45_reset_data = { + .notifier_call = at91sam9g45_restart, +}; + +static const struct at91_reset_data sama5d3_reset_data = { + .notifier_call = sama5d3_restart, +}; + +static const struct at91_reset_data samx7_reset_data = { + .notifier_call = samx7_restart, +}; + static const struct of_device_id at91_reset_of_match[] = { - { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart }, - { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart }, - { .compatible = "atmel,sama5d3-rstc", .data = sama5d3_restart }, - { .compatible = "atmel,samx7-rstc", .data = samx7_restart }, - { .compatible = "microchip,sam9x60-rstc", .data = samx7_restart }, + { + .compatible = "atmel,at91sam9260-rstc", + .data = &at91sam9260_reset_data + }, + { + .compatible = "atmel,at91sam9g45-rstc", + .data = &at91sam9g45_reset_data + }, + { + .compatible = "atmel,sama5d3-rstc", + .data = &sama5d3_reset_data + }, + { + .compatible = "atmel,samx7-rstc", + .data = &samx7_reset_data + }, + { + .compatible = "microchip,sam9x60-rstc", + .data = &samx7_reset_data + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, at91_reset_of_match); static int __init at91_reset_probe(struct platform_device *pdev) { + const struct at91_reset_data *reset_data; const struct of_device_id *match; struct at91_reset *reset; struct device_node *np; @@ -244,7 +281,8 @@ static int __init at91_reset_probe(struct platform_device *pdev) } match = of_match_node(at91_reset_of_match, pdev->dev.of_node); - reset->nb.notifier_call = match->data; + reset_data = match->data; + reset->nb.notifier_call = reset_data->notifier_call; reset->nb.priority = 192; reset->sclk = devm_clk_get(&pdev->dev, NULL); -- cgit From 25b80b7d5a5b41cb52db441e37a04d71e7196f60 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:33 +0000 Subject: power: reset: at91-reset: introduce args member in at91_reset_data Introduce args member in struct at91_reset_data. It stores the value that needs to be written in mode register so that the reboot actions to happen. With these changes samx7_restart() could be removed. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index c653bd7ac29a..dc48f6850796 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -52,6 +52,7 @@ enum reset_type { struct at91_reset_data { int (*notifier_call)(struct notifier_block *this, unsigned long mode, void *cmd); + u32 args; }; struct at91_reset { @@ -59,6 +60,7 @@ struct at91_reset { void __iomem *ramc_base[2]; struct clk *sclk; struct notifier_block nb; + u32 args; }; /* @@ -90,7 +92,7 @@ static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, "r" (reset->rstc_base), "r" (1), "r" cpu_to_le32(AT91_SDRAMC_LPCB_POWER_DOWN), - "r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)); + "r" (reset->args)); return NOTIFY_DONE; } @@ -135,7 +137,7 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, "r" (reset->rstc_base), "r" (1), "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN), - "r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST) + "r" (reset->args) : "r0"); return NOTIFY_DONE; @@ -146,19 +148,7 @@ static int sama5d3_restart(struct notifier_block *this, unsigned long mode, { struct at91_reset *reset = container_of(this, struct at91_reset, nb); - writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST), - reset->rstc_base); - - return NOTIFY_DONE; -} - -static int samx7_restart(struct notifier_block *this, unsigned long mode, - void *cmd) -{ - struct at91_reset *reset = container_of(this, struct at91_reset, nb); - - writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PROCRST), - reset->rstc_base); + writel(reset->args, reset->rstc_base); return NOTIFY_DONE; } @@ -210,18 +200,22 @@ static const struct of_device_id at91_ramc_of_match[] = { static const struct at91_reset_data at91sam9260_reset_data = { .notifier_call = at91sam9260_restart, + .args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, }; static const struct at91_reset_data at91sam9g45_reset_data = { .notifier_call = at91sam9g45_restart, + .args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, }; static const struct at91_reset_data sama5d3_reset_data = { .notifier_call = sama5d3_restart, + .args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, }; static const struct at91_reset_data samx7_reset_data = { - .notifier_call = samx7_restart, + .notifier_call = sama5d3_restart, + .args = AT91_RSTC_KEY | AT91_RSTC_PROCRST, }; static const struct of_device_id at91_reset_of_match[] = { @@ -284,6 +278,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) reset_data = match->data; reset->nb.notifier_call = reset_data->notifier_call; reset->nb.priority = 192; + reset->args = reset_data->args; reset->sclk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(reset->sclk)) -- cgit From 7cb290d3dd559dff5028b9418a31ecb99988f640 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:33 +0000 Subject: power: reset: at91-reset: use r4 as tmp argument Use r4 as temporary register. On ARM r0-r3 should be used to hold function arguments. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index dc48f6850796..3b1d566350f4 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -113,8 +113,8 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, "beq 1f\n\t" /* Then, test that the RAM controller is enabled */ - "ldr r0, [%1]\n\t" - "cmp r0, #0\n\t" + "ldr r4, [%1]\n\t" + "cmp r4, #0\n\t" /* Align to cache lines */ ".balign 32\n\t" @@ -138,7 +138,7 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, "r" (1), "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN), "r" (reset->args) - : "r0"); + : "r4"); return NOTIFY_DONE; } -- cgit From 68a84a3e68a2238036dd6c7dbb677fe62a92d70a Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:34 +0000 Subject: power: reset: at91-reset: introduce ramc_lpr to struct at91_reset Introduce ramc_lpr to struct at91_reset. This will lead to the unification of at91sam9260_restart() and at91sam9g45_restart(). Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 3b1d566350f4..4e1961334e4d 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -61,6 +61,7 @@ struct at91_reset { struct clk *sclk; struct notifier_block nb; u32 args; + u32 ramc_lpr; }; /* @@ -81,7 +82,7 @@ static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, "str %2, [%0, #" __stringify(AT91_SDRAMC_TR) "]\n\t" /* Power down SDRAM */ - "str %3, [%0, #" __stringify(AT91_SDRAMC_LPR) "]\n\t" + "str %3, [%0, %5]\n\t" /* Reset CPU */ "str %4, [%1, #" __stringify(AT91_RSTC_CR) "]\n\t" @@ -92,7 +93,8 @@ static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, "r" (reset->rstc_base), "r" (1), "r" cpu_to_le32(AT91_SDRAMC_LPCB_POWER_DOWN), - "r" (reset->args)); + "r" (reset->args), + "r" (reset->ramc_lpr)); return NOTIFY_DONE; } @@ -122,11 +124,11 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, /* Disable SDRAM0 accesses */ "1: str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" /* Power down SDRAM0 */ - " str %4, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t" + " str %4, [%0, %6]\n\t" /* Disable SDRAM1 accesses */ " strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" /* Power down SDRAM1 */ - " strne %4, [%1, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t" + " strne %4, [%1, %6]\n\t" /* Reset CPU */ " str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t" @@ -137,7 +139,8 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, "r" (reset->rstc_base), "r" (1), "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN), - "r" (reset->args) + "r" (reset->args), + "r" (reset->ramc_lpr) : "r4"); return NOTIFY_DONE; @@ -193,8 +196,14 @@ static void __init at91_reset_status(struct platform_device *pdev, } static const struct of_device_id at91_ramc_of_match[] = { - { .compatible = "atmel,at91sam9260-sdramc", }, - { .compatible = "atmel,at91sam9g45-ddramc", }, + { + .compatible = "atmel,at91sam9260-sdramc", + .data = (void *)AT91_SDRAMC_LPR, + }, + { + .compatible = "atmel,at91sam9g45-ddramc", + .data = (void *)AT91_DDRSDRC_LPR, + }, { /* sentinel */ } }; @@ -263,7 +272,8 @@ static int __init at91_reset_probe(struct platform_device *pdev) if (!of_device_is_compatible(pdev->dev.of_node, "atmel,sama5d3-rstc")) { /* we need to shutdown the ddr controller, so get ramc base */ - for_each_matching_node(np, at91_ramc_of_match) { + for_each_matching_node_and_match(np, at91_ramc_of_match, &match) { + reset->ramc_lpr = (u32)match->data; reset->ramc_base[idx] = of_iomap(np, 0); if (!reset->ramc_base[idx]) { dev_err(&pdev->dev, "Could not map ram controller address\n"); -- cgit From fcd0532fac2ac82cec6d7b43298c8ecfc93e1049 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:37 +0000 Subject: power: reset: at91-reset: make at91sam9g45_restart() generic Make at91sam9g45_restart() generic. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 4e1961334e4d..61433060d784 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -105,32 +105,23 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, struct at91_reset *reset = container_of(this, struct at91_reset, nb); asm volatile( - /* - * Test wether we have a second RAM controller to care - * about. - * - * First, test that we can dereference the virtual address. - */ - "cmp %1, #0\n\t" - "beq 1f\n\t" - - /* Then, test that the RAM controller is enabled */ - "ldr r4, [%1]\n\t" - "cmp r4, #0\n\t" - /* Align to cache lines */ ".balign 32\n\t" /* Disable SDRAM0 accesses */ - "1: str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" + " tst %0, #0\n\t" + " beq 1f\n\t" + " str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" /* Power down SDRAM0 */ " str %4, [%0, %6]\n\t" /* Disable SDRAM1 accesses */ + "1: tst %1, #0\n\t" + " beq 2f\n\t" " strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" /* Power down SDRAM1 */ " strne %4, [%1, %6]\n\t" /* Reset CPU */ - " str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t" + "2: str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t" " b .\n\t" : -- cgit From 51aa7d45f905ca03d3c61d32a09537903a7ea707 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:38 +0000 Subject: power: reset: at91-reset: keep only one reset function Keep only one reset function. With this, notifier_call member of struct at91_reset_data could be removed. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 52 +++------------------------------------- 1 file changed, 3 insertions(+), 49 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 61433060d784..9c1b69f76a01 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -50,8 +50,6 @@ enum reset_type { }; struct at91_reset_data { - int (*notifier_call)(struct notifier_block *this, unsigned long mode, - void *cmd); u32 args; }; @@ -69,38 +67,8 @@ struct at91_reset { * reset register it can be left driving the data bus and * killing the chance of a subsequent boot from NAND */ -static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, - void *cmd) -{ - struct at91_reset *reset = container_of(this, struct at91_reset, nb); - - asm volatile( - /* Align to cache lines */ - ".balign 32\n\t" - - /* Disable SDRAM accesses */ - "str %2, [%0, #" __stringify(AT91_SDRAMC_TR) "]\n\t" - - /* Power down SDRAM */ - "str %3, [%0, %5]\n\t" - - /* Reset CPU */ - "str %4, [%1, #" __stringify(AT91_RSTC_CR) "]\n\t" - - "b .\n\t" - : - : "r" (reset->ramc_base[0]), - "r" (reset->rstc_base), - "r" (1), - "r" cpu_to_le32(AT91_SDRAMC_LPCB_POWER_DOWN), - "r" (reset->args), - "r" (reset->ramc_lpr)); - - return NOTIFY_DONE; -} - -static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, - void *cmd) +static int at91_reset(struct notifier_block *this, unsigned long mode, + void *cmd) { struct at91_reset *reset = container_of(this, struct at91_reset, nb); @@ -137,16 +105,6 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, return NOTIFY_DONE; } -static int sama5d3_restart(struct notifier_block *this, unsigned long mode, - void *cmd) -{ - struct at91_reset *reset = container_of(this, struct at91_reset, nb); - - writel(reset->args, reset->rstc_base); - - return NOTIFY_DONE; -} - static void __init at91_reset_status(struct platform_device *pdev, void __iomem *base) { @@ -199,22 +157,18 @@ static const struct of_device_id at91_ramc_of_match[] = { }; static const struct at91_reset_data at91sam9260_reset_data = { - .notifier_call = at91sam9260_restart, .args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, }; static const struct at91_reset_data at91sam9g45_reset_data = { - .notifier_call = at91sam9g45_restart, .args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, }; static const struct at91_reset_data sama5d3_reset_data = { - .notifier_call = sama5d3_restart, .args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, }; static const struct at91_reset_data samx7_reset_data = { - .notifier_call = sama5d3_restart, .args = AT91_RSTC_KEY | AT91_RSTC_PROCRST, }; @@ -277,7 +231,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) match = of_match_node(at91_reset_of_match, pdev->dev.of_node); reset_data = match->data; - reset->nb.notifier_call = reset_data->notifier_call; + reset->nb.notifier_call = at91_reset; reset->nb.priority = 192; reset->args = reset_data->args; -- cgit From 766b0162e613a89a330382e566e29da57f5f0de5 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:39 +0000 Subject: power: reset: at91-reset: get rid of at91_reset_data After refactoring struct at91_reset_data and struct at91_reset_data at91sam9260_reset_data are not needed anymore. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 9c1b69f76a01..537ccb180568 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -49,10 +49,6 @@ enum reset_type { RESET_TYPE_ULP2 = 8, }; -struct at91_reset_data { - u32 args; -}; - struct at91_reset { void __iomem *rstc_base; void __iomem *ramc_base[2]; @@ -156,42 +152,29 @@ static const struct of_device_id at91_ramc_of_match[] = { { /* sentinel */ } }; -static const struct at91_reset_data at91sam9260_reset_data = { - .args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, -}; - -static const struct at91_reset_data at91sam9g45_reset_data = { - .args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, -}; - -static const struct at91_reset_data sama5d3_reset_data = { - .args = AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST, -}; - -static const struct at91_reset_data samx7_reset_data = { - .args = AT91_RSTC_KEY | AT91_RSTC_PROCRST, -}; - static const struct of_device_id at91_reset_of_match[] = { { .compatible = "atmel,at91sam9260-rstc", - .data = &at91sam9260_reset_data + .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST | + AT91_RSTC_PROCRST), }, { .compatible = "atmel,at91sam9g45-rstc", - .data = &at91sam9g45_reset_data + .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST | + AT91_RSTC_PROCRST) }, { .compatible = "atmel,sama5d3-rstc", - .data = &sama5d3_reset_data + .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST | + AT91_RSTC_PROCRST) }, { .compatible = "atmel,samx7-rstc", - .data = &samx7_reset_data + .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PROCRST) }, { .compatible = "microchip,sam9x60-rstc", - .data = &samx7_reset_data + .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PROCRST) }, { /* sentinel */ } }; @@ -199,7 +182,6 @@ MODULE_DEVICE_TABLE(of, at91_reset_of_match); static int __init at91_reset_probe(struct platform_device *pdev) { - const struct at91_reset_data *reset_data; const struct of_device_id *match; struct at91_reset *reset; struct device_node *np; @@ -230,10 +212,9 @@ static int __init at91_reset_probe(struct platform_device *pdev) } match = of_match_node(at91_reset_of_match, pdev->dev.of_node); - reset_data = match->data; reset->nb.notifier_call = at91_reset; reset->nb.priority = 192; - reset->args = reset_data->args; + reset->args = (u32)match->data; reset->sclk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(reset->sclk)) -- cgit From e48bbb52a2aad8613291a9e4e757bbf995769015 Mon Sep 17 00:00:00 2001 From: "Claudiu.Beznea@microchip.com" Date: Tue, 21 Jan 2020 10:03:39 +0000 Subject: power: reset: at91-reset: handle nrst async for sam9x60 Handle NRST asynchronously for SAM9X60 to avoid problem with fast drop of VDDCORE on shutdown operations in the first 100 us after CPU is shutdown. Signed-off-by: Claudiu Beznea Signed-off-by: Sebastian Reichel --- drivers/power/reset/at91-reset.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 537ccb180568..3ff9d93a5226 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -35,6 +35,7 @@ #define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */ #define AT91_RSTC_URSTEN BIT(0) /* User Reset Enable */ +#define AT91_RSTC_URSTASYNC BIT(2) /* User Reset Asynchronous Control */ #define AT91_RSTC_URSTIEN BIT(4) /* User Reset Interrupt Enable */ #define AT91_RSTC_ERSTL GENMASK(11, 8) /* External Reset Length */ @@ -228,6 +229,13 @@ static int __init at91_reset_probe(struct platform_device *pdev) platform_set_drvdata(pdev, reset); + if (of_device_is_compatible(pdev->dev.of_node, "microchip,sam9x60-rstc")) { + u32 val = readl(reset->rstc_base + AT91_RSTC_MR); + + writel(AT91_RSTC_KEY | AT91_RSTC_URSTASYNC | val, + reset->rstc_base + AT91_RSTC_MR); + } + ret = register_restart_handler(&reset->nb); if (ret) { clk_disable_unprepare(reset->sclk); -- cgit From 6cdd5b09cbe67365c42aee539f6fd00f2ecfdaab Mon Sep 17 00:00:00 2001 From: Sherry Zong Date: Mon, 9 Mar 2020 16:18:44 +0800 Subject: power: reset: sc27xx: Power off the external subsystems' connection When powering off the whole system, we should power off some external subsystems' connection firstly, otherwise some external subsystems will hold some power and result in powering down abnormally. Signed-off-by: Sherry Zong Signed-off-by: Baolin Wang Signed-off-by: Sebastian Reichel --- drivers/power/reset/sc27xx-poweroff.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/sc27xx-poweroff.c b/drivers/power/reset/sc27xx-poweroff.c index 29fb08b8faa0..2bedd4c58ddc 100644 --- a/drivers/power/reset/sc27xx-poweroff.c +++ b/drivers/power/reset/sc27xx-poweroff.c @@ -13,6 +13,8 @@ #define SC27XX_PWR_PD_HW 0xc2c #define SC27XX_PWR_OFF_EN BIT(0) +#define SC27XX_SLP_CTRL 0xdf0 +#define SC27XX_LDO_XTL_EN BIT(3) static struct regmap *regmap; @@ -40,6 +42,9 @@ static struct syscore_ops poweroff_syscore_ops = { static void sc27xx_poweroff_do_poweroff(void) { + /* Disable the external subsys connection's power firstly */ + regmap_write(regmap, SC27XX_SLP_CTRL, SC27XX_LDO_XTL_EN); + regmap_write(regmap, SC27XX_PWR_PD_HW, SC27XX_PWR_OFF_EN); } -- cgit From 274afbc3ad33136962d66447e89d02e3c142a30a Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Mon, 9 Mar 2020 16:18:45 +0800 Subject: power: reset: sc27xx: Change to use cpu_down() To allow the SC27XX driver can be built as a module, and the freeze_secondary_cpus() symbol is not exported, thus we can change to use the exported cpu_down() API to shut down other cpus to avoid racing, which is same as the freeze_secondary_cpus(). Signed-off-by: Baolin Wang Signed-off-by: Sebastian Reichel --- drivers/power/reset/sc27xx-poweroff.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/sc27xx-poweroff.c b/drivers/power/reset/sc27xx-poweroff.c index 2bedd4c58ddc..91b5eceeb810 100644 --- a/drivers/power/reset/sc27xx-poweroff.c +++ b/drivers/power/reset/sc27xx-poweroff.c @@ -29,10 +29,13 @@ static struct regmap *regmap; */ static void sc27xx_poweroff_shutdown(void) { -#ifdef CONFIG_PM_SLEEP_SMP - int cpu = smp_processor_id(); +#ifdef CONFIG_HOTPLUG_CPU + int cpu; - freeze_secondary_cpus(cpu); + for_each_online_cpu(cpu) { + if (cpu != smp_processor_id()) + cpu_down(cpu); + } #endif } -- cgit From f78c55e3b4806974f7d590b2aab8683232b7bd25 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Mon, 9 Mar 2020 16:18:46 +0800 Subject: power: reset: sc27xx: Allow the SC27XX poweroff driver building into a module Change the config to 'tristate' and use module_platform_driver() to allow the SC27XX poweroff driver building into a module, as well as adding some mudule information. Signed-off-by: Baolin Wang Signed-off-by: Sebastian Reichel --- drivers/power/reset/Kconfig | 2 +- drivers/power/reset/sc27xx-poweroff.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/power/reset') diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 513efe8e7628..890380302080 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -248,7 +248,7 @@ config SYSCON_REBOOT_MODE action according to the mode. config POWER_RESET_SC27XX - bool "Spreadtrum SC27xx PMIC power-off driver" + tristate "Spreadtrum SC27xx PMIC power-off driver" depends on MFD_SC27XX_PMIC || COMPILE_TEST help This driver supports powering off a system through diff --git a/drivers/power/reset/sc27xx-poweroff.c b/drivers/power/reset/sc27xx-poweroff.c index 91b5eceeb810..69863074daf6 100644 --- a/drivers/power/reset/sc27xx-poweroff.c +++ b/drivers/power/reset/sc27xx-poweroff.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -71,4 +72,8 @@ static struct platform_driver sc27xx_poweroff_driver = { .name = "sc27xx-poweroff", }, }; -builtin_platform_driver(sc27xx_poweroff_driver); +module_platform_driver(sc27xx_poweroff_driver); + +MODULE_DESCRIPTION("Power off driver for SC27XX PMIC Device"); +MODULE_AUTHOR("Baolin Wang "); +MODULE_LICENSE("GPL v2"); -- cgit