Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make linux power off when halt is run?

I have successfully used the pm_power_off function pointer to make my custom Linux board call its power management chip over i2c (to turn the power off).

I would like the Linux halt command to switch the power off too.

How can I achieve this?

The (ARM) code for machine_halt does not have an pointer analogous to machine_power_off's pm_power_off.

arch/arm/kernel/reboot.c:

/*
 * Halting simply requires that the secondary CPUs stop performing any
 * activity (executing tasks, handling interrupts). smp_send_stop()
 * achieves this.
 */
void machine_halt(void)
{
    local_irq_disable();
    smp_send_stop();

    local_irq_disable();
    while (1);
}

/*
 * Power-off simply requires that the secondary CPUs stop performing any
 * activity (executing tasks, handling interrupts). smp_send_stop()
 * achieves this. When the system power is turned off, it will take all CPUs
 * with it.
 */
void machine_power_off(void)
{
    local_irq_disable();
    smp_send_stop();

    if (pm_power_off)
        pm_power_off();
}

I could obviously just hack machine_halt, but I would like to do this "properly", if possible.

Have I missed something (perhaps in userspace) which could cause a halt command to execute a "power off"?


Update: Thanks for the answer and all of your comments, they have helped me realise what the actual issue is.

My problem is:

I have an input edge, available to the custom power management unit. Think of it as a start button, with no stop or reset functionality. I have full control of the PMU code (it's an ATMEGA running as an i2c slave).

  1. If the Linux kernel is running, I want the edge to be ignored.
  2. If the CPU is powered off, I want the edge to power-on the CPU.
  3. If the Linux kernel is halted, I want the edge to reset the CPU.

Case 1 is easy, nothing to do.

Case 2 was easy, define pm_power_off in my driver to send an i2c message to the PMU. Luckily the i2c subsystem is still in a working state when pm_power_off is called.

Case 3 is the problem - I was looking for a pm_halt to define, to send an i2c message to the PMU.

Perhaps there is another way, as 0andriy comments?

Is there a place in the kernel to keep prodding the PMU with i2c messages at a few Hz, unless the machine is halted?

The answer at: https://unix.stackexchange.com/a/42576/17288 reads:

"* These days halt is smart enough to automatically call poweroff if ACPI is enabled. In fact, they are functionally equivalent now."

Perhaps there is some way of providing or hooking into ACPI - I will have to read up on it.

like image 370
fadedbee Avatar asked Oct 17 '22 19:10

fadedbee


2 Answers

You should use poweroff command or halt -p. As per man 8 halt, halt command (with no arguments) doesn't guarantee to power off your machine. Reasons are described here:

halt was used before ACPI (which today will turn off the power for you)*. It would halt the system and then print a message to the effect of "it's ok to power off now". Back then there were physical on/off switches, rather than the combo ACPI controlled power button of modern computers.

*These days halt is smart enough to automatically call poweroff if ACPI is enabled. In fact, they are functionally equivalent now.

As you can see from halt tool source code, it issues reboot() system call with cmd = RB_POWER_OFF = LINUX_REBOOT_CMD_POWER_OFF.

In kernel, that system call is implemented here, and on cmd = LINUX_REBOOT_CMD_POWER_OFF, it calls:
   -> kernel_power_off()
   -> machine_power_off()
   -> pm_power_off()

like image 149
Sam Protsenko Avatar answered Oct 21 '22 04:10

Sam Protsenko


On Debian/Ubuntu systems (I don't know if in other Linux OSes will work this), if you want the halt command does a poweroff you can create this file:

/etc/default/halt

Write this content of that file:

# Default behaviour of shutdown -h / halt. Set to "halt" or "poweroff".
HALT=poweroff

As the comment says, you can set now how halt should work. If you set it to halt it will only shutdown the computer without powering off. If you set poweroff it will work like as the poweroff command powering off the computer after closing all.

like image 45
NetVicious Avatar answered Oct 21 '22 04:10

NetVicious