2022-05-10 04:12:55

by Dmitry Osipenko

[permalink] [raw]
Subject: [PATCH v8 00/27] Introduce power-off+restart call chain API

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



2022-05-10 06:23:05

by Dmitry Osipenko

[permalink] [raw]
Subject: [PATCH v8 11/27] riscv: Use do_kernel_power_off()

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 <[email protected]>
Reviewed-by: Michał Mirosław <[email protected]>
Signed-off-by: Dmitry Osipenko <[email protected]>
---
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


2022-05-10 09:18:09

by Dmitry Osipenko

[permalink] [raw]
Subject: [PATCH v8 08/27] kernel/reboot: Add register_platform_power_off()

Add platform-level registration helpers that will ease transition of the
arch/platform power-off callbacks to the new sys-off based API, allowing
us to remove the global pm_power_off variable in the future.

Signed-off-by: Dmitry Osipenko <[email protected]>
---
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


2022-05-10 09:40:57

by Dmitry Osipenko

[permalink] [raw]
Subject: [PATCH v8 02/27] notifier: Add blocking/atomic_notifier_chain_register_unique_prio()

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 <[email protected]>
Signed-off-by: Dmitry Osipenko <[email protected]>
---
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


2022-05-10 12:50:13

by Dmitry Osipenko

[permalink] [raw]
Subject: [PATCH v8 10/27] csky: Use do_kernel_power_off()

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 <[email protected]>
Reviewed-by: Michał Mirosław <[email protected]>
Signed-off-by: Dmitry Osipenko <[email protected]>
---
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


2022-05-10 13:14:37

by Dmitry Osipenko

[permalink] [raw]
Subject: [PATCH v8 23/27] regulator: pfuze100: Use devm_register_sys_off_handler()

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 <[email protected]>
Signed-off-by: Dmitry Osipenko <[email protected]>
---
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


2022-05-18 14:51:07

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v8 00/27] Introduce power-off+restart call chain API

On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
<[email protected]> 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
>

2022-05-19 12:58:02

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: [PATCH v8 00/27] Introduce power-off+restart call chain API

On 5/18/22 17:46, Rafael J. Wysocki wrote:
> On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
> <[email protected]> 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/[email protected]/T/#u

--
Best regards,
Dmitry

2022-05-23 18:35:01

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v8 00/27] Introduce power-off+restart call chain API

Hi Rafael,

On Wed, May 18, 2022 at 4:46 PM Rafael J. Wysocki <[email protected]> wrote:
> On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
> <[email protected]> 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/[email protected]
soon.

Can you please include that in your PR?
Thanks!

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2022-05-25 07:05:49

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v8 00/27] Introduce power-off+restart call chain API

Hi Geert,

On Mon, May 23, 2022 at 8:08 PM Geert Uytterhoeven <[email protected]> wrote:
>
> Hi Rafael,
>
> On Wed, May 18, 2022 at 4:46 PM Rafael J. Wysocki <[email protected]> wrote:
> > On Tue, May 10, 2022 at 1:33 AM Dmitry Osipenko
> > <[email protected]> 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/[email protected]
> soon.
>
> Can you please include that in your PR?

I will.

Thanks!