Message ID | 20211007060253.17049-5-digetx@gmail.com |
---|---|
State | Changes Requested |
Headers | show |
Series | Introduce power off call chain API | expand |
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@gmail.com> > --- > 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; >
19.10.2021 18:31, Lee Jones пишет: > 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@gmail.com> >> --- >> 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. > Thank you for taking a look at this. Guenter Roeck gave me advice based on his previous experience of working on this topic and I'm now in a process of finalizing v2 that will be a more comprehensive and nicer solution. So you will need to take another look soon, thanks.
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;
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@gmail.com> --- drivers/mfd/max77620.c | 22 +++++++++++++++------- include/linux/mfd/max77620.h | 2 ++ 2 files changed, 17 insertions(+), 7 deletions(-)