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(-) 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; -- 2.32.0