How can I register a call-back on suspend in a linux driver?
I'm writing a linux driver and I would like to register a callba开发者_运维问答ck function to be invoked when the system goes to sleep. What is the api to do this?
Thanks.
It depends on what kind of driver you have. For example, if you have a driver that is registered with platform_device_register()
, then the struct platform_driver
includes a .suspend
member for the device's suspend callback. With PCI devices, the struct pci_driver
that you pass to pci_register_driver()
similarly includes a .suspend
member.
Most device classes should provide a similar mechanism.
I'm pretty sure you want acpi_install_fixed_event_handler()
, found in acpi/acpi.h
, the generic events found in acpi/actypes.h
(which is included from acpi.h
).
The second argument to acpi_install_fixed_event()
wants a handler of type u32
, with the last argument being a void *context
. What I could not find is a list of possibilities that *context might be. However, it looks like you just something to be entered on events, which means you probably don't care about the context. Not quite 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 should be entered on the respective event. I'm not 100% sure ACPI_EVENT_SLEEP_BUTTON
is what you want, i.e. I can't quite tell if its the same event as the system going to sleep on its own. Testing and further investigation is, of course, and exercise for the reader.
An example of using it can be found in drivers/rtc/rtc-cmos.c
.
Please take care to wrap any code from acpi.h in
#ifdef CONFIG_ACPI
....
#endif /* CONFIG_ACPI */
I could be completely wrong here, I have not actually needed to do this for any of the drivers that I've written. The above is the result of about 30 minutes of digging through the source of 2.6.32.8 , which may be completely different than the kernel you are working with.
Please leave a comment if I am way off base :) I think this is what you are looking for.
Additional
As for licensing, its exported:
drivers/acpi/acpica/evxface.c:ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
Not
*_EXPORT_SYMBOL_GPL()
... So you should have no issues using it, whatever you happen to be doing.
Finally, this is a perfectly good question that would probably be met with a good reception on the Linux Kernel mailing list. If in doubt, ask there. Even if this 'just works', its a good idea to confirm it.
The solution I settled on was using notifier chains. On later versions of the kernel you can register with register_pm_notifier. If your kernel doesn't support that api you can use the notifier for cpu hot-plug events (this appears to be what KVM uses). On the way in and out of suspend the cpu hotplug notifier chain fires.
The ACPI Howto probably will give you a good headstart...
精彩评论