On Thu, 07 Oct 2021, Dmitry Osipenko wrote: > Use new power off call chain API which allows multiple power off handlers > to coexist. Nexus 7 Android tablet can be powered off using MAX77663 PMIC > and using a special bootloader command. At first the bootloader option > should be tried, it will have a higher priority than the PMIC. > > Signed-off-by: Dmitry Osipenko <digetx@xxxxxxxxx> > --- > drivers/mfd/max77620.c | 22 +++++++++++++++------- > include/linux/mfd/max77620.h | 2 ++ > 2 files changed, 17 insertions(+), 7 deletions(-) I don't have a problem with the approach in general. I guess it's up to the relevant maintainers to decide. > diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c > index fec2096474ad..ad40eed1f0c6 100644 > --- a/drivers/mfd/max77620.c > +++ b/drivers/mfd/max77620.c > @@ -31,11 +31,10 @@ > #include <linux/init.h> > #include <linux/of.h> > #include <linux/of_device.h> > +#include <linux/reboot.h> > #include <linux/regmap.h> > #include <linux/slab.h> > > -static struct max77620_chip *max77620_scratch; > - > static const struct resource gpio_resources[] = { > DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO), > }; > @@ -483,13 +482,17 @@ static int max77620_read_es_version(struct max77620_chip *chip) > return ret; > } > > -static void max77620_pm_power_off(void) > +static int max77620_pm_power_off(struct notifier_block *nb, > + unsigned long reboot_mode, void *data) > { > - struct max77620_chip *chip = max77620_scratch; > + struct max77620_chip *chip = container_of(nb, struct max77620_chip, > + pm_off_nb); > > regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1, > MAX77620_ONOFFCNFG1_SFT_RST, > MAX77620_ONOFFCNFG1_SFT_RST); > + > + return NOTIFY_DONE; > } > > static int max77620_probe(struct i2c_client *client, > @@ -566,9 +569,14 @@ static int max77620_probe(struct i2c_client *client, > } > > pm_off = of_device_is_system_power_controller(client->dev.of_node); > - if (pm_off && !pm_power_off) { > - max77620_scratch = chip; > - pm_power_off = max77620_pm_power_off; > + if (pm_off) { > + chip->pm_off_nb.notifier_call = max77620_pm_power_off; > + chip->pm_off_nb.priority = 128; > + > + ret = devm_register_poweroff_handler(chip->dev, &chip->pm_off_nb); > + if (ret < 0) > + dev_err(chip->dev, > + "Failed to register poweroff handler: %d\n", ret); > } > > return 0; > diff --git a/include/linux/mfd/max77620.h b/include/linux/mfd/max77620.h > index f552ef5b1100..99de4f8c9cbf 100644 > --- a/include/linux/mfd/max77620.h > +++ b/include/linux/mfd/max77620.h > @@ -8,6 +8,7 @@ > #ifndef _MFD_MAX77620_H_ > #define _MFD_MAX77620_H_ > > +#include <linux/notifier.h> > #include <linux/types.h> > > /* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */ > @@ -327,6 +328,7 @@ enum max77620_chip_id { > struct max77620_chip { > struct device *dev; > struct regmap *rmap; > + struct notifier_block pm_off_nb; > > int chip_irq; > -- Lee Jones [李琼斯] Senior Technical Lead - Developer Services Linaro.org │ Open source software for Arm SoCs Follow Linaro: Facebook | Twitter | Blog