How can I register a pause callback in a Linux driver?
The solution I ended up with is using notification chains. In more recent kernels, you can register with register_pm_notifier . If your kernel does not support this api, you can use a notifier for cpu hot-plug events (this is similar to what KVM uses). On the way to and from suspend, a hotpug cpu notification chain is launched.
a source to share
It depends on what kind of driver you have. For example, if you have a driver that is registered with platform_device_register()
, then it struct platform_driver
includes an item .suspend
to suspend the call to the device. With PCI devices struct pci_driver
, the one you pass in pci_register_driver()
likewise includes a member .suspend
.
Most device classes should provide a similar mechanism.
a source to share
I'm sure what you want acpi_install_fixed_event_handler()
, found in acpi/acpi.h
, common events found in acpi/actypes.h
(which is included from acpi.h
).
The second argument acpi_install_fixed_event()
requires a type handler u32
, with the last argument being void *context
. What I could not find is a list of possibilities that might be context. However, it looks like you are just injecting something into events, which means that you probably don't need context. Not exactly a callback, but the same result.
If you register a fixed handler for (say, ACPI_EVENT_POWER_BUTTON
or ACPI_EVENT_SLEEP_BUTTON
), your handler must be injected into the appropriate event. I'm not 100% sure ACPI_EVENT_SLEEP_BUTTON
- this is what you want, i.e. I cannot say if it will be the same event as a system that will sleep on its own. Testing and further research, of course, and exercises for the reader.
An example of its use can be found in drivers/rtc/rtc-cmos.c
.
Please take care of porting any code from acpi.h to
#ifdef CONFIG_ACPI
....
#endif /* CONFIG_ACPI */
I could be completely wrong here, I didn't actually need to do this for any of the drivers I wrote. The above is the result of roughly 30 minutes of copying through source 2.6.32.8 , which may be completely different from the kernel you are working with.
Please leave a comment if I'm going away from base :) I think this is what you are looking for.
Additional
As for licensing, its export:
drivers/acpi/acpica/evxface.c:ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
Not
*_EXPORT_SYMBOL_GPL()
... So you shouldn't have any problem using it, no matter what you do.
Finally, this is a great question that is likely to get well received on the Linux Kernel mailing list. If in doubt, ask. Even if it "just works", its a good idea to confirm it.
a source to share