Skip to content

Commit

Permalink
Merge branch 'pm-sysoff'
Browse files Browse the repository at this point in the history
Merge system power off handling rework from Dmitry Osipenko for
5.19-rc1.

This introduces a mechanism allowing power sequences to be used for
powering off the system and makes related changes in platform-specific
code for multiple platforms.

* pm-sysoff: (29 commits)
  kernel/reboot: Change registration order of legacy power-off handler
  m68k: virt: Switch to new sys-off handler API
  kernel/reboot: Add devm_register_restart_handler()
  kernel/reboot: Add devm_register_power_off_handler()
  soc/tegra: pmc: Use sys-off handler API to power off Nexus 7 properly
  reboot: Remove pm_power_off_prepare()
  regulator: pfuze100: Use devm_register_sys_off_handler()
  ACPI: power: Switch to sys-off handler API
  memory: emif: Use kernel_can_power_off()
  mips: Use do_kernel_power_off()
  ia64: Use do_kernel_power_off()
  x86: Use do_kernel_power_off()
  sh: Use do_kernel_power_off()
  m68k: Switch to new sys-off handler API
  powerpc: Use do_kernel_power_off()
  xen/x86: Use do_kernel_power_off()
  parisc: Use do_kernel_power_off()
  arm64: Use do_kernel_power_off()
  riscv: Use do_kernel_power_off()
  csky: Use do_kernel_power_off()
  ...
  • Loading branch information
Rafael J. Wysocki committed May 30, 2022
2 parents 1cdc5ba + da007f1 commit 9f9c1f6
Show file tree
Hide file tree
Showing 28 changed files with 643 additions and 125 deletions.
4 changes: 1 addition & 3 deletions arch/arm/kernel/reboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

/*
Expand Down
3 changes: 1 addition & 2 deletions arch/arm64/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

/*
Expand Down
6 changes: 2 additions & 4 deletions arch/csky/kernel/power.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down
4 changes: 2 additions & 2 deletions arch/ia64/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -599,8 +600,7 @@ machine_halt (void)
void
machine_power_off (void)
{
if (pm_power_off)
pm_power_off();
do_kernel_power_off();
machine_halt();
}

Expand Down
3 changes: 2 additions & 1 deletion arch/m68k/emu/natfeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);
}
1 change: 0 additions & 1 deletion arch/m68k/include/asm/machdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions arch/m68k/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion arch/m68k/kernel/setup_mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion arch/m68k/kernel/setup_no.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion arch/m68k/mac/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand All @@ -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);
}


Expand Down
4 changes: 3 additions & 1 deletion arch/m68k/virt/config.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0

#include <linux/reboot.h>
#include <linux/serial_core.h>
#include <clocksource/timer-goldfish.h>

Expand Down Expand Up @@ -126,5 +127,6 @@ void __init config_virt(void)
mach_get_model = virt_get_model;
mach_reset = virt_reset;
mach_halt = virt_halt;
mach_power_off = virt_halt;

register_platform_power_off(virt_halt);
}
3 changes: 1 addition & 2 deletions arch/mips/kernel/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions arch/parisc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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. */
Expand Down
4 changes: 1 addition & 3 deletions arch/powerpc/kernel/setup-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
3 changes: 1 addition & 2 deletions arch/powerpc/xmon/xmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}

Expand Down
12 changes: 4 additions & 8 deletions arch/riscv/kernel/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
3 changes: 1 addition & 2 deletions arch/sh/kernel/reboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/reboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/xen/enlighten_pv.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <linux/pci.h>
#include <linux/gfp.h>
#include <linux/edd.h>
#include <linux/reboot.h>

#include <xen/xen.h>
#include <xen/events.h>
Expand Down Expand Up @@ -1069,8 +1070,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);
}

Expand Down
16 changes: 12 additions & 4 deletions drivers/acpi/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,20 +1035,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)
Expand All @@ -1067,8 +1069,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;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/memory/emif.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
Loading

0 comments on commit 9f9c1f6

Please sign in to comment.