[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v8 08/27] 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: Dmitry Osipenko <dmitry.osipenko@xxxxxxxxxxxxx>
---
 include/linux/reboot.h |  3 +++
 kernel/reboot.c        | 55 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index c52f77ee4ddd..f185b64faae0 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -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.
  */
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 982e58c11ce8..e74103f2a801 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -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)
-- 
2.35.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.