On Sun, 24 Oct 2021 21:00:10 -0500 Samuel Holland <[email protected]> wrote:
> The AXP PMICs have the ability to power off the system. The existing > code for this is duplicated for each PMIC variant, and uses the legacy > non-DM "pmic_bus" interface. When SYSRESET is enabled, this can all be > replaced with a sysreset device using the DM_PMIC interface. > > Since the trigger bit is the same on all PMIC variants, use the register > definitions from the oldest supported PMIC. > > Signed-off-by: Samuel Holland <[email protected]> Thanks for the quick turnaround! Reviewed-by: Andre Przywara <[email protected]> Cheers, Andre > --- > > Changes in v2: > - Rebased on top of u-boot/master (axp_pmic_bind) > > drivers/power/pmic/Kconfig | 2 ++ > drivers/power/pmic/axp.c | 49 +++++++++++++++++++++++++++++++++++++- > 2 files changed, 50 insertions(+), 1 deletion(-) > > diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig > index 92e2ace279..b9fda428df 100644 > --- a/drivers/power/pmic/Kconfig > +++ b/drivers/power/pmic/Kconfig > @@ -66,6 +66,8 @@ config PMIC_ACT8846 > config PMIC_AXP > bool "Enable Driver Model for X-Powers AXP PMICs" > depends on DM_I2C > + select SYSRESET_CMD_POWEROFF if SYSRESET && CMD_POWEROFF > + imply CMD_POWEROFF if SYSRESET > help > This config enables driver-model PMIC uclass features for > X-Powers AXP152, AXP2xx, and AXP8xx PMICs. > diff --git a/drivers/power/pmic/axp.c b/drivers/power/pmic/axp.c > index 74c94bdb47..0f2b24a8b5 100644 > --- a/drivers/power/pmic/axp.c > +++ b/drivers/power/pmic/axp.c > @@ -1,8 +1,37 @@ > // SPDX-License-Identifier: GPL-2.0+ > > +#include <axp_pmic.h> > #include <dm.h> > +#include <dm/lists.h> > #include <i2c.h> > #include <power/pmic.h> > +#include <sysreset.h> > + > +#if CONFIG_IS_ENABLED(SYSRESET) > +static int axp_sysreset_request(struct udevice *dev, enum sysreset_t type) > +{ > + int ret; > + > + if (type != SYSRESET_POWER_OFF) > + return -EPROTONOSUPPORT; > + > + ret = pmic_clrsetbits(dev->parent, AXP152_SHUTDOWN, 0, AXP152_POWEROFF); > + if (ret < 0) > + return ret; > + > + return -EINPROGRESS; > +} > + > +static struct sysreset_ops axp_sysreset_ops = { > + .request = axp_sysreset_request, > +}; > + > +U_BOOT_DRIVER(axp_sysreset) = { > + .name = "axp_sysreset", > + .id = UCLASS_SYSRESET, > + .ops = &axp_sysreset_ops, > +}; > +#endif > > static int axp_pmic_reg_count(struct udevice *dev) > { > @@ -16,6 +45,24 @@ static struct dm_pmic_ops axp_pmic_ops = { > .write = dm_i2c_write, > }; > > +static int axp_pmic_bind(struct udevice *dev) > +{ > + int ret; > + > + ret = dm_scan_fdt_dev(dev); > + if (ret) > + return ret; > + > + if (CONFIG_IS_ENABLED(SYSRESET)) { > + ret = device_bind_driver_to_node(dev, "axp_sysreset", > "axp_sysreset", > + dev_ofnode(dev), NULL); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > static const struct udevice_id axp_pmic_ids[] = { > { .compatible = "x-powers,axp152" }, > { .compatible = "x-powers,axp202" }, > @@ -33,6 +80,6 @@ U_BOOT_DRIVER(axp_pmic) = { > .name = "axp_pmic", > .id = UCLASS_PMIC, > .of_match = axp_pmic_ids, > - .bind = dm_scan_fdt_dev, > + .bind = axp_pmic_bind, > .ops = &axp_pmic_ops, > };

