[SOLVED] Kernel code: calling suspend to ram function from keyboard module
Linux - KernelThis forum is for all discussion relating to the Linux kernel.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Kernel code: calling suspend to ram function from keyboard module
Hello to you all linux lovers.
I have a dream.... I(ve been working on it for a while but I am getting out of clues...
My dream is to hack the kernel so that, being in console (not under X), pressing a key on the keyboard directly calls a suspend to ram function (the one that 'echo mem>/sys/power/state' calls for example).
So I looked at the kernel sources and in particular:
kernel/power/main.c and drivers/tty/vt/keyboard.c
In keyboard.c in one of the function handlers I have success to poweroff the machine using:
orderly_poweroff(0);
but now I would like to be able to use something like:
suspend_state_t state = PM_SUSPEND_MEM;
return = pm_suspend(state);
Compilation of the kernel works fine, but when I press the key I get a lot of characters and "call trace..."; I also tried to call enter_state(state) but with no success. Please note that 'echo mem>/sys/power/state' suspend to ram with success.
So... nobody has an idea? Or maybe this problem is not taken the right way?
Anyway, I found a very interesting article on the philosophy and the architecture of power management in the kernel: it's here:
landley.net/kdocs/ols/2003/ols2003-pages-325-339.pdf
(and attached to this post)
I am now trying to identify the variables that are passed to kernel/power/main.c when I type echo mem>/sys/power/state by using printk()...
One thing I want to try is writing directly to /sys/power/state using the sysfs_write_file() function defined in linux/fs/sysfs/file.c
I just found out that you could trace function calls via the debug file system (just check "debug file system" and "function trace" in the kernel hacking section of the kernel configuration menu).
Unfortunately when you turn on function tracing:
# mount -t debugfs none /sys/kernel/debug
# cd /sys/kernel/debug/tracing/
# echo function > current_tracer
# echo 1 > tracing_enabled
then suspend to ram doesn't work (actually it goes to sleep but at wakeup the bios decides to go through the whole booting process instead of just resuming)...
Ok this is turning into a debugfs issue.
I am now trying to get a simple echo something into the sysfs
(something not related to suspend to ram, but something that works, like echo 1 > /sys/devices/system/cpu/sched_mc_power_savings )
to be recorded with the function tracer, so I can find out which function I should trigger first...
The thing is, I can't get the tracing to work twice (the trace file stays empty the second time), I guess I get a buffer full or something.
I am progressing (very slightly) on the function identification using ftrace. I now understand that in the "debugfs" directory created at/sys/kernel/debug/tracing
when you compile your kernel (which version I am working on is 3.0.4 by the way) with the ftrace function (kernel hacking directory in make menuconfig), the trace file is not actually a real file, it answers to a reading using cat.
The thing is, reading from that file always gives a 159800 (or so) lines 13 Mo file that just records 1 to 2 seconds (amazing what these cpus accomplish these days !!!).
My new goal is to target the recording of function with ftrace when I echo something (with a reaction) into the sysfs...
This is turning into a blog... I strongly hope it will help other people interested in the kernel.
Currently reading Linux Device Drivers, 3rd Edition By Jonathan Corbet, Greg Kroah-Hartman, Alessandro Rubini
Publisher : O'Reilly
Pub Date : February 2005
ISBN : 0-596-00590-3
Pages : 636
Succeeded in suspending my system by calling pm_suspend (which is in kernel/power/suspend.c) from a module I created and insmod_ded...
Now my new question is: why can't I call successfully the function pm_suspend from drivers/tty/vt/keyboard.c when I am able to call it successfully from my own module?
To you people out there trying to transform an input into a useful kernel action (such as suspend to ram), keep on believing: I am sure it is possible.
I recently learned that inputs are not always handled by the keyboard module. A very good clue is done in console using
#watch cat /proc/interrupts
and type a key. If the number on the i8042 line increases, you very probably have a PS2 keyboard handled by the module which sources you can find in drivers/input/keyboard/atkbd.c in the linux kernel sources tree. You will find it very interesting that even on this type of keyboard typing the brightness increase/decrease keys is not handled by this module but by the acpi module!!!. On the other hand if you have a usb keyboard, at least in my case, key typing reporting is done by another module found at: drivers/hid/hid-input.c.
Now I have to call pm_suspend from one of this modules, being specific of a key type and key press/release action type, and I still think my problem is that I call a function that modifies a lot of things and is, by definition, long (time) to finish, so calling it from an interrupt context seems like a bad idea. I am planning on using the schedule_delayed_work() function found in atkbd module.
Anybody's help telling me whether or not this is the good direction to take is very welcome.
This WAS an interrupt issue. I could achieve calling suspend to ram from a keyboard key press by modifying the drivers/input/input.c file:
add to the includes:
#include <linux/workqueue.h>
#include <linux/suspend.h>
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.