ACPI AC Adapter Implementation in Linux Kernel
ACPI AC Adapter (1) introduced the theory of interfaces between BIOS and an OS, but a real example is always more convincing than anything else.
As ACPI covers very broad and rich features, kernel developers may find some of them "uninteresting". For example. _PSR is required, in software's perspective, to know whether AC is online, but which parts of a system is powered (i.e. _PCL) may not be that useful for laptop PCs (which AC usually powers everything). In some other cases, few BIOS implements _PIF and there is hardly any reason that someone decides to add _PIF supports to Linux.
It is very interesting to see how an driver responds to ACPI events. In the above source code it is obvious that the driver behaves the same for all events equals 0x80, 0x00, 0x01. It also responds the same to all other ACPI events with an additional error message.
For example, it was seen that some BIOSes issue Notify(AC, 0x81) when AC adapter is plugged or plugged. Apparently Linux kernel does not think 0x81 is a valid event (nor can I find any 0x81 for AC in ACPI); however, Linux still behaves as well with Notify(AC, 0x80).
Another interesting part in ACPI AC driver is acpi_ac_resume called when a system resumes from suspend or hiberation. It compares the "before" and "after" _PSR and issues an uEvent if they are different. This implies BIOSes need not to issue a Notify(AC, 0x80) during waking up to save some CPU cycles; however, this may be specific to Linux. As there is no rule in ACPI spec, one may want to verify the behaviors of the target OSes (ex. Windows).
SysFs Node
In Linux, one can find out whether a laptop PC has AC plugged in by "cat /sys/class/power_supply/online". Linux ACPI AC driver evaluates _PSR and returns 1 for "AC is online" and 0 for "AC is offline". The sysfs node is also used by user-space applications.Supported Objects
Surprisingly (or not), not all control methods defined in ACPI AC are supported. In fact, only _PSR is evaluated in Linux ACPI AC driver.As ACPI covers very broad and rich features, kernel developers may find some of them "uninteresting". For example. _PSR is required, in software's perspective, to know whether AC is online, but which parts of a system is powered (i.e. _PCL) may not be that useful for laptop PCs (which AC usually powers everything). In some other cases, few BIOS implements _PIF and there is hardly any reason that someone decides to add _PIF supports to Linux.
AC Events
It is very interesting to see how an driver responds to ACPI events. In the above source code it is obvious that the driver behaves the same for all events equals 0x80, 0x00, 0x01. It also responds the same to all other ACPI events with an additional error message.
For example, it was seen that some BIOSes issue Notify(AC, 0x81) when AC adapter is plugged or plugged. Apparently Linux kernel does not think 0x81 is a valid event (nor can I find any 0x81 for AC in ACPI); however, Linux still behaves as well with Notify(AC, 0x80).
Suspend and Resume
Another interesting part in ACPI AC driver is acpi_ac_resume called when a system resumes from suspend or hiberation. It compares the "before" and "after" _PSR and issues an uEvent if they are different. This implies BIOSes need not to issue a Notify(AC, 0x80) during waking up to save some CPU cycles; however, this may be specific to Linux. As there is no rule in ACPI spec, one may want to verify the behaviors of the target OSes (ex. Windows).
References
Linux kernel source code (3.10): ACPI AC adpater driver in drivers/acpi/ac.c
Thanks for the article. I wonder though, how can a laptop know when an inappropriate AC adapter has been plugged in when _PIF is not implemented?
ReplyDelete