diff options
Diffstat (limited to 'drivers')
49 files changed, 1762 insertions, 747 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 0f9d4be7ed7..1639998e4d2 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -11,7 +11,7 @@ config ACPI bool "ACPI Support" depends on IA64 || X86 depends on PCI - select PM + depends on PM default y ---help--- Advanced Configuration and Power Interface (ACPI) support for @@ -97,6 +97,7 @@ config ACPI_BATTERY config ACPI_BUTTON tristate "Button" + depends on INPUT default y help This driver handles events on the power, sleep and lid buttons. @@ -172,6 +173,7 @@ config ACPI_NUMA config ACPI_ASUS tristate "ASUS/Medion Laptop Extras" depends on X86 + select BACKLIGHT_CLASS_DEVICE ---help--- This driver provides support for extra features of ACPI-compatible ASUS laptops. As some of Medion laptops are made by ASUS, it may also @@ -200,6 +202,7 @@ config ACPI_ASUS config ACPI_IBM tristate "IBM ThinkPad Laptop Extras" depends on X86 + select BACKLIGHT_CLASS_DEVICE ---help--- This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds support for Fn-Fx key combinations, Bluetooth control, video @@ -222,9 +225,21 @@ config ACPI_IBM_DOCK If you are not sure, say N here. +config ACPI_IBM_BAY + bool "Legacy Removable Bay Support" + depends on ACPI_IBM + depends on ACPI_BAY=n + default n + ---help--- + Allows the ibm_acpi driver to handle removable bays. + This support is obsoleted by CONFIG_ACPI_BAY. + + If you are not sure, say N here. + config ACPI_TOSHIBA tristate "Toshiba Laptop Extras" depends on X86 + select BACKLIGHT_CLASS_DEVICE ---help--- This driver adds support for access to certain system settings on "legacy free" Toshiba laptops. These laptops can be recognized by diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 11abc7bf777..6daeace796a 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -109,7 +109,7 @@ static struct proc_dir_entry *acpi_ac_dir; static int acpi_ac_seq_show(struct seq_file *seq, void *offset) { - struct acpi_ac *ac = (struct acpi_ac *)seq->private; + struct acpi_ac *ac = seq->private; if (!ac) @@ -187,7 +187,7 @@ static int acpi_ac_remove_fs(struct acpi_device *device) static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_ac *ac = (struct acpi_ac *)data; + struct acpi_ac *ac = data; struct acpi_device *device = NULL; @@ -221,10 +221,9 @@ static int acpi_ac_add(struct acpi_device *device) if (!device) return -EINVAL; - ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL); + ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); if (!ac) return -ENOMEM; - memset(ac, 0, sizeof(struct acpi_ac)); ac->device = device; strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); @@ -269,7 +268,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - ac = (struct acpi_ac *)acpi_driver_data(device); + ac = acpi_driver_data(device); status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_ac_notify); diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 6bcd9e8e7bc..cd946ed192d 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -395,10 +395,9 @@ static int acpi_memory_device_add(struct acpi_device *device) if (!device) return -EINVAL; - mem_device = kmalloc(sizeof(struct acpi_memory_device), GFP_KERNEL); + mem_device = kzalloc(sizeof(struct acpi_memory_device), GFP_KERNEL); if (!mem_device) return -ENOMEM; - memset(mem_device, 0, sizeof(struct acpi_memory_device)); INIT_LIST_HEAD(&mem_device->res_list); mem_device->device = device; @@ -429,7 +428,7 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - mem_device = (struct acpi_memory_device *)acpi_driver_data(device); + mem_device = acpi_driver_data(device); kfree(mem_device); return 0; diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index c7ac9297a20..396140bbbe5 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -35,6 +35,7 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/proc_fs.h> +#include <linux/backlight.h> #include <acpi/acpi_drivers.h> #include <acpi/acpi_bus.h> #include <asm/uaccess.h> @@ -402,6 +403,8 @@ static struct model_data model_conf[END_MODEL] = { /* procdir we use */ static struct proc_dir_entry *asus_proc_dir; +static struct backlight_device *asus_backlight_device; + /* * This header is made available to allow proper configuration given model, * revision number , ... this info cannot go in struct asus_hotk because it is @@ -779,7 +782,7 @@ proc_write_lcd(struct file *file, const char __user * buffer, return rv; } -static int read_brightness(void) +static int read_brightness(struct backlight_device *bd) { int value; @@ -801,9 +804,10 @@ static int read_brightness(void) /* * Change the brightness level */ -static void set_brightness(int value) +static int set_brightness(int value) { acpi_status status = 0; + int ret = 0; /* SPLV laptop */ if (hotk->methods->brightness_set) { @@ -811,11 +815,12 @@ static void set_brightness(int value) value, NULL)) printk(KERN_WARNING "Asus ACPI: Error changing brightness\n"); - return; + ret = -EIO; + goto out; } /* No SPLV method if we are here, act as appropriate */ - value -= read_brightness(); + value -= read_brightness(NULL); while (value != 0) { status = acpi_evaluate_object(NULL, (value > 0) ? hotk->methods->brightness_up : @@ -825,15 +830,22 @@ static void set_brightness(int value) if (ACPI_FAILURE(status)) printk(KERN_WARNING "Asus ACPI: Error changing brightness\n"); + ret = -EIO; } - return; +out: + return ret; +} + +static int set_brightness_status(struct backlight_device *bd) +{ + return set_brightness(bd->props->brightness); } static int proc_read_brn(char *page, char **start, off_t off, int count, int *eof, void *data) { - return sprintf(page, "%d\n", read_brightness()); + return sprintf(page, "%d\n", read_brightness(NULL)); } static int @@ -1134,7 +1146,7 @@ static int asus_hotk_get_info(void) if (ACPI_FAILURE(status)) printk(KERN_WARNING " Couldn't get the DSDT table header\n"); else - asus_info = (struct acpi_table_header *)dsdt.pointer; + asus_info = dsdt.pointer; /* We have to write 0 on init this far for all ASUS models */ if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { @@ -1156,7 +1168,7 @@ static int asus_hotk_get_info(void) * asus_model_match() and try something completely different. */ if (buffer.pointer) { - model = (union acpi_object *)buffer.pointer; + model = buffer.pointer; switch (model->type) { case ACPI_TYPE_STRING: string = model->string.pointer; @@ -1252,11 +1264,9 @@ static int asus_hotk_add(struct acpi_device *device) printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", ASUS_ACPI_VERSION); - hotk = - (struct asus_hotk *)kmalloc(sizeof(struct asus_hotk), GFP_KERNEL); + hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); if (!hotk) return -ENOMEM; - memset(hotk, 0, sizeof(struct asus_hotk)); hotk->handle = device->handle; strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME); @@ -1333,6 +1343,26 @@ static int asus_hotk_remove(struct acpi_device *device, int type) return 0; } +static struct backlight_properties asus_backlight_data = { + .owner = THIS_MODULE, + .get_brightness = read_brightness, + .update_status = set_brightness_status, + .max_brightness = 15, +}; + +static void __exit asus_acpi_exit(void) +{ + if (asus_backlight_device) + backlight_device_unregister(asus_backlight_device); + + acpi_bus_unregister_driver(&asus_hotk_driver); + remove_proc_entry(PROC_ASUS, acpi_root_dir); + + kfree(asus_info); + + return; +} + static int __init asus_acpi_init(void) { int result; @@ -1370,17 +1400,15 @@ static int __init asus_acpi_init(void) return result; } - return 0; -} - -static void __exit asus_acpi_exit(void) -{ - acpi_bus_unregister_driver(&asus_hotk_driver); - remove_proc_entry(PROC_ASUS, acpi_root_dir); - - kfree(asus_info); + asus_backlight_device = backlight_device_register("asus",NULL,NULL, + &asus_backlight_data); + if (IS_ERR(asus_backlight_device)) { + printk(KERN_ERR "Could not register asus backlight device\n"); + asus_backlight_device = NULL; + asus_acpi_exit(); + } - return; + return 0; } module_init(asus_acpi_init); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 026e40755cd..5f43e0d1489 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -149,7 +149,7 @@ acpi_battery_get_info(struct acpi_battery *battery, return -ENODEV; } - package = (union acpi_object *)buffer.pointer; + package = buffer.pointer; /* Extract Package Data */ @@ -160,12 +160,11 @@ acpi_battery_get_info(struct acpi_battery *battery, goto end; } - data.pointer = kmalloc(data.length, GFP_KERNEL); + data.pointer = kzalloc(data.length, GFP_KERNEL); if (!data.pointer) { result = -ENOMEM; goto end; } - memset(data.pointer, 0, data.length); status = acpi_extract_package(package, &format, &data); if (ACPI_FAILURE(status)) { @@ -179,7 +178,7 @@ acpi_battery_get_info(struct acpi_battery *battery, kfree(buffer.pointer); if (!result) - (*bif) = (struct acpi_battery_info *)data.pointer; + (*bif) = data.pointer; return result; } @@ -209,7 +208,7 @@ acpi_battery_get_status(struct acpi_battery *battery, return -ENODEV; } - package = (union acpi_object *)buffer.pointer; + package = buffer.pointer; /* Extract Package Data */ @@ -220,12 +219,11 @@ acpi_battery_get_status(struct acpi_battery *battery, goto end; } - data.pointer = kmalloc(data.length, GFP_KERNEL); + data.pointer = kzalloc(data.length, GFP_KERNEL); if (!data.pointer) { result = -ENOMEM; goto end; } - memset(data.pointer, 0, data.length); status = acpi_extract_package(package, &format, &data); if (ACPI_FAILURE(status)) { @@ -239,7 +237,7 @@ acpi_battery_get_status(struct acpi_battery *battery, kfree(buffer.pointer); if (!result) - (*bst) = (struct acpi_battery_status *)data.pointer; + (*bst) = data.pointer; return result; } @@ -334,7 +332,7 @@ static struct proc_dir_entry *acpi_battery_dir; static int acpi_battery_read_info(struct seq_file *seq, void *offset) { int result = 0; - struct acpi_battery *battery = (struct acpi_battery *)seq->private; + struct acpi_battery *battery = seq->private; struct acpi_battery_info *bif = NULL; char *units = "?"; @@ -418,7 +416,7 @@ static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) static int acpi_battery_read_state(struct seq_file *seq, void *offset) { int result = 0; - struct acpi_battery *battery = (struct acpi_battery *)seq->private; + struct acpi_battery *battery = seq->private; struct acpi_battery_status *bst = NULL; char *units = "?"; @@ -494,7 +492,7 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) { - struct acpi_battery *battery = (struct acpi_battery *)seq->private; + struct acpi_battery *battery = seq->private; char *units = "?"; @@ -531,8 +529,8 @@ acpi_battery_write_alarm(struct file *file, { int result = 0; char alarm_string[12] = { '\0' }; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_battery *battery = (struct acpi_battery *)m->private; + struct seq_file *m = file->private_data; + struct acpi_battery *battery = m->private; if (!battery || (count > sizeof(alarm_string) - 1)) @@ -658,7 +656,7 @@ static int acpi_battery_remove_fs(struct acpi_device *device) static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_battery *battery = (struct acpi_battery *)data; + struct acpi_battery *battery = data; struct acpi_device *device = NULL; @@ -694,10 +692,9 @@ static int acpi_battery_add(struct acpi_device *device) if (!device) return -EINVAL; - battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL); + battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); if (!battery) return -ENOMEM; - memset(battery, 0, sizeof(struct acpi_battery)); battery->device = device; strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); @@ -742,7 +739,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - battery = (struct acpi_battery *)acpi_driver_data(device); + battery = acpi_driver_data(device); status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 5ef885e82c7..ac860583c20 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -29,6 +29,7 @@ #include <linux/types.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/input.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> @@ -62,7 +63,7 @@ #define _COMPONENT ACPI_BUTTON_COMPONENT ACPI_MODULE_NAME("acpi_button") - MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME); MODULE_LICENSE("GPL"); @@ -78,12 +79,14 @@ static struct acpi_driver acpi_button_driver = { .ops = { .add = acpi_button_add, .remove = acpi_button_remove, - }, + }, }; struct acpi_button { struct acpi_device *device; /* Fixed button kludge */ - u8 type; + unsigned int type; + struct input_dev *input; + char phys[32]; /* for input device */ unsigned long pushed; }; @@ -109,8 +112,7 @@ static struct proc_dir_entry *acpi_button_dir; static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_button *button = (struct acpi_button *)seq->private; - + struct acpi_button *button = seq->private; if (!button || !button->device) return 0; @@ -128,22 +130,17 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file) static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) { - struct acpi_button *button = (struct acpi_button *)seq->private; + struct acpi_button *button = seq->private; acpi_status status; unsigned long state; - if (!button || !button->device) return 0; status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state); - if (ACPI_FAILURE(status)) { - seq_printf(seq, "state: unsupported\n"); - } else { - seq_printf(seq, "state: %s\n", - (state ? "open" : "closed")); - } - + seq_printf(seq, "state: %s\n", + ACPI_FAILURE(status) ? "unsupported" : + (state ? "open" : "closed")); return 0; } @@ -159,8 +156,7 @@ static struct proc_dir_entry *acpi_lid_dir; static int acpi_button_add_fs(struct acpi_device *device) { struct proc_dir_entry *entry = NULL; - struct acpi_button *button = NULL; - + struct acpi_button *button; if (!device || !acpi_driver_data(device)) return -EINVAL; @@ -228,10 +224,8 @@ static int acpi_button_add_fs(struct acpi_device *device) static int acpi_button_remove_fs(struct acpi_device *device) { - struct acpi_button *button = NULL; - + struct acpi_button *button = acpi_driver_data(device); - button = acpi_driver_data(device); if (acpi_device_dir(device)) { if (button->type == ACPI_BUTTON_TYPE_LID) remove_proc_entry(ACPI_BUTTON_FILE_STATE, @@ -253,14 +247,34 @@ static int acpi_button_remove_fs(struct acpi_device *device) static void acpi_button_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_button *button = (struct acpi_button *)data; - + struct acpi_button *button = data; + struct input_dev *input; if (!button || !button->device) return; switch (event) { case ACPI_BUTTON_NOTIFY_STATUS: + input = button->input; + + if (button->type == ACPI_BUTTON_TYPE_LID) { + struct acpi_handle *handle = button->device->handle; + unsigned long state; + + if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID", + NULL, &state))) + input_report_switch(input, SW_LID, !state); + + } else { + int keycode = test_bit(KEY_SLEEP, input->keybit) ? + KEY_SLEEP : KEY_POWER; + + input_report_key(input, keycode, 1); + input_sync(input); + input_report_key(input, keycode, 0); + } + input_sync(input); + acpi_bus_generate_event(button->device, event, ++button->pushed); break; @@ -275,8 +289,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) static acpi_status acpi_button_notify_fixed(void *data) { - struct acpi_button *button = (struct acpi_button *)data; - + struct acpi_button *button = data; if (!button) return AE_BAD_PARAMETER; @@ -286,24 +299,75 @@ static acpi_status acpi_button_notify_fixed(void *data) return AE_OK; } -static int acpi_button_add(struct acpi_device *device) +static int acpi_button_install_notify_handlers(struct acpi_button *button) { - int result = 0; - acpi_status status = AE_OK; - struct acpi_button *button = NULL; + acpi_status status; + switch (button->type) { + case ACPI_BUTTON_TYPE_POWERF: + status = + acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, + acpi_button_notify_fixed, + button); + break; + case ACPI_BUTTON_TYPE_SLEEPF: + status = + acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, + acpi_button_notify_fixed, + button); + break; + default: + status = acpi_install_notify_handler(button->device->handle, + ACPI_DEVICE_NOTIFY, + acpi_button_notify, + button); + break; + } + + return ACPI_FAILURE(status) ? -ENODEV : 0; +} + +static void acpi_button_remove_notify_handlers(struct acpi_button *button) +{ + switch (button->type) { + case ACPI_BUTTON_TYPE_POWERF: + acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, + acpi_button_notify_fixed); + break; + case ACPI_BUTTON_TYPE_SLEEPF: + acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, + acpi_button_notify_fixed); + break; + default: + acpi_remove_notify_handler(button->device->handle, + ACPI_DEVICE_NOTIFY, + acpi_button_notify); + break; + } +} + +static int acpi_button_add(struct acpi_device *device) +{ + int error; + struct acpi_button *button; + struct input_dev *input; if (!device) return -EINVAL; - button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL); + button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); if (!button) return -ENOMEM; - memset(button, 0, sizeof(struct acpi_button)); button->device = device; acpi_driver_data(device) = button; + button->input = input = input_allocate_device(); + if (!input) { + error = -ENOMEM; + goto err_free_button; + } + /* * Determine the button type (via hid), as fixed-feature buttons * need to be handled a bit differently than generic-space. @@ -338,39 +402,48 @@ static int acpi_button_add(struct acpi_device *device) } else { printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", acpi_device_hid(device)); - result = -ENODEV; - goto end; + error = -ENODEV; + goto err_free_input; } - result = acpi_button_add_fs(device); - if (result) - goto end; + error = acpi_button_add_fs(device); + if (error) + goto err_free_input; + + error = acpi_button_install_notify_handlers(button); + if (error) + goto err_remove_fs; + + snprintf(button->phys, sizeof(button->phys), + "%s/button/input0", acpi_device_hid(device)); + + input->name = acpi_device_name(device); + input->phys = button->phys; + input->id.bustype = BUS_HOST; + input->id.product = button->type; switch (button->type) { + case ACPI_BUTTON_TYPE_POWER: case ACPI_BUTTON_TYPE_POWERF: - status = - acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, - acpi_button_notify_fixed, - button); + input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_POWER, input->keybit); break; + + case ACPI_BUTTON_TYPE_SLEEP: case ACPI_BUTTON_TYPE_SLEEPF: - status = - acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, - acpi_button_notify_fixed, - button); + input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_SLEEP, input->keybit); break; - default: - status = acpi_install_notify_handler(device->handle, - ACPI_DEVICE_NOTIFY, - acpi_button_notify, - button); + + case ACPI_BUTTON_TYPE_LID: + input->evbit[0] = BIT(EV_SW); + set_bit(SW_LID, input->swbit); break; } - if (ACPI_FAILURE(status)) { - result = -ENODEV; - goto end; - } + error = input_register_device(input); + if (error) + goto err_remove_handlers; if (device->wakeup.flags.valid) { /* Button's GPE is run-wake GPE */ @@ -385,47 +458,31 @@ static int acpi_button_add(struct acpi_device *device) printk(KERN_INFO PREFIX "%s [%s]\n", acpi_device_name(device), acpi_device_bid(device)); - end: - if (result) { - acpi_button_remove_fs(device); - kfree(button); - } + return 0; - return result; + err_remove_handlers: + acpi_button_remove_notify_handlers(button); + err_remove_fs: + acpi_button_remove_fs(device); + err_free_input: + input_free_device(input); + err_free_button: + kfree(button); + return error; } static int acpi_button_remove(struct acpi_device *device, int type) { - acpi_status status = 0; - struct acpi_button *button = NULL; - + struct acpi_button *button; if (!device || !acpi_driver_data(device)) return -EINVAL; button = acpi_driver_data(device); - /* Unregister for device notifications. */ - switch (button->type) { - case ACPI_BUTTON_TYPE_POWERF: - status = - acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, - acpi_button_notify_fixed); - break; - case ACPI_BUTTON_TYPE_SLEEPF: - status = |