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).
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 halt
ed?
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.
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()
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With