On 3/1/23 10:07 AM, Lee Jones wrote:I'm not completely clear about PRIO recommendations. Will follow your suggestion.
On Fri, 03 Feb 2023, Jerome Neanne wrote:
Use new API for power-off mode support:
Link: https://lwn.net/Articles/894511/
Link: https://lore.kernel.org/all/7hfseqa7l0.fsf@xxxxxxxxxxxx/
sys-off API allows support of shutdown handler and restart handler.
Shutdown was not supported before that enhancement.
This is required for platform that are not using PSCI.
Not sure what platform doesn't have PSCI off, since you tested on
AM62-SK I'm guessing you manually disabled the PSCI off for testing?
Anyway I don't see any huge issues with the code itself, small comment below.
Test:
- restart:
# reboot
Default is cold reset:
# cat /sys/kernel/reboot/mode
Switch boot mode to warm reset:
# echo warm > /sys/kernel/reboot/mode
- power-off:
# halt
Tested on AM62-SP-SK board.
Signed-off-by: Jerome Neanne <jneanne@xxxxxxxxxxxx>
Suggested-by: Andrew Davis <afd@xxxxxx>
A review from Andrew would be helpful here.
---
drivers/mfd/tps65219.c | 45 +++++++++++++++++++++++++++++++-----------
1 file changed, 34 insertions(+), 11 deletions(-)
diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c
index 0e402fda206b..c134f3f6e202 100644
--- a/drivers/mfd/tps65219.c
+++ b/drivers/mfd/tps65219.c
@@ -25,25 +25,34 @@ static int tps65219_cold_reset(struct tps65219 *tps)
TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK);
}
-static int tps65219_restart(struct notifier_block *this,
- unsigned long reboot_mode, void *cmd)
+static int tps65219_soft_shutdown(struct tps65219 *tps)
{
- struct tps65219 *tps;
+ return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
+ TPS65219_MFP_I2C_OFF_REQ_MASK,
+ TPS65219_MFP_I2C_OFF_REQ_MASK);
+}
- tps = container_of(this, struct tps65219, nb);
+static int tps65219_power_off_handler(struct sys_off_data *data)
+{
+ tps65219_soft_shutdown(data->cb_data);
+ return NOTIFY_DONE;
+}
+static int tps65219_restart(struct tps65219 *tps,
+ unsigned long reboot_mode)
+{
if (reboot_mode == REBOOT_WARM)
tps65219_warm_reset(tps);
else
tps65219_cold_reset(tps);
-
return NOTIFY_DONE;
}
-static struct notifier_block pmic_rst_restart_nb = {
- .notifier_call = tps65219_restart,
- .priority = 200,
-};
+static int tps65219_restart_handler(struct sys_off_data *data)
+{
+ tps65219_restart(data->cb_data, data->mode);
+ return NOTIFY_DONE;
+}
static const struct resource tps65219_pwrbutton_resources[] = {
DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_FALLING_EDGE_DETECT, "falling"),
@@ -269,13 +278,27 @@ static int tps65219_probe(struct i2c_client *client)
}
}
- tps->nb = pmic_rst_restart_nb;
- ret = register_restart_handler(&tps->nb);
+ ret = devm_register_sys_off_handler(tps->dev,
+ SYS_OFF_MODE_RESTART,
+ SYS_OFF_PRIO_HIGH,
Why not default prio? SYS_OFF_PRIO_DEFAULT
Sure!
Then you can use this new helper devm_register_restart_handler()
Oh yes, right, this is solving the PRIO question by construction. This is definitely a better option
+ tps65219_restart_handler,
+ tps);
+
if (ret) {
dev_err(tps->dev, "cannot register restart handler, %d\n", ret);
return ret;
}
+ ret = devm_register_sys_off_handler(tps->dev,
+ SYS_OFF_MODE_POWER_OFF,
+ SYS_OFF_PRIO_DEFAULT,
+ tps65219_power_off_handler,
+ tps);
devm_register_power_off_handler()?
Otherwise I see no major issues,
Reviewed-by: Andrew Davis <afd@xxxxxx>
Andrew
+ if (ret) {
+ dev_err(tps->dev, "failed to register sys-off handler: %d\n",
+ ret);
+ return ret;
+ }
return 0;
}
--
2.34.1