aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlexey Starikovskiy <alexey.y.starikovskiy@intel.com>2005-03-18 15:35:22 -0500
committerLen Brown <len.brown@intel.com>2005-07-11 23:17:07 -0400
commitbd4698dad3023ae137b366c736e29ca6eaf3b9f7 (patch)
treeb35f8030988849e44dc0e6a116fdd373bb272c3a /drivers
parent45b1b196677b8009ab6cdc4b656265f1d7015c1b (diff)
[ACPI] Allow simultaneous Fixed Feature and Control Method buttons
delete /proc/acpi/button http://bugzilla.kernel.org/show_bug.cgi?id=1920 Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/button.c245
1 files changed, 1 insertions, 244 deletions
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index ec4430e3053f..0f45d45f05a0 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -26,9 +26,6 @@
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>
32#include <acpi/acpi_bus.h> 29#include <acpi/acpi_bus.h>
33#include <acpi/acpi_drivers.h> 30#include <acpi/acpi_drivers.h>
34 31
@@ -36,9 +33,6 @@
36#define ACPI_BUTTON_COMPONENT 0x00080000 33#define ACPI_BUTTON_COMPONENT 0x00080000
37#define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver" 34#define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver"
38#define ACPI_BUTTON_CLASS "button" 35#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
42#define ACPI_BUTTON_NOTIFY_STATUS 0x80 36#define ACPI_BUTTON_NOTIFY_STATUS 0x80
43 37
44#define ACPI_BUTTON_SUBCLASS_POWER "power" 38#define ACPI_BUTTON_SUBCLASS_POWER "power"
@@ -70,8 +64,6 @@ MODULE_LICENSE("GPL");
70 64
71static int acpi_button_add (struct acpi_device *device); 65static int acpi_button_add (struct acpi_device *device);
72static int acpi_button_remove (struct acpi_device *device, int type); 66static int acpi_button_remove (struct acpi_device *device, int type);
73static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
74static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
75 67
76static struct acpi_driver acpi_button_driver = { 68static struct acpi_driver acpi_button_driver = {
77 .name = ACPI_BUTTON_DRIVER_NAME, 69 .name = ACPI_BUTTON_DRIVER_NAME,
@@ -90,187 +82,6 @@ struct acpi_button {
90 unsigned long pushed; 82 unsigned long pushed;
91}; 83};
92 84
93static 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
100static 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
110static struct proc_dir_entry *acpi_button_dir;
111
112static 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
127static 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
132static 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
154static 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
159static int
160acpi_button_add_fs (
161 struct acpi_device *device)
162{
163 struct proc_dir_entry *entry = NULL;
164 struct acpi_button *button = NULL;
165
166 ACPI_FUNCTION_TRACE("acpi_button_add_fs");
167
168 if (!device || !acpi_driver_data(device))
169 return_VALUE(-EINVAL);
170
171 button = acpi_driver_data(device);
172
173 switch (button->type) {
174 case ACPI_BUTTON_TYPE_POWER:
175 case ACPI_BUTTON_TYPE_POWERF:
176 entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,
177 acpi_button_dir);
178 break;
179 case ACPI_BUTTON_TYPE_SLEEP:
180 case ACPI_BUTTON_TYPE_SLEEPF:
181 entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
182 acpi_button_dir);
183 break;
184 case ACPI_BUTTON_TYPE_LID:
185 entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID,
186 acpi_button_dir);
187 break;
188 }
189
190 if (!entry)
191 return_VALUE(-ENODEV);
192 entry->owner = THIS_MODULE;
193
194 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
195 if (!acpi_device_dir(device))
196 return_VALUE(-ENODEV);
197 acpi_device_dir(device)->owner = THIS_MODULE;
198
199 /* 'info' [R] */
200 entry = create_proc_entry(ACPI_BUTTON_FILE_INFO,
201 S_IRUGO, acpi_device_dir(device));
202 if (!entry)
203 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
204 "Unable to create '%s' fs entry\n",
205 ACPI_BUTTON_FILE_INFO));
206 else {
207 entry->proc_fops = &acpi_button_info_fops;
208 entry->data = acpi_driver_data(device);
209 entry->owner = THIS_MODULE;
210 }
211
212 /* show lid state [R] */
213 if (button->type == ACPI_BUTTON_TYPE_LID) {
214 entry = create_proc_entry(ACPI_BUTTON_FILE_STATE,
215 S_IRUGO, acpi_device_dir(device));
216 if (!entry)
217 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
218 "Unable to create '%s' fs entry\n",
219 ACPI_BUTTON_FILE_INFO));
220 else {
221 entry->proc_fops = &acpi_button_state_fops;
222 entry->data = acpi_driver_data(device);
223 entry->owner = THIS_MODULE;
224 }
225 }
226
227 return_VALUE(0);
228}
229
230
231static int
232acpi_button_remove_fs (
233 struct acpi_device *device)
234{
235 struct acpi_button *button = NULL;
236
237 ACPI_FUNCTION_TRACE("acpi_button_remove_fs");
238
239 button = acpi_driver_data(device);
240 if (acpi_device_dir(device)) {
241 if (button->type == ACPI_BUTTON_TYPE_LID)
242 remove_proc_entry(ACPI_BUTTON_FILE_STATE,
243 acpi_device_dir(device));
244 remove_proc_entry(ACPI_BUTTON_FILE_INFO,
245 acpi_device_dir(device));
246
247 remove_proc_entry(acpi_device_bid(device),
248 acpi_device_dir(device)->parent);
249
250
251 switch (button->type) {
252 case ACPI_BUTTON_TYPE_POWER:
253 case ACPI_BUTTON_TYPE_POWERF:
254 remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER,
255 acpi_button_dir);
256 break;
257 case ACPI_BUTTON_TYPE_SLEEP:
258 case ACPI_BUTTON_TYPE_SLEEPF:
259 remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP,
260 acpi_button_dir);
261 break;
262 case ACPI_BUTTON_TYPE_LID:
263 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID,
264 acpi_button_dir);
265 break;
266 }
267 acpi_device_dir(device) = NULL;
268 }
269
270 return_VALUE(0);
271}
272
273
274/* -------------------------------------------------------------------------- 85/* --------------------------------------------------------------------------
275 Driver Interface 86 Driver Interface
276 -------------------------------------------------------------------------- */ 87 -------------------------------------------------------------------------- */
@@ -310,8 +121,7 @@ acpi_button_notify_fixed (
310 121
311 ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); 122 ACPI_FUNCTION_TRACE("acpi_button_notify_fixed");
312 123
313 if (!button) 124 BUG_ON(!button);
314 return_ACPI_STATUS(AE_BAD_PARAMETER);
315 125
316 acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); 126 acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
317 127
@@ -327,10 +137,6 @@ acpi_button_add (
327 acpi_status status = AE_OK; 137 acpi_status status = AE_OK;
328 struct acpi_button *button = NULL; 138 struct acpi_button *button = NULL;
329 139
330 static struct acpi_device *power_button;
331 static struct acpi_device *sleep_button;
332 static struct acpi_device *lid_button;
333
334 ACPI_FUNCTION_TRACE("acpi_button_add"); 140 ACPI_FUNCTION_TRACE("acpi_button_add");
335 141
336 if (!device) 142 if (!device)
@@ -391,42 +197,6 @@ acpi_button_add (
391 goto end; 197 goto end;
392 } 198 }
393 199
394 /*
395 * Ensure only one button of each type is used.
396 */
397 switch (button->type) {
398 case ACPI_BUTTON_TYPE_POWER:
399 case ACPI_BUTTON_TYPE_POWERF:
400 if (!power_button)
401 power_button = device;
402 else {
403 kfree(button);
404 return_VALUE(-ENODEV);
405 }
406 break;
407 case ACPI_BUTTON_TYPE_SLEEP:
408 case ACPI_BUTTON_TYPE_SLEEPF:
409 if (!sleep_button)
410 sleep_button = device;
411 else {
412 kfree(button);
413 return_VALUE(-ENODEV);
414 }
415 break;
416 case ACPI_BUTTON_TYPE_LID:
417 if (!lid_button)
418 lid_button = device;
419 else {
420 kfree(button);
421 return_VALUE(-ENODEV);
422 }
423 break;
424 }
425
426 result = acpi_button_add_fs(device);
427 if (result)
428 goto end;
429
430 switch (button->type) { 200 switch (button->type) {
431 case ACPI_BUTTON_TYPE_POWERF: 201 case ACPI_BUTTON_TYPE_POWERF:
432 status = acpi_install_fixed_event_handler ( 202 status = acpi_install_fixed_event_handler (
@@ -470,7 +240,6 @@ acpi_button_add (
470 240
471end: 241end:
472 if (result) { 242 if (result) {
473 acpi_button_remove_fs(device);
474 kfree(button); 243 kfree(button);
475 } 244 }
476 245
@@ -511,8 +280,6 @@ acpi_button_remove (struct acpi_device *device, int type)
511 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 280 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
512 "Error removing notify handler\n")); 281 "Error removing notify handler\n"));
513 282
514 acpi_button_remove_fs(device);
515
516 kfree(button); 283 kfree(button);
517 284
518 return_VALUE(0); 285 return_VALUE(0);
@@ -526,21 +293,14 @@ acpi_button_init (void)
526 293
527 ACPI_FUNCTION_TRACE("acpi_button_init"); 294 ACPI_FUNCTION_TRACE("acpi_button_init");
528 295
529 acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
530 if (!acpi_button_dir)
531 return_VALUE(-ENODEV);
532 acpi_button_dir->owner = THIS_MODULE;
533
534 result = acpi_bus_register_driver(&acpi_button_driver); 296 result = acpi_bus_register_driver(&acpi_button_driver);
535 if (result < 0) { 297 if (result < 0) {
536 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
537 return_VALUE(-ENODEV); 298 return_VALUE(-ENODEV);
538 } 299 }
539 300
540 return_VALUE(0); 301 return_VALUE(0);
541} 302}
542 303
543
544static void __exit 304static void __exit
545acpi_button_exit (void) 305acpi_button_exit (void)
546{ 306{
@@ -548,11 +308,8 @@ acpi_button_exit (void)
548 308
549 acpi_bus_unregister_driver(&acpi_button_driver); 309 acpi_bus_unregister_driver(&acpi_button_driver);
550 310
551 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
552
553 return_VOID; 311 return_VOID;
554} 312}
555 313
556
557module_init(acpi_button_init); 314module_init(acpi_button_init);
558module_exit(acpi_button_exit); 315module_exit(acpi_button_exit);