Skip to content

Commit

Permalink
kernel/reboot: Add register_platform_power_off()
Browse files Browse the repository at this point in the history
Add platform-level registration helpers that will ease transition of the
arch/platform power-off callbacks to the new sys-off based API, allowing
us to remove the global pm_power_off variable in the future.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Dmitry Osipenko authored and Rafael J. Wysocki committed May 19, 2022
1 parent 0e2110d commit fb61375
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/linux/reboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ int devm_register_sys_off_handler(struct device *dev,
int (*callback)(struct sys_off_data *data),
void *cb_data);

int register_platform_power_off(void (*power_off)(void));
void unregister_platform_power_off(void (*power_off)(void));

/*
* Architecture independent implemenations of sys_reboot commands.
*/
Expand Down
55 changes: 55 additions & 0 deletions kernel/reboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,61 @@ int devm_register_sys_off_handler(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_register_sys_off_handler);

static struct sys_off_handler *platform_power_off_handler;

static int platform_power_off_notify(struct sys_off_data *data)
{
void (*platform_power_power_off_cb)(void) = data->cb_data;

platform_power_power_off_cb();

return NOTIFY_DONE;
}

/**
* register_platform_power_off - Register platform-level power-off callback
* @power_off: Power-off callback
*
* Registers power-off callback that will be called as last step
* of the power-off sequence. This callback is expected to be invoked
* for the last resort. Only one platform power-off callback is allowed
* to be registered at a time.
*
* Returns zero on success, or error code on failure.
*/
int register_platform_power_off(void (*power_off)(void))
{
struct sys_off_handler *handler;

handler = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
SYS_OFF_PRIO_PLATFORM,
platform_power_off_notify,
power_off);
if (IS_ERR(handler))
return PTR_ERR(handler);

platform_power_off_handler = handler;

return 0;
}
EXPORT_SYMBOL_GPL(register_platform_power_off);

/**
* unregister_platform_power_off - Unregister platform-level power-off callback
* @power_off: Power-off callback
*
* Unregisters previously registered platform power-off callback.
*/
void unregister_platform_power_off(void (*power_off)(void))
{
if (platform_power_off_handler &&
platform_power_off_handler->cb_data == power_off) {
unregister_sys_off_handler(platform_power_off_handler);
platform_power_off_handler = NULL;
}
}
EXPORT_SYMBOL_GPL(unregister_platform_power_off);

static int legacy_pm_power_off_prepare(struct sys_off_data *data)
{
if (pm_power_off_prepare)
Expand Down

0 comments on commit fb61375

Please sign in to comment.