[PATCH] soc: renesas: rmobile-sysc: Set OF_POPULATED and absorb reset handling

Sebastian Reichel sre at kernel.org
Tue Mar 2 15:44:06 GMT 2021


Hi,

On Fri, Feb 05, 2021 at 02:33:19PM +0100, Geert Uytterhoeven wrote:
> Currently, there are two drivers binding to the R-Mobile System
> Controller (SYSC):
>   - The rmobile-sysc driver registers PM domains from a core_initcall(),
>     and does not use a platform driver,
>   - The rmobile-reset driver registers a reset handler, and does use a
>     platform driver.
> 
> As fw_devlink only considers devices, it does not know that the
> rmobile-sysc driver is ready.  Hence if fw_devlink is enabled, probing
> of on-chip devices that are part of the SYSC PM domain is deferred until
> the optional rmobile-reset has been bound, which may happen too late
> (for e.g. the system timer on SoCs lacking an ARM architectured or
> global timer), or not at all, leading to complete system boot failures.
> 
> Fix this by:
>   1. Setting the OF_POPULATED flag for the SYSC device node after
>      successful initialization.
>      This will make of_link_to_phandle() ignore the SYSC device node as
>      a dependency, making consumer devices probe again.
>   2. Move reset handling from its own driver into the rmobile-sysc
>      driver.
>      This is needed because setting OF_POPULATED prevents the
>      rmobile-reset driver from binding against the same device.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
> To be queued in renesas-devel for v5.13.

Acked-by: Sebastian Reichel <sre at kernel.org>

-- Sebastian

> 
> Tested on:
>   - SH-Mobile AG5 (KZM-A9-GT),
>   - R-Mobile APE6 (APE6-EVM),
>   - R-Mobile A1 (Armadillo-800 EVA).
> 
>  drivers/power/reset/Kconfig         |  7 ---
>  drivers/power/reset/Makefile        |  1 -
>  drivers/power/reset/rmobile-reset.c | 88 -----------------------------
>  drivers/soc/renesas/rmobile-sysc.c  | 65 ++++++++++++++++++++-
>  4 files changed, 64 insertions(+), 97 deletions(-)
>  delete mode 100644 drivers/power/reset/rmobile-reset.c
> 
> diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
> index 1737e227b16e5136..417b112be3f660de 100644
> --- a/drivers/power/reset/Kconfig
> +++ b/drivers/power/reset/Kconfig
> @@ -251,13 +251,6 @@ config POWER_RESET_SYSCON_POWEROFF
>  	help
>  	  Poweroff support for generic SYSCON mapped register poweroff.
>  
> -config POWER_RESET_RMOBILE
> -	tristate "Renesas R-Mobile reset driver"
> -	depends on ARCH_RMOBILE || COMPILE_TEST
> -	depends on HAS_IOMEM
> -	help
> -	  Reboot support for Renesas R-Mobile and SH-Mobile SoCs.
> -
>  config POWER_RESET_ZX
>  	tristate "ZTE SoCs reset driver"
>  	depends on ARCH_ZX || COMPILE_TEST
> diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
> index b4601c0a96ed26c7..77a57ca8e5300d60 100644
> --- a/drivers/power/reset/Makefile
> +++ b/drivers/power/reset/Makefile
> @@ -29,7 +29,6 @@ obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o
>  obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o
>  obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o
>  obj-$(CONFIG_POWER_RESET_SYSCON_POWEROFF) += syscon-poweroff.o
> -obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o
>  obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
>  obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
>  obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
> diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
> deleted file mode 100644
> index bd3b396558e0df8c..0000000000000000
> --- a/drivers/power/reset/rmobile-reset.c
> +++ /dev/null
> @@ -1,88 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * Renesas R-Mobile Reset Driver
> - *
> - * Copyright (C) 2014 Glider bvba
> - */
> -
> -#include <linux/io.h>
> -#include <linux/module.h>
> -#include <linux/notifier.h>
> -#include <linux/of_address.h>
> -#include <linux/platform_device.h>
> -#include <linux/printk.h>
> -#include <linux/reboot.h>
> -
> -/* SYSC Register Bank 2 */
> -#define RESCNT2		0x20		/* Reset Control Register 2 */
> -
> -/* Reset Control Register 2 */
> -#define RESCNT2_PRES	0x80000000	/* Soft power-on reset */
> -
> -static void __iomem *sysc_base2;
> -
> -static int rmobile_reset_handler(struct notifier_block *this,
> -				 unsigned long mode, void *cmd)
> -{
> -	pr_debug("%s %lu\n", __func__, mode);
> -
> -	/* Let's assume we have acquired the HPB semaphore */
> -	writel(RESCNT2_PRES, sysc_base2 + RESCNT2);
> -
> -	return NOTIFY_DONE;
> -}
> -
> -static struct notifier_block rmobile_reset_nb = {
> -	.notifier_call = rmobile_reset_handler,
> -	.priority = 192,
> -};
> -
> -static int rmobile_reset_probe(struct platform_device *pdev)
> -{
> -	int error;
> -
> -	sysc_base2 = of_iomap(pdev->dev.of_node, 1);
> -	if (!sysc_base2)
> -		return -ENODEV;
> -
> -	error = register_restart_handler(&rmobile_reset_nb);
> -	if (error) {
> -		dev_err(&pdev->dev,
> -			"cannot register restart handler (err=%d)\n", error);
> -		goto fail_unmap;
> -	}
> -
> -	return 0;
> -
> -fail_unmap:
> -	iounmap(sysc_base2);
> -	return error;
> -}
> -
> -static int rmobile_reset_remove(struct platform_device *pdev)
> -{
> -	unregister_restart_handler(&rmobile_reset_nb);
> -	iounmap(sysc_base2);
> -	return 0;
> -}
> -
> -static const struct of_device_id rmobile_reset_of_match[] = {
> -	{ .compatible = "renesas,sysc-rmobile", },
> -	{ /* sentinel */ }
> -};
> -MODULE_DEVICE_TABLE(of, rmobile_reset_of_match);
> -
> -static struct platform_driver rmobile_reset_driver = {
> -	.probe = rmobile_reset_probe,
> -	.remove = rmobile_reset_remove,
> -	.driver = {
> -		.name = "rmobile_reset",
> -		.of_match_table = rmobile_reset_of_match,
> -	},
> -};
> -
> -module_platform_driver(rmobile_reset_driver);
> -
> -MODULE_DESCRIPTION("Renesas R-Mobile Reset Driver");
> -MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas at glider.be>");
> -MODULE_LICENSE("GPL v2");
> diff --git a/drivers/soc/renesas/rmobile-sysc.c b/drivers/soc/renesas/rmobile-sysc.c
> index bf64d052f9245db5..a8d85d111924d9ee 100644
> --- a/drivers/soc/renesas/rmobile-sysc.c
> +++ b/drivers/soc/renesas/rmobile-sysc.c
> @@ -1,10 +1,11 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /*
> - * rmobile power management support
> + * R-Mobile power management and reset support
>   *
>   * Copyright (C) 2012  Renesas Solutions Corp.
>   * Copyright (C) 2012  Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
>   * Copyright (C) 2014  Glider bvba
> + * Copyright (C) 2021  Glider bv
>   *
>   * based on pm-sh7372.c
>   *  Copyright (C) 2011 Magnus Damm
> @@ -12,11 +13,13 @@
>  #include <linux/clk/renesas.h>
>  #include <linux/console.h>
>  #include <linux/delay.h>
> +#include <linux/notifier.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/pm.h>
>  #include <linux/pm_clock.h>
>  #include <linux/pm_domain.h>
> +#include <linux/reboot.h>
>  #include <linux/slab.h>
>  
>  #include <asm/io.h>
> @@ -29,6 +32,11 @@
>  #define PSTR_RETRIES	100
>  #define PSTR_DELAY_US	10
>  
> +/* SYSC Register Bank 2 */
> +#define RESCNT2		0x20	/* Reset Control Register 2 */
> +
> +#define RESCNT2_PRES	BIT(31)	/* Soft power-on reset */
> +
>  struct rmobile_pm_domain {
>  	struct generic_pm_domain genpd;
>  	struct dev_power_governor *gov;
> @@ -309,6 +317,54 @@ static int __init rmobile_add_pm_domains(void __iomem *base,
>  	return 0;
>  }
>  
> +struct rmobile_reset {
> +	void __iomem *base;
> +	struct notifier_block nb;
> +};
> +
> +static int rmobile_reset_handler(struct notifier_block *this,
> +				 unsigned long mode, void *cmd)
> +{
> +	struct rmobile_reset *reset = container_of(this, struct rmobile_reset,
> +						   nb);
> +
> +	pr_debug("%s %lu\n", __func__, mode);
> +
> +	/* Let's assume we have acquired the HPB semaphore */
> +	writel(RESCNT2_PRES, reset->base + RESCNT2);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static int rmobile_reset_setup(struct device_node *np)
> +{
> +	struct rmobile_reset *reset;
> +	int error;
> +
> +	reset = kzalloc(sizeof(*reset), GFP_KERNEL);
> +	if (!reset)
> +		return -ENOMEM;
> +
> +	reset->base = of_iomap(np, 1);
> +	if (!reset->base)
> +		goto fail_free;
> +
> +	reset->nb.notifier_call = rmobile_reset_handler;
> +	reset->nb.priority = 192;
> +
> +	error = register_restart_handler(&reset->nb);
> +	if (error)
> +		goto fail_unmap;
> +
> +	return 0;
> +
> +fail_unmap:
> +	iounmap(reset->base);
> +fail_free:
> +	kfree(reset);
> +	return error;
> +}
> +
>  static int __init rmobile_init_pm_domains(void)
>  {
>  	struct device_node *np, *pmd;
> @@ -342,6 +398,13 @@ static int __init rmobile_init_pm_domains(void)
>  			of_node_put(np);
>  			break;
>  		}
> +
> +		of_node_set_flag(np, OF_POPULATED);
> +
> +		ret = rmobile_reset_setup(np);
> +		if (ret)
> +			pr_err("%pOF: cannot register restart handler (%d)\n",
> +			       np, ret);
>  	}
>  
>  	put_special_pds();
> -- 
> 2.25.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210302/efcb937e/attachment.sig>


More information about the linux-arm-kernel mailing list