Commit fb61375e authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Rafael J. Wysocki
Browse files

kernel/reboot: Add register_platform_power_off()



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: default avatarDmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 0e2110d2
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -141,6 +141,9 @@ int devm_register_sys_off_handler(struct device *dev,
				  int (*callback)(struct sys_off_data *data),
				  int (*callback)(struct sys_off_data *data),
				  void *cb_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.
 * Architecture independent implemenations of sys_reboot commands.
 */
 */
+55 −0
Original line number Original line Diff line number Diff line
@@ -469,6 +469,61 @@ int devm_register_sys_off_handler(struct device *dev,
}
}
EXPORT_SYMBOL_GPL(devm_register_sys_off_handler);
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)
static int legacy_pm_power_off_prepare(struct sys_off_data *data)
{
{
	if (pm_power_off_prepare)
	if (pm_power_off_prepare)