[v2,4/4] power: reset: Add new driver for RZ/V2M PWC poweroff

Message ID 20221221210917.458537-5-fabrizio.castro.jz@renesas.com
State New
Headers
Series Driver support for RZ/V2M PWC |

Commit Message

Fabrizio Castro Dec. 21, 2022, 9:09 p.m. UTC
  The RZ/V2M PWC IP controls external power supplies and therefore
can turn the power supplies off when powering down the system.

Add driver to poweroff the system.

Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---

v1->v2: Dropped OF match table and syscon as a result of the change in
        DT model

 drivers/power/reset/Kconfig              |  9 ++++
 drivers/power/reset/Makefile             |  1 +
 drivers/power/reset/rzv2m-pwc-poweroff.c | 67 ++++++++++++++++++++++++
 3 files changed, 77 insertions(+)
 create mode 100644 drivers/power/reset/rzv2m-pwc-poweroff.c
  

Comments

Sebastian Reichel Jan. 2, 2023, 7:22 p.m. UTC | #1
Hi,

On Wed, Dec 21, 2022 at 09:09:17PM +0000, Fabrizio Castro wrote:
> The RZ/V2M PWC IP controls external power supplies and therefore
> can turn the power supplies off when powering down the system.
> 
> Add driver to poweroff the system.
> 
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> ---

Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

> 
> v1->v2: Dropped OF match table and syscon as a result of the change in
>         DT model
> 
>  drivers/power/reset/Kconfig              |  9 ++++
>  drivers/power/reset/Makefile             |  1 +
>  drivers/power/reset/rzv2m-pwc-poweroff.c | 67 ++++++++++++++++++++++++
>  3 files changed, 77 insertions(+)
>  create mode 100644 drivers/power/reset/rzv2m-pwc-poweroff.c
> 
> diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
> index a8c46ba5878f..1fcf691ae68e 100644
> --- a/drivers/power/reset/Kconfig
> +++ b/drivers/power/reset/Kconfig
> @@ -303,4 +303,13 @@ config POWER_MLXBF
>  	help
>  	  This driver supports reset or low power mode handling for Mellanox BlueField.
>  
> +config POWER_RESET_RZV2M_PWC
> +	tristate "Renesas RZ/V2M PWC Power OFF support"
> +	depends on MFD_RZV2M_PWC_CORE || COMPILE_TEST
> +	help
> +	  The RZ/V2M PWC IP controls external power supplies and therefore can
> +	  turn the power supplies off when powering down the system.
> +	  Enable this driver when PWC is in control of the system power supplies
> +	  and it's the preferred way to shutdown the system.
> +
>  endif
> diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
> index 0a39424fc558..f05a8abff2eb 100644
> --- a/drivers/power/reset/Makefile
> +++ b/drivers/power/reset/Makefile
> @@ -36,3 +36,4 @@ obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
>  obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
>  obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o
>  obj-$(CONFIG_POWER_MLXBF) += pwr-mlxbf.o
> +obj-$(CONFIG_POWER_RESET_RZV2M_PWC) += rzv2m-pwc-poweroff.o
> diff --git a/drivers/power/reset/rzv2m-pwc-poweroff.c b/drivers/power/reset/rzv2m-pwc-poweroff.c
> new file mode 100644
> index 000000000000..f5bc383c22e1
> --- /dev/null
> +++ b/drivers/power/reset/rzv2m-pwc-poweroff.c
> @@ -0,0 +1,67 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2022 Renesas Electronics Corporation
> + *
> + * Reset driver for Renesas RZ/V2M External Power Sequence Controller (PWC)
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/reboot.h>
> +#include "../../mfd/rzv2m-pwc.h"
> +
> +#define PWC_PWCRST_RSTSOFTAX		0x1
> +#define PWC_PWCCKEN_ENGCKMAIN		0x1
> +#define PWC_PWCCTL_PWOFF		0x1
> +
> +struct rzv2m_pwc_poweroff_priv {
> +	void __iomem *base;
> +	struct device *dev;
> +};
> +
> +static int rzv2m_pwc_poweroff(struct sys_off_data *data)
> +{
> +	struct rzv2m_pwc_poweroff_priv *priv =
> +		(struct rzv2m_pwc_poweroff_priv *)data->cb_data;
> +
> +	writel(PWC_PWCRST_RSTSOFTAX, priv->base + PWC_PWCRST);
> +	writel(PWC_PWCCKEN_ENGCKMAIN, priv->base + PWC_PWCCKEN);
> +	writel(PWC_PWCCTL_PWOFF, priv->base + PWC_PWCCTL);
> +
> +	mdelay(150);
> +
> +	dev_err(priv->dev, "Failed to power off the system");
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static int rzv2m_pwc_poweroff_probe(struct platform_device *pdev)
> +{
> +	struct rzv2m_pwc_priv *pdata = dev_get_drvdata(pdev->dev.parent);
> +	struct rzv2m_pwc_poweroff_priv *priv;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->base = pdata->base;
> +	priv->dev = &pdev->dev;
> +
> +	return devm_register_power_off_handler(&pdev->dev, rzv2m_pwc_poweroff,
> +					       priv);
> +}
> +
> +static struct platform_driver rzv2m_pwc_poweroff_driver = {
> +	.probe = rzv2m_pwc_poweroff_probe,
> +	.driver = {
> +		.name = "rzv2m_pwc_poweroff",
> +	},
> +};
> +module_platform_driver(rzv2m_pwc_poweroff_driver);
> +
> +MODULE_ALIAS("platform:rzv2m_pwc_poweroff");
> +MODULE_SOFTDEP("pre: rzv2m_pwc");
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Fabrizio Castro <castro.fabrizio.jz@renesas.com>");
> +MODULE_DESCRIPTION("Renesas RZ/V2M PWC power OFF driver");
> -- 
> 2.34.1
>
  
Geert Uytterhoeven Jan. 3, 2023, 8:26 a.m. UTC | #2
Hi Fabrizio,

On Wed, Dec 21, 2022 at 10:09 PM Fabrizio Castro
<fabrizio.castro.jz@renesas.com> wrote:
> The RZ/V2M PWC IP controls external power supplies and therefore
> can turn the power supplies off when powering down the system.
>
> Add driver to poweroff the system.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> ---
>
> v1->v2: Dropped OF match table and syscon as a result of the change in
>         DT model

Thanks for your patch!

> --- /dev/null
> +++ b/drivers/power/reset/rzv2m-pwc-poweroff.c
> @@ -0,0 +1,67 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2022 Renesas Electronics Corporation
> + *
> + * Reset driver for Renesas RZ/V2M External Power Sequence Controller (PWC)
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/reboot.h>
> +#include "../../mfd/rzv2m-pwc.h"
> +
> +#define PWC_PWCRST_RSTSOFTAX           0x1
> +#define PWC_PWCCKEN_ENGCKMAIN          0x1
> +#define PWC_PWCCTL_PWOFF               0x1
> +
> +struct rzv2m_pwc_poweroff_priv {
> +       void __iomem *base;
> +       struct device *dev;
> +};
> +
> +static int rzv2m_pwc_poweroff(struct sys_off_data *data)
> +{
> +       struct rzv2m_pwc_poweroff_priv *priv =
> +               (struct rzv2m_pwc_poweroff_priv *)data->cb_data;

No need for this cast.

> +
> +       writel(PWC_PWCRST_RSTSOFTAX, priv->base + PWC_PWCRST);
> +       writel(PWC_PWCCKEN_ENGCKMAIN, priv->base + PWC_PWCCKEN);
> +       writel(PWC_PWCCTL_PWOFF, priv->base + PWC_PWCCTL);
> +
> +       mdelay(150);
> +
> +       dev_err(priv->dev, "Failed to power off the system");
> +
> +       return NOTIFY_DONE;
> +}

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
  
Fabrizio Castro Jan. 5, 2023, 5:33 p.m. UTC | #3
Hi Geert,

Thanks for your feedback!

> 
> Hi Fabrizio,
> 
> On Wed, Dec 21, 2022 at 10:09 PM Fabrizio Castro
> <fabrizio.castro.jz@renesas.com> wrote:
> > The RZ/V2M PWC IP controls external power supplies and therefore
> > can turn the power supplies off when powering down the system.
> >
> > Add driver to poweroff the system.
> >
> > Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> > ---
> >
> > v1->v2: Dropped OF match table and syscon as a result of the change in
> >         DT model
> 
> Thanks for your patch!
> 
> > --- /dev/null
> > +++ b/drivers/power/reset/rzv2m-pwc-poweroff.c
> > @@ -0,0 +1,67 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (C) 2022 Renesas Electronics Corporation
> > + *
> > + * Reset driver for Renesas RZ/V2M External Power Sequence Controller
> (PWC)
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/io.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/reboot.h>
> > +#include "../../mfd/rzv2m-pwc.h"
> > +
> > +#define PWC_PWCRST_RSTSOFTAX           0x1
> > +#define PWC_PWCCKEN_ENGCKMAIN          0x1
> > +#define PWC_PWCCTL_PWOFF               0x1
> > +
> > +struct rzv2m_pwc_poweroff_priv {
> > +       void __iomem *base;
> > +       struct device *dev;
> > +};
> > +
> > +static int rzv2m_pwc_poweroff(struct sys_off_data *data)
> > +{
> > +       struct rzv2m_pwc_poweroff_priv *priv =
> > +               (struct rzv2m_pwc_poweroff_priv *)data->cb_data;
> 
> No need for this cast.

Thanks for pointing this out. I'll fix that in v3.

Thanks,
Fab

> 
> > +
> > +       writel(PWC_PWCRST_RSTSOFTAX, priv->base + PWC_PWCRST);
> > +       writel(PWC_PWCCKEN_ENGCKMAIN, priv->base + PWC_PWCCKEN);
> > +       writel(PWC_PWCCTL_PWOFF, priv->base + PWC_PWCCTL);
> > +
> > +       mdelay(150);
> > +
> > +       dev_err(priv->dev, "Failed to power off the system");
> > +
> > +       return NOTIFY_DONE;
> > +}
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker.
> But
> when I'm talking to journalists I just say "programmer" or something like
> that.
>                                 -- Linus Torvalds
  

Patch

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index a8c46ba5878f..1fcf691ae68e 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -303,4 +303,13 @@  config POWER_MLXBF
 	help
 	  This driver supports reset or low power mode handling for Mellanox BlueField.
 
+config POWER_RESET_RZV2M_PWC
+	tristate "Renesas RZ/V2M PWC Power OFF support"
+	depends on MFD_RZV2M_PWC_CORE || COMPILE_TEST
+	help
+	  The RZ/V2M PWC IP controls external power supplies and therefore can
+	  turn the power supplies off when powering down the system.
+	  Enable this driver when PWC is in control of the system power supplies
+	  and it's the preferred way to shutdown the system.
+
 endif
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 0a39424fc558..f05a8abff2eb 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -36,3 +36,4 @@  obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
 obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
 obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o
 obj-$(CONFIG_POWER_MLXBF) += pwr-mlxbf.o
+obj-$(CONFIG_POWER_RESET_RZV2M_PWC) += rzv2m-pwc-poweroff.o
diff --git a/drivers/power/reset/rzv2m-pwc-poweroff.c b/drivers/power/reset/rzv2m-pwc-poweroff.c
new file mode 100644
index 000000000000..f5bc383c22e1
--- /dev/null
+++ b/drivers/power/reset/rzv2m-pwc-poweroff.c
@@ -0,0 +1,67 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Renesas Electronics Corporation
+ *
+ * Reset driver for Renesas RZ/V2M External Power Sequence Controller (PWC)
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include "../../mfd/rzv2m-pwc.h"
+
+#define PWC_PWCRST_RSTSOFTAX		0x1
+#define PWC_PWCCKEN_ENGCKMAIN		0x1
+#define PWC_PWCCTL_PWOFF		0x1
+
+struct rzv2m_pwc_poweroff_priv {
+	void __iomem *base;
+	struct device *dev;
+};
+
+static int rzv2m_pwc_poweroff(struct sys_off_data *data)
+{
+	struct rzv2m_pwc_poweroff_priv *priv =
+		(struct rzv2m_pwc_poweroff_priv *)data->cb_data;
+
+	writel(PWC_PWCRST_RSTSOFTAX, priv->base + PWC_PWCRST);
+	writel(PWC_PWCCKEN_ENGCKMAIN, priv->base + PWC_PWCCKEN);
+	writel(PWC_PWCCTL_PWOFF, priv->base + PWC_PWCCTL);
+
+	mdelay(150);
+
+	dev_err(priv->dev, "Failed to power off the system");
+
+	return NOTIFY_DONE;
+}
+
+static int rzv2m_pwc_poweroff_probe(struct platform_device *pdev)
+{
+	struct rzv2m_pwc_priv *pdata = dev_get_drvdata(pdev->dev.parent);
+	struct rzv2m_pwc_poweroff_priv *priv;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->base = pdata->base;
+	priv->dev = &pdev->dev;
+
+	return devm_register_power_off_handler(&pdev->dev, rzv2m_pwc_poweroff,
+					       priv);
+}
+
+static struct platform_driver rzv2m_pwc_poweroff_driver = {
+	.probe = rzv2m_pwc_poweroff_probe,
+	.driver = {
+		.name = "rzv2m_pwc_poweroff",
+	},
+};
+module_platform_driver(rzv2m_pwc_poweroff_driver);
+
+MODULE_ALIAS("platform:rzv2m_pwc_poweroff");
+MODULE_SOFTDEP("pre: rzv2m_pwc");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabrizio Castro <castro.fabrizio.jz@renesas.com>");
+MODULE_DESCRIPTION("Renesas RZ/V2M PWC power OFF driver");