linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 00/27] Introduce power-off+restart call chain API
@ 2022-05-09 23:32 Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 01/27] notifier: Add atomic_notifier_call_chain_is_empty() Dmitry Osipenko
                   ` (27 more replies)
  0 siblings, 28 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Problem
-------

SoC devices require power-off call chaining functionality from kernel.
We have a widely used restart chaining provided by restart notifier API,
but nothing for power-off.

Solution
--------

Introduce new API that provides call chains support for all restart and
power-off modes. The new API is designed with simplicity and extensibility
in mind.

This is a third attempt to introduce the new API. First was made by
Guenter Roeck back in 2014, second was made by Thierry Reding in 2017.
In fact the work didn't stop and recently arm_pm_restart() was removed
from v5.14 kernel, which was a part of preparatory work started by
Guenter Roeck.

Adoption plan
-------------

This patchset introduces the new API. It also converts multiple drivers
and arch code to the new API to demonstrate how it all looks in practice,
removing the pm_power_off_prepare global variable.

The plan is:

1. Merge the new API and convert arch code to use do_kernel_power_off().
   For now the new API will co-exist with the older API.

2. Convert all drivers and platform code to the new API.

3. Remove obsoleted pm_power_off and pm_power_off_prepare variables.

Results
-------

1. Devices can be powered off properly.

2. Global variables are removed from drivers.

3. Global pm_power_off and pm_power_off_prepare callback variables are
removed once all users are converted to the new API. The latter callback
is removed by patch #24 of this series.

4. Ambiguous call chain ordering is prohibited for non-default priorities.

Changelog:

v8: - Reworked sys-off handler like was suggested by Rafael Wysocki in
      the comments to v7.

    - The struct sys-off handler now is private to kernel/reboot.c and
      new API is simplified.

    - There is a single sys-off API function for all handler types.
      Users shall pass the required sys-off mode type (restart, power-off
      and etc).

    - There is single struct sys_off_data callback argument for all
      handler modes.

    - User's callback now must return NOTIFY_DONE or NOTIFY_STOP.

    - The default priority level is zero now.

    - Multiple handlers now allowed to be registered at the default
      priority level.

    - Power-off call chain is atomic now, like the restart chain.

    - kernel/reboot.c changes are split up into several logical patches.

    - Added r-b from Michał Mirosław to unmodified patches from v7.

    - Added acks that were missing in v7 by accident.

v7: - Rebased on a recent linux-next. Dropped the recently removed
      NDS32 architecture. Only SH and x86 arches left un-acked.

    - Added acks from Thomas Bogendoerfer and Krzysztof Kozlowski
      to the MIPS and memory/emif patches respectively.

    - Made couple minor cosmetic improvements to the new API.

    - A month ago I joined Collabora and continuing to work on this series
      on the company's time, so changed my email address to collabora.com

v6: - Rebased on a recent linux-next.

    - Made minor couple cosmetic changes.

v5: - Dropped patches which cleaned up notifier/reboot headers, as was
      requested by Rafael Wysocki.

    - Dropped WARN_ON() from the code, as was requested by Rafael Wysocki.
      Replaced it with pr_err() appropriately.

    - Dropped *_notifier_has_unique_priority() functions and added
      *_notifier_chain_register_unique_prio() instead, as was suggested
      by Michał Mirosław and Rafael Wysocki.

    - Dropped export of blocking_notifier_call_chain_is_empty() symbol,
      as was suggested by Rafael Wysocki.

    - Michał Mirosław suggested that will be better to split up patch
      that adds the new API to ease reviewing, but Rafael Wysocki asked
      not add more patches, so I kept it as a single patch.

    - Added temporary "weak" stub for pm_power_off() which fixes linkage
      failure once symbol is removed from arch/* code. Previously I missed
      this problem because was only compile-testing object files.

v4: - Made a very minor improvement to doc comments, clarifying couple
      default values.

    - Corrected list of emails recipient by adding Linus, Sebastian,
      Philipp and more NDS people. Removed bouncing emails.

    - Added acks that were given to v3.

v3: - Renamed power_handler to sys_off_handler as was suggested by
      Rafael Wysocki.

    - Improved doc-comments as was suggested by Rafael Wysocki. Added more
      doc-comments.

    - Implemented full set of 180 patches which convert whole kernel in
      accordance to the plan, see link [1] above. Slightly adjusted API to
      better suit for the remaining converted drivers.

      * Added unregister_sys_off_handler() that is handy for a couple old
        platform drivers.

      * Dropped devm_register_trivial_restart_handler(), 'simple' variant
        is enough to have.

    - Improved "Add atomic/blocking_notifier_has_unique_priority()" patch,
      as was suggested by Andy Shevchenko. Also replaced down_write() with
      down_read() and factored out common notifier_has_unique_priority().

    - Added stop_chain field to struct restart_data and reboot_prep_data
      after discovering couple drivers wanting that feature.

    - Added acks that were given to v2.

v2: - Replaced standalone power-off call chain demo-API with the combined
      power-off+restart API because this is what drivers want. It's a more
      comprehensive solution.

    - Converted multiple drivers and arch code to the new API. Suggested by
      Andy Shevchenko. I skimmed through the rest of drivers, verifying that
      new API suits them. The rest of the drivers will be converted once we
      will settle on the new API, otherwise will be too many patches here.

    - v2 API doesn't expose notifier to users and require handlers to
      have unique priority. Suggested by Guenter Roeck.

    - v2 API has power-off chaining disabled by default and require
      drivers to explicitly opt-in to the chaining. This preserves old
      behaviour for existing drivers once they are converted to the new
      API.

Dmitry Osipenko (27):
  notifier: Add atomic_notifier_call_chain_is_empty()
  notifier: Add blocking/atomic_notifier_chain_register_unique_prio()
  kernel/reboot: Introduce sys-off handler API
  kernel/reboot: Wrap legacy power-off callbacks into sys-off handlers
  kernel/reboot: Add do_kernel_power_off()
  kernel/reboot: Add stub for pm_power_off
  kernel/reboot: Add kernel_can_power_off()
  kernel/reboot: Add register_platform_power_off()
  ARM: Use do_kernel_power_off()
  csky: Use do_kernel_power_off()
  riscv: Use do_kernel_power_off()
  arm64: Use do_kernel_power_off()
  parisc: Use do_kernel_power_off()
  xen/x86: Use do_kernel_power_off()
  powerpc: Use do_kernel_power_off()
  m68k: Switch to new sys-off handler API
  sh: Use do_kernel_power_off()
  x86: Use do_kernel_power_off()
  ia64: Use do_kernel_power_off()
  mips: Use do_kernel_power_off()
  memory: emif: Use kernel_can_power_off()
  ACPI: power: Switch to sys-off handler API
  regulator: pfuze100: Use devm_register_sys_off_handler()
  reboot: Remove pm_power_off_prepare()
  soc/tegra: pmc: Use sys-off handler API to power off Nexus 7 properly
  kernel/reboot: Add devm_register_power_off_handler()
  kernel/reboot: Add devm_register_restart_handler()

 arch/arm/kernel/reboot.c               |   4 +-
 arch/arm64/kernel/process.c            |   3 +-
 arch/csky/kernel/power.c               |   6 +-
 arch/ia64/kernel/process.c             |   4 +-
 arch/m68k/emu/natfeat.c                |   3 +-
 arch/m68k/include/asm/machdep.h        |   1 -
 arch/m68k/kernel/process.c             |   5 +-
 arch/m68k/kernel/setup_mm.c            |   1 -
 arch/m68k/kernel/setup_no.c            |   1 -
 arch/m68k/mac/config.c                 |   4 +-
 arch/mips/kernel/reset.c               |   3 +-
 arch/parisc/kernel/process.c           |   4 +-
 arch/powerpc/kernel/setup-common.c     |   4 +-
 arch/powerpc/xmon/xmon.c               |   3 +-
 arch/riscv/kernel/reset.c              |  12 +-
 arch/sh/kernel/reboot.c                |   3 +-
 arch/x86/kernel/reboot.c               |   4 +-
 arch/x86/xen/enlighten_pv.c            |   4 +-
 drivers/acpi/sleep.c                   |  16 +-
 drivers/memory/emif.c                  |   2 +-
 drivers/regulator/pfuze100-regulator.c |  42 ++-
 drivers/soc/tegra/pmc.c                |  87 +++++--
 include/linux/notifier.h               |   7 +
 include/linux/pm.h                     |   1 -
 include/linux/reboot.h                 |  91 +++++++
 kernel/notifier.c                      | 101 +++++--
 kernel/reboot.c                        | 347 ++++++++++++++++++++++++-
 27 files changed, 639 insertions(+), 124 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v8 01/27] notifier: Add atomic_notifier_call_chain_is_empty()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-10 18:14   ` Rafael J. Wysocki
  2022-05-09 23:32 ` [PATCH v8 02/27] notifier: Add blocking/atomic_notifier_chain_register_unique_prio() Dmitry Osipenko
                   ` (26 subsequent siblings)
  27 siblings, 1 reply; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Add atomic_notifier_call_chain_is_empty() that returns true if given
atomic call chain is empty.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 include/linux/notifier.h |  2 ++
 kernel/notifier.c        | 13 +++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 87069b8459af..95e2440037de 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -173,6 +173,8 @@ extern int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh
 extern int raw_notifier_call_chain_robust(struct raw_notifier_head *nh,
 		unsigned long val_up, unsigned long val_down, void *v);
 
+extern bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh);
+
 #define NOTIFY_DONE		0x0000		/* Don't care */
 #define NOTIFY_OK		0x0001		/* Suits me */
 #define NOTIFY_STOP_MASK	0x8000		/* Don't call further */
diff --git a/kernel/notifier.c b/kernel/notifier.c
index ba005ebf4730..aaf5b56452a6 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -204,6 +204,19 @@ int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
 EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
 NOKPROBE_SYMBOL(atomic_notifier_call_chain);
 
+/**
+ *	atomicnotifier_call_chain_is_empty - Check whether notifier chain is empty
+ *	@nh: Pointer to head of the blocking notifier chain
+ *
+ *	Checks whether notifier chain is empty.
+ *
+ *	Returns true is notifier chain is empty, false otherwise.
+ */
+bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh)
+{
+	return !rcu_access_pointer(nh->head);
+}
+
 /*
  *	Blocking notifier chain routines.  All access to the chain is
  *	synchronized by an rwsem.
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 02/27] notifier: Add blocking/atomic_notifier_chain_register_unique_prio()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 01/27] notifier: Add atomic_notifier_call_chain_is_empty() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 03/27] kernel/reboot: Introduce sys-off handler API Dmitry Osipenko
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Add variant of blocking/atomic_notifier_chain_register() functions that
allow registration of a notifier only if it has unique priority, otherwise
-EBUSY error code is returned by the new functions.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 include/linux/notifier.h |  5 +++
 kernel/notifier.c        | 88 +++++++++++++++++++++++++++++++---------
 2 files changed, 74 insertions(+), 19 deletions(-)

diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 95e2440037de..aef88c2d1173 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -150,6 +150,11 @@ extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
 extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
 		struct notifier_block *nb);
 
+extern int atomic_notifier_chain_register_unique_prio(
+		struct atomic_notifier_head *nh, struct notifier_block *nb);
+extern int blocking_notifier_chain_register_unique_prio(
+		struct blocking_notifier_head *nh, struct notifier_block *nb);
+
 extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
 		struct notifier_block *nb);
 extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
diff --git a/kernel/notifier.c b/kernel/notifier.c
index aaf5b56452a6..684fe04f5f70 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -20,7 +20,8 @@ BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
  */
 
 static int notifier_chain_register(struct notifier_block **nl,
-				   struct notifier_block *n)
+				   struct notifier_block *n,
+				   bool unique_priority)
 {
 	while ((*nl) != NULL) {
 		if (unlikely((*nl) == n)) {
@@ -30,6 +31,8 @@ static int notifier_chain_register(struct notifier_block **nl,
 		}
 		if (n->priority > (*nl)->priority)
 			break;
+		if (n->priority == (*nl)->priority && unique_priority)
+			return -EBUSY;
 		nl = &((*nl)->next);
 	}
 	n->next = *nl;
@@ -144,12 +147,35 @@ int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
 	int ret;
 
 	spin_lock_irqsave(&nh->lock, flags);
-	ret = notifier_chain_register(&nh->head, n);
+	ret = notifier_chain_register(&nh->head, n, false);
 	spin_unlock_irqrestore(&nh->lock, flags);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
 
+/**
+ *	atomic_notifier_chain_register_unique_prio - Add notifier to an atomic notifier chain
+ *	@nh: Pointer to head of the atomic notifier chain
+ *	@n: New entry in notifier chain
+ *
+ *	Adds a notifier to an atomic notifier chain if there is no other
+ *	notifier registered using the same priority.
+ *
+ *	Returns 0 on success, %-EEXIST or %-EBUSY on error.
+ */
+int atomic_notifier_chain_register_unique_prio(struct atomic_notifier_head *nh,
+					       struct notifier_block *n)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&nh->lock, flags);
+	ret = notifier_chain_register(&nh->head, n, true);
+	spin_unlock_irqrestore(&nh->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_chain_register_unique_prio);
+
 /**
  *	atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
  *	@nh: Pointer to head of the atomic notifier chain
@@ -222,18 +248,9 @@ bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh)
  *	synchronized by an rwsem.
  */
 
-/**
- *	blocking_notifier_chain_register - Add notifier to a blocking notifier chain
- *	@nh: Pointer to head of the blocking notifier chain
- *	@n: New entry in notifier chain
- *
- *	Adds a notifier to a blocking notifier chain.
- *	Must be called in process context.
- *
- *	Returns 0 on success, %-EEXIST on error.
- */
-int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
-		struct notifier_block *n)
+static int __blocking_notifier_chain_register(struct blocking_notifier_head *nh,
+					      struct notifier_block *n,
+					      bool unique_priority)
 {
 	int ret;
 
@@ -243,15 +260,48 @@ int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
 	 * such times we must not call down_write().
 	 */
 	if (unlikely(system_state == SYSTEM_BOOTING))
-		return notifier_chain_register(&nh->head, n);
+		return notifier_chain_register(&nh->head, n, unique_priority);
 
 	down_write(&nh->rwsem);
-	ret = notifier_chain_register(&nh->head, n);
+	ret = notifier_chain_register(&nh->head, n, unique_priority);
 	up_write(&nh->rwsem);
 	return ret;
 }
+
+/**
+ *	blocking_notifier_chain_register - Add notifier to a blocking notifier chain
+ *	@nh: Pointer to head of the blocking notifier chain
+ *	@n: New entry in notifier chain
+ *
+ *	Adds a notifier to a blocking notifier chain.
+ *	Must be called in process context.
+ *
+ *	Returns 0 on success, %-EEXIST on error.
+ */
+int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
+		struct notifier_block *n)
+{
+	return __blocking_notifier_chain_register(nh, n, false);
+}
 EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
 
+/**
+ *	blocking_notifier_chain_register_unique_prio - Add notifier to a blocking notifier chain
+ *	@nh: Pointer to head of the blocking notifier chain
+ *	@n: New entry in notifier chain
+ *
+ *	Adds a notifier to an blocking notifier chain if there is no other
+ *	notifier registered using the same priority.
+ *
+ *	Returns 0 on success, %-EEXIST or %-EBUSY on error.
+ */
+int blocking_notifier_chain_register_unique_prio(struct blocking_notifier_head *nh,
+						 struct notifier_block *n)
+{
+	return __blocking_notifier_chain_register(nh, n, true);
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_chain_register_unique_prio);
+
 /**
  *	blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
  *	@nh: Pointer to head of the blocking notifier chain
@@ -354,7 +404,7 @@ EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
 int raw_notifier_chain_register(struct raw_notifier_head *nh,
 		struct notifier_block *n)
 {
-	return notifier_chain_register(&nh->head, n);
+	return notifier_chain_register(&nh->head, n, false);
 }
 EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
 
@@ -433,10 +483,10 @@ int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
 	 * such times we must not call mutex_lock().
 	 */
 	if (unlikely(system_state == SYSTEM_BOOTING))
-		return notifier_chain_register(&nh->head, n);
+		return notifier_chain_register(&nh->head, n, false);
 
 	mutex_lock(&nh->mutex);
-	ret = notifier_chain_register(&nh->head, n);
+	ret = notifier_chain_register(&nh->head, n, false);
 	mutex_unlock(&nh->mutex);
 	return ret;
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 03/27] kernel/reboot: Introduce sys-off handler API
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 01/27] notifier: Add atomic_notifier_call_chain_is_empty() Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 02/27] notifier: Add blocking/atomic_notifier_chain_register_unique_prio() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 04/27] kernel/reboot: Wrap legacy power-off callbacks into sys-off handlers Dmitry Osipenko
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

In order to support power-off chaining we need to get rid of the global
pm_* variables, replacing them with the new kernel API functions that
support chaining.

Introduce new generic sys-off handler API that brings the following
features:

1. Power-off and restart handlers are registered using same API function
   that supports chaining, hence all power-off and restart modes will
   support chaining using this unified function.

2. Prevents notifier priority collisions by disallowing registration of
   multiple handlers at the non-default priority level.

3. Supports passing opaque user argument to callback, which allows us to
   remove global variables from drivers.

This patch adds support of the following sys-off modes:

- SYS_OFF_MODE_POWER_OFF_PREPARE that replaces global pm_power_off_prepare
  variable and provides chaining support for power-off-prepare handlers.

- SYS_OFF_MODE_POWER_OFF that replaces global pm_power_off variable and
  provides chaining support for power-off handlers.

- SYS_OFF_MODE_RESTART that provides a better restart API, removing a need
  from drivers to have a global scratch variable by utilizing the opaque
  callback argument.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 include/linux/reboot.h |  77 +++++++++++++++++
 kernel/reboot.c        | 182 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 259 insertions(+)

diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index a2429648d831..05981ef079d8 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -7,6 +7,7 @@
 #include <uapi/linux/reboot.h>
 
 struct device;
+struct sys_off_handler;
 
 #define SYS_DOWN	0x0001	/* Notify of system down */
 #define SYS_RESTART	SYS_DOWN
@@ -62,6 +63,82 @@ extern void machine_shutdown(void);
 struct pt_regs;
 extern void machine_crash_shutdown(struct pt_regs *);
 
+/*
+ * sys-off handler API.
+ */
+
+/*
+ * Standard sys-off priority levels. Users are expected to set priorities
+ * relative to the standard levels.
+ *
+ * SYS_OFF_PRIO_PLATFORM:	Use this for platform-level handlers.
+ *
+ * SYS_OFF_PRIO_LOW:		Use this for handler of last resort.
+ *
+ * SYS_OFF_PRIO_DEFAULT:	Use this for normal handlers.
+ *
+ * SYS_OFF_PRIO_HIGH:		Use this for higher priority handlers.
+ *
+ * SYS_OFF_PRIO_FIRMWARE:	Use this if handler uses firmware call.
+ */
+#define SYS_OFF_PRIO_PLATFORM		-256
+#define SYS_OFF_PRIO_LOW		-128
+#define SYS_OFF_PRIO_DEFAULT		0
+#define SYS_OFF_PRIO_HIGH		192
+#define SYS_OFF_PRIO_FIRMWARE		224
+
+enum sys_off_mode {
+	/**
+	 * @SYS_OFF_MODE_POWER_OFF_PREPARE:
+	 *
+	 * Handlers prepare system to be powered off. Handlers are
+	 * allowed to sleep.
+	 */
+	SYS_OFF_MODE_POWER_OFF_PREPARE,
+
+	/**
+	 * @SYS_OFF_MODE_POWER_OFF:
+	 *
+	 * Handlers power-off system. Handlers are disallowed to sleep.
+	 */
+	SYS_OFF_MODE_POWER_OFF,
+
+	/**
+	 * @SYS_OFF_MODE_RESTART:
+	 *
+	 * Handlers restart system. Handlers are disallowed to sleep.
+	 */
+	SYS_OFF_MODE_RESTART,
+};
+
+/**
+ * struct sys_off_data - sys-off callback argument
+ *
+ * @mode: Mode ID. Currently used only by the sys-off restart mode,
+ *        see enum reboot_mode for the available modes.
+ * @cb_data: User's callback data.
+ * @cmd: Command string. Currently used only by the sys-off restart mode,
+ *       NULL otherwise.
+ */
+struct sys_off_data {
+	int mode;
+	void *cb_data;
+	const char *cmd;
+};
+
+struct sys_off_handler *
+register_sys_off_handler(enum sys_off_mode mode,
+			 int priority,
+			 int (*callback)(struct sys_off_data *data),
+			 void *cb_data);
+void unregister_sys_off_handler(struct sys_off_handler *handler);
+
+int devm_register_sys_off_handler(struct device *dev,
+				  enum sys_off_mode mode,
+				  int priority,
+				  int (*callback)(struct sys_off_data *data),
+				  void *cb_data);
+
 /*
  * Architecture independent implemenations of sys_reboot commands.
  */
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 8ce30fa0a104..672a658f21ee 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -48,6 +48,15 @@ int reboot_cpu;
 enum reboot_type reboot_type = BOOT_ACPI;
 int reboot_force;
 
+struct sys_off_handler {
+	struct notifier_block nb;
+	int (*sys_off_cb)(struct sys_off_data *data);
+	void *cb_data;
+	enum sys_off_mode mode;
+	bool blocking;
+	void *list;
+};
+
 /*
  * If set, this is used for preparing the system to power off.
  */
@@ -281,6 +290,179 @@ void kernel_halt(void)
 }
 EXPORT_SYMBOL_GPL(kernel_halt);
 
+/*
+ *	Notifier list for kernel code which wants to be called
+ *	to prepare system for power off.
+ */
+static BLOCKING_NOTIFIER_HEAD(power_off_prep_handler_list);
+
+/*
+ *	Notifier list for kernel code which wants to be called
+ *	to power off system.
+ */
+static ATOMIC_NOTIFIER_HEAD(power_off_handler_list);
+
+static int sys_off_notify(struct notifier_block *nb,
+			  unsigned long mode, void *cmd)
+{
+	struct sys_off_handler *handler;
+	struct sys_off_data data = {};
+
+	handler = container_of(nb, struct sys_off_handler, nb);
+	data.cb_data = handler->cb_data;
+	data.mode = mode;
+	data.cmd = cmd;
+
+	return handler->sys_off_cb(&data);
+}
+
+/**
+ *	register_sys_off_handler - Register sys-off handler
+ *	@mode: Sys-off mode
+ *	@priority: Handler priority
+ *	@callback: Callback function
+ *	@cb_data: Callback argument
+ *
+ *	Registers system power-off or restart handler that will be invoked
+ *	at the step corresponding to the given sys-off mode. Handler's callback
+ *	should return NOTIFY_DONE to permit execution of the next handler in
+ *	the call chain or NOTIFY_STOP to break the chain (in error case for
+ *	example).
+ *
+ *	Multiple handlers can be registered at the default priority level.
+ *
+ *	Only one handler can be registered at the non-default priority level,
+ *	otherwise ERR_PTR(-EBUSY) is returned.
+ *
+ *	Returns a new instance of struct sys_off_handler on success, or
+ *	an ERR_PTR()-encoded error code otherwise.
+ */
+struct sys_off_handler *
+register_sys_off_handler(enum sys_off_mode mode,
+			 int priority,
+			 int (*callback)(struct sys_off_data *data),
+			 void *cb_data)
+{
+	struct sys_off_handler *handler;
+	int err;
+
+	handler = kzalloc(sizeof(*handler), GFP_KERNEL);
+	if (!handler)
+		return ERR_PTR(-ENOMEM);
+
+	switch (mode) {
+	case SYS_OFF_MODE_POWER_OFF_PREPARE:
+		handler->list = &power_off_prep_handler_list;
+		handler->blocking = true;
+		break;
+
+	case SYS_OFF_MODE_POWER_OFF:
+		handler->list = &power_off_handler_list;
+		break;
+
+	case SYS_OFF_MODE_RESTART:
+		handler->list = &restart_handler_list;
+		break;
+
+	default:
+		kfree(handler);
+		return ERR_PTR(-EINVAL);
+	}
+
+	handler->nb.notifier_call = sys_off_notify;
+	handler->nb.priority = priority;
+	handler->sys_off_cb = callback;
+	handler->cb_data = cb_data;
+	handler->mode = mode;
+
+	if (handler->blocking) {
+		if (priority == SYS_OFF_PRIO_DEFAULT)
+			err = blocking_notifier_chain_register(handler->list,
+							       &handler->nb);
+		else
+			err = blocking_notifier_chain_register_unique_prio(handler->list,
+									   &handler->nb);
+	} else {
+		if (priority == SYS_OFF_PRIO_DEFAULT)
+			err = atomic_notifier_chain_register(handler->list,
+							     &handler->nb);
+		else
+			err = atomic_notifier_chain_register_unique_prio(handler->list,
+									 &handler->nb);
+	}
+
+	if (err) {
+		kfree(handler);
+		return ERR_PTR(err);
+	}
+
+	return handler;
+}
+EXPORT_SYMBOL_GPL(register_sys_off_handler);
+
+/**
+ *	unregister_sys_off_handler - Unregister sys-off handler
+ *	@handler: Sys-off handler
+ *
+ *	Unregisters given sys-off handler.
+ */
+void unregister_sys_off_handler(struct sys_off_handler *handler)
+{
+	int err;
+
+	if (!handler)
+		return;
+
+	if (handler->blocking)
+		err = blocking_notifier_chain_unregister(handler->list,
+							 &handler->nb);
+	else
+		err = atomic_notifier_chain_unregister(handler->list,
+						       &handler->nb);
+
+	/* sanity check, shall never happen */
+	WARN_ON(err);
+
+	kfree(handler);
+}
+EXPORT_SYMBOL_GPL(unregister_sys_off_handler);
+
+static void devm_unregister_sys_off_handler(void *data)
+{
+	struct sys_off_handler *handler = data;
+
+	unregister_sys_off_handler(handler);
+}
+
+/**
+ *	devm_register_sys_off_handler - Register sys-off handler
+ *	@dev: Device that registers handler
+ *	@mode: Sys-off mode
+ *	@priority: Handler priority
+ *	@callback: Callback function
+ *	@cb_data: Callback argument
+ *
+ *	Registers resource-managed sys-off handler.
+ *
+ *	Returns zero on success, or error code on failure.
+ */
+int devm_register_sys_off_handler(struct device *dev,
+				  enum sys_off_mode mode,
+				  int priority,
+				  int (*callback)(struct sys_off_data *data),
+				  void *cb_data)
+{
+	struct sys_off_handler *handler;
+
+	handler = register_sys_off_handler(mode, priority, callback, cb_data);
+	if (IS_ERR(handler))
+		return PTR_ERR(handler);
+
+	return devm_add_action_or_reset(dev, devm_unregister_sys_off_handler,
+					handler);
+}
+EXPORT_SYMBOL_GPL(devm_register_sys_off_handler);
+
 /**
  *	kernel_power_off - power_off the system
  *
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 04/27] kernel/reboot: Wrap legacy power-off callbacks into sys-off handlers
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (2 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 03/27] kernel/reboot: Introduce sys-off handler API Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 05/27] kernel/reboot: Add do_kernel_power_off() Dmitry Osipenko
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Wrap legacy power-off callbacks into sys-off handlers in order to
support co-existence of both legacy and new callbacks while we're
in process of upgrading legacy callbacks to the new API.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 kernel/reboot.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/kernel/reboot.c b/kernel/reboot.c
index 672a658f21ee..2fb0357d9483 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -463,6 +463,47 @@ int devm_register_sys_off_handler(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_register_sys_off_handler);
 
+static int legacy_pm_power_off_prepare(struct sys_off_data *data)
+{
+	if (pm_power_off_prepare)
+		pm_power_off_prepare();
+
+	return NOTIFY_DONE;
+}
+
+static int legacy_pm_power_off(struct sys_off_data *data)
+{
+	if (pm_power_off)
+		pm_power_off();
+
+	return NOTIFY_DONE;
+}
+
+/*
+ * Register sys-off handlers for legacy PM callbacks. This allows legacy
+ * PM callbacks co-exist with the new sys-off API.
+ *
+ * TODO: Remove legacy handlers once all legacy PM users will be switched
+ *       to the sys-off based APIs.
+ */
+static int __init legacy_pm_init(void)
+{
+	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF_PREPARE,
+				 SYS_OFF_PRIO_DEFAULT,
+				 legacy_pm_power_off_prepare, NULL);
+
+	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT,
+				 legacy_pm_power_off, NULL);
+
+	return 0;
+}
+core_initcall(legacy_pm_init);
+
+static void do_kernel_power_off_prepare(void)
+{
+	blocking_notifier_call_chain(&power_off_prep_handler_list, 0, NULL);
+}
+
 /**
  *	kernel_power_off - power_off the system
  *
@@ -471,8 +512,7 @@ EXPORT_SYMBOL_GPL(devm_register_sys_off_handler);
 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");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 05/27] kernel/reboot: Add do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (3 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 04/27] kernel/reboot: Wrap legacy power-off callbacks into sys-off handlers Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 06/27] kernel/reboot: Add stub for pm_power_off Dmitry Osipenko
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Add do_kernel_power_off() helper that will remove open-coded pm_power_off
invocations from the architecture code. This is the first step on the way
to remove the global pm_power_off variable, which will allow us to
implement consistent power-off chaining support.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 include/linux/reboot.h |  2 ++
 kernel/reboot.c        | 13 +++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 05981ef079d8..6b951d68c0c7 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -63,6 +63,8 @@ extern void machine_shutdown(void);
 struct pt_regs;
 extern void machine_crash_shutdown(struct pt_regs *);
 
+void do_kernel_power_off(void);
+
 /*
  * sys-off handler API.
  */
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 2fb0357d9483..9afa99a32d62 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -504,6 +504,19 @@ static void do_kernel_power_off_prepare(void)
 	blocking_notifier_call_chain(&power_off_prep_handler_list, 0, NULL);
 }
 
+/**
+ *	do_kernel_power_off - Execute kernel power-off handler call chain
+ *
+ *	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)
+{
+	atomic_notifier_call_chain(&power_off_handler_list, 0, NULL);
+}
+
 /**
  *	kernel_power_off - power_off the system
  *
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 06/27] kernel/reboot: Add stub for pm_power_off
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (4 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 05/27] kernel/reboot: Add do_kernel_power_off() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 07/27] kernel/reboot: Add kernel_can_power_off() Dmitry Osipenko
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Add weak stub for the global pm_power_off callback variable. This will
allow us to remove pm_power_off definitions from arch/ code and transition
to the new sys-off based API that will replace the global variable.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 kernel/reboot.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/kernel/reboot.c b/kernel/reboot.c
index 9afa99a32d62..eaede35f45e2 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -57,6 +57,12 @@ struct sys_off_handler {
 	void *list;
 };
 
+/*
+ * Temporary stub that prevents linkage failure while we're in process
+ * of removing all uses of legacy pm_power_off() around the kernel.
+ */
+void __weak (*pm_power_off)(void);
+
 /*
  * If set, this is used for preparing the system to power off.
  */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 07/27] kernel/reboot: Add kernel_can_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (5 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 06/27] kernel/reboot: Add stub for pm_power_off Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-24 13:14   ` Geert Uytterhoeven
  2022-05-09 23:32 ` [PATCH v8 08/27] kernel/reboot: Add register_platform_power_off() Dmitry Osipenko
                   ` (20 subsequent siblings)
  27 siblings, 1 reply; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Add kernel_can_power_off() helper that replaces open-coded checks of
the global pm_power_off variable. This is a necessary step towards
supporting chained power-off handlers.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 include/linux/reboot.h |  1 +
 kernel/reboot.c        | 14 +++++++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 6b951d68c0c7..c52f77ee4ddd 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -149,6 +149,7 @@ extern void kernel_restart_prepare(char *cmd);
 extern void kernel_restart(char *cmd);
 extern void kernel_halt(void);
 extern void kernel_power_off(void);
+extern bool kernel_can_power_off(void);
 
 void ctrl_alt_del(void);
 
diff --git a/kernel/reboot.c b/kernel/reboot.c
index eaede35f45e2..982e58c11ce8 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -523,6 +523,18 @@ void do_kernel_power_off(void)
 	atomic_notifier_call_chain(&power_off_handler_list, 0, NULL);
 }
 
+/**
+ *	kernel_can_power_off - check whether system can be powered off
+ *
+ *	Returns true if power-off handler is registered and system can be
+ *	powered off, false otherwise.
+ */
+bool kernel_can_power_off(void)
+{
+	return !atomic_notifier_call_chain_is_empty(&power_off_handler_list);
+}
+EXPORT_SYMBOL_GPL(kernel_can_power_off);
+
 /**
  *	kernel_power_off - power_off the system
  *
@@ -581,7 +593,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
 	/* Instead of trying to make the power_off code look like
 	 * halt when pm_power_off is not set do it the easy way.
 	 */
-	if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
+	if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !kernel_can_power_off())
 		cmd = LINUX_REBOOT_CMD_HALT;
 
 	mutex_lock(&system_transition_mutex);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 08/27] kernel/reboot: Add register_platform_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (6 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 07/27] kernel/reboot: Add kernel_can_power_off() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 09/27] ARM: Use do_kernel_power_off() Dmitry Osipenko
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

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>
---
 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


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 09/27] ARM: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (7 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 08/27] kernel/reboot: Add register_platform_power_off() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 10/27] csky: " Dmitry Osipenko
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/arm/kernel/reboot.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 3044fcb8d073..2cb943422554 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -116,9 +116,7 @@ void machine_power_off(void)
 {
 	local_irq_disable();
 	smp_send_stop();
-
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 }
 
 /*
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 10/27] csky: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (8 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 09/27] ARM: Use do_kernel_power_off() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 11/27] riscv: " Dmitry Osipenko
                   ` (17 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Acked-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/csky/kernel/power.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/csky/kernel/power.c b/arch/csky/kernel/power.c
index 923ee4e381b8..86ee202906f8 100644
--- a/arch/csky/kernel/power.c
+++ b/arch/csky/kernel/power.c
@@ -9,16 +9,14 @@ EXPORT_SYMBOL(pm_power_off);
 void machine_power_off(void)
 {
 	local_irq_disable();
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	asm volatile ("bkpt");
 }
 
 void machine_halt(void)
 {
 	local_irq_disable();
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	asm volatile ("bkpt");
 }
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 11/27] riscv: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (9 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 10/27] csky: " Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 12/27] arm64: " Dmitry Osipenko
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Acked-by: Palmer Dabbelt <palmer@dabbelt.com>
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/riscv/kernel/reset.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/riscv/kernel/reset.c b/arch/riscv/kernel/reset.c
index 9c842c41684a..912288572226 100644
--- a/arch/riscv/kernel/reset.c
+++ b/arch/riscv/kernel/reset.c
@@ -23,16 +23,12 @@ void machine_restart(char *cmd)
 
 void machine_halt(void)
 {
-	if (pm_power_off != NULL)
-		pm_power_off();
-	else
-		default_power_off();
+	do_kernel_power_off();
+	default_power_off();
 }
 
 void machine_power_off(void)
 {
-	if (pm_power_off != NULL)
-		pm_power_off();
-	else
-		default_power_off();
+	do_kernel_power_off();
+	default_power_off();
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 12/27] arm64: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (10 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 11/27] riscv: " Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 13/27] parisc: " Dmitry Osipenko
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/arm64/kernel/process.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 142a51256669..92bcc1768f0b 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -111,8 +111,7 @@ void machine_power_off(void)
 {
 	local_irq_disable();
 	smp_send_stop();
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 }
 
 /*
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 13/27] parisc: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (11 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 12/27] arm64: " Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 14/27] xen/x86: " Dmitry Osipenko
                   ` (14 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Acked-by: Helge Deller <deller@gmx.de> # parisc
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/parisc/kernel/process.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index a6a2a558fc5b..7c37e09c92da 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/personality.h>
 #include <linux/ptrace.h>
+#include <linux/reboot.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
 #include <linux/sched/task.h>
@@ -116,8 +117,7 @@ void machine_power_off(void)
 	pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
 
 	/* ipmi_poweroff may have been installed. */
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 		
 	/* It seems we have no way to power the system off via
 	 * software. The user has to press the button himself. */
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 14/27] xen/x86: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (12 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 13/27] parisc: " Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 15/27] powerpc: " Dmitry Osipenko
                   ` (13 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Acked-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/x86/xen/enlighten_pv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 5038edb79ad5..af1f6e886225 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -31,6 +31,7 @@
 #include <linux/gfp.h>
 #include <linux/edd.h>
 #include <linux/objtool.h>
+#include <linux/reboot.h>
 
 #include <xen/xen.h>
 #include <xen/events.h>
@@ -1071,8 +1072,7 @@ static void xen_machine_halt(void)
 
 static void xen_machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	xen_reboot(SHUTDOWN_poweroff);
 }
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 15/27] powerpc: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (13 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 14/27] xen/x86: " Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 16/27] m68k: Switch to new sys-off handler API Dmitry Osipenko
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/powerpc/kernel/setup-common.c | 4 +---
 arch/powerpc/xmon/xmon.c           | 3 +--
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 518ae5aa9410..1b586577e75b 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -161,9 +161,7 @@ void machine_restart(char *cmd)
 void machine_power_off(void)
 {
 	machine_shutdown();
-	if (pm_power_off)
-		pm_power_off();
-
+	do_kernel_power_off();
 	smp_send_stop();
 	machine_hang();
 }
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index b423812e94e0..0300bdfa20d5 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1243,8 +1243,7 @@ static void bootcmds(void)
 	} else if (cmd == 'h') {
 		ppc_md.halt();
 	} else if (cmd == 'p') {
-		if (pm_power_off)
-			pm_power_off();
+		do_kernel_power_off();
 	}
 }
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 16/27] m68k: Switch to new sys-off handler API
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (14 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 15/27] powerpc: " Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-31 19:04   ` Geert Uytterhoeven
  2022-05-09 23:32 ` [PATCH v8 17/27] sh: Use do_kernel_power_off() Dmitry Osipenko
                   ` (11 subsequent siblings)
  27 siblings, 1 reply; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use
register_power_off_handler() that registers power-off handlers and
do_kernel_power_off() that invokes chained power-off handlers. Legacy
pm_power_off() will be removed once all drivers will be converted to
the new sys-off API.

Normally arch code should adopt only the do_kernel_power_off() at first,
but m68k is a special case because it uses pm_power_off() "inside out",
i.e. pm_power_off() invokes machine_power_off() [in fact it does nothing],
while it's machine_power_off() that should invoke the pm_power_off(), and
thus, we can't convert platforms to the new API separately. There are only
two platforms changed here, so it's not a big deal.

Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/m68k/emu/natfeat.c         | 3 ++-
 arch/m68k/include/asm/machdep.h | 1 -
 arch/m68k/kernel/process.c      | 5 ++---
 arch/m68k/kernel/setup_mm.c     | 1 -
 arch/m68k/kernel/setup_no.c     | 1 -
 arch/m68k/mac/config.c          | 4 +++-
 6 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c
index 71b78ecee75c..b19dc00026d9 100644
--- a/arch/m68k/emu/natfeat.c
+++ b/arch/m68k/emu/natfeat.c
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/reboot.h>
 #include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/natfeat.h>
@@ -90,5 +91,5 @@ void __init nf_init(void)
 	pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
 		version & 0xffff);
 
-	mach_power_off = nf_poweroff;
+	register_platform_power_off(nf_poweroff);
 }
diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h
index 8fd80ef1b77e..8d8c3ee2069f 100644
--- a/arch/m68k/include/asm/machdep.h
+++ b/arch/m68k/include/asm/machdep.h
@@ -24,7 +24,6 @@ extern int (*mach_get_rtc_pll)(struct rtc_pll_info *);
 extern int (*mach_set_rtc_pll)(struct rtc_pll_info *);
 extern void (*mach_reset)( void );
 extern void (*mach_halt)( void );
-extern void (*mach_power_off)( void );
 extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
 extern void (*mach_hd_setup)(char *, int *);
 extern void (*mach_heartbeat) (int);
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 221feb0269f1..2cb4a61bcfac 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -67,12 +67,11 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-	if (mach_power_off)
-		mach_power_off();
+	do_kernel_power_off();
 	for (;;);
 }
 
-void (*pm_power_off)(void) = machine_power_off;
+void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
 void show_regs(struct pt_regs * regs)
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index 78ab562beb31..42691abcd908 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -98,7 +98,6 @@ EXPORT_SYMBOL(mach_get_rtc_pll);
 EXPORT_SYMBOL(mach_set_rtc_pll);
 void (*mach_reset)( void );
 void (*mach_halt)( void );
-void (*mach_power_off)( void );
 #ifdef CONFIG_HEARTBEAT
 void (*mach_heartbeat) (int);
 EXPORT_SYMBOL(mach_heartbeat);
diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c
index 5e4104f07a44..00bf82258233 100644
--- a/arch/m68k/kernel/setup_no.c
+++ b/arch/m68k/kernel/setup_no.c
@@ -55,7 +55,6 @@ int (*mach_hwclk) (int, struct rtc_time*);
 /* machine dependent reboot functions */
 void (*mach_reset)(void);
 void (*mach_halt)(void);
-void (*mach_power_off)(void);
 
 #ifdef CONFIG_M68000
 #if defined(CONFIG_M68328)
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 65d124ec80bb..382f656c29ea 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -12,6 +12,7 @@
 
 #include <linux/errno.h>
 #include <linux/module.h>
+#include <linux/reboot.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
@@ -140,7 +141,6 @@ void __init config_mac(void)
 	mach_hwclk = mac_hwclk;
 	mach_reset = mac_reset;
 	mach_halt = mac_poweroff;
-	mach_power_off = mac_poweroff;
 #if IS_ENABLED(CONFIG_INPUT_M68K_BEEP)
 	mach_beep = mac_mksound;
 #endif
@@ -160,6 +160,8 @@ void __init config_mac(void)
 
 	if (macintosh_config->ident == MAC_MODEL_IICI)
 		mach_l2_flush = via_l2_flush;
+
+	register_platform_power_off(mac_poweroff);
 }
 
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 17/27] sh: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (15 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 16/27] m68k: Switch to new sys-off handler API Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 18/27] x86: " Dmitry Osipenko
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/sh/kernel/reboot.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c
index 5c33f036418b..e8eeedc9b182 100644
--- a/arch/sh/kernel/reboot.c
+++ b/arch/sh/kernel/reboot.c
@@ -46,8 +46,7 @@ static void native_machine_shutdown(void)
 
 static void native_machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 }
 
 static void native_machine_halt(void)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 18/27] x86: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (16 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 17/27] sh: Use do_kernel_power_off() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 19/27] ia64: " Dmitry Osipenko
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/x86/kernel/reboot.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index fa700b46588e..c3636ea4aa71 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -739,10 +739,10 @@ static void native_machine_halt(void)
 
 static void native_machine_power_off(void)
 {
-	if (pm_power_off) {
+	if (kernel_can_power_off()) {
 		if (!reboot_force)
 			machine_shutdown();
-		pm_power_off();
+		do_kernel_power_off();
 	}
 	/* A fallback in case there is no PM info available */
 	tboot_shutdown(TB_SHUTDOWN_HALT);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 19/27] ia64: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (17 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 18/27] x86: " Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 20/27] mips: " Dmitry Osipenko
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/ia64/kernel/process.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 167b1765bea1..416305e550e2 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/notifier.h>
 #include <linux/personality.h>
+#include <linux/reboot.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
 #include <linux/sched/hotplug.h>
@@ -602,8 +603,7 @@ machine_halt (void)
 void
 machine_power_off (void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	machine_halt();
 }
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 20/27] mips: Use do_kernel_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (18 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 19/27] ia64: " Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 21/27] memory: emif: Use kernel_can_power_off() Dmitry Osipenko
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Kernel now supports chained power-off handlers. Use do_kernel_power_off()
that invokes chained power-off handlers. It also invokes legacy
pm_power_off() for now, which will be removed once all drivers will
be converted to the new sys-off API.

Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 arch/mips/kernel/reset.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c
index 6288780b779e..e7ce07b3e79b 100644
--- a/arch/mips/kernel/reset.c
+++ b/arch/mips/kernel/reset.c
@@ -114,8 +114,7 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 
 #ifdef CONFIG_SMP
 	preempt_disable();
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 21/27] memory: emif: Use kernel_can_power_off()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (19 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 20/27] mips: " Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 22/27] ACPI: power: Switch to sys-off handler API Dmitry Osipenko
                   ` (6 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Replace legacy pm_power_off with kernel_can_power_off() helper that
is aware about chained power-off handlers.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 drivers/memory/emif.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 6c2a421b86e3..f305643209f0 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -630,7 +630,7 @@ static irqreturn_t emif_threaded_isr(int irq, void *dev_id)
 		dev_emerg(emif->dev, "SDRAM temperature exceeds operating limit.. Needs shut down!!!\n");
 
 		/* If we have Power OFF ability, use it, else try restarting */
-		if (pm_power_off) {
+		if (kernel_can_power_off()) {
 			kernel_power_off();
 		} else {
 			WARN(1, "FIXME: NO pm_power_off!!! trying restart\n");
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 22/27] ACPI: power: Switch to sys-off handler API
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (20 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 21/27] memory: emif: Use kernel_can_power_off() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 23/27] regulator: pfuze100: Use devm_register_sys_off_handler() Dmitry Osipenko
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Switch to sys-off API that replaces legacy pm_power_off callbacks,
allowing us to remove global pm_* variables and support chaining of
all restart and power-off modes consistently.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 drivers/acpi/sleep.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index c992e57b2c79..c3e3cee27f01 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -1023,20 +1023,22 @@ static void acpi_sleep_hibernate_setup(void)
 static inline void acpi_sleep_hibernate_setup(void) {}
 #endif /* !CONFIG_HIBERNATION */
 
-static void acpi_power_off_prepare(void)
+static int acpi_power_off_prepare(struct sys_off_data *data)
 {
 	/* Prepare to power off the system */
 	acpi_sleep_prepare(ACPI_STATE_S5);
 	acpi_disable_all_gpes();
 	acpi_os_wait_events_complete();
+	return NOTIFY_DONE;
 }
 
-static void acpi_power_off(void)
+static int acpi_power_off(struct sys_off_data *data)
 {
 	/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
 	pr_debug("%s called\n", __func__);
 	local_irq_disable();
 	acpi_enter_sleep_state(ACPI_STATE_S5);
+	return NOTIFY_DONE;
 }
 
 int __init acpi_sleep_init(void)
@@ -1055,8 +1057,14 @@ int __init acpi_sleep_init(void)
 
 	if (acpi_sleep_state_supported(ACPI_STATE_S5)) {
 		sleep_states[ACPI_STATE_S5] = 1;
-		pm_power_off_prepare = acpi_power_off_prepare;
-		pm_power_off = acpi_power_off;
+
+		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF_PREPARE,
+					 SYS_OFF_PRIO_FIRMWARE,
+					 acpi_power_off_prepare, NULL);
+
+		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
+					 SYS_OFF_PRIO_FIRMWARE,
+					 acpi_power_off, NULL);
 	} else {
 		acpi_no_s5 = true;
 	}
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 23/27] regulator: pfuze100: Use devm_register_sys_off_handler()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (21 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 22/27] ACPI: power: Switch to sys-off handler API Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 24/27] reboot: Remove pm_power_off_prepare() Dmitry Osipenko
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Use devm_register_sys_off_handler() that replaces global
pm_power_off_prepare variable and allows to register multiple
power-off handlers.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 drivers/regulator/pfuze100-regulator.c | 42 +++++++++++---------------
 1 file changed, 17 insertions(+), 25 deletions(-)

diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index d60d7d1b7fa2..0322f6b1fb60 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -10,6 +10,7 @@
 #include <linux/of_device.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/pfuze100.h>
@@ -569,10 +570,10 @@ static inline struct device_node *match_of_node(int index)
 	return pfuze_matches[index].of_node;
 }
 
-static struct pfuze_chip *syspm_pfuze_chip;
-
-static void pfuze_power_off_prepare(void)
+static int pfuze_power_off_prepare(struct sys_off_data *data)
 {
+	struct pfuze_chip *syspm_pfuze_chip = data->cb_data;
+
 	dev_info(syspm_pfuze_chip->dev, "Configure standby mode for power off");
 
 	/* Switch from default mode: APS/APS to APS/Off */
@@ -607,28 +608,30 @@ static void pfuze_power_off_prepare(void)
 	regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN6VOL,
 			   PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
 			   PFUZE100_VGENxSTBY);
+
+	return NOTIFY_DONE;
 }
 
 static int pfuze_power_off_prepare_init(struct pfuze_chip *pfuze_chip)
 {
+	int err;
+
 	if (pfuze_chip->chip_id != PFUZE100) {
 		dev_warn(pfuze_chip->dev, "Requested pm_power_off_prepare handler for not supported chip\n");
 		return -ENODEV;
 	}
 
-	if (pm_power_off_prepare) {
-		dev_warn(pfuze_chip->dev, "pm_power_off_prepare is already registered.\n");
-		return -EBUSY;
+	err = devm_register_sys_off_handler(pfuze_chip->dev,
+					    SYS_OFF_MODE_POWER_OFF_PREPARE,
+					    SYS_OFF_PRIO_DEFAULT,
+					    pfuze_power_off_prepare,
+					    pfuze_chip);
+	if (err) {
+		dev_err(pfuze_chip->dev, "failed to register sys-off handler: %d\n",
+			err);
+		return err;
 	}
 
-	if (syspm_pfuze_chip) {
-		dev_warn(pfuze_chip->dev, "syspm_pfuze_chip is already set.\n");
-		return -EBUSY;
-	}
-
-	syspm_pfuze_chip = pfuze_chip;
-	pm_power_off_prepare = pfuze_power_off_prepare;
-
 	return 0;
 }
 
@@ -837,23 +840,12 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
 	return 0;
 }
 
-static int pfuze100_regulator_remove(struct i2c_client *client)
-{
-	if (syspm_pfuze_chip) {
-		syspm_pfuze_chip = NULL;
-		pm_power_off_prepare = NULL;
-	}
-
-	return 0;
-}
-
 static struct i2c_driver pfuze_driver = {
 	.driver = {
 		.name = "pfuze100-regulator",
 		.of_match_table = pfuze_dt_ids,
 	},
 	.probe = pfuze100_regulator_probe,
-	.remove = pfuze100_regulator_remove,
 };
 module_i2c_driver(pfuze_driver);
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 24/27] reboot: Remove pm_power_off_prepare()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (22 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 23/27] regulator: pfuze100: Use devm_register_sys_off_handler() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 25/27] soc/tegra: pmc: Use sys-off handler API to power off Nexus 7 properly Dmitry Osipenko
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

All pm_power_off_prepare() users were converted to sys-off handler API.
Remove the obsolete global callback variable.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 include/linux/pm.h |  1 -
 kernel/reboot.c    | 19 -------------------
 2 files changed, 20 deletions(-)

diff --git a/include/linux/pm.h b/include/linux/pm.h
index 70ec69d8bafd..871c9c49ec9d 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -21,7 +21,6 @@
  * Callbacks for platform drivers to implement.
  */
 extern void (*pm_power_off)(void);
-extern void (*pm_power_off_prepare)(void);
 
 struct device; /* we have a circular dep with device.h */
 #ifdef CONFIG_VT_CONSOLE_SLEEP
diff --git a/kernel/reboot.c b/kernel/reboot.c
index e74103f2a801..66033e12e8eb 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -63,13 +63,6 @@ struct sys_off_handler {
  */
 void __weak (*pm_power_off)(void);
 
-/*
- * If set, this is used for preparing the system to power off.
- */
-
-void (*pm_power_off_prepare)(void);
-EXPORT_SYMBOL_GPL(pm_power_off_prepare);
-
 /**
  *	emergency_restart - reboot the system
  *
@@ -524,14 +517,6 @@ void unregister_platform_power_off(void (*power_off)(void))
 }
 EXPORT_SYMBOL_GPL(unregister_platform_power_off);
 
-static int legacy_pm_power_off_prepare(struct sys_off_data *data)
-{
-	if (pm_power_off_prepare)
-		pm_power_off_prepare();
-
-	return NOTIFY_DONE;
-}
-
 static int legacy_pm_power_off(struct sys_off_data *data)
 {
 	if (pm_power_off)
@@ -549,10 +534,6 @@ static int legacy_pm_power_off(struct sys_off_data *data)
  */
 static int __init legacy_pm_init(void)
 {
-	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF_PREPARE,
-				 SYS_OFF_PRIO_DEFAULT,
-				 legacy_pm_power_off_prepare, NULL);
-
 	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT,
 				 legacy_pm_power_off, NULL);
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 25/27] soc/tegra: pmc: Use sys-off handler API to power off Nexus 7 properly
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (23 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 24/27] reboot: Remove pm_power_off_prepare() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 26/27] kernel/reboot: Add devm_register_power_off_handler() Dmitry Osipenko
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Nexus 7 Android tablet can be turned off using a special bootloader
command which is conveyed to bootloader by putting magic value into the
special scratch register and then rebooting normally. This power-off
method should be invoked if USB cable is connected. Bootloader then will
display battery status and power off the device. This behaviour is
borrowed from downstream kernel and matches user expectations, otherwise
it looks like device got hung during power-off and it may wake up on
USB disconnect.

Switch PMC driver to sys-off handler API, which provides drivers with
chained power-off callbacks functionality that is required for powering-off
devices properly. It also brings resource-managed API for the restart
handler registration that makes PMC driver code cleaner.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 drivers/soc/tegra/pmc.c | 87 +++++++++++++++++++++++++++++------------
 1 file changed, 62 insertions(+), 25 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index c77ecf61818b..5611d14d3ba2 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -39,6 +39,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_opp.h>
+#include <linux/power_supply.h>
 #include <linux/reboot.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
@@ -108,6 +109,7 @@
 #define PMC_USB_DEBOUNCE_DEL		0xec
 #define PMC_USB_AO			0xf0
 
+#define PMC_SCRATCH37			0x130
 #define PMC_SCRATCH41			0x140
 
 #define PMC_WAKE2_MASK			0x160
@@ -1101,8 +1103,7 @@ static struct notifier_block tegra_pmc_reboot_notifier = {
 	.notifier_call = tegra_pmc_reboot_notify,
 };
 
-static int tegra_pmc_restart_notify(struct notifier_block *this,
-				    unsigned long action, void *data)
+static void tegra_pmc_restart(void)
 {
 	u32 value;
 
@@ -1110,14 +1111,31 @@ static int tegra_pmc_restart_notify(struct notifier_block *this,
 	value = tegra_pmc_readl(pmc, PMC_CNTRL);
 	value |= PMC_CNTRL_MAIN_RST;
 	tegra_pmc_writel(pmc, value, PMC_CNTRL);
+}
+
+static int tegra_pmc_restart_handler(struct sys_off_data *data)
+{
+	tegra_pmc_restart();
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block tegra_pmc_restart_handler = {
-	.notifier_call = tegra_pmc_restart_notify,
-	.priority = 128,
-};
+static int tegra_pmc_power_off_handler(struct sys_off_data *data)
+{
+	/*
+	 * Reboot Nexus 7 into special bootloader mode if USB cable is
+	 * connected in order to display battery status and power off.
+	 */
+	if (of_machine_is_compatible("asus,grouper") &&
+	    power_supply_is_system_supplied()) {
+		const u32 go_to_charger_mode = 0xa5a55a5a;
+
+		tegra_pmc_writel(pmc, go_to_charger_mode, PMC_SCRATCH37);
+		tegra_pmc_restart();
+	}
+
+	return NOTIFY_DONE;
+}
 
 static int powergate_show(struct seq_file *s, void *data)
 {
@@ -2879,6 +2897,42 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 		pmc->clk = NULL;
 	}
 
+	/*
+	 * PMC should be last resort for restarting since it soft-resets
+	 * CPU without resetting everything else.
+	 */
+	err = devm_register_reboot_notifier(&pdev->dev,
+					    &tegra_pmc_reboot_notifier);
+	if (err) {
+		dev_err(&pdev->dev, "unable to register reboot notifier, %d\n",
+			err);
+		return err;
+	}
+
+	err = devm_register_sys_off_handler(&pdev->dev,
+					    SYS_OFF_MODE_RESTART,
+					    SYS_OFF_PRIO_LOW,
+					    tegra_pmc_restart_handler, NULL);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register sys-off handler: %d\n",
+			err);
+		return err;
+	}
+
+	/*
+	 * PMC should be primary power-off method if it soft-resets CPU,
+	 * asking bootloader to shutdown hardware.
+	 */
+	err = devm_register_sys_off_handler(&pdev->dev,
+					    SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_FIRMWARE,
+					    tegra_pmc_power_off_handler, NULL);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register sys-off handler: %d\n",
+			err);
+		return err;
+	}
+
 	/*
 	 * PCLK clock rate can't be retrieved using CLK API because it
 	 * causes lockup if CPU enters LP2 idle state from some other
@@ -2910,28 +2964,13 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 			goto cleanup_sysfs;
 	}
 
-	err = devm_register_reboot_notifier(&pdev->dev,
-					    &tegra_pmc_reboot_notifier);
-	if (err) {
-		dev_err(&pdev->dev, "unable to register reboot notifier, %d\n",
-			err);
-		goto cleanup_debugfs;
-	}
-
-	err = register_restart_handler(&tegra_pmc_restart_handler);
-	if (err) {
-		dev_err(&pdev->dev, "unable to register restart handler, %d\n",
-			err);
-		goto cleanup_debugfs;
-	}
-
 	err = tegra_pmc_pinctrl_init(pmc);
 	if (err)
-		goto cleanup_restart_handler;
+		goto cleanup_debugfs;
 
 	err = tegra_pmc_regmap_init(pmc);
 	if (err < 0)
-		goto cleanup_restart_handler;
+		goto cleanup_debugfs;
 
 	err = tegra_powergate_init(pmc, pdev->dev.of_node);
 	if (err < 0)
@@ -2954,8 +2993,6 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 
 cleanup_powergates:
 	tegra_powergate_remove_all(pdev->dev.of_node);
-cleanup_restart_handler:
-	unregister_restart_handler(&tegra_pmc_restart_handler);
 cleanup_debugfs:
 	debugfs_remove(pmc->debugfs);
 cleanup_sysfs:
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 26/27] kernel/reboot: Add devm_register_power_off_handler()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (24 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 25/27] soc/tegra: pmc: Use sys-off handler API to power off Nexus 7 properly Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-09 23:32 ` [PATCH v8 27/27] kernel/reboot: Add devm_register_restart_handler() Dmitry Osipenko
  2022-05-18 14:46 ` [PATCH v8 00/27] Introduce power-off+restart call chain API Rafael J. Wysocki
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Add devm_register_power_off_handler() helper that registers sys-off
handler using power-off mode and with a default priority. Most drivers
will want to register power-off handler with a default priority, so this
helper will reduce the boilerplate code and make code easier to read and
follow.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 include/linux/reboot.h |  4 ++++
 kernel/reboot.c        | 22 ++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index f185b64faae0..7c6e1f308f7c 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -141,6 +141,10 @@ int devm_register_sys_off_handler(struct device *dev,
 				  int (*callback)(struct sys_off_data *data),
 				  void *cb_data);
 
+int devm_register_power_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));
 
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 66033e12e8eb..b790025154ac 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -462,6 +462,28 @@ int devm_register_sys_off_handler(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_register_sys_off_handler);
 
+/**
+ *	devm_register_power_off_handler - Register power-off handler
+ *	@dev: Device that registers callback
+ *	@callback: Callback function
+ *	@cb_data: Callback's argument
+ *
+ *	Registers resource-managed sys-off handler with a default priority
+ *	and using power-off mode.
+ *
+ *	Returns zero on success, or error code on failure.
+ */
+int devm_register_power_off_handler(struct device *dev,
+				    int (*callback)(struct sys_off_data *data),
+				    void *cb_data)
+{
+	return devm_register_sys_off_handler(dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_DEFAULT,
+					     callback, cb_data);
+}
+EXPORT_SYMBOL_GPL(devm_register_power_off_handler);
+
 static struct sys_off_handler *platform_power_off_handler;
 
 static int platform_power_off_notify(struct sys_off_data *data)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v8 27/27] kernel/reboot: Add devm_register_restart_handler()
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (25 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 26/27] kernel/reboot: Add devm_register_power_off_handler() Dmitry Osipenko
@ 2022-05-09 23:32 ` Dmitry Osipenko
  2022-05-18 14:46 ` [PATCH v8 00/27] Introduce power-off+restart call chain API Rafael J. Wysocki
  27 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-09 23:32 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław
  Cc: linux-kernel, linux-csky, linux-ia64, linux-m68k, linux-mips,
	linux-parisc, linux-riscv, linux-sh, xen-devel, linux-acpi,
	linux-pm, linux-tegra

Add devm_register_restart_handler() helper that registers sys-off
handler using restart mode and with a default priority. Most drivers
will want to register restart handler with a default priority, so this
helper will reduce the boilerplate code and make code easier to read and
follow.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 include/linux/reboot.h |  4 ++++
 kernel/reboot.c        | 22 ++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 7c6e1f308f7c..e5d9ef886179 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -145,6 +145,10 @@ int devm_register_power_off_handler(struct device *dev,
 				    int (*callback)(struct sys_off_data *data),
 				    void *cb_data);
 
+int devm_register_restart_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));
 
diff --git a/kernel/reboot.c b/kernel/reboot.c
index b790025154ac..2e78bd754a75 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -484,6 +484,28 @@ int devm_register_power_off_handler(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_register_power_off_handler);
 
+/**
+ *	devm_register_restart_handler - Register restart handler
+ *	@dev: Device that registers callback
+ *	@callback: Callback function
+ *	@cb_data: Callback's argument
+ *
+ *	Registers resource-managed sys-off handler with a default priority
+ *	and using restart mode.
+ *
+ *	Returns zero on success, or error code on failure.
+ */
+int devm_register_restart_handler(struct device *dev,
+				  int (*callback)(struct sys_off_data *data),
+				  void *cb_data)
+{
+	return devm_register_sys_off_handler(dev,
+					     SYS_OFF_MODE_RESTART,
+					     SYS_OFF_PRIO_DEFAULT,
+					     callback, cb_data);
+}
+EXPORT_SYMBOL_GPL(devm_register_restart_handler);
+
 static struct sys_off_handler *platform_power_off_handler;
 
 static int platform_power_off_notify(struct sys_off_data *data)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 01/27] notifier: Add atomic_notifier_call_chain_is_empty()
  2022-05-09 23:32 ` [PATCH v8 01/27] notifier: Add atomic_notifier_call_chain_is_empty() Dmitry Osipenko
@ 2022-05-10 18:14   ` Rafael J. Wysocki
  2022-05-11 10:12     ` Dmitry Osipenko
  0 siblings, 1 reply; 40+ messages in thread
From: Rafael J. Wysocki @ 2022-05-10 18:14 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	the arch/x86 maintainers, H. Peter Anvin, Boris Ostrovsky,
	Juergen Gross, Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław, Linux Kernel Mailing List, linux-csky,
	linux-ia64, linux-m68k, open list:BROADCOM NVRAM DRIVER,
	linux-parisc, linux-riscv, Linux-sh list, xen-devel,
	ACPI Devel Maling List, Linux PM, linux-tegra

On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
<dmitry.osipenko@collabora.com> wrote:
>
> Add atomic_notifier_call_chain_is_empty() that returns true if given
> atomic call chain is empty.

It would be good to mention a use case for it.

> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
>  include/linux/notifier.h |  2 ++
>  kernel/notifier.c        | 13 +++++++++++++
>  2 files changed, 15 insertions(+)
>
> diff --git a/include/linux/notifier.h b/include/linux/notifier.h
> index 87069b8459af..95e2440037de 100644
> --- a/include/linux/notifier.h
> +++ b/include/linux/notifier.h
> @@ -173,6 +173,8 @@ extern int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh
>  extern int raw_notifier_call_chain_robust(struct raw_notifier_head *nh,
>                 unsigned long val_up, unsigned long val_down, void *v);
>
> +extern bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh);
> +
>  #define NOTIFY_DONE            0x0000          /* Don't care */
>  #define NOTIFY_OK              0x0001          /* Suits me */
>  #define NOTIFY_STOP_MASK       0x8000          /* Don't call further */
> diff --git a/kernel/notifier.c b/kernel/notifier.c
> index ba005ebf4730..aaf5b56452a6 100644
> --- a/kernel/notifier.c
> +++ b/kernel/notifier.c
> @@ -204,6 +204,19 @@ int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
>  EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
>  NOKPROBE_SYMBOL(atomic_notifier_call_chain);
>
> +/**
> + *     atomicnotifier_call_chain_is_empty - Check whether notifier chain is empty
> + *     @nh: Pointer to head of the blocking notifier chain
> + *
> + *     Checks whether notifier chain is empty.
> + *
> + *     Returns true is notifier chain is empty, false otherwise.
> + */
> +bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh)
> +{
> +       return !rcu_access_pointer(nh->head);
> +}
> +
>  /*
>   *     Blocking notifier chain routines.  All access to the chain is
>   *     synchronized by an rwsem.
> --
> 2.35.1
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 01/27] notifier: Add atomic_notifier_call_chain_is_empty()
  2022-05-10 18:14   ` Rafael J. Wysocki
@ 2022-05-11 10:12     ` Dmitry Osipenko
  0 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-11 10:12 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	the arch/x86 maintainers, H. Peter Anvin, Boris Ostrovsky,
	Juergen Gross, Stefano Stabellini, Len Brown, Santosh Shilimkar,
	Krzysztof Kozlowski, Liam Girdwood, Mark Brown, Pavel Machek,
	Lee Jones, Andrew Morton, Guenter Roeck, Daniel Lezcano,
	Andy Shevchenko, Ulf Hansson, Michał Mirosław,
	Linux Kernel Mailing List, linux-csky, linux-ia64, linux-m68k,
	open list:BROADCOM NVRAM DRIVER, linux-parisc, linux-riscv,
	Linux-sh list, xen-devel, ACPI Devel Maling List, Linux PM,
	linux-tegra

On 5/10/22 21:14, Rafael J. Wysocki wrote:
> On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
> <dmitry.osipenko@collabora.com> wrote:
>> Add atomic_notifier_call_chain_is_empty() that returns true if given
>> atomic call chain is empty.
> It would be good to mention a use case for it.
> 

I'll update this patch for v9.

-- 
Best regards,
Dmitry

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 00/27] Introduce power-off+restart call chain API
  2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
                   ` (26 preceding siblings ...)
  2022-05-09 23:32 ` [PATCH v8 27/27] kernel/reboot: Add devm_register_restart_handler() Dmitry Osipenko
@ 2022-05-18 14:46 ` Rafael J. Wysocki
  2022-05-19 10:57   ` Dmitry Osipenko
  2022-05-23 18:00   ` Geert Uytterhoeven
  27 siblings, 2 replies; 40+ messages in thread
From: Rafael J. Wysocki @ 2022-05-18 14:46 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	the arch/x86 maintainers, H. Peter Anvin, Boris Ostrovsky,
	Juergen Gross, Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław, Linux Kernel Mailing List, linux-csky,
	linux-ia64, linux-m68k, open list:BROADCOM NVRAM DRIVER,
	linux-parisc, linux-riscv, Linux-sh list, xen-devel,
	ACPI Devel Maling List, Linux PM, linux-tegra

On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
<dmitry.osipenko@collabora.com> wrote:
>
> Problem
> -------
>
> SoC devices require power-off call chaining functionality from kernel.
> We have a widely used restart chaining provided by restart notifier API,
> but nothing for power-off.
>
> Solution
> --------
>
> Introduce new API that provides call chains support for all restart and
> power-off modes. The new API is designed with simplicity and extensibility
> in mind.
>
> This is a third attempt to introduce the new API. First was made by
> Guenter Roeck back in 2014, second was made by Thierry Reding in 2017.
> In fact the work didn't stop and recently arm_pm_restart() was removed
> from v5.14 kernel, which was a part of preparatory work started by
> Guenter Roeck.
>
> Adoption plan
> -------------
>
> This patchset introduces the new API. It also converts multiple drivers
> and arch code to the new API to demonstrate how it all looks in practice,
> removing the pm_power_off_prepare global variable.
>
> The plan is:
>
> 1. Merge the new API and convert arch code to use do_kernel_power_off().
>    For now the new API will co-exist with the older API.
>
> 2. Convert all drivers and platform code to the new API.
>
> 3. Remove obsoleted pm_power_off and pm_power_off_prepare variables.
>
> Results
> -------
>
> 1. Devices can be powered off properly.
>
> 2. Global variables are removed from drivers.
>
> 3. Global pm_power_off and pm_power_off_prepare callback variables are
> removed once all users are converted to the new API. The latter callback
> is removed by patch #24 of this series.
>
> 4. Ambiguous call chain ordering is prohibited for non-default priorities.
>
> Changelog:
>
> v8: - Reworked sys-off handler like was suggested by Rafael Wysocki in
>       the comments to v7.
>
>     - The struct sys-off handler now is private to kernel/reboot.c and
>       new API is simplified.
>
>     - There is a single sys-off API function for all handler types.
>       Users shall pass the required sys-off mode type (restart, power-off
>       and etc).
>
>     - There is single struct sys_off_data callback argument for all
>       handler modes.
>
>     - User's callback now must return NOTIFY_DONE or NOTIFY_STOP.
>
>     - The default priority level is zero now.
>
>     - Multiple handlers now allowed to be registered at the default
>       priority level.
>
>     - Power-off call chain is atomic now, like the restart chain.
>
>     - kernel/reboot.c changes are split up into several logical patches.
>
>     - Added r-b from Michał Mirosław to unmodified patches from v7.
>
>     - Added acks that were missing in v7 by accident.

The v8 looks much better than the previous versions to me.

I actually don't really have any comments on it except for the minor
remark regarding patch [1/27] sent separately.

Please just send an update of that one patch and I will queue up the
series for 5.19.

However, I'm going to send a pull request with it in the second half
of the merge window, after the majority of the other changes in the
subsystems touched by it have been integrated.

> v7: - Rebased on a recent linux-next. Dropped the recently removed
>       NDS32 architecture. Only SH and x86 arches left un-acked.
>
>     - Added acks from Thomas Bogendoerfer and Krzysztof Kozlowski
>       to the MIPS and memory/emif patches respectively.
>
>     - Made couple minor cosmetic improvements to the new API.
>
>     - A month ago I joined Collabora and continuing to work on this series
>       on the company's time, so changed my email address to collabora.com
>
> v6: - Rebased on a recent linux-next.
>
>     - Made minor couple cosmetic changes.
>
> v5: - Dropped patches which cleaned up notifier/reboot headers, as was
>       requested by Rafael Wysocki.
>
>     - Dropped WARN_ON() from the code, as was requested by Rafael Wysocki.
>       Replaced it with pr_err() appropriately.
>
>     - Dropped *_notifier_has_unique_priority() functions and added
>       *_notifier_chain_register_unique_prio() instead, as was suggested
>       by Michał Mirosław and Rafael Wysocki.
>
>     - Dropped export of blocking_notifier_call_chain_is_empty() symbol,
>       as was suggested by Rafael Wysocki.
>
>     - Michał Mirosław suggested that will be better to split up patch
>       that adds the new API to ease reviewing, but Rafael Wysocki asked
>       not add more patches, so I kept it as a single patch.
>
>     - Added temporary "weak" stub for pm_power_off() which fixes linkage
>       failure once symbol is removed from arch/* code. Previously I missed
>       this problem because was only compile-testing object files.
>
> v4: - Made a very minor improvement to doc comments, clarifying couple
>       default values.
>
>     - Corrected list of emails recipient by adding Linus, Sebastian,
>       Philipp and more NDS people. Removed bouncing emails.
>
>     - Added acks that were given to v3.
>
> v3: - Renamed power_handler to sys_off_handler as was suggested by
>       Rafael Wysocki.
>
>     - Improved doc-comments as was suggested by Rafael Wysocki. Added more
>       doc-comments.
>
>     - Implemented full set of 180 patches which convert whole kernel in
>       accordance to the plan, see link [1] above. Slightly adjusted API to
>       better suit for the remaining converted drivers.
>
>       * Added unregister_sys_off_handler() that is handy for a couple old
>         platform drivers.
>
>       * Dropped devm_register_trivial_restart_handler(), 'simple' variant
>         is enough to have.
>
>     - Improved "Add atomic/blocking_notifier_has_unique_priority()" patch,
>       as was suggested by Andy Shevchenko. Also replaced down_write() with
>       down_read() and factored out common notifier_has_unique_priority().
>
>     - Added stop_chain field to struct restart_data and reboot_prep_data
>       after discovering couple drivers wanting that feature.
>
>     - Added acks that were given to v2.
>
> v2: - Replaced standalone power-off call chain demo-API with the combined
>       power-off+restart API because this is what drivers want. It's a more
>       comprehensive solution.
>
>     - Converted multiple drivers and arch code to the new API. Suggested by
>       Andy Shevchenko. I skimmed through the rest of drivers, verifying that
>       new API suits them. The rest of the drivers will be converted once we
>       will settle on the new API, otherwise will be too many patches here.
>
>     - v2 API doesn't expose notifier to users and require handlers to
>       have unique priority. Suggested by Guenter Roeck.
>
>     - v2 API has power-off chaining disabled by default and require
>       drivers to explicitly opt-in to the chaining. This preserves old
>       behaviour for existing drivers once they are converted to the new
>       API.
>
> Dmitry Osipenko (27):
>   notifier: Add atomic_notifier_call_chain_is_empty()
>   notifier: Add blocking/atomic_notifier_chain_register_unique_prio()
>   kernel/reboot: Introduce sys-off handler API
>   kernel/reboot: Wrap legacy power-off callbacks into sys-off handlers
>   kernel/reboot: Add do_kernel_power_off()
>   kernel/reboot: Add stub for pm_power_off
>   kernel/reboot: Add kernel_can_power_off()
>   kernel/reboot: Add register_platform_power_off()
>   ARM: Use do_kernel_power_off()
>   csky: Use do_kernel_power_off()
>   riscv: Use do_kernel_power_off()
>   arm64: Use do_kernel_power_off()
>   parisc: Use do_kernel_power_off()
>   xen/x86: Use do_kernel_power_off()
>   powerpc: Use do_kernel_power_off()
>   m68k: Switch to new sys-off handler API
>   sh: Use do_kernel_power_off()
>   x86: Use do_kernel_power_off()
>   ia64: Use do_kernel_power_off()
>   mips: Use do_kernel_power_off()
>   memory: emif: Use kernel_can_power_off()
>   ACPI: power: Switch to sys-off handler API
>   regulator: pfuze100: Use devm_register_sys_off_handler()
>   reboot: Remove pm_power_off_prepare()
>   soc/tegra: pmc: Use sys-off handler API to power off Nexus 7 properly
>   kernel/reboot: Add devm_register_power_off_handler()
>   kernel/reboot: Add devm_register_restart_handler()
>
>  arch/arm/kernel/reboot.c               |   4 +-
>  arch/arm64/kernel/process.c            |   3 +-
>  arch/csky/kernel/power.c               |   6 +-
>  arch/ia64/kernel/process.c             |   4 +-
>  arch/m68k/emu/natfeat.c                |   3 +-
>  arch/m68k/include/asm/machdep.h        |   1 -
>  arch/m68k/kernel/process.c             |   5 +-
>  arch/m68k/kernel/setup_mm.c            |   1 -
>  arch/m68k/kernel/setup_no.c            |   1 -
>  arch/m68k/mac/config.c                 |   4 +-
>  arch/mips/kernel/reset.c               |   3 +-
>  arch/parisc/kernel/process.c           |   4 +-
>  arch/powerpc/kernel/setup-common.c     |   4 +-
>  arch/powerpc/xmon/xmon.c               |   3 +-
>  arch/riscv/kernel/reset.c              |  12 +-
>  arch/sh/kernel/reboot.c                |   3 +-
>  arch/x86/kernel/reboot.c               |   4 +-
>  arch/x86/xen/enlighten_pv.c            |   4 +-
>  drivers/acpi/sleep.c                   |  16 +-
>  drivers/memory/emif.c                  |   2 +-
>  drivers/regulator/pfuze100-regulator.c |  42 ++-
>  drivers/soc/tegra/pmc.c                |  87 +++++--
>  include/linux/notifier.h               |   7 +
>  include/linux/pm.h                     |   1 -
>  include/linux/reboot.h                 |  91 +++++++
>  kernel/notifier.c                      | 101 +++++--
>  kernel/reboot.c                        | 347 ++++++++++++++++++++++++-
>  27 files changed, 639 insertions(+), 124 deletions(-)
>
> --
> 2.35.1
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 00/27] Introduce power-off+restart call chain API
  2022-05-18 14:46 ` [PATCH v8 00/27] Introduce power-off+restart call chain API Rafael J. Wysocki
@ 2022-05-19 10:57   ` Dmitry Osipenko
  2022-05-23 18:00   ` Geert Uytterhoeven
  1 sibling, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-19 10:57 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Geert Uytterhoeven, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	the arch/x86 maintainers, H. Peter Anvin, Boris Ostrovsky,
	Juergen Gross, Stefano Stabellini, Len Brown, Santosh Shilimkar,
	Krzysztof Kozlowski, Liam Girdwood, Mark Brown, Pavel Machek,
	Lee Jones, Andrew Morton, Guenter Roeck, Daniel Lezcano,
	Andy Shevchenko, Ulf Hansson, Michał Mirosław,
	Linux Kernel Mailing List, linux-csky, linux-ia64, linux-m68k,
	open list:BROADCOM NVRAM DRIVER, linux-parisc, linux-riscv,
	Linux-sh list, xen-devel, ACPI Devel Maling List, Linux PM,
	linux-tegra

On 5/18/22 17:46, Rafael J. Wysocki wrote:
> On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
> <dmitry.osipenko@collabora.com> wrote:
...
>> Introduce new API that provides call chains support for all restart and
>> power-off modes. The new API is designed with simplicity and extensibility
>> in mind.
...
> The v8 looks much better than the previous versions to me.
> 
> I actually don't really have any comments on it except for the minor
> remark regarding patch [1/27] sent separately.
> 
> Please just send an update of that one patch and I will queue up the
> series for 5.19.
> 
> However, I'm going to send a pull request with it in the second half
> of the merge window, after the majority of the other changes in the
> subsystems touched by it have been integrated.

Thanks, Rafael. I sent out the updated [1/27] patch to you.

For the reference, the updated patch can be found here as well:

https://lore.kernel.org/all/20220519105015.1195955-1-dmitry.osipenko@collabora.com/T/#u

-- 
Best regards,
Dmitry

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 00/27] Introduce power-off+restart call chain API
  2022-05-18 14:46 ` [PATCH v8 00/27] Introduce power-off+restart call chain API Rafael J. Wysocki
  2022-05-19 10:57   ` Dmitry Osipenko
@ 2022-05-23 18:00   ` Geert Uytterhoeven
  2022-05-24 13:43     ` Rafael J. Wysocki
  1 sibling, 1 reply; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-23 18:00 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Dmitry Osipenko, Thierry Reding, Jonathan Hunter, Russell King,
	Catalin Marinas, Will Deacon, Guo Ren, Greg Ungerer,
	Joshua Thompson, Thomas Bogendoerfer, Sebastian Reichel,
	Linus Walleij, Philipp Zabel, Greentime Hu, Vincent Chen,
	James E.J. Bottomley, Helge Deller, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Yoshinori Sato, Rich Felker,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	the arch/x86 maintainers, H. Peter Anvin, Boris Ostrovsky,
	Juergen Gross, Stefano Stabellini, Len Brown, Santosh Shilimkar,
	Krzysztof Kozlowski, Liam Girdwood, Mark Brown, Pavel Machek,
	Lee Jones, Andrew Morton, Guenter Roeck, Daniel Lezcano,
	Andy Shevchenko, Ulf Hansson, Michał Mirosław,
	Linux Kernel Mailing List, linux-csky, linux-ia64, linux-m68k,
	open list:BROADCOM NVRAM DRIVER, Parisc List, linux-riscv,
	Linux-sh list, xen-devel, ACPI Devel Maling List, Linux PM,
	linux-tegra

Hi Rafael,

On Wed, May 18, 2022 at 4:46 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
> On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
> <dmitry.osipenko@collabora.com> wrote:

> >   m68k: Switch to new sys-off handler API

Sorry, I didn't realize this was going to interact with the new m68k
virtual machine support, which is included in the m68k pull request
for v5.19.

> However, I'm going to send a pull request with it in the second half
> of the merge window, after the majority of the other changes in the
> subsystems touched by it have been integrated.

And presumably you will have to merge in v5.19-rc1, too?

I've sent a fix.  It should appear at
https://lore.kernel.org/r/20220523175520.949681-1-geert@linux-m68k.org
soon.

Can you please include that in your PR?
Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 07/27] kernel/reboot: Add kernel_can_power_off()
  2022-05-09 23:32 ` [PATCH v8 07/27] kernel/reboot: Add kernel_can_power_off() Dmitry Osipenko
@ 2022-05-24 13:14   ` Geert Uytterhoeven
  2022-05-24 13:41     ` Dmitry Osipenko
  0 siblings, 1 reply; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-24 13:14 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Greg Ungerer, Joshua Thompson,
	Thomas Bogendoerfer, Sebastian Reichel, Linus Walleij,
	Philipp Zabel, Greentime Hu, Vincent Chen, James E.J. Bottomley,
	Helge Deller, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Yoshinori Sato, Rich Felker, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, the arch/x86 maintainers,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław, Linux Kernel Mailing List, linux-csky,
	linux-ia64, linux-m68k, open list:BROADCOM NVRAM DRIVER,
	Parisc List, linux-riscv, Linux-sh list, xen-devel,
	ACPI Devel Maling List, Linux PM list, linux-tegra,
	Linux-Renesas

Hi Dmitry,

On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
<dmitry.osipenko@collabora.com> wrote:
> Add kernel_can_power_off() helper that replaces open-coded checks of
> the global pm_power_off variable. This is a necessary step towards
> supporting chained power-off handlers.
>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>

Thanks for your patch, which is now commit 0e2110d2e910e44c
("kernel/reboot: Add kernel_can_power_off()") in pm/linux-next.

This causes the "poweroff" command (Debian nfsroot) to no longer
cleanly halt the system on arm32 systems, but fail with a panic
instead:

-reboot: System halted
+reboot: Power down
+Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
+CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted
5.18.0-rc7-shmobile-00007-g0e2110d2e910 #1274
+Hardware name: Generic R-Car Gen2 (Flattened Device Tree)
+ unwind_backtrace from show_stack+0x10/0x14
+ show_stack from dump_stack_lvl+0x40/0x4c
+ dump_stack_lvl from panic+0xf4/0x330
+ panic from do_exit+0x1c8/0x8e4
+ do_exit from __do_sys_reboot+0x174/0x1fc
+ __do_sys_reboot from ret_fast_syscall+0x0/0x54
+Exception stack(0xf0815fa8 to 0xf0815ff0)
+5fa0:                   004e6954 00000000 fee1dead 28121969 4321fedc f0d94600
+5fc0: 004e6954 00000000 00000000 00000058 befa0c78 00000000 befa0c10 004e56f8
+5fe0: 00000058 befa0b6c b6ec8d45 b6e4a746
+---[ end Kernel panic - not syncing: Attempted to kill init!
exitcode=0x00000000 ]---

On arm64, "poweroff" causes a clean "reboot: Power down" before/after.

On both arm32 and arm64, the same handlers are registered:
  - SYS_OFF_MODE_POWER_OFF_PREPARE: legacy_pm_power_off_prepare
  - SYS_OFF_MODE_POWER_OFF: legacy_pm_power_off

On both arm32 and arm64, legacy_pm_power_off_prepare() is called.
On both arm32 and arm64, legacy_pm_power_off() does not seem to
be called.

On arm32, both pm_power_off_prepare and pm_power_off are NULL.
On arm64, pm_power_off_prepare is NULL, and
pm_power_off is psci_sys_poweroff.

Do you have a clue?
Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 07/27] kernel/reboot: Add kernel_can_power_off()
  2022-05-24 13:14   ` Geert Uytterhoeven
@ 2022-05-24 13:41     ` Dmitry Osipenko
  2022-05-24 15:03       ` Geert Uytterhoeven
  0 siblings, 1 reply; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-24 13:41 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Greg Ungerer, Joshua Thompson,
	Thomas Bogendoerfer, Sebastian Reichel, Linus Walleij,
	Philipp Zabel, Greentime Hu, Vincent Chen, James E.J. Bottomley,
	Helge Deller, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Yoshinori Sato, Rich Felker, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, the arch/x86 maintainers,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław, Linux Kernel Mailing List, linux-csky,
	linux-ia64, linux-m68k, open list:BROADCOM NVRAM DRIVER,
	Parisc List, linux-riscv, Linux-sh list, xen-devel,
	ACPI Devel Maling List, Linux PM list, linux-tegra,
	Linux-Renesas

On 5/24/22 16:14, Geert Uytterhoeven wrote:
> Hi Dmitry,
> 
> On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
> <dmitry.osipenko@collabora.com> wrote:
>> Add kernel_can_power_off() helper that replaces open-coded checks of
>> the global pm_power_off variable. This is a necessary step towards
>> supporting chained power-off handlers.
>>
>> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> 
> Thanks for your patch, which is now commit 0e2110d2e910e44c
> ("kernel/reboot: Add kernel_can_power_off()") in pm/linux-next.
> 
> This causes the "poweroff" command (Debian nfsroot) to no longer
> cleanly halt the system on arm32 systems, but fail with a panic
> instead:
> 
> -reboot: System halted
> +reboot: Power down
> +Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
> +CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted
> 5.18.0-rc7-shmobile-00007-g0e2110d2e910 #1274
> +Hardware name: Generic R-Car Gen2 (Flattened Device Tree)
> + unwind_backtrace from show_stack+0x10/0x14
> + show_stack from dump_stack_lvl+0x40/0x4c
> + dump_stack_lvl from panic+0xf4/0x330
> + panic from do_exit+0x1c8/0x8e4
> + do_exit from __do_sys_reboot+0x174/0x1fc
> + __do_sys_reboot from ret_fast_syscall+0x0/0x54
> +Exception stack(0xf0815fa8 to 0xf0815ff0)
> +5fa0:                   004e6954 00000000 fee1dead 28121969 4321fedc f0d94600
> +5fc0: 004e6954 00000000 00000000 00000058 befa0c78 00000000 befa0c10 004e56f8
> +5fe0: 00000058 befa0b6c b6ec8d45 b6e4a746
> +---[ end Kernel panic - not syncing: Attempted to kill init!
> exitcode=0x00000000 ]---
> 
> On arm64, "poweroff" causes a clean "reboot: Power down" before/after.
> 
> On both arm32 and arm64, the same handlers are registered:
>   - SYS_OFF_MODE_POWER_OFF_PREPARE: legacy_pm_power_off_prepare
>   - SYS_OFF_MODE_POWER_OFF: legacy_pm_power_off
> 
> On both arm32 and arm64, legacy_pm_power_off_prepare() is called.
> On both arm32 and arm64, legacy_pm_power_off() does not seem to
> be called.
> 
> On arm32, both pm_power_off_prepare and pm_power_off are NULL.
> On arm64, pm_power_off_prepare is NULL, and
> pm_power_off is psci_sys_poweroff.
> 
> Do you have a clue?
> Thanks!

Thank you, Geert! I see the problem, the kernel_can_power_off() checks whether power-off handler is registered, but it's always registered because legacy_pm_power_off is registered unconditionally. So it causes trouble for platforms that don't have power-off handler installed at all. All platforms that I tested have a power-off handler, so now wonder that I didn't notice this before.

This change should fix the problem, please give it a try:

--- 8< ---

diff --git a/kernel/reboot.c b/kernel/reboot.c
index 0bdc64ecf4f6..2d55b8bdb444 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -569,22 +569,6 @@ static int legacy_pm_power_off(struct sys_off_data *data)
 	return NOTIFY_DONE;
 }
 
-/*
- * Register sys-off handlers for legacy PM callbacks. This allows legacy
- * PM callbacks co-exist with the new sys-off API.
- *
- * TODO: Remove legacy handlers once all legacy PM users will be switched
- *       to the sys-off based APIs.
- */
-static int __init legacy_pm_init(void)
-{
-	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT,
-				 legacy_pm_power_off, NULL);
-
-	return 0;
-}
-core_initcall(legacy_pm_init);
-
 static void do_kernel_power_off_prepare(void)
 {
 	blocking_notifier_call_chain(&power_off_prep_handler_list, 0, NULL);
@@ -670,6 +654,18 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
 	if (ret)
 		return ret;
 
+	/*
+	 * Register sys-off handler for the legacy PM callback. This allows
+	 * legacy PM callbacks co-exist with the new sys-off API.
+	 *
+	 * TODO: Remove legacy handler once all legacy PM users will be
+	 *       switched to the sys-off based APIs.
+	 */
+	if (pm_power_off)
+		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
+					 SYS_OFF_PRIO_DEFAULT,
+					 legacy_pm_power_off, NULL);
+
 	/* Instead of trying to make the power_off code look like
 	 * halt when pm_power_off is not set do it the easy way.
 	 */




-- 
Best regards,
Dmitry

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 00/27] Introduce power-off+restart call chain API
  2022-05-23 18:00   ` Geert Uytterhoeven
@ 2022-05-24 13:43     ` Rafael J. Wysocki
  0 siblings, 0 replies; 40+ messages in thread
From: Rafael J. Wysocki @ 2022-05-24 13:43 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Rafael J. Wysocki, Dmitry Osipenko, Thierry Reding,
	Jonathan Hunter, Russell King, Catalin Marinas, Will Deacon,
	Guo Ren, Greg Ungerer, Joshua Thompson, Thomas Bogendoerfer,
	Sebastian Reichel, Linus Walleij, Philipp Zabel, Greentime Hu,
	Vincent Chen, James E.J. Bottomley, Helge Deller,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Yoshinori Sato,
	Rich Felker, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, the arch/x86 maintainers, H. Peter Anvin,
	Boris Ostrovsky, Juergen Gross, Stefano Stabellini, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław, Linux Kernel Mailing List, linux-csky,
	linux-ia64, linux-m68k, open list:BROADCOM NVRAM DRIVER,
	Parisc List, linux-riscv, Linux-sh list, xen-devel,
	ACPI Devel Maling List, Linux PM, linux-tegra

Hi Geert,

On Mon, May 23, 2022 at 8:08 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Rafael,
>
> On Wed, May 18, 2022 at 4:46 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
> > On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
> > <dmitry.osipenko@collabora.com> wrote:
>
> > >   m68k: Switch to new sys-off handler API
>
> Sorry, I didn't realize this was going to interact with the new m68k
> virtual machine support, which is included in the m68k pull request
> for v5.19.
>
> > However, I'm going to send a pull request with it in the second half
> > of the merge window, after the majority of the other changes in the
> > subsystems touched by it have been integrated.
>
> And presumably you will have to merge in v5.19-rc1, too?

I will merge this series on top of the Linus' merges of my pull
requests sent yesterday (assuming that he pulls them, that is).

> I've sent a fix.  It should appear at
> https://lore.kernel.org/r/20220523175520.949681-1-geert@linux-m68k.org
> soon.
>
> Can you please include that in your PR?

I will.

Thanks!

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 07/27] kernel/reboot: Add kernel_can_power_off()
  2022-05-24 13:41     ` Dmitry Osipenko
@ 2022-05-24 15:03       ` Geert Uytterhoeven
  2022-05-24 20:16         ` Dmitry Osipenko
  0 siblings, 1 reply; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-24 15:03 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Greg Ungerer, Joshua Thompson,
	Thomas Bogendoerfer, Sebastian Reichel, Linus Walleij,
	Philipp Zabel, Greentime Hu, Vincent Chen, James E.J. Bottomley,
	Helge Deller, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Yoshinori Sato, Rich Felker, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, the arch/x86 maintainers,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław, Linux Kernel Mailing List, linux-csky,
	linux-ia64, linux-m68k, open list:BROADCOM NVRAM DRIVER,
	Parisc List, linux-riscv, Linux-sh list, xen-devel,
	ACPI Devel Maling List, Linux PM list, linux-tegra,
	Linux-Renesas

Hi Dmitry,

On Tue, May 24, 2022 at 3:41 PM Dmitry Osipenko
<dmitry.osipenko@collabora.com> wrote:
> On 5/24/22 16:14, Geert Uytterhoeven wrote:
> > On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
> > <dmitry.osipenko@collabora.com> wrote:
> >> Add kernel_can_power_off() helper that replaces open-coded checks of
> >> the global pm_power_off variable. This is a necessary step towards
> >> supporting chained power-off handlers.
> >>
> >> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> >
> > Thanks for your patch, which is now commit 0e2110d2e910e44c
> > ("kernel/reboot: Add kernel_can_power_off()") in pm/linux-next.
> >
> > This causes the "poweroff" command (Debian nfsroot) to no longer
> > cleanly halt the system on arm32 systems, but fail with a panic
> > instead:
> >
> > -reboot: System halted
> > +reboot: Power down
> > +Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
> > +CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted
> > 5.18.0-rc7-shmobile-00007-g0e2110d2e910 #1274
> > +Hardware name: Generic R-Car Gen2 (Flattened Device Tree)
> > + unwind_backtrace from show_stack+0x10/0x14
> > + show_stack from dump_stack_lvl+0x40/0x4c
> > + dump_stack_lvl from panic+0xf4/0x330
> > + panic from do_exit+0x1c8/0x8e4
> > + do_exit from __do_sys_reboot+0x174/0x1fc
> > + __do_sys_reboot from ret_fast_syscall+0x0/0x54
> > +Exception stack(0xf0815fa8 to 0xf0815ff0)
> > +5fa0:                   004e6954 00000000 fee1dead 28121969 4321fedc f0d94600
> > +5fc0: 004e6954 00000000 00000000 00000058 befa0c78 00000000 befa0c10 004e56f8
> > +5fe0: 00000058 befa0b6c b6ec8d45 b6e4a746
> > +---[ end Kernel panic - not syncing: Attempted to kill init!
> > exitcode=0x00000000 ]---
> >
> > On arm64, "poweroff" causes a clean "reboot: Power down" before/after.
> >
> > On both arm32 and arm64, the same handlers are registered:
> >   - SYS_OFF_MODE_POWER_OFF_PREPARE: legacy_pm_power_off_prepare
> >   - SYS_OFF_MODE_POWER_OFF: legacy_pm_power_off
> >
> > On both arm32 and arm64, legacy_pm_power_off_prepare() is called.
> > On both arm32 and arm64, legacy_pm_power_off() does not seem to
> > be called.
> >
> > On arm32, both pm_power_off_prepare and pm_power_off are NULL.
> > On arm64, pm_power_off_prepare is NULL, and
> > pm_power_off is psci_sys_poweroff.
> >
> > Do you have a clue?
> > Thanks!
>
> Thank you, Geert! I see the problem, the kernel_can_power_off() checks whether power-off handler is registered, but it's always registered because legacy_pm_power_off is registered unconditionally. So it causes trouble for platforms that don't have power-off handler installed at all. All platforms that I tested have a power-off handler, so now wonder that I didn't notice this before.
>
> This change should fix the problem, please give it a try:

Thank you, that fixes the problem for me!

Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 07/27] kernel/reboot: Add kernel_can_power_off()
  2022-05-24 15:03       ` Geert Uytterhoeven
@ 2022-05-24 20:16         ` Dmitry Osipenko
  0 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-24 20:16 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Greg Ungerer, Joshua Thompson,
	Thomas Bogendoerfer, Sebastian Reichel, Linus Walleij,
	Philipp Zabel, Greentime Hu, Vincent Chen, James E.J. Bottomley,
	Helge Deller, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Yoshinori Sato, Rich Felker, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, the arch/x86 maintainers,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław, Linux Kernel Mailing List, linux-csky,
	linux-ia64, linux-m68k, open list:BROADCOM NVRAM DRIVER,
	Parisc List, linux-riscv, Linux-sh list, xen-devel,
	ACPI Devel Maling List, Linux PM list, linux-tegra,
	Linux-Renesas

On 5/24/22 18:03, Geert Uytterhoeven wrote:
> Hi Dmitry,
> 
> On Tue, May 24, 2022 at 3:41 PM Dmitry Osipenko
> <dmitry.osipenko@collabora.com> wrote:
>> On 5/24/22 16:14, Geert Uytterhoeven wrote:
>>> On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
>>> <dmitry.osipenko@collabora.com> wrote:
>>>> Add kernel_can_power_off() helper that replaces open-coded checks of
>>>> the global pm_power_off variable. This is a necessary step towards
>>>> supporting chained power-off handlers.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
>>>
>>> Thanks for your patch, which is now commit 0e2110d2e910e44c
>>> ("kernel/reboot: Add kernel_can_power_off()") in pm/linux-next.
>>>
>>> This causes the "poweroff" command (Debian nfsroot) to no longer
>>> cleanly halt the system on arm32 systems, but fail with a panic
>>> instead:
>>>
>>> -reboot: System halted
>>> +reboot: Power down
>>> +Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
>>> +CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted
>>> 5.18.0-rc7-shmobile-00007-g0e2110d2e910 #1274
>>> +Hardware name: Generic R-Car Gen2 (Flattened Device Tree)
>>> + unwind_backtrace from show_stack+0x10/0x14
>>> + show_stack from dump_stack_lvl+0x40/0x4c
>>> + dump_stack_lvl from panic+0xf4/0x330
>>> + panic from do_exit+0x1c8/0x8e4
>>> + do_exit from __do_sys_reboot+0x174/0x1fc
>>> + __do_sys_reboot from ret_fast_syscall+0x0/0x54
>>> +Exception stack(0xf0815fa8 to 0xf0815ff0)
>>> +5fa0:                   004e6954 00000000 fee1dead 28121969 4321fedc f0d94600
>>> +5fc0: 004e6954 00000000 00000000 00000058 befa0c78 00000000 befa0c10 004e56f8
>>> +5fe0: 00000058 befa0b6c b6ec8d45 b6e4a746
>>> +---[ end Kernel panic - not syncing: Attempted to kill init!
>>> exitcode=0x00000000 ]---
>>>
>>> On arm64, "poweroff" causes a clean "reboot: Power down" before/after.
>>>
>>> On both arm32 and arm64, the same handlers are registered:
>>>   - SYS_OFF_MODE_POWER_OFF_PREPARE: legacy_pm_power_off_prepare
>>>   - SYS_OFF_MODE_POWER_OFF: legacy_pm_power_off
>>>
>>> On both arm32 and arm64, legacy_pm_power_off_prepare() is called.
>>> On both arm32 and arm64, legacy_pm_power_off() does not seem to
>>> be called.
>>>
>>> On arm32, both pm_power_off_prepare and pm_power_off are NULL.
>>> On arm64, pm_power_off_prepare is NULL, and
>>> pm_power_off is psci_sys_poweroff.
>>>
>>> Do you have a clue?
>>> Thanks!
>>
>> Thank you, Geert! I see the problem, the kernel_can_power_off() checks whether power-off handler is registered, but it's always registered because legacy_pm_power_off is registered unconditionally. So it causes trouble for platforms that don't have power-off handler installed at all. All platforms that I tested have a power-off handler, so now wonder that I didn't notice this before.
>>
>> This change should fix the problem, please give it a try:
> 
> Thank you, that fixes the problem for me!
> 
> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>

Great! I'll send the proper patch soon.

-- 
Best regards,
Dmitry

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 16/27] m68k: Switch to new sys-off handler API
  2022-05-09 23:32 ` [PATCH v8 16/27] m68k: Switch to new sys-off handler API Dmitry Osipenko
@ 2022-05-31 19:04   ` Geert Uytterhoeven
  2022-05-31 21:24     ` Dmitry Osipenko
  0 siblings, 1 reply; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-31 19:04 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Greg Ungerer, Joshua Thompson,
	Thomas Bogendoerfer, Sebastian Reichel, Linus Walleij,
	Philipp Zabel, Greentime Hu, Vincent Chen, James E.J. Bottomley,
	Helge Deller, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Yoshinori Sato, Rich Felker, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, the arch/x86 maintainers,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław, Linux Kernel Mailing List, linux-csky,
	linux-ia64, linux-m68k, open list:BROADCOM NVRAM DRIVER,
	Parisc List, linux-riscv, Linux-sh list, xen-devel,
	ACPI Devel Maling List, Linux PM list, linux-tegra

Hi Dmitry,

On Tue, May 10, 2022 at 1:34 AM Dmitry Osipenko
<dmitry.osipenko@collabora.com> wrote:
> Kernel now supports chained power-off handlers. Use
> register_power_off_handler() that registers power-off handlers and
> do_kernel_power_off() that invokes chained power-off handlers. Legacy
> pm_power_off() will be removed once all drivers will be converted to
> the new sys-off API.
>
> Normally arch code should adopt only the do_kernel_power_off() at first,
> but m68k is a special case because it uses pm_power_off() "inside out",
> i.e. pm_power_off() invokes machine_power_off() [in fact it does nothing],
> while it's machine_power_off() that should invoke the pm_power_off(), and
> thus, we can't convert platforms to the new API separately. There are only
> two platforms changed here, so it's not a big deal.
>
> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>

Thanks for your patch, which is now commit f0f7e5265b3b37b0
("m68k: Switch to new sys-off handler API") upstream.

> --- a/arch/m68k/emu/natfeat.c
> +++ b/arch/m68k/emu/natfeat.c
> @@ -15,6 +15,7 @@
>  #include <linux/string.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> +#include <linux/reboot.h>
>  #include <linux/io.h>
>  #include <asm/machdep.h>
>  #include <asm/natfeat.h>
> @@ -90,5 +91,5 @@ void __init nf_init(void)
>         pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
>                 version & 0xffff);
>
> -       mach_power_off = nf_poweroff;
> +       register_platform_power_off(nf_poweroff);

Unfortunately nothing is registered, as this is called very early
(from setup_arch(), before the memory allocator is available.
Hence register_sys_off_handler() fails with -ENOMEM, and poweroff
stops working.

Possible solutions:
  - As at most one handler can be registered,
    register_platform_power_off() could use a static struct sys_off_handler
    instance,
  - Keep mach_power_off, and call register_platform_power_off() later.

Anything else?
Thanks!

> --- a/arch/m68k/mac/config.c
> +++ b/arch/m68k/mac/config.c
> @@ -12,6 +12,7 @@
>
>  #include <linux/errno.h>
>  #include <linux/module.h>
> +#include <linux/reboot.h>
>  #include <linux/types.h>
>  #include <linux/mm.h>
>  #include <linux/tty.h>
> @@ -140,7 +141,6 @@ void __init config_mac(void)
>         mach_hwclk = mac_hwclk;
>         mach_reset = mac_reset;
>         mach_halt = mac_poweroff;
> -       mach_power_off = mac_poweroff;
>  #if IS_ENABLED(CONFIG_INPUT_M68K_BEEP)
>         mach_beep = mac_mksound;
>  #endif
> @@ -160,6 +160,8 @@ void __init config_mac(void)
>
>         if (macintosh_config->ident == MAC_MODEL_IICI)
>                 mach_l2_flush = via_l2_flush;
> +
> +       register_platform_power_off(mac_poweroff);
>  }

This must have the same problem.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v8 16/27] m68k: Switch to new sys-off handler API
  2022-05-31 19:04   ` Geert Uytterhoeven
@ 2022-05-31 21:24     ` Dmitry Osipenko
  0 siblings, 0 replies; 40+ messages in thread
From: Dmitry Osipenko @ 2022-05-31 21:24 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Thierry Reding, Jonathan Hunter, Russell King, Catalin Marinas,
	Will Deacon, Guo Ren, Greg Ungerer, Joshua Thompson,
	Thomas Bogendoerfer, Sebastian Reichel, Linus Walleij,
	Philipp Zabel, Greentime Hu, Vincent Chen, James E.J. Bottomley,
	Helge Deller, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Yoshinori Sato, Rich Felker, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, the arch/x86 maintainers,
	H. Peter Anvin, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Rafael J. Wysocki, Len Brown,
	Santosh Shilimkar, Krzysztof Kozlowski, Liam Girdwood,
	Mark Brown, Pavel Machek, Lee Jones, Andrew Morton,
	Guenter Roeck, Daniel Lezcano, Andy Shevchenko, Ulf Hansson,
	Michał Mirosław, Linux Kernel Mailing List, linux-csky,
	linux-ia64, linux-m68k, open list:BROADCOM NVRAM DRIVER,
	Parisc List, linux-riscv, Linux-sh list, xen-devel,
	ACPI Devel Maling List, Linux PM list, linux-tegra

On 5/31/22 22:04, Geert Uytterhoeven wrote:
> Hi Dmitry,
> 
> On Tue, May 10, 2022 at 1:34 AM Dmitry Osipenko
> <dmitry.osipenko@collabora.com> wrote:
>> Kernel now supports chained power-off handlers. Use
>> register_power_off_handler() that registers power-off handlers and
>> do_kernel_power_off() that invokes chained power-off handlers. Legacy
>> pm_power_off() will be removed once all drivers will be converted to
>> the new sys-off API.
>>
>> Normally arch code should adopt only the do_kernel_power_off() at first,
>> but m68k is a special case because it uses pm_power_off() "inside out",
>> i.e. pm_power_off() invokes machine_power_off() [in fact it does nothing],
>> while it's machine_power_off() that should invoke the pm_power_off(), and
>> thus, we can't convert platforms to the new API separately. There are only
>> two platforms changed here, so it's not a big deal.
>>
>> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
>> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> 
> Thanks for your patch, which is now commit f0f7e5265b3b37b0
> ("m68k: Switch to new sys-off handler API") upstream.
> 
>> --- a/arch/m68k/emu/natfeat.c
>> +++ b/arch/m68k/emu/natfeat.c
>> @@ -15,6 +15,7 @@
>>  #include <linux/string.h>
>>  #include <linux/kernel.h>
>>  #include <linux/module.h>
>> +#include <linux/reboot.h>
>>  #include <linux/io.h>
>>  #include <asm/machdep.h>
>>  #include <asm/natfeat.h>
>> @@ -90,5 +91,5 @@ void __init nf_init(void)
>>         pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
>>                 version & 0xffff);
>>
>> -       mach_power_off = nf_poweroff;
>> +       register_platform_power_off(nf_poweroff);
> 
> Unfortunately nothing is registered, as this is called very early
> (from setup_arch(), before the memory allocator is available.
> Hence register_sys_off_handler() fails with -ENOMEM, and poweroff
> stops working.
> 
> Possible solutions:
>   - As at most one handler can be registered,
>     register_platform_power_off() could use a static struct sys_off_handler
>     instance,
>   - Keep mach_power_off, and call register_platform_power_off() later.
> 
> Anything else?
> Thanks!
> 
>> --- a/arch/m68k/mac/config.c
>> +++ b/arch/m68k/mac/config.c
>> @@ -12,6 +12,7 @@
>>
>>  #include <linux/errno.h>
>>  #include <linux/module.h>
>> +#include <linux/reboot.h>
>>  #include <linux/types.h>
>>  #include <linux/mm.h>
>>  #include <linux/tty.h>
>> @@ -140,7 +141,6 @@ void __init config_mac(void)
>>         mach_hwclk = mac_hwclk;
>>         mach_reset = mac_reset;
>>         mach_halt = mac_poweroff;
>> -       mach_power_off = mac_poweroff;
>>  #if IS_ENABLED(CONFIG_INPUT_M68K_BEEP)
>>         mach_beep = mac_mksound;
>>  #endif
>> @@ -160,6 +160,8 @@ void __init config_mac(void)
>>
>>         if (macintosh_config->ident == MAC_MODEL_IICI)
>>                 mach_l2_flush = via_l2_flush;
>> +
>> +       register_platform_power_off(mac_poweroff);
>>  }
> 
> This must have the same problem.

The static variant should be better, IMO. I'm not sure whether other platforms won't face the same problem once they will start using register_platform_power_off(). I'll send the fix, thank you for the testing!

--- >8 ---

diff --git a/kernel/reboot.c b/kernel/reboot.c
index a091145ee710..4fea05d387dc 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -315,6 +315,37 @@ static int sys_off_notify(struct notifier_block *nb,
 	return handler->sys_off_cb(&data);
 }
 
+static struct sys_off_handler platform_sys_off_handler;
+
+static struct sys_off_handler *alloc_sys_off_handler(int priority)
+{
+	struct sys_off_handler *handler;
+
+	/*
+	 * Platforms like m68k can't allocate sys_off handler dynamically
+	 * at the early boot time.
+	 */
+	if (priority == SYS_OFF_PRIO_PLATFORM) {
+		handler = &platform_sys_off_handler;
+		if (handler->cb_data)
+			return ERR_PTR(-EBUSY);
+	} else {
+		handler = kzalloc(sizeof(*handler), GFP_KERNEL);
+		if (!handler)
+			return ERR_PTR(-ENOMEM);
+	}
+
+	return handler;
+}
+
+static void free_sys_off_handler(struct sys_off_handler *handler)
+{
+	if (handler == &platform_sys_off_handler)
+		memset(handler, 0, sizeof(*handler));
+	else
+		kfree(handler);
+}
+
 /**
  *	register_sys_off_handler - Register sys-off handler
  *	@mode: Sys-off mode
@@ -345,9 +376,9 @@ register_sys_off_handler(enum sys_off_mode mode,
 	struct sys_off_handler *handler;
 	int err;
 
-	handler = kzalloc(sizeof(*handler), GFP_KERNEL);
-	if (!handler)
-		return ERR_PTR(-ENOMEM);
+	handler = alloc_sys_off_handler(priority);
+	if (IS_ERR(handler))
+		return handler;
 
 	switch (mode) {
 	case SYS_OFF_MODE_POWER_OFF_PREPARE:
@@ -364,7 +395,7 @@ register_sys_off_handler(enum sys_off_mode mode,
 		break;
 
 	default:
-		kfree(handler);
+		free_sys_off_handler(handler);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -391,7 +422,7 @@ register_sys_off_handler(enum sys_off_mode mode,
 	}
 
 	if (err) {
-		kfree(handler);
+		free_sys_off_handler(handler);
 		return ERR_PTR(err);
 	}
 
@@ -422,7 +453,7 @@ void unregister_sys_off_handler(struct sys_off_handler *handler)
 	/* sanity check, shall never happen */
 	WARN_ON(err);
 
-	kfree(handler);
+	free_sys_off_handler(handler);
 }
 EXPORT_SYMBOL_GPL(unregister_sys_off_handler);
 

^ permalink raw reply related	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2022-05-31 21:25 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-09 23:32 [PATCH v8 00/27] Introduce power-off+restart call chain API Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 01/27] notifier: Add atomic_notifier_call_chain_is_empty() Dmitry Osipenko
2022-05-10 18:14   ` Rafael J. Wysocki
2022-05-11 10:12     ` Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 02/27] notifier: Add blocking/atomic_notifier_chain_register_unique_prio() Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 03/27] kernel/reboot: Introduce sys-off handler API Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 04/27] kernel/reboot: Wrap legacy power-off callbacks into sys-off handlers Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 05/27] kernel/reboot: Add do_kernel_power_off() Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 06/27] kernel/reboot: Add stub for pm_power_off Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 07/27] kernel/reboot: Add kernel_can_power_off() Dmitry Osipenko
2022-05-24 13:14   ` Geert Uytterhoeven
2022-05-24 13:41     ` Dmitry Osipenko
2022-05-24 15:03       ` Geert Uytterhoeven
2022-05-24 20:16         ` Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 08/27] kernel/reboot: Add register_platform_power_off() Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 09/27] ARM: Use do_kernel_power_off() Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 10/27] csky: " Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 11/27] riscv: " Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 12/27] arm64: " Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 13/27] parisc: " Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 14/27] xen/x86: " Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 15/27] powerpc: " Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 16/27] m68k: Switch to new sys-off handler API Dmitry Osipenko
2022-05-31 19:04   ` Geert Uytterhoeven
2022-05-31 21:24     ` Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 17/27] sh: Use do_kernel_power_off() Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 18/27] x86: " Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 19/27] ia64: " Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 20/27] mips: " Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 21/27] memory: emif: Use kernel_can_power_off() Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 22/27] ACPI: power: Switch to sys-off handler API Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 23/27] regulator: pfuze100: Use devm_register_sys_off_handler() Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 24/27] reboot: Remove pm_power_off_prepare() Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 25/27] soc/tegra: pmc: Use sys-off handler API to power off Nexus 7 properly Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 26/27] kernel/reboot: Add devm_register_power_off_handler() Dmitry Osipenko
2022-05-09 23:32 ` [PATCH v8 27/27] kernel/reboot: Add devm_register_restart_handler() Dmitry Osipenko
2022-05-18 14:46 ` [PATCH v8 00/27] Introduce power-off+restart call chain API Rafael J. Wysocki
2022-05-19 10:57   ` Dmitry Osipenko
2022-05-23 18:00   ` Geert Uytterhoeven
2022-05-24 13:43     ` Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).