diff options
author | Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | 2005-08-03 17:55:21 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-08-03 17:57:24 -0400 |
commit | b34a8030eeab4d59dcdd86de38f6927b9edd441f (patch) | |
tree | b0bdf2532175ea0209b2782b9a077d25a6f33aec /drivers/acpi/button.c | |
parent | 7b15f5e7bb180ac7bfb8926dbbd8835fecc07fad (diff) |
[ACPI] restore /proc/acpi/button/ (ala 2.6.12)
Signed-off-by Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/button.c')
-rw-r--r-- | drivers/acpi/button.c | 206 |
1 files changed, 205 insertions, 1 deletions
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 0f45d45f05a0..8162fd0c21a7 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -26,6 +26,9 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/types.h> | ||
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/seq_file.h> | ||
29 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
30 | #include <acpi/acpi_drivers.h> | 33 | #include <acpi/acpi_drivers.h> |
31 | 34 | ||
@@ -33,6 +36,9 @@ | |||
33 | #define ACPI_BUTTON_COMPONENT 0x00080000 | 36 | #define ACPI_BUTTON_COMPONENT 0x00080000 |
34 | #define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver" | 37 | #define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver" |
35 | #define ACPI_BUTTON_CLASS "button" | 38 | #define ACPI_BUTTON_CLASS "button" |
39 | #define ACPI_BUTTON_FILE_INFO "info" | ||
40 | #define ACPI_BUTTON_FILE_STATE "state" | ||
41 | #define ACPI_BUTTON_TYPE_UNKNOWN 0x00 | ||
36 | #define ACPI_BUTTON_NOTIFY_STATUS 0x80 | 42 | #define ACPI_BUTTON_NOTIFY_STATUS 0x80 |
37 | 43 | ||
38 | #define ACPI_BUTTON_SUBCLASS_POWER "power" | 44 | #define ACPI_BUTTON_SUBCLASS_POWER "power" |
@@ -64,6 +70,8 @@ MODULE_LICENSE("GPL"); | |||
64 | 70 | ||
65 | static int acpi_button_add (struct acpi_device *device); | 71 | static int acpi_button_add (struct acpi_device *device); |
66 | static int acpi_button_remove (struct acpi_device *device, int type); | 72 | static int acpi_button_remove (struct acpi_device *device, int type); |
73 | static int acpi_button_info_open_fs(struct inode *inode, struct file *file); | ||
74 | static int acpi_button_state_open_fs(struct inode *inode, struct file *file); | ||
67 | 75 | ||
68 | static struct acpi_driver acpi_button_driver = { | 76 | static struct acpi_driver acpi_button_driver = { |
69 | .name = ACPI_BUTTON_DRIVER_NAME, | 77 | .name = ACPI_BUTTON_DRIVER_NAME, |
@@ -82,6 +90,179 @@ struct acpi_button { | |||
82 | unsigned long pushed; | 90 | unsigned long pushed; |
83 | }; | 91 | }; |
84 | 92 | ||
93 | static struct file_operations acpi_button_info_fops = { | ||
94 | .open = acpi_button_info_open_fs, | ||
95 | .read = seq_read, | ||
96 | .llseek = seq_lseek, | ||
97 | .release = single_release, | ||
98 | }; | ||
99 | |||
100 | static struct file_operations acpi_button_state_fops = { | ||
101 | .open = acpi_button_state_open_fs, | ||
102 | .read = seq_read, | ||
103 | .llseek = seq_lseek, | ||
104 | .release = single_release, | ||
105 | }; | ||
106 | /* -------------------------------------------------------------------------- | ||
107 | FS Interface (/proc) | ||
108 | -------------------------------------------------------------------------- */ | ||
109 | |||
110 | static struct proc_dir_entry *acpi_button_dir; | ||
111 | |||
112 | static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) | ||
113 | { | ||
114 | struct acpi_button *button = (struct acpi_button *) seq->private; | ||
115 | |||
116 | ACPI_FUNCTION_TRACE("acpi_button_info_seq_show"); | ||
117 | |||
118 | if (!button || !button->device) | ||
119 | return_VALUE(0); | ||
120 | |||
121 | seq_printf(seq, "type: %s\n", | ||
122 | acpi_device_name(button->device)); | ||
123 | |||
124 | return_VALUE(0); | ||
125 | } | ||
126 | |||
127 | static int acpi_button_info_open_fs(struct inode *inode, struct file *file) | ||
128 | { | ||
129 | return single_open(file, acpi_button_info_seq_show, PDE(inode)->data); | ||
130 | } | ||
131 | |||
132 | static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) | ||
133 | { | ||
134 | struct acpi_button *button = (struct acpi_button *) seq->private; | ||
135 | acpi_status status; | ||
136 | unsigned long state; | ||
137 | |||
138 | ACPI_FUNCTION_TRACE("acpi_button_state_seq_show"); | ||
139 | |||
140 | if (!button || !button->device) | ||
141 | return_VALUE(0); | ||
142 | |||
143 | status = acpi_evaluate_integer(button->handle,"_LID",NULL,&state); | ||
144 | if (ACPI_FAILURE(status)) { | ||
145 | seq_printf(seq, "state: unsupported\n"); | ||
146 | } | ||
147 | else{ | ||
148 | seq_printf(seq, "state: %s\n", (state ? "open" : "closed")); | ||
149 | } | ||
150 | |||
151 | return_VALUE(0); | ||
152 | } | ||
153 | |||
154 | static int acpi_button_state_open_fs(struct inode *inode, struct file *file) | ||
155 | { | ||
156 | return single_open(file, acpi_button_state_seq_show, PDE(inode)->data); | ||
157 | } | ||
158 | |||
159 | static struct proc_dir_entry *acpi_power_dir; | ||
160 | static struct proc_dir_entry *acpi_sleep_dir; | ||
161 | static struct proc_dir_entry *acpi_lid_dir; | ||
162 | |||
163 | static int | ||
164 | acpi_button_add_fs ( | ||
165 | struct acpi_device *device) | ||
166 | { | ||
167 | struct proc_dir_entry *entry = NULL; | ||
168 | struct acpi_button *button = NULL; | ||
169 | |||
170 | ACPI_FUNCTION_TRACE("acpi_button_add_fs"); | ||
171 | |||
172 | if (!device || !acpi_driver_data(device)) | ||
173 | return_VALUE(-EINVAL); | ||
174 | |||
175 | button = acpi_driver_data(device); | ||
176 | |||
177 | switch (button->type) { | ||
178 | case ACPI_BUTTON_TYPE_POWER: | ||
179 | case ACPI_BUTTON_TYPE_POWERF: | ||
180 | if (!acpi_power_dir) | ||
181 | acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, | ||
182 | acpi_button_dir); | ||
183 | entry = acpi_power_dir; | ||
184 | break; | ||
185 | case ACPI_BUTTON_TYPE_SLEEP: | ||
186 | case ACPI_BUTTON_TYPE_SLEEPF: | ||
187 | if (!acpi_sleep_dir) | ||
188 | acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, | ||
189 | acpi_button_dir); | ||
190 | entry = acpi_sleep_dir; | ||
191 | break; | ||
192 | case ACPI_BUTTON_TYPE_LID: | ||
193 | if (!acpi_lid_dir) | ||
194 | acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, | ||
195 | acpi_button_dir); | ||
196 | entry = acpi_lid_dir; | ||
197 | break; | ||
198 | } | ||
199 | |||
200 | if (!entry) | ||
201 | return_VALUE(-ENODEV); | ||
202 | entry->owner = THIS_MODULE; | ||
203 | |||
204 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); | ||
205 | if (!acpi_device_dir(device)) | ||
206 | return_VALUE(-ENODEV); | ||
207 | acpi_device_dir(device)->owner = THIS_MODULE; | ||
208 | |||
209 | /* 'info' [R] */ | ||
210 | entry = create_proc_entry(ACPI_BUTTON_FILE_INFO, | ||
211 | S_IRUGO, acpi_device_dir(device)); | ||
212 | if (!entry) | ||
213 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
214 | "Unable to create '%s' fs entry\n", | ||
215 | ACPI_BUTTON_FILE_INFO)); | ||
216 | else { | ||
217 | entry->proc_fops = &acpi_button_info_fops; | ||
218 | entry->data = acpi_driver_data(device); | ||
219 | entry->owner = THIS_MODULE; | ||
220 | } | ||
221 | |||
222 | /* show lid state [R] */ | ||
223 | if (button->type == ACPI_BUTTON_TYPE_LID) { | ||
224 | entry = create_proc_entry(ACPI_BUTTON_FILE_STATE, | ||
225 | S_IRUGO, acpi_device_dir(device)); | ||
226 | if (!entry) | ||
227 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
228 | "Unable to create '%s' fs entry\n", | ||
229 | ACPI_BUTTON_FILE_INFO)); | ||
230 | else { | ||
231 | entry->proc_fops = &acpi_button_state_fops; | ||
232 | entry->data = acpi_driver_data(device); | ||
233 | entry->owner = THIS_MODULE; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | return_VALUE(0); | ||
238 | } | ||
239 | |||
240 | |||
241 | static int | ||
242 | acpi_button_remove_fs ( | ||
243 | struct acpi_device *device) | ||
244 | { | ||
245 | struct acpi_button *button = NULL; | ||
246 | |||
247 | ACPI_FUNCTION_TRACE("acpi_button_remove_fs"); | ||
248 | |||
249 | button = acpi_driver_data(device); | ||
250 | if (acpi_device_dir(device)) { | ||
251 | if (button->type == ACPI_BUTTON_TYPE_LID) | ||
252 | remove_proc_entry(ACPI_BUTTON_FILE_STATE, | ||
253 | acpi_device_dir(device)); | ||
254 | remove_proc_entry(ACPI_BUTTON_FILE_INFO, | ||
255 | acpi_device_dir(device)); | ||
256 | |||
257 | remove_proc_entry(acpi_device_bid(device), | ||
258 | acpi_device_dir(device)->parent); | ||
259 | acpi_device_dir(device) = NULL; | ||
260 | } | ||
261 | |||
262 | return_VALUE(0); | ||
263 | } | ||
264 | |||
265 | |||
85 | /* -------------------------------------------------------------------------- | 266 | /* -------------------------------------------------------------------------- |
86 | Driver Interface | 267 | Driver Interface |
87 | -------------------------------------------------------------------------- */ | 268 | -------------------------------------------------------------------------- */ |
@@ -121,7 +302,8 @@ acpi_button_notify_fixed ( | |||
121 | 302 | ||
122 | ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); | 303 | ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); |
123 | 304 | ||
124 | BUG_ON(!button); | 305 | if (!button) |
306 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
125 | 307 | ||
126 | acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); | 308 | acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); |
127 | 309 | ||
@@ -197,6 +379,10 @@ acpi_button_add ( | |||
197 | goto end; | 379 | goto end; |
198 | } | 380 | } |
199 | 381 | ||
382 | result = acpi_button_add_fs(device); | ||
383 | if (result) | ||
384 | goto end; | ||
385 | |||
200 | switch (button->type) { | 386 | switch (button->type) { |
201 | case ACPI_BUTTON_TYPE_POWERF: | 387 | case ACPI_BUTTON_TYPE_POWERF: |
202 | status = acpi_install_fixed_event_handler ( | 388 | status = acpi_install_fixed_event_handler ( |
@@ -240,6 +426,7 @@ acpi_button_add ( | |||
240 | 426 | ||
241 | end: | 427 | end: |
242 | if (result) { | 428 | if (result) { |
429 | acpi_button_remove_fs(device); | ||
243 | kfree(button); | 430 | kfree(button); |
244 | } | 431 | } |
245 | 432 | ||
@@ -280,6 +467,8 @@ acpi_button_remove (struct acpi_device *device, int type) | |||
280 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 467 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
281 | "Error removing notify handler\n")); | 468 | "Error removing notify handler\n")); |
282 | 469 | ||
470 | acpi_button_remove_fs(device); | ||
471 | |||
283 | kfree(button); | 472 | kfree(button); |
284 | 473 | ||
285 | return_VALUE(0); | 474 | return_VALUE(0); |
@@ -293,14 +482,20 @@ acpi_button_init (void) | |||
293 | 482 | ||
294 | ACPI_FUNCTION_TRACE("acpi_button_init"); | 483 | ACPI_FUNCTION_TRACE("acpi_button_init"); |
295 | 484 | ||
485 | acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
486 | if (!acpi_button_dir) | ||
487 | return_VALUE(-ENODEV); | ||
488 | acpi_button_dir->owner = THIS_MODULE; | ||
296 | result = acpi_bus_register_driver(&acpi_button_driver); | 489 | result = acpi_bus_register_driver(&acpi_button_driver); |
297 | if (result < 0) { | 490 | if (result < 0) { |
491 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
298 | return_VALUE(-ENODEV); | 492 | return_VALUE(-ENODEV); |
299 | } | 493 | } |
300 | 494 | ||
301 | return_VALUE(0); | 495 | return_VALUE(0); |
302 | } | 496 | } |
303 | 497 | ||
498 | |||
304 | static void __exit | 499 | static void __exit |
305 | acpi_button_exit (void) | 500 | acpi_button_exit (void) |
306 | { | 501 | { |
@@ -308,8 +503,17 @@ acpi_button_exit (void) | |||
308 | 503 | ||
309 | acpi_bus_unregister_driver(&acpi_button_driver); | 504 | acpi_bus_unregister_driver(&acpi_button_driver); |
310 | 505 | ||
506 | if (acpi_power_dir) | ||
507 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir); | ||
508 | if (acpi_sleep_dir) | ||
509 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir); | ||
510 | if (acpi_lid_dir) | ||
511 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); | ||
512 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
513 | |||
311 | return_VOID; | 514 | return_VOID; |
312 | } | 515 | } |
313 | 516 | ||
517 | |||
314 | module_init(acpi_button_init); | 518 | module_init(acpi_button_init); |
315 | module_exit(acpi_button_exit); | 519 | module_exit(acpi_button_exit); |