[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>

authored by Alexey Starikovskiy and committed by Len Brown b34a8030 7b15f5e7

+205 -1
+205 -1
drivers/acpi/button.c
··· 26 26 #include <linux/kernel.h> 27 27 #include <linux/module.h> 28 28 #include <linux/init.h> 29 + #include <linux/types.h> 30 + #include <linux/proc_fs.h> 31 + #include <linux/seq_file.h> 29 32 #include <acpi/acpi_bus.h> 30 33 #include <acpi/acpi_drivers.h> 31 34 ··· 36 33 #define ACPI_BUTTON_COMPONENT 0x00080000 37 34 #define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver" 38 35 #define ACPI_BUTTON_CLASS "button" 36 + #define ACPI_BUTTON_FILE_INFO "info" 37 + #define ACPI_BUTTON_FILE_STATE "state" 38 + #define ACPI_BUTTON_TYPE_UNKNOWN 0x00 39 39 #define ACPI_BUTTON_NOTIFY_STATUS 0x80 40 40 41 41 #define ACPI_BUTTON_SUBCLASS_POWER "power" ··· 70 64 71 65 static int acpi_button_add (struct acpi_device *device); 72 66 static int acpi_button_remove (struct acpi_device *device, int type); 67 + static int acpi_button_info_open_fs(struct inode *inode, struct file *file); 68 + static int acpi_button_state_open_fs(struct inode *inode, struct file *file); 73 69 74 70 static struct acpi_driver acpi_button_driver = { 75 71 .name = ACPI_BUTTON_DRIVER_NAME, ··· 89 81 u8 type; 90 82 unsigned long pushed; 91 83 }; 84 + 85 + static struct file_operations acpi_button_info_fops = { 86 + .open = acpi_button_info_open_fs, 87 + .read = seq_read, 88 + .llseek = seq_lseek, 89 + .release = single_release, 90 + }; 91 + 92 + static struct file_operations acpi_button_state_fops = { 93 + .open = acpi_button_state_open_fs, 94 + .read = seq_read, 95 + .llseek = seq_lseek, 96 + .release = single_release, 97 + }; 98 + /* -------------------------------------------------------------------------- 99 + FS Interface (/proc) 100 + -------------------------------------------------------------------------- */ 101 + 102 + static struct proc_dir_entry *acpi_button_dir; 103 + 104 + static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) 105 + { 106 + struct acpi_button *button = (struct acpi_button *) seq->private; 107 + 108 + ACPI_FUNCTION_TRACE("acpi_button_info_seq_show"); 109 + 110 + if (!button || !button->device) 111 + return_VALUE(0); 112 + 113 + seq_printf(seq, "type: %s\n", 114 + acpi_device_name(button->device)); 115 + 116 + return_VALUE(0); 117 + } 118 + 119 + static int acpi_button_info_open_fs(struct inode *inode, struct file *file) 120 + { 121 + return single_open(file, acpi_button_info_seq_show, PDE(inode)->data); 122 + } 123 + 124 + static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) 125 + { 126 + struct acpi_button *button = (struct acpi_button *) seq->private; 127 + acpi_status status; 128 + unsigned long state; 129 + 130 + ACPI_FUNCTION_TRACE("acpi_button_state_seq_show"); 131 + 132 + if (!button || !button->device) 133 + return_VALUE(0); 134 + 135 + status = acpi_evaluate_integer(button->handle,"_LID",NULL,&state); 136 + if (ACPI_FAILURE(status)) { 137 + seq_printf(seq, "state: unsupported\n"); 138 + } 139 + else{ 140 + seq_printf(seq, "state: %s\n", (state ? "open" : "closed")); 141 + } 142 + 143 + return_VALUE(0); 144 + } 145 + 146 + static int acpi_button_state_open_fs(struct inode *inode, struct file *file) 147 + { 148 + return single_open(file, acpi_button_state_seq_show, PDE(inode)->data); 149 + } 150 + 151 + static struct proc_dir_entry *acpi_power_dir; 152 + static struct proc_dir_entry *acpi_sleep_dir; 153 + static struct proc_dir_entry *acpi_lid_dir; 154 + 155 + static int 156 + acpi_button_add_fs ( 157 + struct acpi_device *device) 158 + { 159 + struct proc_dir_entry *entry = NULL; 160 + struct acpi_button *button = NULL; 161 + 162 + ACPI_FUNCTION_TRACE("acpi_button_add_fs"); 163 + 164 + if (!device || !acpi_driver_data(device)) 165 + return_VALUE(-EINVAL); 166 + 167 + button = acpi_driver_data(device); 168 + 169 + switch (button->type) { 170 + case ACPI_BUTTON_TYPE_POWER: 171 + case ACPI_BUTTON_TYPE_POWERF: 172 + if (!acpi_power_dir) 173 + acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, 174 + acpi_button_dir); 175 + entry = acpi_power_dir; 176 + break; 177 + case ACPI_BUTTON_TYPE_SLEEP: 178 + case ACPI_BUTTON_TYPE_SLEEPF: 179 + if (!acpi_sleep_dir) 180 + acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, 181 + acpi_button_dir); 182 + entry = acpi_sleep_dir; 183 + break; 184 + case ACPI_BUTTON_TYPE_LID: 185 + if (!acpi_lid_dir) 186 + acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, 187 + acpi_button_dir); 188 + entry = acpi_lid_dir; 189 + break; 190 + } 191 + 192 + if (!entry) 193 + return_VALUE(-ENODEV); 194 + entry->owner = THIS_MODULE; 195 + 196 + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); 197 + if (!acpi_device_dir(device)) 198 + return_VALUE(-ENODEV); 199 + acpi_device_dir(device)->owner = THIS_MODULE; 200 + 201 + /* 'info' [R] */ 202 + entry = create_proc_entry(ACPI_BUTTON_FILE_INFO, 203 + S_IRUGO, acpi_device_dir(device)); 204 + if (!entry) 205 + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 206 + "Unable to create '%s' fs entry\n", 207 + ACPI_BUTTON_FILE_INFO)); 208 + else { 209 + entry->proc_fops = &acpi_button_info_fops; 210 + entry->data = acpi_driver_data(device); 211 + entry->owner = THIS_MODULE; 212 + } 213 + 214 + /* show lid state [R] */ 215 + if (button->type == ACPI_BUTTON_TYPE_LID) { 216 + entry = create_proc_entry(ACPI_BUTTON_FILE_STATE, 217 + S_IRUGO, acpi_device_dir(device)); 218 + if (!entry) 219 + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 220 + "Unable to create '%s' fs entry\n", 221 + ACPI_BUTTON_FILE_INFO)); 222 + else { 223 + entry->proc_fops = &acpi_button_state_fops; 224 + entry->data = acpi_driver_data(device); 225 + entry->owner = THIS_MODULE; 226 + } 227 + } 228 + 229 + return_VALUE(0); 230 + } 231 + 232 + 233 + static int 234 + acpi_button_remove_fs ( 235 + struct acpi_device *device) 236 + { 237 + struct acpi_button *button = NULL; 238 + 239 + ACPI_FUNCTION_TRACE("acpi_button_remove_fs"); 240 + 241 + button = acpi_driver_data(device); 242 + if (acpi_device_dir(device)) { 243 + if (button->type == ACPI_BUTTON_TYPE_LID) 244 + remove_proc_entry(ACPI_BUTTON_FILE_STATE, 245 + acpi_device_dir(device)); 246 + remove_proc_entry(ACPI_BUTTON_FILE_INFO, 247 + acpi_device_dir(device)); 248 + 249 + remove_proc_entry(acpi_device_bid(device), 250 + acpi_device_dir(device)->parent); 251 + acpi_device_dir(device) = NULL; 252 + } 253 + 254 + return_VALUE(0); 255 + } 256 + 92 257 93 258 /* -------------------------------------------------------------------------- 94 259 Driver Interface ··· 302 121 303 122 ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); 304 123 305 - BUG_ON(!button); 124 + if (!button) 125 + return_ACPI_STATUS(AE_BAD_PARAMETER); 306 126 307 127 acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); 308 128 ··· 379 197 goto end; 380 198 } 381 199 200 + result = acpi_button_add_fs(device); 201 + if (result) 202 + goto end; 203 + 382 204 switch (button->type) { 383 205 case ACPI_BUTTON_TYPE_POWERF: 384 206 status = acpi_install_fixed_event_handler ( ··· 426 240 427 241 end: 428 242 if (result) { 243 + acpi_button_remove_fs(device); 429 244 kfree(button); 430 245 } 431 246 ··· 467 280 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 468 281 "Error removing notify handler\n")); 469 282 283 + acpi_button_remove_fs(device); 284 + 470 285 kfree(button); 471 286 472 287 return_VALUE(0); ··· 482 293 483 294 ACPI_FUNCTION_TRACE("acpi_button_init"); 484 295 296 + acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); 297 + if (!acpi_button_dir) 298 + return_VALUE(-ENODEV); 299 + acpi_button_dir->owner = THIS_MODULE; 485 300 result = acpi_bus_register_driver(&acpi_button_driver); 486 301 if (result < 0) { 302 + remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); 487 303 return_VALUE(-ENODEV); 488 304 } 489 305 490 306 return_VALUE(0); 491 307 } 308 + 492 309 493 310 static void __exit 494 311 acpi_button_exit (void) ··· 503 308 504 309 acpi_bus_unregister_driver(&acpi_button_driver); 505 310 311 + if (acpi_power_dir) 312 + remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir); 313 + if (acpi_sleep_dir) 314 + remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir); 315 + if (acpi_lid_dir) 316 + remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); 317 + remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); 318 + 506 319 return_VOID; 507 320 } 321 + 508 322 509 323 module_init(acpi_button_init); 510 324 module_exit(acpi_button_exit);