[PATCH v2 1/2] power: pmic: pca9450: Add support for system reset
Paul Geurts
paul.geurts at prodrive-technologies.com
Mon Aug 18 09:45:14 CEST 2025
> The family of PCA9450 PMICs have the ability to perform system resets.
> Restarting via PMIC is preferred method of restarting the system as all
> the peripherals are brought to a know state after a power-cycle. The
> PCA9450 features a cold restart procedure which is initiated by an I2C
> command 0x14 to the SW_RST register.
>
> Support in Linux for restarting via PCA9450 PMIC has been added by
> Linux commit 6157e62b07d9 ("regulator: pca9450: Add restart handler").
>
> Now add support for it also in the U-Boot via sysreset framework.
>
> Signed-off-by: Primoz Fiser <primoz.fiser at norik.com>
Reviewed-by: Paul Geurts <paul.geurts at prodrive-technologies.com>
> ---
> Change in v2:
> - no change
>
> Link to v1: https://lore.kernel.org/all/20250716114547.1343797-1-primoz.fiser@norik.com/
>
> drivers/power/pmic/pca9450.c | 42 ++++++++++++++++++++++++++++++++++++
> include/power/pca9450.h | 2 ++
> 2 files changed, 44 insertions(+)
>
> diff --git a/drivers/power/pmic/pca9450.c b/drivers/power/pmic/pca9450.c
> index 9d875f8bdbe8..abc39d0a1946 100644
> --- a/drivers/power/pmic/pca9450.c
> +++ b/drivers/power/pmic/pca9450.c
> @@ -7,15 +7,18 @@
> #include <errno.h>
> #include <dm.h>
> #include <dm/device_compat.h>
> +#include <dm/lists.h>
> #include <i2c.h>
> #include <linux/err.h>
> #include <log.h>
> #include <asm/global_data.h>
> #include <asm-generic/gpio.h>
> +#include <linux/delay.h>
> #include <linux/printk.h>
> #include <power/pmic.h>
> #include <power/regulator.h>
> #include <power/pca9450.h>
> +#include <sysreset.h>
>
> DECLARE_GLOBAL_DATA_PTR;
>
> @@ -101,6 +104,14 @@ static int pca9450_probe(struct udevice *dev)
> }
> }
>
> + if (CONFIG_IS_ENABLED(SYSRESET)) {
> + ret = device_bind_driver_to_node(dev, "pca9450_sysreset",
> + "pca9450_sysreset",
> + dev_ofnode(dev), NULL);
> + if (ret)
> + return ret;
> + }
> +
> if (ofnode_read_bool(dev_ofnode(dev), "nxp,wdog_b-warm-reset"))
> reset_ctrl = PCA9450_PMIC_RESET_WDOG_B_CFG_WARM;
> else
> @@ -134,3 +145,34 @@ U_BOOT_DRIVER(pmic_pca9450) = {
> .ops = &pca9450_ops,
> .priv_auto = sizeof(struct pca9450_priv),
> };
> +
> +#ifdef CONFIG_SYSRESET
> +static int pca9450_sysreset_request(struct udevice *dev, enum sysreset_t type)
> +{
> + u8 cmd = PCA9450_SW_RST_COLD_RST;
> +
> + if (type != SYSRESET_COLD)
> + return -EPROTONOSUPPORT;
> +
> + if (pmic_write(dev->parent, PCA9450_SW_RST, &cmd, 1)) {
> + dev_err(dev, "reset command failed\n");
> + } else {
> + /* tRESTART is 250ms, delay 300ms just to be sure */
> + mdelay(300);
> + /* Should not get here, warn if we do */
> + dev_warn(dev, "didn't respond to reset command\n");
> + }
> +
> + return -EINPROGRESS;
> +}
> +
> +static struct sysreset_ops pca9450_sysreset_ops = {
> + .request = pca9450_sysreset_request,
> +};
> +
> +U_BOOT_DRIVER(pca9450_sysreset) = {
> + .name = "pca9450_sysreset",
> + .id = UCLASS_SYSRESET,
> + .ops = &pca9450_sysreset_ops,
> +};
> +#endif /* CONFIG_SYSRESET */
> diff --git a/include/power/pca9450.h b/include/power/pca9450.h
> index e5ab09fb8c83..9119ef793b1f 100644
> --- a/include/power/pca9450.h
> +++ b/include/power/pca9450.h
> @@ -75,4 +75,6 @@ enum {
> #define PCA9450_PMIC_RESET_WDOG_B_CFG_WARM 0x40
> #define PCA9450_PMIC_RESET_WDOG_B_CFG_COLD_LDO12 0x80
>
> +#define PCA9450_SW_RST_COLD_RST 0x14
> +
> #endif
> --
> 2.34.1
br,
Paul
More information about the U-Boot
mailing list