Re: [PATCH v7 04/20] kernel: Add combined power-off+restart handler call chain API

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

 



On 4/20/22 21:47, Rafael J. Wysocki wrote:
+       spin_unlock(&platform_power_off_lock);
+
+       if (ret)
+               return ret;
+
+       ret = register_power_off_handler(&priv->power_off_nb);
+       if (ret)
+               priv->platform_power_off_cb = NULL;
+
+       return ret;
+}
+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.
+ *
+ *     Returns zero on success, or error code on failure.
+ */
+int unregister_platform_power_off(void (*power_off)(void))
+{
+       struct sys_off_handler_private_data *priv;
+       int ret;
+
+       priv = sys_off_handler_private_data(&platform_power_off_handler);
+
+       if (priv->platform_power_off_cb != power_off)
+               return -EINVAL;
+
+       ret = unregister_power_off_handler(&priv->power_off_nb);
+       priv->platform_power_off_cb = NULL;
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(unregister_platform_power_off);
+
+/**
+ *     do_kernel_power_off - Execute kernel power-off handler call chain
+ *
+ *     Calls functions registered with register_power_off_handler.
+ *
+ *     Expected to be called as last step of the power-off sequence.
+ *
+ *     Powers off the system immediately if a power-off handler function has
+ *     been registered. Otherwise does nothing.
+ */
+void do_kernel_power_off(void)
+{
+       /* legacy pm_power_off() is unchained and has highest priority */
+       if (pm_power_off && pm_power_off != dummy_pm_power_off)
+               return pm_power_off();
+
+       blocking_notifier_call_chain(&power_off_handler_list, POWEROFF_NORMAL,
+                                    NULL);
+}
+
+static void do_kernel_power_off_prepare(void)
+{
+       /* legacy pm_power_off_prepare() is unchained and has highest priority */
+       if (pm_power_off_prepare)
+               return pm_power_off_prepare();
+
+       blocking_notifier_call_chain(&power_off_handler_list, POWEROFF_PREPARE,
+                                    NULL);
+}
+
 /**
  *     kernel_power_off - power_off the system
  *
@@ -304,8 +893,7 @@ EXPORT_SYMBOL_GPL(kernel_halt);
 void kernel_power_off(void)
 {
        kernel_shutdown_prepare(SYSTEM_POWER_OFF);
-       if (pm_power_off_prepare)
-               pm_power_off_prepare();
+       do_kernel_power_off_prepare();
        migrate_to_reboot_cpu();
        syscore_shutdown();
        pr_emerg("Power down\n");
@@ -314,6 +902,16 @@ void kernel_power_off(void)
 }
 EXPORT_SYMBOL_GPL(kernel_power_off);

+bool kernel_can_power_off(void)
+{
+       if (!pm_power_off &&
+           blocking_notifier_call_chain_is_empty(&power_off_handler_list))
+               return false;
+
+       return true;
return pm_power_off ||
blocking_notifier_call_chain_is_empty(&power_off_handler_list);
Thank you for the thorough review!
You're very welcome!

Thanks again for taking a look at the patches. I don't have strong
preferences about the names and etc, so I'll update it all in v8 like
you suggested.

-- 
Best regards,
Dmitry



[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux