From 50dd096973f1d95aa03c6a6d9e148d706b62b68e Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 1 Oct 2006 00:28:50 +0200 Subject: ACPI: Remove unnecessary from/to-void* and to-void casts in drivers/acpi Signed-off-by: Jan Engelhardt Signed-off-by: Len Brown --- drivers/acpi/ac.c | 6 ++-- drivers/acpi/acpi_memhotplug.c | 2 +- drivers/acpi/asus_acpi.c | 7 ++--- drivers/acpi/battery.c | 22 +++++++------- drivers/acpi/button.c | 8 ++--- drivers/acpi/container.c | 2 +- drivers/acpi/dock.c | 6 ++-- drivers/acpi/ec.c | 12 ++++---- drivers/acpi/fan.c | 6 ++-- drivers/acpi/glue.c | 4 +-- drivers/acpi/hotkey.c | 5 ++-- drivers/acpi/i2c_ec.c | 2 +- drivers/acpi/ibm_acpi.c | 6 ++-- drivers/acpi/numa.c | 2 +- drivers/acpi/osl.c | 4 +-- drivers/acpi/pci_bind.c | 4 +-- drivers/acpi/pci_irq.c | 2 +- drivers/acpi/pci_link.c | 8 ++--- drivers/acpi/pci_root.c | 4 +-- drivers/acpi/power.c | 6 ++-- drivers/acpi/processor_core.c | 10 +++---- drivers/acpi/processor_idle.c | 14 ++++----- drivers/acpi/processor_perflib.c | 10 +++---- drivers/acpi/processor_thermal.c | 6 ++-- drivers/acpi/processor_throttling.c | 6 ++-- drivers/acpi/sbs.c | 24 +++++++-------- drivers/acpi/tables.c | 2 +- drivers/acpi/thermal.c | 30 +++++++++---------- drivers/acpi/utils.c | 4 +-- drivers/acpi/video.c | 59 +++++++++++++++++-------------------- 30 files changed, 138 insertions(+), 145 deletions(-) diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 11abc7bf777e..46e58663dcb5 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; @@ -269,7 +269,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 98099de59b45..13687835c460 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -427,7 +427,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 e9ee4c52a5f6..f7db8ea7ac0a 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -1128,7 +1128,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)) { @@ -1150,7 +1150,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; @@ -1245,8 +1245,7 @@ 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 = kmalloc(sizeof(struct asus_hotk), GFP_KERNEL); if (!hotk) return -ENOMEM; memset(hotk, 0, sizeof(struct asus_hotk)); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 9810e2a55d0a..adb0d2725731 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -147,7 +147,7 @@ acpi_battery_get_info(struct acpi_battery *battery, return -ENODEV; } - package = (union acpi_object *)buffer.pointer; + package = buffer.pointer; /* Extract Package Data */ @@ -177,7 +177,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; } @@ -207,7 +207,7 @@ acpi_battery_get_status(struct acpi_battery *battery, return -ENODEV; } - package = (union acpi_object *)buffer.pointer; + package = buffer.pointer; /* Extract Package Data */ @@ -237,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; } @@ -332,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 = "?"; @@ -416,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 = "?"; @@ -492,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 = "?"; @@ -529,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)) @@ -656,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; @@ -740,7 +740,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 5ef885e82c78..fe914ebc4bbc 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -109,7 +109,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) @@ -128,7 +128,7 @@ 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; @@ -253,7 +253,7 @@ 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; if (!button || !button->device) @@ -275,7 +275,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) diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 871aa520ece7..a15381789462 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -117,7 +117,7 @@ static int acpi_container_remove(struct acpi_device *device, int type) acpi_status status = AE_OK; struct acpi_container *pc = NULL; - pc = (struct acpi_container *)acpi_driver_data(device); + pc = acpi_driver_data(device); kfree(pc); return status; } diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 578b99b71d9c..3c3dee844dfc 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -524,7 +524,7 @@ EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); */ static void dock_notify(acpi_handle handle, u32 event, void *data) { - struct dock_station *ds = (struct dock_station *)data; + struct dock_station *ds = data; switch (event) { case ACPI_NOTIFY_BUS_CHECK: @@ -587,7 +587,7 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; acpi_handle tmp; - struct dock_station *ds = (struct dock_station *)context; + struct dock_station *ds = context; struct dock_dependent_device *dd; status = acpi_bus_get_ejd(handle, &tmp); @@ -702,7 +702,7 @@ static int dock_remove(void) static acpi_status find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) { - int *count = (int *)context; + int *count = context; acpi_status status = AE_OK; if (is_dock(handle)) { diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e5d796362854..d560b5e8dd3f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -716,7 +716,7 @@ static void acpi_ec_gpe_poll_query(void *ec_cxt) } static void acpi_ec_gpe_intr_query(void *ec_cxt) { - union acpi_ec *ec = (union acpi_ec *)ec_cxt; + union acpi_ec *ec = ec_cxt; u32 value; int result = -ENODATA; static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; @@ -752,7 +752,7 @@ static u32 acpi_ec_gpe_handler(void *data) static u32 acpi_ec_gpe_poll_handler(void *data) { acpi_status status = AE_OK; - union acpi_ec *ec = (union acpi_ec *)data; + union acpi_ec *ec = data; if (!ec) return ACPI_INTERRUPT_NOT_HANDLED; @@ -770,7 +770,7 @@ static u32 acpi_ec_gpe_intr_handler(void *data) { acpi_status status = AE_OK; u32 value; - union acpi_ec *ec = (union acpi_ec *)data; + union acpi_ec *ec = data; if (!ec) return ACPI_INTERRUPT_NOT_HANDLED; @@ -848,7 +848,7 @@ acpi_ec_space_handler(u32 function, return AE_BAD_PARAMETER; } - ec = (union acpi_ec *)handler_context; + ec = handler_context; next_byte: switch (function) { @@ -905,7 +905,7 @@ static struct proc_dir_entry *acpi_ec_dir; static int acpi_ec_read_info(struct seq_file *seq, void *offset) { - union acpi_ec *ec = (union acpi_ec *)seq->private; + union acpi_ec *ec = seq->private; if (!ec) @@ -1136,7 +1136,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type) static acpi_status acpi_ec_io_ports(struct acpi_resource *resource, void *context) { - union acpi_ec *ec = (union acpi_ec *)context; + union acpi_ec *ec = context; struct acpi_generic_address *addr; if (resource->type != ACPI_RESOURCE_TYPE_IO) { diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 045c89477e59..c413e69fea8e 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -99,8 +99,8 @@ acpi_fan_write_state(struct file *file, const char __user * buffer, size_t count, loff_t * ppos) { int result = 0; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_fan *fan = (struct acpi_fan *)m->private; + struct seq_file *m = file->private_data; + struct acpi_fan *fan = m->private; char state_string[12] = { '\0' }; @@ -229,7 +229,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - fan = (struct acpi_fan *)acpi_driver_data(device); + fan = acpi_driver_data(device); acpi_fan_remove_fs(device); diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 10f160dc75b1..ba5686fa4750 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -96,7 +96,7 @@ struct acpi_find_pci_root { static acpi_status do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) { - unsigned long *busnr = (unsigned long *)data; + unsigned long *busnr = data; struct acpi_resource_address64 address; if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && @@ -217,7 +217,7 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) acpi_status status; struct acpi_device_info *info; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_find_child *find = (struct acpi_find_child *)context; + struct acpi_find_child *find = context; status = acpi_get_object_info(handle, &buffer); if (ACPI_SUCCESS(status)) { diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c index 1ba2db671865..8edfb92f7ede 100644 --- a/drivers/acpi/hotkey.c +++ b/drivers/acpi/hotkey.c @@ -265,8 +265,7 @@ static char *format_result(union acpi_object *object) static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) { - struct acpi_polling_hotkey *poll_hotkey = - (struct acpi_polling_hotkey *)seq->private; + struct acpi_polling_hotkey *poll_hotkey = seq->private; char *buf; @@ -577,7 +576,7 @@ init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry, if (ACPI_FAILURE(status)) goto do_fail_zero; key->poll_hotkey.poll_result = - (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL); + kmalloc(sizeof(union acpi_object), GFP_KERNEL); if (!key->poll_hotkey.poll_result) goto do_fail_zero; return AE_OK; diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c index 6342e612c203..82e3e64483fb 100644 --- a/drivers/acpi/i2c_ec.c +++ b/drivers/acpi/i2c_ec.c @@ -393,7 +393,7 @@ static void __exit acpi_ec_hc_exit(void) struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device) { - return ((struct acpi_ec_hc *)acpi_driver_data(device->parent)); + return acpi_driver_data(device->parent); } EXPORT_SYMBOL(acpi_get_ec_hc); diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 15fc12482ba0..6fbb42048890 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1721,7 +1721,7 @@ static struct ibm_struct ibms[] = { static int dispatch_read(char *page, char **start, off_t off, int count, int *eof, void *data) { - struct ibm_struct *ibm = (struct ibm_struct *)data; + struct ibm_struct *ibm = data; int len; if (!ibm || !ibm->read) @@ -1746,7 +1746,7 @@ static int dispatch_read(char *page, char **start, off_t off, int count, static int dispatch_write(struct file *file, const char __user * userbuf, unsigned long count, void *data) { - struct ibm_struct *ibm = (struct ibm_struct *)data; + struct ibm_struct *ibm = data; char *kernbuf; int ret; @@ -1775,7 +1775,7 @@ static int dispatch_write(struct file *file, const char __user * userbuf, static void dispatch_notify(acpi_handle handle, u32 event, void *data) { - struct ibm_struct *ibm = (struct ibm_struct *)data; + struct ibm_struct *ibm = data; if (!ibm || !ibm->notify) return; diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index e5e448edca41..bd96a7045925 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -248,7 +248,7 @@ int acpi_get_pxm(acpi_handle h) handle = phandle; status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm); if (ACPI_SUCCESS(status)) - return (int)pxm; + return pxm; status = acpi_get_parent(handle, &phandle); } while (ACPI_SUCCESS(status)); return -1; diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 068fe4f100b0..2ed2d701f6e1 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -569,7 +569,7 @@ static void acpi_os_execute_deferred(void *context) struct acpi_os_dpc *dpc = NULL; - dpc = (struct acpi_os_dpc *)context; + dpc = context; if (!dpc) { printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); return; @@ -1060,7 +1060,7 @@ acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) acpi_status acpi_os_purge_cache(acpi_cache_t * cache) { - (void)kmem_cache_shrink(cache); + kmem_cache_shrink(cache); return (AE_OK); } diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 1e2ae6e7a7e4..70b440f3f262 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c @@ -281,7 +281,7 @@ int acpi_pci_unbind(struct acpi_device *device) if (!device || !device->parent) return -EINVAL; - pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; memset(pathname, 0, ACPI_PATHNAME_MAX); @@ -332,7 +332,7 @@ acpi_pci_bind_root(struct acpi_device *device, struct acpi_buffer buffer = { 0, NULL }; - pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; memset(pathname, 0, ACPI_PATHNAME_MAX); diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index feda0341f5a7..226892eaf987 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -161,7 +161,7 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) static int first_time = 1; - pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; memset(pathname, 0, ACPI_PATHNAME_MAX); diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 7f3e7e77e794..6718198bfae7 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -103,7 +103,7 @@ DEFINE_MUTEX(acpi_link_lock); static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) { - struct acpi_pci_link *link = (struct acpi_pci_link *)context; + struct acpi_pci_link *link = context; u32 i = 0; @@ -613,7 +613,7 @@ acpi_pci_link_allocate_irq(acpi_handle handle, return -1; } - link = (struct acpi_pci_link *)acpi_driver_data(device); + link = acpi_driver_data(device); if (!link) { printk(KERN_ERR PREFIX "Invalid link context\n"); return -1; @@ -668,7 +668,7 @@ int acpi_pci_link_free_irq(acpi_handle handle) return -1; } - link = (struct acpi_pci_link *)acpi_driver_data(device); + link = acpi_driver_data(device); if (!link) { printk(KERN_ERR PREFIX "Invalid link context\n"); return -1; @@ -808,7 +808,7 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - link = (struct acpi_pci_link *)acpi_driver_data(device); + link = acpi_driver_data(device); mutex_lock(&acpi_link_lock); list_del(&link->node); diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 0984a1ee24ed..03e03741c140 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -119,7 +119,7 @@ EXPORT_SYMBOL(acpi_pci_unregister_driver); static acpi_status get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) { - int *busnr = (int *)data; + int *busnr = data; struct acpi_resource_address64 address; if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && @@ -331,7 +331,7 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - root = (struct acpi_pci_root *)acpi_driver_data(device); + root = acpi_driver_data(device); kfree(root); diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index fec225d1b6b7..e9dab54bd541 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -108,7 +108,7 @@ acpi_power_get_context(acpi_handle handle, return result; } - *resource = (struct acpi_power_resource *)acpi_driver_data(device); + *resource = acpi_driver_data(device); if (!resource) return -ENODEV; @@ -445,7 +445,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset) struct acpi_power_resource *resource = NULL; - resource = (struct acpi_power_resource *)seq->private; + resource = seq->private; if (!resource) goto end; @@ -593,7 +593,7 @@ static int acpi_power_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - resource = (struct acpi_power_resource *)acpi_driver_data(device); + resource = acpi_driver_data(device); acpi_power_remove_fs(device); diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index b13d64415b7a..44c624bd40cb 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -277,7 +277,7 @@ static struct proc_dir_entry *acpi_processor_dir = NULL; static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_processor *pr = (struct acpi_processor *)seq->private; + struct acpi_processor *pr = seq->private; if (!pr) @@ -542,12 +542,12 @@ static int acpi_processor_start(struct acpi_device *device) * Don't trust it blindly */ if (processor_device_array[pr->id] != NULL && - processor_device_array[pr->id] != (void *)device) { + processor_device_array[pr->id] != device) { printk(KERN_WARNING "BIOS reported wrong ACPI id" "for the processor\n"); return -ENODEV; } - processor_device_array[pr->id] = (void *)device; + processor_device_array[pr->id] = device; processors[pr->id] = pr; @@ -578,7 +578,7 @@ static int acpi_processor_start(struct acpi_device *device) static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_processor *pr = (struct acpi_processor *)data; + struct acpi_processor *pr = data; struct acpi_device *device = NULL; @@ -637,7 +637,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - pr = (struct acpi_processor *)acpi_driver_data(device); + pr = acpi_driver_data(device); if (pr->id >= NR_CPUS) { kfree(pr); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 0a395fca843b..4504684671f6 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -671,7 +671,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) return -ENODEV; } - cst = (union acpi_object *)buffer.pointer; + cst = buffer.pointer; /* There must be at least 2 elements */ if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) { @@ -700,14 +700,14 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) memset(&cx, 0, sizeof(cx)); - element = (union acpi_object *)&(cst->package.elements[i]); + element = &(cst->package.elements[i]); if (element->type != ACPI_TYPE_PACKAGE) continue; if (element->package.count != 4) continue; - obj = (union acpi_object *)&(element->package.elements[0]); + obj = &(element->package.elements[0]); if (obj->type != ACPI_TYPE_BUFFER) continue; @@ -722,7 +722,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) 0 : reg->address; /* There should be an easy way to extract an integer... */ - obj = (union acpi_object *)&(element->package.elements[1]); + obj = &(element->package.elements[1]); if (obj->type != ACPI_TYPE_INTEGER) continue; @@ -735,13 +735,13 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3)) continue; - obj = (union acpi_object *)&(element->package.elements[2]); + obj = &(element->package.elements[2]); if (obj->type != ACPI_TYPE_INTEGER) continue; cx.latency = obj->integer.value; - obj = (union acpi_object *)&(element->package.elements[3]); + obj = &(element->package.elements[3]); if (obj->type != ACPI_TYPE_INTEGER) continue; @@ -1004,7 +1004,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) { - struct acpi_processor *pr = (struct acpi_processor *)seq->private; + struct acpi_processor *pr = seq->private; unsigned int i; diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 7ba5e49ab302..39fdbcc37d43 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -238,7 +238,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) return -ENODEV; } - pss = (union acpi_object *)buffer.pointer; + pss = buffer.pointer; if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { printk(KERN_ERR PREFIX "Invalid _PSS data\n"); result = -EFAULT; @@ -412,7 +412,7 @@ static struct file_operations acpi_processor_perf_fops = { static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) { - struct acpi_processor *pr = (struct acpi_processor *)seq->private; + struct acpi_processor *pr = seq->private; int i; @@ -453,8 +453,8 @@ acpi_processor_write_performance(struct file *file, size_t count, loff_t * data) { int result = 0; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_processor *pr = (struct acpi_processor *)m->private; + struct seq_file *m = file->private_data; + struct acpi_processor *pr = m->private; struct acpi_processor_performance *perf; char state_string[12] = { '\0' }; unsigned int new_state = 0; @@ -553,7 +553,7 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) return -ENODEV; } - psd = (union acpi_object *) buffer.pointer; + psd = buffer.pointer; if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); result = -EFAULT; diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index ef5e0f6efdba..40fecd67ad83 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -208,7 +208,7 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type) if (result) return result; - pr = (struct acpi_processor *)acpi_driver_data(device); + pr = acpi_driver_data(device); if (!pr) return -ENODEV; @@ -348,8 +348,8 @@ static ssize_t acpi_processor_write_limit(struct file * file, size_t count, loff_t * data) { int result = 0; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_processor *pr = (struct acpi_processor *)m->private; + struct seq_file *m = file->private_data; + struct acpi_processor *pr = m->private; char limit_string[25] = { '\0' }; int px = 0; int tx = 0; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index d044ec519db0..0ec7dcde0063 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -259,7 +259,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset) { - struct acpi_processor *pr = (struct acpi_processor *)seq->private; + struct acpi_processor *pr = seq->private; int i = 0; int result = 0; @@ -307,8 +307,8 @@ static ssize_t acpi_processor_write_throttling(struct file * file, size_t count, loff_t * data) { int result = 0; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_processor *pr = (struct acpi_processor *)m->private; + struct seq_file *m = file->private_data; + struct acpi_processor *pr = m->private; char state_string[12] = { '\0' }; diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 62bef0b3b614..c6a819adcc9e 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -923,7 +923,7 @@ static struct proc_dir_entry *acpi_battery_dir = NULL; static int acpi_battery_read_info(struct seq_file *seq, void *offset) { - struct acpi_battery *battery = (struct acpi_battery *)seq->private; + struct acpi_battery *battery = seq->private; int cscale; int result = 0; @@ -1076,7 +1076,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; int result = 0; int cscale; @@ -1125,8 +1125,8 @@ static ssize_t acpi_battery_write_alarm(struct file *file, const char __user * buffer, size_t count, loff_t * ppos) { - struct seq_file *seq = (struct seq_file *)file->private_data; - struct acpi_battery *battery = (struct acpi_battery *)seq->private; + struct seq_file *seq = file->private_data; + struct acpi_battery *battery = seq->private; char alarm_string[12] = { '\0' }; int result, old_alarm, new_alarm; @@ -1160,14 +1160,14 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer, if (result) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_battery_set_alarm() failed\n")); - (void)acpi_battery_set_alarm(battery, old_alarm); + acpi_battery_set_alarm(battery, old_alarm); goto end; } result = acpi_battery_get_alarm(battery); if (result) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_battery_get_alarm() failed\n")); - (void)acpi_battery_set_alarm(battery, old_alarm); + acpi_battery_set_alarm(battery, old_alarm); goto end; } @@ -1217,7 +1217,7 @@ static struct proc_dir_entry *acpi_ac_dir = NULL; static int acpi_ac_read_state(struct seq_file *seq, void *offset) { - struct acpi_sbs *sbs = (struct acpi_sbs *)seq->private; + struct acpi_sbs *sbs = seq->private; int result; if (sbs->zombie) { @@ -1302,7 +1302,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) battery->init_state = 1; } - (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); + sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); result = acpi_sbs_generic_add_fs(&battery->battery_entry, acpi_battery_dir, @@ -1485,7 +1485,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type) } if (old_battery_present != new_battery_present) { - (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); + sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); result = acpi_sbs_generate_event(sbs->device, ACPI_SBS_BATTERY_NOTIFY_STATUS, new_battery_present, @@ -1498,7 +1498,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type) } } if (old_remaining_capacity != battery->state.remaining_capacity) { - (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); + sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); result = acpi_sbs_generate_event(sbs->device, ACPI_SBS_BATTERY_NOTIFY_STATUS, new_battery_present, @@ -1659,7 +1659,7 @@ static int acpi_sbs_add(struct acpi_device *device) init_timer(&sbs->update_timer); if (update_mode == QUEUE_UPDATE_MODE) { status = acpi_os_execute(OSL_GPE_HANDLER, - acpi_sbs_update_queue, (void *)sbs); + acpi_sbs_update_queue, sbs); if (status != AE_OK) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_os_execute() failed\n")); @@ -1685,7 +1685,7 @@ static int acpi_sbs_add(struct acpi_device *device) int acpi_sbs_remove(struct acpi_device *device, int type) { - struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device); + struct acpi_sbs *sbs = acpi_driver_data(device); int id; if (!device || !sbs) { diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index bfb3bfcf9e91..ffa30c9fccbf 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -228,7 +228,7 @@ void acpi_table_print_madt_entry(acpi_table_entry_header * header) static int acpi_table_compute_checksum(void *table_pointer, unsigned long length) { - u8 *p = (u8 *) table_pointer; + u8 *p = table_pointer; unsigned long remains = length; unsigned long sum = 0; diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 5753d06b7860..4d75085ca2d2 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -663,7 +663,7 @@ static void acpi_thermal_run(unsigned long data) static void acpi_thermal_check(void *data) { int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *)data; + struct acpi_thermal *tz = data; unsigned long sleep_time = 0; int i = 0; struct acpi_thermal_state state; @@ -778,7 +778,7 @@ static struct proc_dir_entry *acpi_thermal_dir; static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) { - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; if (!tz) @@ -813,7 +813,7 @@ static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file) static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) { int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; if (!tz) @@ -837,7 +837,7 @@ static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file) static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) { - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; int i = 0; int j = 0; @@ -893,8 +893,8 @@ acpi_thermal_write_trip_points(struct file *file, const char __user * buffer, size_t count, loff_t * ppos) { - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_thermal *tz = (struct acpi_thermal *)m->private; + struct seq_file *m = file->private_data; + struct acpi_thermal *tz = m->private; char *limit_string; int num, critical, hot, passive; @@ -953,7 +953,7 @@ acpi_thermal_write_trip_points(struct file *file, static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) { - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; if (!tz) @@ -984,8 +984,8 @@ acpi_thermal_write_cooling_mode(struct file *file, const char __user * buffer, size_t count, loff_t * ppos) { - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_thermal *tz = (struct acpi_thermal *)m->private; + struct seq_file *m = file->private_data; + struct acpi_thermal *tz = m->private; int result = 0; char mode_string[12] = { '\0' }; @@ -1014,7 +1014,7 @@ acpi_thermal_write_cooling_mode(struct file *file, static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) { - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; if (!tz) @@ -1043,8 +1043,8 @@ acpi_thermal_write_polling(struct file *file, const char __user * buffer, size_t count, loff_t * ppos) { - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_thermal *tz = (struct acpi_thermal *)m->private; + struct seq_file *m = file->private_data; + struct acpi_thermal *tz = m->private; int result = 0; char polling_string[12] = { '\0' }; int seconds = 0; @@ -1170,7 +1170,7 @@ static int acpi_thermal_remove_fs(struct acpi_device *device) static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_thermal *tz = (struct acpi_thermal *)data; + struct acpi_thermal *tz = data; struct acpi_device *device = NULL; @@ -1324,7 +1324,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - tz = (struct acpi_thermal *)acpi_driver_data(device); + tz = acpi_driver_data(device); /* avoid timer adding new defer task */ tz->zombie = 1; @@ -1364,7 +1364,7 @@ static int acpi_thermal_resume(struct acpi_device *device, int state) if (!device || !acpi_driver_data(device)) return -EINVAL; - tz = (struct acpi_thermal *)acpi_driver_data(device); + tz = acpi_driver_data(device); acpi_thermal_get_temperature(tz); diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index d0d84c43a9d4..91fed70a65a6 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -83,7 +83,7 @@ acpi_extract_package(union acpi_object *package, return AE_BAD_DATA; } - format_string = (char *)format->pointer; + format_string = format->pointer; /* * Calculate size_required. @@ -361,7 +361,7 @@ acpi_evaluate_reference(acpi_handle handle, if (ACPI_FAILURE(status)) goto end; - package = (union acpi_object *)buffer.pointer; + package = buffer.pointer; if ((buffer.length == 0) || !package) { printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n", diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 56666a982476..53a9eb015d6b 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -386,7 +386,7 @@ acpi_video_device_EDID(struct acpi_video_device *device, if (ACPI_FAILURE(status)) return -ENODEV; - obj = (union acpi_object *)buffer.pointer; + obj = buffer.pointer; if (obj && obj->type == ACPI_TYPE_BUFFER) *edid = obj; @@ -654,8 +654,7 @@ static struct proc_dir_entry *acpi_video_dir; static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_device *dev = - (struct acpi_video_device *)seq->private; + struct acpi_video_device *dev = seq->private; if (!dev) @@ -688,8 +687,7 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file) static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) { int status; - struct acpi_video_device *dev = - (struct acpi_video_device *)seq->private; + struct acpi_video_device *dev = seq->private; unsigned long state; @@ -727,8 +725,8 @@ acpi_video_device_write_state(struct file *file, size_t count, loff_t * data) { int status; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_video_device *dev = (struct acpi_video_device *)m->private; + struct seq_file *m = file->private_data; + struct acpi_video_device *dev = m->private; char str[12] = { 0 }; u32 state = 0; @@ -754,8 +752,7 @@ acpi_video_device_write_state(struct file *file, static int acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_device *dev = - (struct acpi_video_device *)seq->private; + struct acpi_video_device *dev = seq->private; int i; @@ -784,8 +781,8 @@ acpi_video_device_write_brightness(struct file *file, const char __user * buffer, size_t count, loff_t * data) { - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_video_device *dev = (struct acpi_video_device *)m->private; + struct seq_file *m = file->private_data; + struct acpi_video_device *dev = m->private; char str[4] = { 0 }; unsigned int level = 0; int i; @@ -817,8 +814,7 @@ acpi_video_device_write_brightness(struct file *file, static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_device *dev = - (struct acpi_video_device *)seq->private; + struct acpi_video_device *dev = seq->private; int status; int i; union acpi_object *edid = NULL; @@ -866,7 +862,7 @@ static int acpi_video_device_add_fs(struct acpi_device *device) if (!device) return -ENODEV; - vid_dev = (struct acpi_video_device *)acpi_driver_data(device); + vid_dev = acpi_driver_data(device); if (!vid_dev) return -ENODEV; @@ -931,7 +927,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device) { struct acpi_video_device *vid_dev; - vid_dev = (struct acpi_video_device *)acpi_driver_data(device); + vid_dev = acpi_driver_data(device); if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) return -ENODEV; @@ -950,7 +946,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device) /* video bus */ static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; if (!video) @@ -975,7 +971,7 @@ static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file) static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; if (!video) @@ -995,7 +991,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; unsigned long options; int status; @@ -1033,7 +1029,7 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; int status; unsigned long id; @@ -1054,7 +1050,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); @@ -1079,8 +1075,8 @@ acpi_video_bus_write_POST(struct file *file, size_t count, loff_t * data) { int status; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; + struct seq_file *m = file->private_data; + struct acpi_video_bus *video = m->private; char str[12] = { 0 }; unsigned long opt, options; @@ -1119,8 +1115,8 @@ acpi_video_bus_write_DOS(struct file *file, size_t count, loff_t * data) { int status; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; + struct seq_file *m = file->private_data; + struct acpi_video_bus *video = m->private; char str[12] = { 0 }; unsigned long opt; @@ -1150,7 +1146,7 @@ static int acpi_video_bus_add_fs(struct acpi_device *device) struct acpi_video_bus *video; - video = (struct acpi_video_bus *)acpi_driver_data(device); + video = acpi_driver_data(device); if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), @@ -1226,7 +1222,7 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) struct acpi_video_bus *video; - video = (struct acpi_video_bus *)acpi_driver_data(device); + video = acpi_driver_data(device); if (acpi_device_dir(device)) { remove_proc_entry("info", acpi_device_dir(device)); @@ -1403,7 +1399,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) return status; } - dod = (union acpi_object *)buffer.pointer; + dod = buffer.pointer; if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); status = -EFAULT; @@ -1426,7 +1422,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) count = 0; for (i = 0; i < dod->package.count; i++) { - obj = (union acpi_object *)&dod->package.elements[i]; + obj = &dod->package.elements[i]; if (obj->type != ACPI_TYPE_INTEGER) { printk(KERN_ERR PREFIX "Invalid _DOD data\n"); @@ -1612,7 +1608,7 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_video_bus *video = (struct acpi_video_bus *)data; + struct acpi_video_bus *video = data; struct acpi_device *device = NULL; printk("video bus notify\n"); @@ -1654,8 +1650,7 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_video_device *video_device = - (struct acpi_video_device *)data; + struct acpi_video_device *video_device = data; struct acpi_device *device = NULL; @@ -1757,7 +1752,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; - video = (struct acpi_video_bus *)acpi_driver_data(device); + video = acpi_driver_data(device); acpi_video_bus_stop_devices(video); -- cgit v1.2.3-59-g8ed1b From 965a3d447276491b7ed053b25679c062beb04194 Mon Sep 17 00:00:00 2001 From: Martin Bligh Date: Fri, 20 Oct 2006 14:30:26 -0700 Subject: ACPI: avoid gcc warnings in ACPI mutex debug code 32bit vs 64 bit issues. sizeof(sizeof) and sizeof(pointer) is variable, but we're trying to print it as unsigned int or u32. Casts to unsigned long are used because type acpi_thread_id can be any one of typedef u64 acpi_native_uint; typedef u32 acpi_native_uint; typedef u16 acpi_native_uint; #define acpi_thread_id struct task_struct * Signed-off-by: Martin J. Bligh Acked-by: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/executer/exmutex.c | 6 +++--- drivers/acpi/utilities/utdebug.c | 5 +++-- drivers/acpi/utilities/utmutex.c | 16 +++++++++------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c index 3a39c2e8e104..bf90f04f2c60 100644 --- a/drivers/acpi/executer/exmutex.c +++ b/drivers/acpi/executer/exmutex.c @@ -266,10 +266,10 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, walk_state->thread->thread_id) && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) { ACPI_ERROR((AE_INFO, - "Thread %X cannot release Mutex [%4.4s] acquired by thread %X", - (u32) walk_state->thread->thread_id, + "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", + (unsigned long)walk_state->thread->thread_id, acpi_ut_get_node_name(obj_desc->mutex.node), - (u32) obj_desc->mutex.owner_thread->thread_id)); + (unsigned long)obj_desc->mutex.owner_thread->thread_id)); return_ACPI_STATUS(AE_AML_NOT_OWNER); } diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c index bb1eaf9aa653..9e9054e155c1 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/utilities/utdebug.c @@ -180,8 +180,9 @@ acpi_ut_debug_print(u32 requested_debug_level, if (thread_id != acpi_gbl_prev_thread_id) { if (ACPI_LV_THREADS & acpi_dbg_level) { acpi_os_printf - ("\n**** Context Switch from TID %X to TID %X ****\n\n", - (u32) acpi_gbl_prev_thread_id, (u32) thread_id); + ("\n**** Context Switch from TID %lX to TID %lX ****\n\n", + (unsigned long) acpi_gbl_prev_thread_id, + (unsigned long) thread_id); } acpi_gbl_prev_thread_id = thread_id; diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c index c39062a047cd..180e73ceb6e2 100644 --- a/drivers/acpi/utilities/utmutex.c +++ b/drivers/acpi/utilities/utmutex.c @@ -243,23 +243,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) #endif ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %X attempting to acquire Mutex [%s]\n", - (u32) this_thread_id, acpi_ut_get_mutex_name(mutex_id))); + "Thread %lX attempting to acquire Mutex [%s]\n", + (unsigned long) this_thread_id, + acpi_ut_get_mutex_name(mutex_id))); status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, ACPI_WAIT_FOREVER); if (ACPI_SUCCESS(status)) { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %X acquired Mutex [%s]\n", - (u32) this_thread_id, + "Thread %lX acquired Mutex [%s]\n", + (unsigned long) this_thread_id, acpi_ut_get_mutex_name(mutex_id))); acpi_gbl_mutex_info[mutex_id].use_count++; acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; } else { ACPI_EXCEPTION((AE_INFO, status, - "Thread %X could not acquire Mutex [%X]", - (u32) this_thread_id, mutex_id)); + "Thread %lX could not acquire Mutex [%X]", + (unsigned long) this_thread_id, mutex_id)); } return (status); @@ -285,7 +286,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) this_thread_id = acpi_os_get_thread_id(); ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %X releasing Mutex [%s]\n", (u32) this_thread_id, + "Thread %lX releasing Mutex [%s]\n", + (unsigned long) this_thread_id, acpi_ut_get_mutex_name(mutex_id))); if (mutex_id > ACPI_MAX_MUTEX) { -- cgit v1.2.3-59-g8ed1b From d0a9081b1e75ba62bb4450c5b8e8299a41d25278 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 20 Oct 2006 14:30:27 -0700 Subject: ACPI: uninline ACPI global locking functions - Fixes a build problem with CONFIG_M386=y (include file dependencies get messy). - Share the implementation between x86 and x86_64 - These are too big to inline anyway. Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- arch/i386/kernel/acpi/boot.c | 22 ++++++++++++++++++++++ include/asm-i386/acpi.h | 26 ++------------------------ include/asm-x86_64/acpi.h | 26 ++------------------------ 3 files changed, 26 insertions(+), 48 deletions(-) diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index ab974ff97073..bf7099ca41a5 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -1319,3 +1319,25 @@ static int __init setup_acpi_sci(char *s) return 0; } early_param("acpi_sci", setup_acpi_sci); + +int __acpi_acquire_global_lock(unsigned int *lock) +{ + unsigned int old, new, val; + do { + old = *lock; + new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); + val = cmpxchg(lock, old, new); + } while (unlikely (val != old)); + return (new < 3) ? -1 : 0; +} + +int __acpi_release_global_lock(unsigned int *lock) +{ + unsigned int old, new, val; + do { + old = *lock; + new = old & ~0x3; + val = cmpxchg(lock, old, new); + } while (unlikely (val != old)); + return old & 0x1; +} diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h index 6016632d032f..29bee1dcde72 100644 --- a/include/asm-i386/acpi.h +++ b/include/asm-i386/acpi.h @@ -56,30 +56,8 @@ #define ACPI_ENABLE_IRQS() local_irq_enable() #define ACPI_FLUSH_CPU_CACHE() wbinvd() - -static inline int -__acpi_acquire_global_lock (unsigned int *lock) -{ - unsigned int old, new, val; - do { - old = *lock; - new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); - val = cmpxchg(lock, old, new); - } while (unlikely (val != old)); - return (new < 3) ? -1 : 0; -} - -static inline int -__acpi_release_global_lock (unsigned int *lock) -{ - unsigned int old, new, val; - do { - old = *lock; - new = old & ~0x3; - val = cmpxchg(lock, old, new); - } while (unlikely (val != old)); - return old & 0x1; -} +int __acpi_acquire_global_lock(unsigned int *lock); +int __acpi_release_global_lock(unsigned int *lock); #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr)) diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h index ed59aa4c6ff9..1371e88666ed 100644 --- a/include/asm-x86_64/acpi.h +++ b/include/asm-x86_64/acpi.h @@ -54,30 +54,8 @@ #define ACPI_ENABLE_IRQS() local_irq_enable() #define ACPI_FLUSH_CPU_CACHE() wbinvd() - -static inline int -__acpi_acquire_global_lock (unsigned int *lock) -{ - unsigned int old, new, val; - do { - old = *lock; - new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); - val = cmpxchg(lock, old, new); - } while (unlikely (val != old)); - return (new < 3) ? -1 : 0; -} - -static inline int -__acpi_release_global_lock (unsigned int *lock) -{ - unsigned int old, new, val; - do { - old = *lock; - new = old & ~0x3; - val = cmpxchg(lock, old, new); - } while (unlikely (val != old)); - return old & 0x1; -} +int __acpi_acquire_global_lock(unsigned int *lock); +int __acpi_release_global_lock(unsigned int *lock); #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr)) -- cgit v1.2.3-59-g8ed1b From 5c5e81aaa821822309fd2663c22c94ca0802e407 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 20 Oct 2006 14:30:30 -0700 Subject: ACPI: acpi-cpufreq: remove unused data when !CONFIG_SMP acpi-cpufreq.c, speedstep-centrino.c: warning: 'sw_any_bug_dmi_table' defined but not used Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 57c880bf0bd6..41e1289f8a42 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -402,6 +402,7 @@ static int sw_any_bug_found(struct dmi_system_id *d) return 0; } +#ifdef CONFIG_SMP static struct dmi_system_id sw_any_bug_dmi_table[] = { { .callback = sw_any_bug_found, @@ -414,6 +415,7 @@ static struct dmi_system_id sw_any_bug_dmi_table[] = { }, { } }; +#endif static int acpi_cpufreq_cpu_init ( -- cgit v1.2.3-59-g8ed1b From 8acb025085aa88c41063bfa0f2c3b4d0a3f2ef11 Mon Sep 17 00:00:00 2001 From: Holger Macht Date: Fri, 20 Oct 2006 14:30:28 -0700 Subject: ACPI: ibm_acpi: Add support for the generic backlight device Add support for the generic backlight interface below /sys/class/backlight. The patch keeps the procfs brightness handling for backward compatibility. Add two generic functions brightness_get and brightness_set to be used both by the procfs related and the sysfs related methods. [apw@shadowen.org: backlight users need to select BACKLIGHT_CLASS_DEVICE] Signed-off-by: Holger Macht Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 1 + drivers/acpi/ibm_acpi.c | 75 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 0f9d4be7ed75..bc58a3b18e06 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -200,6 +200,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 diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 003a9876c968..cd8722e4157e 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -78,6 +78,7 @@ #include #include #include +#include #include #include @@ -243,6 +244,8 @@ struct ibm_struct { static struct proc_dir_entry *proc_dir = NULL; +static struct backlight_device *ibm_backlight_device; + #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") #define strlencmp(a,b) (strncmp((a), (b), strlen(b))) @@ -1381,12 +1384,22 @@ static int ecdump_write(char *buf) static int brightness_offset = 0x31; +static int brightness_get(struct backlight_device *bd) +{ + u8 level; + if (!acpi_ec_read(brightness_offset, &level)) + return -EIO; + + level &= 0x7; + return level; +} + static int brightness_read(char *p) { int len = 0; - u8 level; + int level; - if (!acpi_ec_read(brightness_offset, &level)) { + if ((level = brightness_get(NULL)) < 0) { len += sprintf(p + len, "level:\t\tunreadable\n"); } else { len += sprintf(p + len, "level:\t\t%d\n", level & 0x7); @@ -1401,16 +1414,34 @@ static int brightness_read(char *p) #define BRIGHTNESS_UP 4 #define BRIGHTNESS_DOWN 5 -static int brightness_write(char *buf) +static int brightness_set(int value) { int cmos_cmd, inc, i; - u8 level; + int current_value = brightness_get(NULL); + + value &= 7; + + cmos_cmd = value > current_value ? BRIGHTNESS_UP : BRIGHTNESS_DOWN; + inc = value > current_value ? 1 : -1; + for (i = current_value; i != value; i += inc) { + if (!cmos_eval(cmos_cmd)) + return -EIO; + if (!acpi_ec_write(brightness_offset, i + inc)) + return -EIO; + } + + return 0; +} + +static int brightness_write(char *buf) +{ + int level; int new_level; char *cmd; while ((cmd = next_cmd(&buf))) { - if (!acpi_ec_read(brightness_offset, &level)) - return -EIO; + if ((level = brightness_get(NULL)) < 0) + return level; level &= 7; if (strlencmp(cmd, "up") == 0) { @@ -1423,19 +1454,17 @@ static int brightness_write(char *buf) } else return -EINVAL; - cmos_cmd = new_level > level ? BRIGHTNESS_UP : BRIGHTNESS_DOWN; - inc = new_level > level ? 1 : -1; - for (i = level; i != new_level; i += inc) { - if (!cmos_eval(cmos_cmd)) - return -EIO; - if (!acpi_ec_write(brightness_offset, i + inc)) - return -EIO; - } + brightness_set(new_level); } return 0; } +static int brightness_update_status(struct backlight_device *bd) +{ + return brightness_set(bd->props->brightness); +} + static int volume_offset = 0x30; static int volume_read(char *p) @@ -1963,10 +1992,20 @@ IBM_PARAM(brightness); IBM_PARAM(volume); IBM_PARAM(fan); +static struct backlight_properties ibm_backlight_data = { + .owner = THIS_MODULE, + .get_brightness = brightness_get, + .update_status = brightness_update_status, + .max_brightness = 7, +}; + static void acpi_ibm_exit(void) { int i; + if (ibm_backlight_device) + backlight_device_unregister(ibm_backlight_device); + for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--) ibm_exit(&ibms[i]); @@ -2034,6 +2073,14 @@ static int __init acpi_ibm_init(void) } } + ibm_backlight_device = backlight_device_register("ibm", NULL, + &ibm_backlight_data); + if (IS_ERR(ibm_backlight_device)) { + printk(IBM_ERR "Could not register ibm backlight device\n"); + ibm_backlight_device = NULL; + acpi_ibm_exit(); + } + return 0; } -- cgit v1.2.3-59-g8ed1b From 2039a6eb72d4b5d0dd71de5c4dff5db129848c44 Mon Sep 17 00:00:00 2001 From: Holger Macht Date: Fri, 20 Oct 2006 14:30:29 -0700 Subject: ACPI: asus_acpi: Add support for the generic backlight device Add support for the generic backlight interface below /sys/class/backlight. Keep the procfs brightness handling for backward compatibility. [apw@shadowen.org: backlight users need to select BACKLIGHT_CLASS_DEVICE] Signed-off-by: Holger Macht Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 1 + drivers/acpi/asus_acpi.c | 62 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index bc58a3b18e06..9b64c4e6c63e 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -172,6 +172,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 diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index c7ac9297a204..bf7bc25e680e 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -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 @@ -1333,6 +1345,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 +1402,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, + &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); -- cgit v1.2.3-59-g8ed1b From c92635572489b810d03acdf03f61bf6dd1af5433 Mon Sep 17 00:00:00 2001 From: Holger Macht Date: Fri, 20 Oct 2006 14:30:29 -0700 Subject: ACPI: toshiba_acpi: Add support for the generic backlight device Add support for the generic backlight interface below /sys/class/backlight. Keep the procfs brightness handling for backward compatibility. To achive this, add two generic functions get_lcd and set_lcd to be used both by the procfs related and the sysfs related methods. [apw@shadowen.org: backlight users need to select BACKLIGHT_CLASS_DEVICE] Signed-off-by: Holger Macht Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 1 + drivers/acpi/toshiba_acpi.c | 88 +++++++++++++++++++++++++++++++++------------ 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 9b64c4e6c63e..59f9def21720 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -227,6 +227,7 @@ config ACPI_IBM_DOCK 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/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 7fe0b7ae9733..2f35f891593f 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c @@ -41,6 +41,8 @@ #include #include #include +#include + #include #include @@ -210,6 +212,7 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result) } static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; +static struct backlight_device *toshiba_backlight_device; static int force_fan; static int last_key_event; static int key_event_valid; @@ -271,14 +274,23 @@ dispatch_write(struct file *file, const char __user * buffer, return result; } -static char *read_lcd(char *p) +static int get_lcd(struct backlight_device *bd) { u32 hci_result; u32 value; hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); if (hci_result == HCI_SUCCESS) { - value = value >> HCI_LCD_BRIGHTNESS_SHIFT; + return (value >> HCI_LCD_BRIGHTNESS_SHIFT); + } else + return -EFAULT; +} + +static char *read_lcd(char *p) +{ + int value = get_lcd(NULL); + + if (value >= 0) { p += sprintf(p, "brightness: %d\n", value); p += sprintf(p, "brightness_levels: %d\n", HCI_LCD_BRIGHTNESS_LEVELS); @@ -289,22 +301,34 @@ static char *read_lcd(char *p) return p; } +static int set_lcd(int value) +{ + u32 hci_result; + + value = value << HCI_LCD_BRIGHTNESS_SHIFT; + hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); + if (hci_result != HCI_SUCCESS) + return -EFAULT; + + return 0; +} + +static int set_lcd_status(struct backlight_device *bd) +{ + return set_lcd(bd->props->brightness); +} + static unsigned long write_lcd(const char *buffer, unsigned long count) { int value; - u32 hci_result; + int ret = count; if (sscanf(buffer, " brightness : %i", &value) == 1 && - value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { - value = value << HCI_LCD_BRIGHTNESS_SHIFT; - hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); - if (hci_result != HCI_SUCCESS) - return -EFAULT; - } else { - return -EINVAL; - } - - return count; + value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) + ret = set_lcd(value); + else + ret = -EINVAL; + return ret; } static char *read_video(char *p) @@ -506,6 +530,26 @@ static acpi_status __exit remove_device(void) return AE_OK; } +static struct backlight_properties toshiba_backlight_data = { + .owner = THIS_MODULE, + .get_brightness = get_lcd, + .update_status = set_lcd_status, + .max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1, +}; + +static void __exit toshiba_acpi_exit(void) +{ + if (toshiba_backlight_device) + backlight_device_unregister(toshiba_backlight_device); + + remove_device(); + + if (toshiba_proc_dir) + remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + + return; +} + static int __init toshiba_acpi_init(void) { acpi_status status = AE_OK; @@ -546,17 +590,15 @@ static int __init toshiba_acpi_init(void) remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); } - return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; -} - -static void __exit toshiba_acpi_exit(void) -{ - remove_device(); - - if (toshiba_proc_dir) - remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + toshiba_backlight_device = backlight_device_register("toshiba", NULL, + &toshiba_backlight_data); + if (IS_ERR(toshiba_backlight_device)) { + printk(KERN_ERR "Could not register toshiba backlight device\n"); + toshiba_backlight_device = NULL; + toshiba_acpi_exit(); + } - return; + return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; } module_init(toshiba_acpi_init); -- cgit v1.2.3-59-g8ed1b From 616362de2fe224512fe105aec08f19f5470afb01 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 27 Oct 2006 01:47:34 -0400 Subject: ACPI: make ec_transaction not extern Fix sparse warning: drivers/acpi/ec.c:372:12: warning: function 'ec_transaction' with external linkage has definition Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/ec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e6d4b084dca2..7aa600794ae4 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -369,7 +369,7 @@ int ec_write(u8 addr, u8 val) EXPORT_SYMBOL(ec_write); -extern int ec_transaction(u8 command, +int ec_transaction(u8 command, const u8 *wdata, unsigned wdata_len, u8 *rdata, unsigned rdata_len) { -- cgit v1.2.3-59-g8ed1b From 2f000f5c153e984d5c166e42a9d38113de8693b3 Mon Sep 17 00:00:00 2001 From: "Chen, Justin" Date: Tue, 10 Oct 2006 17:07:00 -0400 Subject: ACPI: optimize pci_rootbridge search acpi_get_pci_rootbridge_handle() walks the ACPI name space searching for seg, bus and the PCI_ROOT_HID_STRING -- returning the handle as soon as if find the match. But the current codes always parses through the whole namespace because the user_function find_pci_rootbridge() returns status=AE_OK when it finds the match. Make the find_pci_rootbridge() return AE_CTRL_TERMINATE when it finds the match. This reduces the ACPI namespace walk for acpi_get_pci_rootbridge_handle(). Signed-off-by: Justin Chen Signed-off-by: Len Brown --- drivers/acpi/glue.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 10f160dc75b1..ba8fe83c6298 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -189,8 +189,12 @@ find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv) bus = tmp; if (seg == find->seg && bus == find->bus) + { find->handle = handle; - status = AE_OK; + status = AE_CTRL_TERMINATE; + } + else + status = AE_OK; exit: kfree(buffer.pointer); return status; -- cgit v1.2.3-59-g8ed1b From 8b0dc866dd9b8d10a53cb3537385a51b7ee54b62 Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Mon, 30 Oct 2006 11:18:45 -0800 Subject: ACPI: dock: use mutex instead of spinlock http://bugzilla.kernel.org/show_bug.cgi?id=7303 Use a mutex instead of a spinlock for locking the hotplug list because we need to call into the ACPI subsystem which might sleep. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Len Brown --- drivers/acpi/dock.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 578b99b71d9c..c7df2a1ea9d7 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -44,7 +44,7 @@ struct dock_station { unsigned long last_dock_time; u32 flags; spinlock_t dd_lock; - spinlock_t hp_lock; + struct mutex hp_lock; struct list_head dependent_devices; struct list_head hotplug_devices; }; @@ -114,9 +114,9 @@ static void dock_add_hotplug_device(struct dock_station *ds, struct dock_dependent_device *dd) { - spin_lock(&ds->hp_lock); + mutex_lock(&ds->hp_lock); list_add_tail(&dd->hotplug_list, &ds->hotplug_devices); - spin_unlock(&ds->hp_lock); + mutex_unlock(&ds->hp_lock); } /** @@ -130,9 +130,9 @@ static void dock_del_hotplug_device(struct dock_station *ds, struct dock_dependent_device *dd) { - spin_lock(&ds->hp_lock); + mutex_lock(&ds->hp_lock); list_del(&dd->hotplug_list); - spin_unlock(&ds->hp_lock); + mutex_unlock(&ds->hp_lock); } /** @@ -295,7 +295,7 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) { struct dock_dependent_device *dd; - spin_lock(&ds->hp_lock); + mutex_lock(&ds->hp_lock); /* * First call driver specific hotplug functions @@ -317,7 +317,7 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) else dock_create_acpi_device(dd->handle); } - spin_unlock(&ds->hp_lock); + mutex_unlock(&ds->hp_lock); } static void dock_event(struct dock_station *ds, u32 event, int num) @@ -625,7 +625,7 @@ static int dock_add(acpi_handle handle) INIT_LIST_HEAD(&dock_station->dependent_devices); INIT_LIST_HEAD(&dock_station->hotplug_devices); spin_lock_init(&dock_station->dd_lock); - spin_lock_init(&dock_station->hp_lock); + mutex_init(&dock_station->hp_lock); ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); /* Find dependent devices */ -- cgit v1.2.3-59-g8ed1b From 9185cfa92507d07ac787bc73d06c42222eec7239 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 1 Nov 2006 13:23:14 +0100 Subject: ACPI: S4: Use "platform" rather than "shutdown" mode by default It has been reported that on some systems the functionality after a resume from disk is limited if the system is simply powered off during the suspend instead of using the ACPI S4 suspend (aka platform mode). Unfortunately the default is currently to power off the system during the suspend so the users of these systems experience problems after the resume if they don't switch to the platform mode explicitly. This patch makes swsusp use the platform mode by default to avoid such situations. Signed-off-by: Rafael J. Wysocki Acked-by: Stefan Seyfried Acked-by: Pavel Machek Signed-off-by: Len Brown --- kernel/power/disk.c | 8 +++++--- kernel/power/main.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/kernel/power/disk.c b/kernel/power/disk.c index d3a158a60312..ae6bbc903b7d 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -44,9 +44,11 @@ static void power_down(suspend_disk_method_t mode) switch(mode) { case PM_DISK_PLATFORM: - kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); - error = pm_ops->enter(PM_SUSPEND_DISK); - break; + if (pm_ops && pm_ops->enter) { + kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); + error = pm_ops->enter(PM_SUSPEND_DISK); + break; + } case PM_DISK_SHUTDOWN: kernel_power_off(); break; diff --git a/kernel/power/main.c b/kernel/power/main.c index 873228c71dab..1210961a5aa7 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -27,7 +27,7 @@ DECLARE_MUTEX(pm_sem); struct pm_ops *pm_ops; -suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN; +suspend_disk_method_t pm_disk_mode = PM_DISK_PLATFORM; /** * pm_set_ops - Set the global power method table. -- cgit v1.2.3-59-g8ed1b From 6b15484ccb91e85100cf164067bf3bc6c5038726 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 2 Nov 2006 13:13:22 +0100 Subject: ACPI: Get rid of 'unused variable' warning in acpi_ev_global_lock_handler() Fix this warning : drivers/acpi/events/evmisc.c: In function `acpi_ev_global_lock_handler': drivers/acpi/events/evmisc.c:334: warning: unused variable `status' Signed-off-by: Jesper Juhl Signed-off-by: Len Brown --- drivers/acpi/events/evmisc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index ee2a10bf9077..bf63edc6608d 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -331,7 +331,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context) static u32 acpi_ev_global_lock_handler(void *context) { u8 acquired = FALSE; - acpi_status status; /* * Attempt to get the lock -- cgit v1.2.3-59-g8ed1b From b7b09b1cdf4de7e28424250972d4a5526e5bdfb9 Mon Sep 17 00:00:00 2001 From: Satoru Takeuchi Date: Thu, 2 Nov 2006 19:08:57 +0900 Subject: ACPI: update comment Fixing wrong description for acpi_gpe_sleep_prepare(). acpi_gpe_sleep_prepare() had only used on power off and was changed to also used on entering some sleep state. However its description isn't changed yet. Signed-off-by: Satoru Takeuchi Signed-off-by: Len Brown --- drivers/acpi/sleep/wakeup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index af1dbabaf0b1..fab8f2694f03 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c @@ -183,11 +183,11 @@ late_initcall(acpi_wakeup_device_init); #endif /* - * Disable all wakeup GPEs before power off. - * + * Disable all wakeup GPEs before entering requested sleep state. + * @sleep_state: ACPI state * Since acpi_enter_sleep_state() will disable all * RUNTIME GPEs, we simply mark all GPES that - * are not enabled for wakeup from S5 as RUNTIME. + * are not enabled for wakeup from requested state as RUNTIME. */ void acpi_gpe_sleep_prepare(u32 sleep_state) { -- cgit v1.2.3-59-g8ed1b From c0968f0ea21d10b6720246e1e96bd6a7a161964d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 9 Nov 2006 00:40:13 -0500 Subject: ACPI: button: register with input layer In addition to signalling button/lid events through /proc/acpi/event, create separate input devices and report KEY_POWER, KEY_SLEEP and SW_LID through input layer. Also remove unnecessary casts and variable initializations, clean up formatting. Sleep button may autorepeat but userspace will have to filter duplicate sleep requests anyway (and discard unprocessed events right after wakeup). Unlike /proc/acpi/event interface input device corresponding to LID switch reports true lid state instead of just a counter. SW_LID is active when lid is closed. The driver now depends on CONFIG_INPUT. Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 1 + drivers/acpi/button.c | 223 +++++++++++++++++++++++++++++++------------------- 2 files changed, 139 insertions(+), 85 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 0f9d4be7ed75..0ed801229675 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -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. diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 5ef885e82c78..ac860583c203 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -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 = - acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, - acpi_button_notify_fixed); - break; - default: - status = acpi_remove_notify_handler(device->handle, - ACPI_DEVICE_NOTIFY, - acpi_button_notify); - break; - } - + acpi_button_remove_notify_handlers(button); acpi_button_remove_fs(device); - + input_unregister_device(button->input); kfree(button); return 0; @@ -433,8 +490,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) static int __init acpi_button_init(void) { - int result = 0; - + int result; acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); if (!acpi_button_dir) @@ -451,7 +507,6 @@ static int __init acpi_button_init(void) static void __exit acpi_button_exit(void) { - acpi_bus_unregister_driver(&acpi_button_driver); if (acpi_power_dir) @@ -461,8 +516,6 @@ static void __exit acpi_button_exit(void) if (acpi_lid_dir) remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); - - return; } module_init(acpi_button_init); -- cgit v1.2.3-59-g8ed1b From 7d63c6759188b9b35c789159f6e02cd02d49ec7d Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 8 Nov 2006 13:18:29 -0200 Subject: ACPI: ibm-acpi: new ibm-acpi maintainer I will be taking care of ibm-acpi maintenance for now on, with Borislav's blessing. Many thanks to Borislav Deianov for writing this driver and for the many years he took care of it: his efforts made our ThinkPads much nicer devices to run Linux on, and are very much appreciated. Signed-off-by: Henrique de Moraes Holschuh Cc: Borislav Deianov Signed-off-by: Len Brown --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d708702aba2f..bd4d5dfa65f0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1369,6 +1369,15 @@ W: http://www.ia64-linux.org/ T: git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git S: Maintained +IBM ACPI EXTRAS DRIVER +P: Henrique de Moraes Holschuh +M: ibm-acpi@hmh.eng.br +L: ibm-acpi-devel@lists.sourceforge.net +W: http://ibm-acpi.sourceforge.net +W: http://thinkwiki.org/wiki/Ibm-acpi +T: git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git +S: Maintained + SN-IA64 (Itanium) SUB-PLATFORM P: Jes Sorensen M: jes@sgi.com -- cgit v1.2.3-59-g8ed1b From 3dfd35cd214f7874c4917dfedff81f107d845c15 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 10:32:32 -0200 Subject: ACPI: ibm-acpi: do not use / in driver names ibm-acpi uses sub-device names like ibm/hotkey, which get in the way of a sysfs conversion. Fix it to use ibm_hotkey instead. Thanks to Zhang Rui for noticing this. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index cd8722e4157e..ce69f7592a22 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1854,7 +1854,7 @@ static int __init register_driver(struct ibm_struct *ibm) } memset(ibm->driver, 0, sizeof(struct acpi_driver)); - sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name); + sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name); ibm->driver->ids = ibm->hid; ibm->driver->ops.add = &ibm_device_add; -- cgit v1.2.3-59-g8ed1b From 8d29726434697a5ed08d4e0dfba9399a098922f4 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:07 -0200 Subject: ACPI: ibm-acpi: trivial Lindent cleanups This patch just makes drives/acpi/ibm-acpi.c Lindent-clean, as requested by Len Brown. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index ce69f7592a22..b81a95d2067c 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -584,8 +584,7 @@ static int wan_status(void) { int status; - if (!wan_supported || - !acpi_evalf(hkey_handle, &status, "GWAN", "d")) + if (!wan_supported || !acpi_evalf(hkey_handle, &status, "GWAN", "d")) status = 0; return status; @@ -910,6 +909,7 @@ static int _sta(acpi_handle handle) return status; } + #ifdef CONFIG_ACPI_IBM_DOCK #define dock_docked() (_sta(dock_handle) & 1) @@ -1386,12 +1386,12 @@ static int brightness_offset = 0x31; static int brightness_get(struct backlight_device *bd) { - u8 level; - if (!acpi_ec_read(brightness_offset, &level)) - return -EIO; + u8 level; + if (!acpi_ec_read(brightness_offset, &level)) + return -EIO; - level &= 0x7; - return level; + level &= 0x7; + return level; } static int brightness_read(char *p) @@ -1993,10 +1993,10 @@ IBM_PARAM(volume); IBM_PARAM(fan); static struct backlight_properties ibm_backlight_data = { - .owner = THIS_MODULE, - .get_brightness = brightness_get, - .update_status = brightness_update_status, - .max_brightness = 7, + .owner = THIS_MODULE, + .get_brightness = brightness_get, + .update_status = brightness_update_status, + .max_brightness = 7, }; static void acpi_ibm_exit(void) @@ -2075,7 +2075,7 @@ static int __init acpi_ibm_init(void) ibm_backlight_device = backlight_device_register("ibm", NULL, &ibm_backlight_data); - if (IS_ERR(ibm_backlight_device)) { + if (IS_ERR(ibm_backlight_device)) { printk(IBM_ERR "Could not register ibm backlight device\n"); ibm_backlight_device = NULL; acpi_ibm_exit(); -- cgit v1.2.3-59-g8ed1b From a26f878abcd0491906b5bbac8dd174f27019e907 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:08 -0200 Subject: ACPI: ibm-acpi: Use a enum to select the thermal sensor reading strategy This patch consolidades all decisions regarding the strategy to be used to read thinkpad thermal sensors into a single enum, and refactors the thermal sensor reading code to use a much more readable (and easier to extend) switch() construct, in a separate function. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 90 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 25 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index b81a95d2067c..baf9492f0a79 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -217,6 +217,17 @@ IBM_HANDLE(sfan, ec, "SFAN", /* 570 */ #define IBM_HKEY_HID "IBM0068" #define IBM_PCI_HID "PNP0A03" +enum thermal_access_mode { + IBMACPI_THERMAL_NONE = 0, /* No thermal support */ + IBMACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */ + IBMACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */ +}; + +#define IBMACPI_MAX_THERMAL_SENSORS 8 /* Max thermal sensors supported */ +struct ibm_thermal_sensors_struct { + s32 temp[IBMACPI_MAX_THERMAL_SENSORS]; +}; + struct ibm_struct { char *name; char param[32]; @@ -1275,50 +1286,79 @@ static int acpi_ec_write(int i, u8 v) return 1; } -static int thermal_tmp_supported; -static int thermal_updt_supported; +static enum thermal_access_mode thermal_read_mode; static int thermal_init(void) { - /* temperatures not supported on 570, G4x, R30, R31, R32 */ - thermal_tmp_supported = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); - - /* 600e/x, 770e, 770x */ - thermal_updt_supported = acpi_evalf(ec_handle, NULL, "UPDT", "qv"); + if (acpi_evalf(ec_handle, NULL, "TMP7", "qv")) { + if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) { + /* 600e/x, 770e, 770x */ + thermal_read_mode = IBMACPI_THERMAL_ACPI_UPDT; + } else { + /* Standard ACPI TMPx access, max 8 sensors */ + thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07; + } + } else { + /* temperatures not supported on 570, G4x, R30, R31, R32 */ + thermal_read_mode = IBMACPI_THERMAL_NONE; + } return 0; } -static int thermal_read(char *p) +static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) { - int len = 0; + int i, t; + char tmpi[] = "TMPi"; - if (!thermal_tmp_supported) - len += sprintf(p + len, "temperatures:\tnot supported\n"); - else { - int i, t; - char tmpi[] = "TMPi"; - s8 tmp[8]; + if (!s) + return -EINVAL; - if (thermal_updt_supported) - if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) + switch (thermal_read_mode) { + case IBMACPI_THERMAL_ACPI_UPDT: + if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) + return -EIO; + for (i = 0; i < 8; i++) { + tmpi[3] = '0' + i; + if (!acpi_evalf(ec_handle, &t, tmpi, "d")) return -EIO; + s->temp[i] = (t - 2732) * 100; + } + return 8; + case IBMACPI_THERMAL_ACPI_TMP07: for (i = 0; i < 8; i++) { tmpi[3] = '0' + i; if (!acpi_evalf(ec_handle, &t, tmpi, "d")) return -EIO; - if (thermal_updt_supported) - tmp[i] = (t - 2732 + 5) / 10; - else - tmp[i] = t; + s->temp[i] = t * 1000; } + return 8; - len += sprintf(p + len, - "temperatures:\t%d %d %d %d %d %d %d %d\n", - tmp[0], tmp[1], tmp[2], tmp[3], - tmp[4], tmp[5], tmp[6], tmp[7]); + case IBMACPI_THERMAL_NONE: + default: + return 0; } +} + +static int thermal_read(char *p) +{ + int len = 0; + int n, i; + struct ibm_thermal_sensors_struct t; + + n = thermal_get_sensors(&t); + if (unlikely(n < 0)) + return n; + + len += sprintf(p + len, "temperatures:\t"); + + if (n > 0) { + for (i = 0; i < (n - 1); i++) + len += sprintf(p + len, "%d ", t.temp[i] / 1000); + len += sprintf(p + len, "%d\n", t.temp[i] / 1000); + } else + len += sprintf(p + len, "not supported\n"); return len; } -- cgit v1.2.3-59-g8ed1b From 60eb0b35a9cc3400251cb4028d100e350649cf8a Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:08 -0200 Subject: ACPI: ibm-acpi: Implement direct-ec-access thermal reading modes for up to 16 sensors This patch extends ibm-acpi to support reading thermal sensors directly through ACPI EC register access. It uses a DMI match to detect ThinkPads with a new-style embedded controller, that are known to have forward- compatible register maps and use 0x00 to fill in non-used registers and export thermal sensors at EC offsets 0x78-7F and 0xC0-C7. Direct ACPI EC register access is implemented for 8-sensor and 16-sensor new-style ThinkPad controller firmwares as an experimental feature. The code does some limited sanity checks on the temperatures read through EC access, and will default to the old ACPI TMP0-7 mode if anything is amiss. Userspace ABI is not changed for 8 sensors, but /proc/acpi/ibm/thermal is extended for 16 sensors if the firmware supports 16 sensors. A documentation update is also provided. The information about the ThinkPad register map was determined by studying ibm-acpi "ecdump" output from various ThinkPad models, submitted by subscribers of the linux-thinkpad mailinglist. Futher information was gathered from the DSDT tables, as they describe the EC register map in recent ThinkPads. DSDT source shows that TMP0-7 access and direct register access are actually the same thing on these firmwares, but unfortunately IBM never did update their DSDT EC register map to export TMP8-TMP15 for the second range of sensors. Signed-off-by: Henrique de Moraes Holschuh --- Documentation/ibm-acpi.txt | 55 +++++++++++++++++++++------ drivers/acpi/ibm_acpi.c | 93 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 14 deletions(-) diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt index e50595bfd8ea..30f09e7a423e 100644 --- a/Documentation/ibm-acpi.txt +++ b/Documentation/ibm-acpi.txt @@ -398,25 +398,56 @@ Temperature sensors -- /proc/acpi/ibm/thermal Most ThinkPads include six or more separate temperature sensors but only expose the CPU temperature through the standard ACPI methods. -This feature shows readings from up to eight different sensors. Some -readings may not be valid, e.g. may show large negative values. For -example, on the X40, a typical output may be: +This feature shows readings from up to eight different sensors on older +ThinkPads, and it has experimental support for up to sixteen different +sensors on newer ThinkPads. Readings from sensors that are not available +return -128. +No commands can be written to this file. + +EXPERIMENTAL: The 16-sensors feature is marked EXPERIMENTAL because the +implementation directly accesses hardware registers and may not work as +expected. USE WITH CAUTION! To use this feature, you need to supply the +experimental=1 parameter when loading the module. When EXPERIMENTAL +mode is enabled, reading the first 8 sensors on newer ThinkPads will +also use an new experimental thermal sensor access mode. + +For example, on the X40, a typical output may be: temperatures: 42 42 45 41 36 -128 33 -128 -Thomas Gruber took his R51 apart and traced all six active sensors in -his laptop (the location of sensors may vary on other models): +EXPERIMENTAL: On the T43/p, a typical output may be: +temperatures: 48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128 + +The mapping of thermal sensors to physical locations varies depending on +system-board model (and thus, on ThinkPad model). + +http://thinkwiki.org/wiki/Thermal_Sensors is a public wiki page that +tries to track down these locations for various models. + +Most (newer?) models seem to follow this pattern: 1: CPU -2: Mini PCI Module -3: HDD +2: (depends on model) +3: (depends on model) 4: GPU -5: Battery -6: N/A -7: Battery -8: N/A +5: Main battery: main sensor +6: Bay battery: main sensor +7: Main battery: secondary sensor +8: Bay battery: secondary sensor +9-15: (depends on model) + +For the R51 (source: Thomas Gruber): +2: Mini-PCI +3: Internal HDD + +For the T43, T43/p (source: Shmidoax/Thinkwiki.org) +http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p +2: System board, left side (near PCMCIA slot), reported as HDAPS temp +3: PCMCIA slot +9: MCH (northbridge) to DRAM Bus +10: ICH (southbridge), under Mini-PCI card, under touchpad +11: Power regulator, underside of system board, below F2 key -No commands can be written to this file. EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump ------------------------------------------------------------------------ diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index baf9492f0a79..1703c617c0e8 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -80,6 +80,7 @@ #include #include #include +#include #include #include @@ -221,13 +222,17 @@ enum thermal_access_mode { IBMACPI_THERMAL_NONE = 0, /* No thermal support */ IBMACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */ IBMACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */ + IBMACPI_THERMAL_TPEC_8, /* Use ACPI EC regs, 8 sensors */ + IBMACPI_THERMAL_TPEC_16, /* Use ACPI EC regs, 16 sensors */ }; -#define IBMACPI_MAX_THERMAL_SENSORS 8 /* Max thermal sensors supported */ +#define IBMACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */ struct ibm_thermal_sensors_struct { s32 temp[IBMACPI_MAX_THERMAL_SENSORS]; }; +static int ibm_thinkpad_ec_found; + struct ibm_struct { char *name; char param[32]; @@ -1290,7 +1295,52 @@ static enum thermal_access_mode thermal_read_mode; static int thermal_init(void) { - if (acpi_evalf(ec_handle, NULL, "TMP7", "qv")) { + u8 t, ta1, ta2; + int i; + int acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); + + if (ibm_thinkpad_ec_found && experimental) { + /* + * Direct EC access mode: sensors at registers + * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for + * non-implemented, thermal sensors return 0x80 when + * not available + */ + + ta1 = ta2 = 0; + for (i = 0; i < 8; i++) { + if (likely(acpi_ec_read(0x78 + i, &t))) { + ta1 |= t; + } else { + ta1 = 0; + break; + } + if (likely(acpi_ec_read(0xC0 + i, &t))) { + ta2 |= t; + } else { + ta1 = 0; + break; + } + } + if (ta1 == 0) { + /* This is sheer paranoia, but we handle it anyway */ + if (acpi_tmp7) { + printk(IBM_ERR + "ThinkPad ACPI EC access misbehaving, " + "falling back to ACPI TMPx access mode\n"); + thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07; + } else { + printk(IBM_ERR + "ThinkPad ACPI EC access misbehaving, " + "disabling thermal sensors access\n"); + thermal_read_mode = IBMACPI_THERMAL_NONE; + } + } else { + thermal_read_mode = + (ta2 != 0) ? + IBMACPI_THERMAL_TPEC_16 : IBMACPI_THERMAL_TPEC_8; + } + } else if (acpi_tmp7) { if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) { /* 600e/x, 770e, 770x */ thermal_read_mode = IBMACPI_THERMAL_ACPI_UPDT; @@ -1309,12 +1359,30 @@ static int thermal_init(void) static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) { int i, t; + s8 tmp; char tmpi[] = "TMPi"; if (!s) return -EINVAL; switch (thermal_read_mode) { +#if IBMACPI_MAX_THERMAL_SENSORS >= 16 + case IBMACPI_THERMAL_TPEC_16: + for (i = 0; i < 8; i++) { + if (!acpi_ec_read(0xC0 + i, &tmp)) + return -EIO; + s->temp[i + 8] = tmp * 1000; + } + /* fallthrough */ +#endif + case IBMACPI_THERMAL_TPEC_8: + for (i = 0; i < 8; i++) { + if (!acpi_ec_read(0x78 + i, &tmp)) + return -EIO; + s->temp[i] = tmp * 1000; + } + return (thermal_read_mode == IBMACPI_THERMAL_TPEC_16) ? 16 : 8; + case IBMACPI_THERMAL_ACPI_UPDT: if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) return -EIO; @@ -2052,6 +2120,24 @@ static void acpi_ibm_exit(void) remove_proc_entry(IBM_DIR, acpi_root_dir); } +static int __init check_dmi_for_ec(void) +{ + struct dmi_device *dev = NULL; + + /* + * ThinkPad T23 or newer, A31 or newer, R50e or newer, + * X32 or newer, all Z series; Some models must have an + * up-to-date BIOS or they will not be detected. + * + * See http://thinkwiki.org/wiki/List_of_DMI_IDs + */ + while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { + if (strstr(dev->name, "IBM ThinkPad Embedded Controller")) + return 1; + } + return 0; +} + static int __init acpi_ibm_init(void) { int ret, i; @@ -2071,6 +2157,9 @@ static int __init acpi_ibm_init(void) return -ENODEV; } + /* Models with newer firmware report the EC in DMI */ + ibm_thinkpad_ec_found = check_dmi_for_ec(); + /* these handles are not required */ IBM_HANDLE_INIT(vid); IBM_HANDLE_INIT(vid2); -- cgit v1.2.3-59-g8ed1b From 88679a15b3a84366e90cee2a84973abef962b727 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:09 -0200 Subject: ACPI: ibm-acpi: document thermal sensor locations for the A31 The A31 has a very atypical layout, so I separated its thermal sensors location in a separate patch. Signed-off-by: Henrique de Moraes Holschuh --- Documentation/ibm-acpi.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt index 30f09e7a423e..333b8eb97f96 100644 --- a/Documentation/ibm-acpi.txt +++ b/Documentation/ibm-acpi.txt @@ -448,6 +448,17 @@ http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p 10: ICH (southbridge), under Mini-PCI card, under touchpad 11: Power regulator, underside of system board, below F2 key +The A31 has a very atypical layout for the thermal sensors +(source: Milos Popovic, http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_A31) +1: CPU +2: Main Battery: main sensor +3: Power Converter +4: Bay Battery: main sensor +5: MCH (northbridge) +6: PCMCIA/ambient +7: Main Battery: secondary sensor +8: Bay Battery: secondary sensor + EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump ------------------------------------------------------------------------ -- cgit v1.2.3-59-g8ed1b From 69ba91cbd6d79aa197adbdd10a44e71c84044b44 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:09 -0200 Subject: ACPI: ibm-acpi: prepare to cleanup fan_read and fan_write This patch lays some groundwork for a fan_read and fan_write cleanup in the next patches. To do so, it provides a new fan_init initializer, and also some constants (through enums). Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 1703c617c0e8..7d0bd61eebc7 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -231,6 +231,31 @@ struct ibm_thermal_sensors_struct { s32 temp[IBMACPI_MAX_THERMAL_SENSORS]; }; +enum fan_status_access_mode { + IBMACPI_FAN_NONE = 0, /* No fan status or control */ + IBMACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */ + IBMACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */ +}; + +enum fan_control_access_mode { + IBMACPI_FAN_WR_NONE = 0, /* No fan control */ + IBMACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */ + IBMACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */ + IBMACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */ +}; + +enum fan_control_commands { + IBMACPI_FAN_CMD_SPEED = 0x0001, /* speed command */ + IBMACPI_FAN_CMD_LEVEL = 0x0002, /* level command */ + IBMACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd */ +}; + +enum { /* Fan control constants */ + fan_status_offset = 0x2f, /* EC register 0x2f */ + fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) + * 0x84 must be read before 0x85 */ +}; + static int ibm_thinkpad_ec_found; struct ibm_struct { @@ -1659,8 +1684,59 @@ static int volume_write(char *buf) return 0; } -static int fan_status_offset = 0x2f; -static int fan_rpm_offset = 0x84; +static enum fan_status_access_mode fan_status_access_mode; +static enum fan_control_access_mode fan_control_access_mode; +static enum fan_control_commands fan_control_commands; + +static int fan_init(void) +{ + u8 status; + + fan_status_access_mode = IBMACPI_FAN_NONE; + fan_control_access_mode = IBMACPI_FAN_WR_NONE; + fan_control_commands = 0; + + if (gfan_handle) { + /* 570, 600e/x, 770e, 770x */ + fan_status_access_mode = IBMACPI_FAN_RD_ACPI_GFAN; + } else { + /* all other ThinkPads: note that even old-style + * ThinkPad ECs supports the fan control register */ + if (likely(acpi_ec_read(fan_status_offset, &status))) { + fan_status_access_mode = IBMACPI_FAN_RD_TPEC; + } else { + printk(IBM_ERR + "ThinkPad ACPI EC access misbehaving, " + "fan status and control unavailable\n"); + return 0; + } + } + + if (sfan_handle) { + /* 570, 770x-JL */ + fan_control_access_mode = IBMACPI_FAN_WR_ACPI_SFAN; + fan_control_commands |= IBMACPI_FAN_CMD_LEVEL; + } else { + if (!gfan_handle) { + /* gfan without sfan means no fan control */ + /* all other models implement TP EC 0x2f control */ + + if (fans_handle) { + /* X31, X40 */ + fan_control_access_mode = + IBMACPI_FAN_WR_ACPI_FANS; + fan_control_commands |= + IBMACPI_FAN_CMD_SPEED | + IBMACPI_FAN_CMD_ENABLE; + } else { + fan_control_access_mode = IBMACPI_FAN_WR_TPEC; + fan_control_commands |= IBMACPI_FAN_CMD_ENABLE; + } + } + } + + return 0; +} static int fan_read(char *p) { @@ -1849,6 +1925,7 @@ static struct ibm_struct ibms[] = { .name = "fan", .read = fan_read, .write = fan_write, + .init = fan_init, .experimental = 1, }, }; -- cgit v1.2.3-59-g8ed1b From 3ef8a6096ca98d45a54999a97c7c8e14977d2e3e Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:10 -0200 Subject: ACPI: ibm-acpi: clean up fan_read This patch cleans up fan_read so that it is much easier to read and extend. The patch fixes the userspace ABI to return "status: not supported" (like all other ibm-acpi functions) when neither fan status or fan control are possible. It also fixes the userspace ABI to return EIO if ACPI access to the EC fails, instead of returning "status: unreadable" or "speed: unreadable". Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 7d0bd61eebc7..e8de5e349d21 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1741,40 +1741,48 @@ static int fan_init(void) static int fan_read(char *p) { int len = 0; - int s; u8 lo, hi, status; - if (gfan_handle) { + switch (fan_status_access_mode) { + case IBMACPI_FAN_RD_ACPI_GFAN: /* 570, 600e/x, 770e, 770x */ - if (!acpi_evalf(gfan_handle, &s, NULL, "d")) + if (unlikely(!acpi_evalf(gfan_handle, &status, NULL, "d"))) return -EIO; - len += sprintf(p + len, "level:\t\t%d\n", s); - } else { + len += sprintf(p + len, "level:\t\t%d\n", status); + + break; + + case IBMACPI_FAN_RD_TPEC: /* all except 570, 600e/x, 770e, 770x */ - if (!acpi_ec_read(fan_status_offset, &status)) - len += sprintf(p + len, "status:\t\tunreadable\n"); + if (unlikely(!acpi_ec_read(fan_status_offset, &status))) + return -EIO; else len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 7)); - if (!acpi_ec_read(fan_rpm_offset, &lo) || - !acpi_ec_read(fan_rpm_offset + 1, &hi)) - len += sprintf(p + len, "speed:\t\tunreadable\n"); + if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || + !acpi_ec_read(fan_rpm_offset + 1, &hi))) + return -EIO; else len += sprintf(p + len, "speed:\t\t%d\n", (hi << 8) + lo); + + break; + + case IBMACPI_FAN_NONE: + default: + len += sprintf(p + len, "status:\t\tnot supported\n"); } - if (sfan_handle) - /* 570, 770x-JL */ + if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) len += sprintf(p + len, "commands:\tlevel " " ( is 0-7)\n"); - if (!gfan_handle) - /* all except 570, 600e/x, 770e, 770x */ + + if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE) len += sprintf(p + len, "commands:\tenable, disable\n"); - if (fans_handle) - /* X31, X40 */ + + if (fan_control_commands & IBMACPI_FAN_CMD_SPEED) len += sprintf(p + len, "commands:\tspeed " " ( is 0-65535)\n"); -- cgit v1.2.3-59-g8ed1b From c52f0aa574246f133a0bc2041e9468a06d34da7b Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:10 -0200 Subject: ACPI: ibm-acpi: break fan_read into separate functions This patch breaks fan_read mechanics into a generic function to get fan status and speed, and leaves only the procfs interface code in fan_read. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 78 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index e8de5e349d21..9275dfc130f2 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1738,36 +1738,90 @@ static int fan_init(void) return 0; } -static int fan_read(char *p) +static int fan_get_status(u8 *status) { - int len = 0; - u8 lo, hi, status; + u8 s; switch (fan_status_access_mode) { case IBMACPI_FAN_RD_ACPI_GFAN: /* 570, 600e/x, 770e, 770x */ - if (unlikely(!acpi_evalf(gfan_handle, &status, NULL, "d"))) + + if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) return -EIO; - len += sprintf(p + len, "level:\t\t%d\n", status); + if (likely(status)) + *status = s & 0x07; break; case IBMACPI_FAN_RD_TPEC: /* all except 570, 600e/x, 770e, 770x */ - if (unlikely(!acpi_ec_read(fan_status_offset, &status))) + if (unlikely(!acpi_ec_read(fan_status_offset, &s))) return -EIO; - else - len += sprintf(p + len, "status:\t\t%s\n", - enabled(status, 7)); + if (likely(status)) + *status = s; + + break; + + default: + return -ENXIO; + } + + return 0; +} + +static int fan_get_speed(unsigned int *speed) +{ + u8 hi, lo; + + switch (fan_status_access_mode) { + case IBMACPI_FAN_RD_TPEC: + /* all except 570, 600e/x, 770e, 770x */ if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || !acpi_ec_read(fan_rpm_offset + 1, &hi))) return -EIO; - else - len += sprintf(p + len, "speed:\t\t%d\n", - (hi << 8) + lo); + if (likely(speed)) + *speed = (hi << 8) | lo; + + break; + + default: + return -ENXIO; + } + + return 0; +} + +static int fan_read(char *p) +{ + int len = 0; + int rc; + u8 status; + unsigned int speed = 0; + + switch (fan_status_access_mode) { + case IBMACPI_FAN_RD_ACPI_GFAN: + /* 570, 600e/x, 770e, 770x */ + if ((rc = fan_get_status(&status)) < 0) + return rc; + + len += sprintf(p + len, "level:\t\t%d\n", status); + + break; + + case IBMACPI_FAN_RD_TPEC: + /* all except 570, 600e/x, 770e, 770x */ + if ((rc = fan_get_status(&status)) < 0) + return rc; + + len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 7)); + + if ((rc = fan_get_speed(&speed)) < 0) + return rc; + + len += sprintf(p + len, "speed:\t\t%d\n", speed); break; case IBMACPI_FAN_NONE: -- cgit v1.2.3-59-g8ed1b From 18ad7996e17649d81c15a2c9dae03c75050a05a8 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:11 -0200 Subject: ACPI: ibm-acpi: cleanup fan_write This patch cleans up fan_write so that it is much easier to read and extend. It separates the proc api handling from the operations themselves. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 147 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 125 insertions(+), 22 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 9275dfc130f2..187af1bfcb9d 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1843,40 +1843,143 @@ static int fan_read(char *p) return len; } -static int fan_write(char *buf) +static int fan_set_level(int level) { - char *cmd; - int level, speed; - - while ((cmd = next_cmd(&buf))) { - if (sfan_handle && - sscanf(cmd, "level %d", &level) == 1 && - level >= 0 && level <= 7) { - /* 570, 770x-JL */ + switch (fan_control_access_mode) { + case IBMACPI_FAN_WR_ACPI_SFAN: + if (level >= 0 && level <= 7) { if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) return -EIO; - } else if (!gfan_handle && strlencmp(cmd, "enable") == 0) { - /* all except 570, 600e/x, 770e, 770x */ - if (!acpi_ec_write(fan_status_offset, 0x80)) - return -EIO; - } else if (!gfan_handle && strlencmp(cmd, "disable") == 0) { - /* all except 570, 600e/x, 770e, 770x */ - if (!acpi_ec_write(fan_status_offset, 0x00)) - return -EIO; - } else if (fans_handle && - sscanf(cmd, "speed %d", &speed) == 1 && - speed >= 0 && speed <= 65535) { - /* X31, X40 */ + } else + return -EINVAL; + break; + + default: + return -ENXIO; + } + return 0; +} + +static int fan_set_enable(void) +{ + switch (fan_control_access_mode) { + case IBMACPI_FAN_WR_ACPI_FANS: + case IBMACPI_FAN_WR_TPEC: + if (!acpi_ec_write(fan_status_offset, 0x80)) + return -EIO; + break; + + default: + return -ENXIO; + } + return 0; +} + +static int fan_set_disable(void) +{ + switch (fan_control_access_mode) { + case IBMACPI_FAN_WR_ACPI_FANS: + case IBMACPI_FAN_WR_TPEC: + if (!acpi_ec_write(fan_status_offset, 0x00)) + return -EIO; + break; + + default: + return -ENXIO; + } + return 0; +} + +static int fan_set_speed(int speed) +{ + switch (fan_control_access_mode) { + case IBMACPI_FAN_WR_ACPI_FANS: + if (speed >= 0 && speed <= 65535) { if (!acpi_evalf(fans_handle, NULL, NULL, "vddd", speed, speed, speed)) return -EIO; } else return -EINVAL; - } + break; + default: + return -ENXIO; + } return 0; } +static int fan_write_cmd_level(const char *cmd, int *rc) +{ + int level; + + if (sscanf(cmd, "level %d", &level) != 1) + return 0; + + if ((*rc = fan_set_level(level)) == -ENXIO) + printk(IBM_ERR "level command accepted for unsupported " + "access mode %d", fan_control_access_mode); + + return 1; +} + +static int fan_write_cmd_enable(const char *cmd, int *rc) +{ + if (strlencmp(cmd, "enable") != 0) + return 0; + + if ((*rc = fan_set_enable()) == -ENXIO) + printk(IBM_ERR "enable command accepted for unsupported " + "access mode %d", fan_control_access_mode); + + return 1; +} + +static int fan_write_cmd_disable(const char *cmd, int *rc) +{ + if (strlencmp(cmd, "disable") != 0) + return 0; + + if ((*rc = fan_set_disable()) == -ENXIO) + printk(IBM_ERR "disable command accepted for unsupported " + "access mode %d", fan_control_access_mode); + + return 1; +} + +static int fan_write_cmd_speed(const char *cmd, int *rc) +{ + int speed; + + if (sscanf(cmd, "speed %d", &speed) != 1) + return 0; + + if ((*rc = fan_set_speed(speed)) == -ENXIO) + printk(IBM_ERR "speed command accepted for unsupported " + "access mode %d", fan_control_access_mode); + + return 1; +} + +static int fan_write(char *buf) +{ + char *cmd; + int rc = 0; + + while (!rc && (cmd = next_cmd(&buf))) { + if (!((fan_control_commands & IBMACPI_FAN_CMD_LEVEL) && + fan_write_cmd_level(cmd, &rc)) && + !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) && + (fan_write_cmd_enable(cmd, &rc) || + fan_write_cmd_disable(cmd, &rc))) && + !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) && + fan_write_cmd_speed(cmd, &rc)) + ) + rc = -EINVAL; + } + + return rc; +} + static struct ibm_struct ibms[] = { { .name = "driver", -- cgit v1.2.3-59-g8ed1b From a8b7a6626d7605a795b33317cd730b7d76da3d0a Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:11 -0200 Subject: ACPI: ibm-acpi: document fan control This patch documents the ThinkPad fan control strategies. Source of the data: 0. ibm-acpi source 1. DSDTs for various ThinkPads (770, X31, X40, X41, T43, A21m, T22) 2. http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues 3. http://thinkwiki.org/wiki/How_to_control_fan_speed 4. Various threads about windows fan control utilities in thinkpads.com Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 187af1bfcb9d..faf78d3eac2d 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -205,7 +205,7 @@ IBM_HANDLE(led, ec, "SLED", /* 570 */ IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */ IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */ -IBM_HANDLE(fans, ec, "FANS"); /* X31, X40 */ +IBM_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */ IBM_HANDLE(gfan, ec, "GFAN", /* 570 */ "\\FSPD", /* 600e/x, 770e, 770x */ @@ -231,6 +231,106 @@ struct ibm_thermal_sensors_struct { s32 temp[IBMACPI_MAX_THERMAL_SENSORS]; }; +/* + * FAN ACCESS MODES + * + * IBMACPI_FAN_RD_ACPI_GFAN: + * ACPI GFAN method: returns fan level + * + * see IBMACPI_FAN_WR_ACPI_SFAN + * EC 0x2f not available if GFAN exists + * + * IBMACPI_FAN_WR_ACPI_SFAN: + * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max) + * + * EC 0x2f might be available *for reading*, but never for writing. + * + * IBMACPI_FAN_WR_TPEC: + * ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported + * on almost all ThinkPads + * + * Fan speed changes of any sort (including those caused by the + * disengaged mode) are usually done slowly by the firmware as the + * maximum ammount of fan duty cycle change per second seems to be + * limited. + * + * Reading is not available if GFAN exists. + * Writing is not available if SFAN exists. + * + * Bits + * 7 automatic mode engaged; + * (default operation mode of the ThinkPad) + * fan level is ignored in this mode. + * 6 disengage mode (takes precedence over bit 7); + * not available on all thinkpads. May disable + * the tachometer, and speeds up fan to 100% duty-cycle, + * which speeds it up far above the standard RPM + * levels. It is not impossible that it could cause + * hardware damage. + * 5-3 unused in some models. Extra bits for fan level + * in others, but still useless as all values above + * 7 map to the same speed as level 7 in these models. + * 2-0 fan level (0..7 usually) + * 0x00 = stop + * 0x07 = max (set when temperatures critical) + * Some ThinkPads may have other levels, see + * IBMACPI_FAN_WR_ACPI_FANS (X31/X40/X41) + * + * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at + * boot. Apparently the EC does not intialize it, so unless ACPI DSDT + * does so, its initial value is meaningless (0x07). + * + * For firmware bugs, refer to: + * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues + * + * ---- + * + * ThinkPad EC register 0x84 (LSB), 0x85 (MSB): + * Main fan tachometer reading (in RPM) + * + * This register is present on all ThinkPads with a new-style EC, and + * it is known not to be present on the A21m/e, and T22, as there is + * something else in offset 0x84 according to the ACPI DSDT. Other + * ThinkPads from this same time period (and earlier) probably lack the + * tachometer as well. + * + * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare + * was never fixed by IBM to report the EC firmware version string + * probably support the tachometer (like the early X models), so + * detecting it is quite hard. We need more data to know for sure. + * + * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings + * might result. + * + * FIRMWARE BUG: when EC 0x2f bit 6 is set (disengaged mode), this + * register is not invalidated in ThinkPads that disable tachometer + * readings. Thus, the tachometer readings go stale. + * + * For firmware bugs, refer to: + * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues + * + * IBMACPI_FAN_WR_ACPI_FANS: + * ThinkPad X31, X40, X41. Not available in the X60. + * + * FANS ACPI handle: takes three arguments: low speed, medium speed, + * high speed. ACPI DSDT seems to map these three speeds to levels + * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH + * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3") + * + * The speeds are stored on handles + * (FANA:FAN9), (FANC:FANB), (FANE:FAND). + * + * There are three default speed sets, acessible as handles: + * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H + * + * ACPI DSDT switches which set is in use depending on various + * factors. + * + * IBMACPI_FAN_WR_TPEC is also available and should be used to + * command the fan. The X31/X40/X41 seems to have 8 fan levels, + * but the ACPI tables just mention level 7. + */ + enum fan_status_access_mode { IBMACPI_FAN_NONE = 0, /* No fan status or control */ IBMACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */ @@ -1722,7 +1822,7 @@ static int fan_init(void) /* all other models implement TP EC 0x2f control */ if (fans_handle) { - /* X31, X40 */ + /* X31, X40, X41 */ fan_control_access_mode = IBMACPI_FAN_WR_ACPI_FANS; fan_control_commands |= @@ -1742,6 +1842,9 @@ static int fan_get_status(u8 *status) { u8 s; + /* TODO: + * Add IBMACPI_FAN_RD_ACPI_FANS ? */ + switch (fan_status_access_mode) { case IBMACPI_FAN_RD_ACPI_GFAN: /* 570, 600e/x, 770e, 770x */ @@ -1950,6 +2053,9 @@ static int fan_write_cmd_speed(const char *cmd, int *rc) { int speed; + /* TODO: + * Support speed ? */ + if (sscanf(cmd, "speed %d", &speed) != 1) return 0; -- cgit v1.2.3-59-g8ed1b From bab812a329cc244ca63c2675b0e05016518855ce Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:12 -0200 Subject: ACPI: ibm-acpi: extend fan status functions This patch fixes fan_read to return correct values for all fan access modes. It also implements some fan access mode status output that was missing, and normalizes the proc fan abi to return consistent data across all fan read/write modes. Userspace ABI changes and extensions: 1. Return status: enable/disable for *all* modes (this actually improves compatibility with userspace utils!) 2. Return level: auto and level: disengaged for EC 2f access mode 3. Return level: for EC 0x2f access mode 4. Return level 0 as well as "disabled" in level-aware modes Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index faf78d3eac2d..b6ad2ed5fd6c 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -354,6 +354,11 @@ enum { /* Fan control constants */ fan_status_offset = 0x2f, /* EC register 0x2f */ fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) * 0x84 must be read before 0x85 */ + + IBMACPI_FAN_EC_DISENGAGED = 0x40, /* EC mode: tachometer + * disengaged */ + IBMACPI_FAN_EC_AUTO = 0x80, /* EC mode: auto fan + * control */ }; static int ibm_thinkpad_ec_found; @@ -1910,8 +1915,9 @@ static int fan_read(char *p) if ((rc = fan_get_status(&status)) < 0) return rc; - len += sprintf(p + len, "level:\t\t%d\n", status); - + len += sprintf(p + len, "status:\t\t%s\n" + "level:\t\t%d\n", + (status != 0) ? "enabled" : "disabled", status); break; case IBMACPI_FAN_RD_TPEC: @@ -1919,12 +1925,21 @@ static int fan_read(char *p) if ((rc = fan_get_status(&status)) < 0) return rc; - len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 7)); + len += sprintf(p + len, "status:\t\t%s\n", + (status != 0) ? "enabled" : "disabled"); if ((rc = fan_get_speed(&speed)) < 0) return rc; len += sprintf(p + len, "speed:\t\t%d\n", speed); + + if (status & IBMACPI_FAN_EC_DISENGAGED) + /* Disengaged mode takes precedence */ + len += sprintf(p + len, "level:\t\tdisengaged\n"); + else if (status & IBMACPI_FAN_EC_AUTO) + len += sprintf(p + len, "level:\t\tauto\n"); + else + len += sprintf(p + len, "level:\t\t%d\n", status); break; case IBMACPI_FAN_NONE: -- cgit v1.2.3-59-g8ed1b From 1c6a334e9c028c2b72c5350650cb14e6d5fdc232 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:12 -0200 Subject: ACPI: ibm-acpi: fix and extend fan enable This patch fix fan enable to attempt to do the right thing and not slow down the fan if it is forced to the maximum speed. It also extends fan enable to work on older thinkpads. ABI changes: 1. Support enable/disable for all level-based write access modes Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index b6ad2ed5fd6c..ecb5ece79a37 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1820,7 +1820,8 @@ static int fan_init(void) if (sfan_handle) { /* 570, 770x-JL */ fan_control_access_mode = IBMACPI_FAN_WR_ACPI_SFAN; - fan_control_commands |= IBMACPI_FAN_CMD_LEVEL; + fan_control_commands |= + IBMACPI_FAN_CMD_LEVEL | IBMACPI_FAN_CMD_ENABLE; } else { if (!gfan_handle) { /* gfan without sfan means no fan control */ @@ -1980,10 +1981,34 @@ static int fan_set_level(int level) static int fan_set_enable(void) { + u8 s; + int rc; + switch (fan_control_access_mode) { case IBMACPI_FAN_WR_ACPI_FANS: case IBMACPI_FAN_WR_TPEC: - if (!acpi_ec_write(fan_status_offset, 0x80)) + if ((rc = fan_get_status(&s)) < 0) + return rc; + + /* Don't go out of emergency fan mode */ + if (s != 7) + s = IBMACPI_FAN_EC_AUTO; + + if (!acpi_ec_write(fan_status_offset, s)) + return -EIO; + break; + + case IBMACPI_FAN_WR_ACPI_SFAN: + if ((rc = fan_get_status(&s)) < 0) + return rc; + + s &= 0x07; + + /* Set fan to at least level 4 */ + if (s < 4) + s = 4; + + if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s)) return -EIO; break; @@ -2002,6 +2027,11 @@ static int fan_set_disable(void) return -EIO; break; + case IBMACPI_FAN_WR_ACPI_SFAN: + if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00)) + return -EIO; + break; + default: return -ENXIO; } -- cgit v1.2.3-59-g8ed1b From a12095c2b50c8a7c80517e37c00d6e6c863d43c5 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:13 -0200 Subject: ACPI: ibm-acpi: fix and extend fan control functions This patch extend fan control functions, implementing enable/disable for all write access modes, implementing level control for all level-capable write access modes. The patch also updates the documentation, explaining levels auto and disengaged. ABI changes: 1. Support level 0 as an equivalent to disable 2. Add support for level auto and level disengaged when doing EC 0x2f fan control 3. Support enable/disable for all level-based write access modes 4. Add support for level command on FANS thinkpads, as per thinkwiki reports Signed-off-by: Henrique de Moraes Holschuh --- Documentation/ibm-acpi.txt | 65 ++++++++++++++++++++++++++++++++-------------- drivers/acpi/ibm_acpi.c | 39 ++++++++++++++++++++++++---- 2 files changed, 80 insertions(+), 24 deletions(-) diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt index 333b8eb97f96..cbd3a603a7ef 100644 --- a/Documentation/ibm-acpi.txt +++ b/Documentation/ibm-acpi.txt @@ -571,27 +571,57 @@ directly accesses hardware registers and may not work as expected. USE WITH CAUTION! To use this feature, you need to supply the experimental=1 parameter when loading the module. -This feature attempts to show the current fan speed. The speed is read -directly from the hardware registers of the embedded controller. This -is known to work on later R, T and X series ThinkPads but may show a -bogus value on other models. +This feature attempts to show the current fan speed, control mode and +other fan data that might be available. The speed is read directly +from the hardware registers of the embedded controller. This is known +to work on later R, T and X series ThinkPads but may show a bogus +value on other models. + +Most ThinkPad fans work in "levels". Level 0 stops the fan. The higher +the level, the higher the fan speed, although adjacent levels often map +to the same fan speed. 7 is the highest level, where the fan reaches +the maximum recommended speed. Level "auto" means the EC changes the +fan level according to some internal algorithm, usually based on +readings from the thermal sensors. Level "disengaged" means the EC +disables the speed-locked closed-loop fan control, and drives the fan as +fast as it can go, which might exceed hardware limits, so use this level +with caution. + +The fan usually ramps up or down slowly from one speed to another, +and it is normal for the EC to take several seconds to react to fan +commands. The fan may be enabled or disabled with the following commands: echo enable >/proc/acpi/ibm/fan echo disable >/proc/acpi/ibm/fan +Placing a fan on level 0 is the same as disabling it. Enabling a fan +will try to place it in a safe level if it is too slow or disabled. + WARNING WARNING WARNING: do not leave the fan disabled unless you are -monitoring the temperature sensor readings and you are ready to enable -it if necessary to avoid overheating. +monitoring all of the temperature sensor readings and you are ready to +enable it if necessary to avoid overheating. + +An enabled fan in level "auto" may stop spinning if the EC decides the +ThinkPad is cool enough and doesn't need the extra airflow. This is +normal, and the EC will spin the fan up if the varios thermal readings +rise too much. + +On the X40, this seems to depend on the CPU and HDD temperatures. +Specifically, the fan is turned on when either the CPU temperature +climbs to 56 degrees or the HDD temperature climbs to 46 degrees. The +fan is turned off when the CPU temperature drops to 49 degrees and the +HDD temperature drops to 41 degrees. These thresholds cannot +currently be controlled. + +The fan level can be controlled with the command: -The fan only runs if it's enabled *and* the various temperature -sensors which control it read high enough. On the X40, this seems to -depend on the CPU and HDD temperatures. Specifically, the fan is -turned on when either the CPU temperature climbs to 56 degrees or the -HDD temperature climbs to 46 degrees. The fan is turned off when the -CPU temperature drops to 49 degrees and the HDD temperature drops to -41 degrees. These thresholds cannot currently be controlled. + echo 'level ' > /proc/acpi/ibm/thermal + +Where is an integer from 0 to 7, or one of the words "auto" +or "disengaged" (without the quotes). Not all ThinkPads support the +"auto" and "disengaged" levels. On the X31 and X40 (and ONLY on those models), the fan speed can be controlled to a certain degree. Once the fan is running, it can be @@ -604,12 +634,9 @@ about 3700 to about 7350. Values outside this range either do not have any effect or the fan speed eventually settles somewhere in that range. The fan cannot be stopped or started with this command. -On the 570, temperature readings are not available through this -feature and the fan control works a little differently. The fan speed -is reported in levels from 0 (off) to 7 (max) and can be controlled -with the following command: - - echo 'level ' > /proc/acpi/ibm/thermal +The ThinkPad's ACPI DSDT code will reprogram the fan on its own when +certain conditions are met. It will override any fan programming done +through ibm-acpi. EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan --------------------------------------- diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index ecb5ece79a37..4001ad193ddc 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1833,10 +1833,13 @@ static int fan_init(void) IBMACPI_FAN_WR_ACPI_FANS; fan_control_commands |= IBMACPI_FAN_CMD_SPEED | + IBMACPI_FAN_CMD_LEVEL | IBMACPI_FAN_CMD_ENABLE; } else { fan_control_access_mode = IBMACPI_FAN_WR_TPEC; - fan_control_commands |= IBMACPI_FAN_CMD_ENABLE; + fan_control_commands |= + IBMACPI_FAN_CMD_LEVEL | + IBMACPI_FAN_CMD_ENABLE; } } } @@ -1948,9 +1951,20 @@ static int fan_read(char *p) len += sprintf(p + len, "status:\t\tnot supported\n"); } - if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) - len += sprintf(p + len, "commands:\tlevel " - " ( is 0-7)\n"); + if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) { + len += sprintf(p + len, "commands:\tlevel "); + + switch (fan_control_access_mode) { + case IBMACPI_FAN_WR_ACPI_SFAN: + len += sprintf(p + len, " ( is 0-7)\n"); + break; + + default: + len += sprintf(p + len, " ( is 0-7, " + "auto, disengaged)\n"); + break; + } + } if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE) len += sprintf(p + len, "commands:\tenable, disable\n"); @@ -1973,6 +1987,17 @@ static int fan_set_level(int level) return -EINVAL; break; + case IBMACPI_FAN_WR_ACPI_FANS: + case IBMACPI_FAN_WR_TPEC: + if ((level != IBMACPI_FAN_EC_AUTO) && + (level != IBMACPI_FAN_EC_DISENGAGED) && + ((level < 0) || (level > 7))) + return -EINVAL; + + if (!acpi_ec_write(fan_status_offset, level)) + return -EIO; + break; + default: return -ENXIO; } @@ -2060,7 +2085,11 @@ static int fan_write_cmd_level(const char *cmd, int *rc) { int level; - if (sscanf(cmd, "level %d", &level) != 1) + if (strlencmp(cmd, "level auto") == 0) + level = IBMACPI_FAN_EC_AUTO; + else if (strlencmp(cmd, "level disengaged") == 0) + level = IBMACPI_FAN_EC_DISENGAGED; + else if (sscanf(cmd, "level %d", &level) != 1) return 0; if ((*rc = fan_set_level(level)) == -ENXIO) -- cgit v1.2.3-59-g8ed1b From 49a13cd6a2acd284ee106eaea7eeea8f2cc6796a Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:13 -0200 Subject: ACPI: ibm-acpi: store embedded controller firmware version for matching This patch changes the ThinkPad Embedded Controller DMI matching code to store the firmware version of the EC for later usage, e.g. for quirks. It also prints the firmware version when starting up. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 4001ad193ddc..3c091c4b461f 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -361,7 +362,7 @@ enum { /* Fan control constants */ * control */ }; -static int ibm_thinkpad_ec_found; +static char* ibm_thinkpad_ec_found = NULL; struct ibm_struct { char *name; @@ -2540,11 +2541,15 @@ static void acpi_ibm_exit(void) ibm_exit(&ibms[i]); remove_proc_entry(IBM_DIR, acpi_root_dir); + + if (ibm_thinkpad_ec_found) + kfree(ibm_thinkpad_ec_found); } -static int __init check_dmi_for_ec(void) +static char* __init check_dmi_for_ec(void) { struct dmi_device *dev = NULL; + char ec_fw_string[18]; /* * ThinkPad T23 or newer, A31 or newer, R50e or newer, @@ -2554,10 +2559,15 @@ static int __init check_dmi_for_ec(void) * See http://thinkwiki.org/wiki/List_of_DMI_IDs */ while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { - if (strstr(dev->name, "IBM ThinkPad Embedded Controller")) - return 1; + if (sscanf(dev->name, + "IBM ThinkPad Embedded Controller -[%17c", + ec_fw_string) == 1) { + ec_fw_string[sizeof(ec_fw_string) - 1] = 0; + ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; + return kstrdup(ec_fw_string, GFP_KERNEL); + } } - return 0; + return NULL; } static int __init acpi_ibm_init(void) @@ -2581,6 +2591,9 @@ static int __init acpi_ibm_init(void) /* Models with newer firmware report the EC in DMI */ ibm_thinkpad_ec_found = check_dmi_for_ec(); + if (ibm_thinkpad_ec_found) + printk(IBM_INFO "ThinkPad EC firmware %s\n", + ibm_thinkpad_ec_found); /* these handles are not required */ IBM_HANDLE_INIT(vid); -- cgit v1.2.3-59-g8ed1b From 778b4d742b210b9cac31f223527f30f1fc70312b Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:14 -0200 Subject: ACPI: ibm-acpi: workaround for EC 0x2f initialization bug A few ThinkPads fail to initialize EC register 0x2f both in the EC firmware and ACPI DSDT. If the BIOS and the ACPI DSDT also do not initialize it, then the initial status of that register does not correspond to reality. On all reported buggy machines, EC 0x2f will read 0x07 (fan level 7) upon cold boot, when the EC is actually in mode 0x80 (auto mode). Since returning a text string ("unknown") would break a number of userspace programs, instead we correct the reading for the most probably correct answer, and return it is in auto mode. The workaround flags the status and level as unknown on module load/kernel boot, until we are certain at least one fan control command was issued, either by us, or by something else. We don't work around the bug by doing a "fan enable" at module load/startup (which would initialize the EC register) because it is not known if these ThinkPad ACPI DSDT might have set the fan to level 7 instead of "auto" (we don't know if they can do this or not) due to a thermal condition, and we don't want to override that, should they be capable of it. We should be setting the workaround flag to "status known" upon resume, as both reports and a exaustive search on the DSDT tables at acpi.sf.net show that the DSDTs always enable the fan on resume, thus working around the bug. But since we don't have suspend/resume handlers in ibm-acpi yet and the "EC register 0x2f was modified" logic is likely to catch the change anyway, we don't. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 53 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 3c091c4b461f..56743c5a0439 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -362,7 +362,7 @@ enum { /* Fan control constants */ * control */ }; -static char* ibm_thinkpad_ec_found = NULL; +static char *ibm_thinkpad_ec_found = NULL; struct ibm_struct { char *name; @@ -1794,13 +1794,15 @@ static enum fan_status_access_mode fan_status_access_mode; static enum fan_control_access_mode fan_control_access_mode; static enum fan_control_commands fan_control_commands; +static int fan_control_status_known; +static u8 fan_control_initial_status; + static int fan_init(void) { - u8 status; - fan_status_access_mode = IBMACPI_FAN_NONE; fan_control_access_mode = IBMACPI_FAN_WR_NONE; fan_control_commands = 0; + fan_control_status_known = 1; if (gfan_handle) { /* 570, 600e/x, 770e, 770x */ @@ -1808,8 +1810,33 @@ static int fan_init(void) } else { /* all other ThinkPads: note that even old-style * ThinkPad ECs supports the fan control register */ - if (likely(acpi_ec_read(fan_status_offset, &status))) { + if (likely(acpi_ec_read(fan_status_offset, + &fan_control_initial_status))) { fan_status_access_mode = IBMACPI_FAN_RD_TPEC; + + /* In some ThinkPads, neither the EC nor the ACPI + * DSDT initialize the fan status, and it ends up + * being set to 0x07 when it *could* be either + * 0x07 or 0x80. + * + * Enable for TP-1Y (T43), TP-78 (R51e), + * TP-76 (R52), TP-70 (T43, R52), which are known + * to be buggy. */ + if (fan_control_initial_status == 0x07 && + ibm_thinkpad_ec_found && + ((ibm_thinkpad_ec_found[0] == '1' && + ibm_thinkpad_ec_found[1] == 'Y') || + (ibm_thinkpad_ec_found[0] == '7' && + (ibm_thinkpad_ec_found[1] == '6' || + ibm_thinkpad_ec_found[1] == '8' || + ibm_thinkpad_ec_found[1] == '0')) + )) { + printk(IBM_NOTICE + "fan_init: initial fan status is " + "unknown, assuming it is in auto " + "mode\n"); + fan_control_status_known = 0; + } } else { printk(IBM_ERR "ThinkPad ACPI EC access misbehaving, " @@ -1930,9 +1957,21 @@ static int fan_read(char *p) if ((rc = fan_get_status(&status)) < 0) return rc; + if (unlikely(!fan_control_status_known)) { + if (status != fan_control_initial_status) + fan_control_status_known = 1; + else + /* Return most likely status. In fact, it + * might be the only possible status */ + status = IBMACPI_FAN_EC_AUTO; + } + len += sprintf(p + len, "status:\t\t%s\n", (status != 0) ? "enabled" : "disabled"); + /* No ThinkPad boots on disengaged mode, we can safely + * assume the tachometer is online if fan control status + * was unknown */ if ((rc = fan_get_speed(&speed)) < 0) return rc; @@ -1997,6 +2036,8 @@ static int fan_set_level(int level) if (!acpi_ec_write(fan_status_offset, level)) return -EIO; + else + fan_control_status_known = 1; break; default: @@ -2022,6 +2063,8 @@ static int fan_set_enable(void) if (!acpi_ec_write(fan_status_offset, s)) return -EIO; + else + fan_control_status_known = 1; break; case IBMACPI_FAN_WR_ACPI_SFAN: @@ -2051,6 +2094,8 @@ static int fan_set_disable(void) case IBMACPI_FAN_WR_TPEC: if (!acpi_ec_write(fan_status_offset, 0x00)) return -EIO; + else + fan_control_status_known = 1; break; case IBMACPI_FAN_WR_ACPI_SFAN: -- cgit v1.2.3-59-g8ed1b From 16663a87ad1df7022661bc8813b7a2e84e7f5e66 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 24 Nov 2006 11:47:14 -0200 Subject: ACPI: ibm-acpi: implement fan watchdog command This patch implements a fan control safety watchdog, by request of the authors of userspace fan control scripts. When the watchdog timer expires, the equivalent action of a "fan enable" command is executed. The watchdog timer is reset at every reception of a fan control command that could change the state of the fan itself. This command is meant to be used by userspace fan control daemons, to make sure the fan is never left set to an unsafe level because of userspace problems. Users of the X31/X40/X41 "speed" command are on their own, the current implementation of "speed" is just too incomplete to be used safely, anyway. Better to never use it, and just use the "level" command instead. The watchdog is programmed using echo "watchdog " > fan, where number is the number of seconds to wait before doing an "enable", and zero disables the watchdog. Signed-off-by: Henrique de Moraes Holschuh --- Documentation/ibm-acpi.txt | 20 +++++++++++++ drivers/acpi/ibm_acpi.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt index cbd3a603a7ef..0132d363feb5 100644 --- a/Documentation/ibm-acpi.txt +++ b/Documentation/ibm-acpi.txt @@ -670,6 +670,26 @@ example: modprobe ibm_acpi hotkey=enable,0xffff video=auto_disable +The ibm-acpi kernel driver can be programmed to revert the fan level +to a safe setting if userspace does not issue one of the fan commands: +"enable", "disable", "level" or "watchdog" within a configurable +ammount of time. To do this, use the "watchdog" command. + + echo 'watchdog ' > /proc/acpi/ibm/fan + +Interval is the ammount of time in seconds to wait for one of the +above mentioned fan commands before reseting the fan level to a safe +one. If set to zero, the watchdog is disabled (default). When the +watchdog timer runs out, it does the exact equivalent of the "enable" +fan command. + +Note that the watchdog timer stops after it enables the fan. It will +be rearmed again automatically (using the same interval) when one of +the above mentioned fan commands is received. The fan watchdog is, +therefore, not suitable to protect against fan mode changes made +through means other than the "enable", "disable", and "level" fan +commands. + Example Configuration --------------------- diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 56743c5a0439..e5b8745b9070 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -82,6 +82,8 @@ #include #include #include +#include +#include #include #include @@ -348,7 +350,8 @@ enum fan_control_access_mode { enum fan_control_commands { IBMACPI_FAN_CMD_SPEED = 0x0001, /* speed command */ IBMACPI_FAN_CMD_LEVEL = 0x0002, /* level command */ - IBMACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd */ + IBMACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd, + * and also watchdog cmd */ }; enum { /* Fan control constants */ @@ -1797,12 +1800,17 @@ static enum fan_control_commands fan_control_commands; static int fan_control_status_known; static u8 fan_control_initial_status; +static void fan_watchdog_fire(void *ignored); +static int fan_watchdog_maxinterval; +static DECLARE_WORK(fan_watchdog_task, fan_watchdog_fire, NULL); + static int fan_init(void) { fan_status_access_mode = IBMACPI_FAN_NONE; fan_control_access_mode = IBMACPI_FAN_WR_NONE; fan_control_commands = 0; fan_control_status_known = 1; + fan_watchdog_maxinterval = 0; if (gfan_handle) { /* 570, 600e/x, 770e, 770x */ @@ -1934,6 +1942,31 @@ static int fan_get_speed(unsigned int *speed) return 0; } +static void fan_exit(void) +{ + cancel_delayed_work(&fan_watchdog_task); + flush_scheduled_work(); +} + +static void fan_watchdog_reset(void) +{ + static int fan_watchdog_active = 0; + + if (fan_watchdog_active) + cancel_delayed_work(&fan_watchdog_task); + + if (fan_watchdog_maxinterval > 0) { + fan_watchdog_active = 1; + if (!schedule_delayed_work(&fan_watchdog_task, + msecs_to_jiffies(fan_watchdog_maxinterval + * 1000))) { + printk(IBM_ERR "failed to schedule the fan watchdog, " + "watchdog will not trigger\n"); + } + } else + fan_watchdog_active = 0; +} + static int fan_read(char *p) { int len = 0; @@ -2007,7 +2040,9 @@ static int fan_read(char *p) } if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE) - len += sprintf(p + len, "commands:\tenable, disable\n"); + len += sprintf(p + len, "commands:\tenable, disable\n" + "commands:\twatchdog ( is 0 (off), " + "1-120 (seconds))\n"); if (fan_control_commands & IBMACPI_FAN_CMD_SPEED) len += sprintf(p + len, "commands:\tspeed " @@ -2186,6 +2221,21 @@ static int fan_write_cmd_speed(const char *cmd, int *rc) return 1; } +static int fan_write_cmd_watchdog(const char *cmd, int *rc) +{ + int interval; + + if (sscanf(cmd, "watchdog %d", &interval) != 1) + return 0; + + if (interval < 0 || interval > 120) + *rc = -EINVAL; + else + fan_watchdog_maxinterval = interval; + + return 1; +} + static int fan_write(char *buf) { char *cmd; @@ -2196,16 +2246,29 @@ static int fan_write(char *buf) fan_write_cmd_level(cmd, &rc)) && !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) && (fan_write_cmd_enable(cmd, &rc) || - fan_write_cmd_disable(cmd, &rc))) && + fan_write_cmd_disable(cmd, &rc) || + fan_write_cmd_watchdog(cmd, &rc))) && !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) && fan_write_cmd_speed(cmd, &rc)) ) rc = -EINVAL; + else if (!rc) + fan_watchdog_reset(); } return rc; } +static void fan_watchdog_fire(void *ignored) +{ + printk(IBM_NOTICE "fan watchdog: enabling fan\n"); + if (fan_set_enable()) { + printk(IBM_ERR "fan watchdog: error while enabling fan\n"); + /* reschedule for later */ + fan_watchdog_reset(); + } +} + static struct ibm_struct ibms[] = { { .name = "driver", @@ -2317,6 +2380,7 @@ static struct ibm_struct ibms[] = { .read = fan_read, .write = fan_write, .init = fan_init, + .exit = fan_exit, .experimental = 1, }, }; -- cgit v1.2.3-59-g8ed1b From e0298997acdba929e7f5b5987d305b67b50a3969 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 25 Nov 2006 16:35:09 -0200 Subject: ACPI: ibm-acpi: add support for the ultrabay on the T60,X60 This patch adds support for the ultrabay on the T60, X60 and other new ThinkPads that have a SATA ultrabay. I intend to keep bay and dock support in ibm-acpi working and updated until it finally gets deprecated and removed in favour of the generic dock and bay support. But we aren't there yet. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index e5b8745b9070..392abbb7d2dc 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -174,6 +174,7 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ #endif IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */ "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */ + "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */ "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */ ); /* A21e, R30, R31 */ -- cgit v1.2.3-59-g8ed1b From 2df910b4c3edcce9a0c12394db6f5f4a6e69c712 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 25 Nov 2006 16:35:09 -0200 Subject: ACPI: ibm-acpi: make non-generic bay support optional This patch makes it possible to disable ibm-acpi non-generic bay support, as generic bay support already works well for a number of ThinkPads. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/Kconfig | 11 +++++++++++ drivers/acpi/ibm_acpi.c | 13 ++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 59f9def21720..6f8c50ea54e1 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -224,6 +224,17 @@ 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 diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 392abbb7d2dc..fbb4970ce16a 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -172,6 +172,7 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ "\\_SB.PCI.ISA.SLCE", /* 570 */ ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */ #endif +#ifdef CONFIG_ACPI_IBM_BAY IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */ "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */ "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */ @@ -189,6 +190,7 @@ IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */ IBM_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */ "_EJ0", /* 770x */ ); /* all others */ +#endif /* don't list other alternatives as we install a notify handler on the 570 */ IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */ @@ -1051,6 +1053,7 @@ static int light_write(char *buf) return 0; } +#if defined(CONFIG_ACPI_IBM_DOCK) || defined(CONFIG_ACPI_IBM_BAY) static int _sta(acpi_handle handle) { int status; @@ -1060,7 +1063,7 @@ static int _sta(acpi_handle handle) return status; } - +#endif #ifdef CONFIG_ACPI_IBM_DOCK #define dock_docked() (_sta(dock_handle) & 1) @@ -1126,6 +1129,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event) } #endif +#ifdef CONFIG_ACPI_IBM_BAY static int bay_status_supported; static int bay_status2_supported; static int bay_eject_supported; @@ -1201,6 +1205,7 @@ static void bay_notify(struct ibm_struct *ibm, u32 event) { acpi_bus_generate_event(ibm->device, event, 0); } +#endif static int cmos_read(char *p) { @@ -2330,6 +2335,7 @@ static struct ibm_struct ibms[] = { .type = ACPI_SYSTEM_NOTIFY, }, #endif +#ifdef CONFIG_ACPI_IBM_BAY { .name = "bay", .init = bay_init, @@ -2339,6 +2345,7 @@ static struct ibm_struct ibms[] = { .handle = &bay_handle, .type = ACPI_SYSTEM_NOTIFY, }, +#endif { .name = "cmos", .read = cmos_read, @@ -2624,7 +2631,9 @@ IBM_PARAM(light); #ifdef CONFIG_ACPI_IBM_DOCK IBM_PARAM(dock); #endif +#ifdef CONFIG_ACPI_IBM_BAY IBM_PARAM(bay); +#endif IBM_PARAM(cmos); IBM_PARAM(led); IBM_PARAM(beep); @@ -2717,12 +2726,14 @@ static int __init acpi_ibm_init(void) IBM_HANDLE_INIT(dock); #endif IBM_HANDLE_INIT(pci); +#ifdef CONFIG_ACPI_IBM_BAY IBM_HANDLE_INIT(bay); if (bay_handle) IBM_HANDLE_INIT(bay_ej); IBM_HANDLE_INIT(bay2); if (bay2_handle) IBM_HANDLE_INIT(bay2_ej); +#endif IBM_HANDLE_INIT(beep); IBM_HANDLE_INIT(ecrd); IBM_HANDLE_INIT(ecwr); -- cgit v1.2.3-59-g8ed1b From fb87a811a4c232e2af8d746dc75330cbe5b0780c Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 25 Nov 2006 16:35:09 -0200 Subject: ACPI: ibm-acpi: backlight device cleanup This patch cleans up the recently added backlight device support by Holger Macht to fit well with the rest of the code, using the ibms struct as the other "subdrivers" in ibm-acpi. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 50 ++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index fbb4970ce16a..36e2667d8652 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -397,7 +397,7 @@ struct ibm_struct { static struct proc_dir_entry *proc_dir = NULL; -static struct backlight_device *ibm_backlight_device; +static struct backlight_device *ibm_backlight_device = NULL; #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") @@ -1639,6 +1639,7 @@ static int brightness_get(struct backlight_device *bd) return -EIO; level &= 0x7; + return level; } @@ -1713,6 +1714,33 @@ static int brightness_update_status(struct backlight_device *bd) return brightness_set(bd->props->brightness); } +static struct backlight_properties ibm_backlight_data = { + .owner = THIS_MODULE, + .get_brightness = brightness_get, + .update_status = brightness_update_status, + .max_brightness = 7, +}; + +static int brightness_init(void) +{ + ibm_backlight_device = backlight_device_register("ibm", NULL, + &ibm_backlight_data); + if (IS_ERR(ibm_backlight_device)) { + printk(IBM_ERR "Could not register backlight device\n"); + return PTR_ERR(ibm_backlight_device); + } + + return 0; +} + +static void brightness_exit(void) +{ + if (ibm_backlight_device) { + backlight_device_unregister(ibm_backlight_device); + ibm_backlight_device = NULL; + } +} + static int volume_offset = 0x30; static int volume_read(char *p) @@ -2377,6 +2405,8 @@ static struct ibm_struct ibms[] = { .name = "brightness", .read = brightness_read, .write = brightness_write, + .init = brightness_init, + .exit = brightness_exit, }, { .name = "volume", @@ -2642,20 +2672,10 @@ IBM_PARAM(brightness); IBM_PARAM(volume); IBM_PARAM(fan); -static struct backlight_properties ibm_backlight_data = { - .owner = THIS_MODULE, - .get_brightness = brightness_get, - .update_status = brightness_update_status, - .max_brightness = 7, -}; - static void acpi_ibm_exit(void) { int i; - if (ibm_backlight_device) - backlight_device_unregister(ibm_backlight_device); - for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--) ibm_exit(&ibms[i]); @@ -2758,14 +2778,6 @@ static int __init acpi_ibm_init(void) } } - ibm_backlight_device = backlight_device_register("ibm", NULL, - &ibm_backlight_data); - if (IS_ERR(ibm_backlight_device)) { - printk(IBM_ERR "Could not register ibm backlight device\n"); - ibm_backlight_device = NULL; - acpi_ibm_exit(); - } - return 0; } -- cgit v1.2.3-59-g8ed1b From 9a8e1738c1136a857c1fd3ae0c5019f9767427ad Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 25 Nov 2006 16:36:00 -0200 Subject: ACPI: ibm-acpi: style fixes and cruft removal This patch just fixes style, move some #defines to enums, and removes some old cruft. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 100 +++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 57 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 36e2667d8652..8bb41bd85cd3 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -78,9 +78,11 @@ #include #include #include + #include #include #include + #include #include #include @@ -121,28 +123,6 @@ static acpi_handle root_handle = NULL; static char *object##_path; \ static char *object##_paths[] = { paths } -/* - * The following models are supported to various degrees: - * - * 570, 600e, 600x, 770e, 770x - * A20m, A21e, A21m, A21p, A22p, A30, A30p, A31, A31p - * G40, G41 - * R30, R31, R32, R40, R40e, R50, R50e, R50p, R51 - * T20, T21, T22, T23, T30, T40, T40p, T41, T41p, T42, T42p, T43 - * X20, X21, X22, X23, X24, X30, X31, X40 - * - * The following models have no supported features: - * - * 240, 240x, i1400 - * - * Still missing DSDTs for the following models: - * - * A20p, A22e, A22m - * R52 - * S31 - * T43p - */ - IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */ "\\_SB.PCI.ISA.EC", /* 570 */ "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */ @@ -785,12 +765,15 @@ static int wan_write(char *buf) return 0; } -static int video_supported; -static int video_orig_autosw; +enum video_access_mode { + IBMACPI_VIDEO_NONE = 0, + IBMACPI_VIDEO_570, /* 570 */ + IBMACPI_VIDEO_770, /* 600e/x, 770e, 770x */ + IBMACPI_VIDEO_NEW, /* all others */ +}; -#define VIDEO_570 1 -#define VIDEO_770 2 -#define VIDEO_NEW 3 +static enum video_access_mode video_supported; +static int video_orig_autosw; static int video_init(void) { @@ -802,16 +785,16 @@ static int video_init(void) if (!vid_handle) /* video switching not supported on R30, R31 */ - video_supported = 0; + video_supported = IBMACPI_VIDEO_NONE; else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) /* 570 */ - video_supported = VIDEO_570; + video_supported = IBMACPI_VIDEO_570; else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) /* 600e/x, 770e, 770x */ - video_supported = VIDEO_770; + video_supported = IBMACPI_VIDEO_770; else /* all others */ - video_supported = VIDEO_NEW; + video_supported = IBMACPI_VIDEO_NEW; return 0; } @@ -821,15 +804,15 @@ static int video_status(void) int status = 0; int i; - if (video_supported == VIDEO_570) { + if (video_supported == IBMACPI_VIDEO_570) { if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87)) status = i & 3; - } else if (video_supported == VIDEO_770) { + } else if (video_supported == IBMACPI_VIDEO_770) { if (acpi_evalf(NULL, &i, "\\VCDL", "d")) status |= 0x01 * i; if (acpi_evalf(NULL, &i, "\\VCDC", "d")) status |= 0x02 * i; - } else if (video_supported == VIDEO_NEW) { + } else if (video_supported == IBMACPI_VIDEO_NEW) { acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1); if (acpi_evalf(NULL, &i, "\\VCDC", "d")) status |= 0x02 * i; @@ -848,9 +831,10 @@ static int video_autosw(void) { int autosw = 0; - if (video_supported == VIDEO_570) + if (video_supported == IBMACPI_VIDEO_570) acpi_evalf(vid_handle, &autosw, "SWIT", "d"); - else if (video_supported == VIDEO_770 || video_supported == VIDEO_NEW) + else if (video_supported == IBMACPI_VIDEO_770 || + video_supported == IBMACPI_VIDEO_NEW) acpi_evalf(vid_handle, &autosw, "^VDEE", "d"); return autosw & 1; @@ -870,12 +854,12 @@ static int video_read(char *p) len += sprintf(p + len, "status:\t\tsupported\n"); len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); - if (video_supported == VIDEO_NEW) + if (video_supported == IBMACPI_VIDEO_NEW) len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); - if (video_supported == VIDEO_NEW) + if (video_supported == IBMACPI_VIDEO_NEW) len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); @@ -890,7 +874,7 @@ static int video_switch(void) if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) return -EIO; - ret = video_supported == VIDEO_570 ? + ret = video_supported == IBMACPI_VIDEO_570 ? acpi_evalf(ec_handle, NULL, "_Q16", "v") : acpi_evalf(vid_handle, NULL, "VSWT", "v"); acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw); @@ -900,9 +884,9 @@ static int video_switch(void) static int video_expand(void) { - if (video_supported == VIDEO_570) + if (video_supported == IBMACPI_VIDEO_570) return acpi_evalf(ec_handle, NULL, "_Q17", "v"); - else if (video_supported == VIDEO_770) + else if (video_supported == IBMACPI_VIDEO_770) return acpi_evalf(vid_handle, NULL, "VEXP", "v"); else return acpi_evalf(NULL, NULL, "\\VEXP", "v"); @@ -912,10 +896,10 @@ static int video_switch2(int status) { int ret; - if (video_supported == VIDEO_570) { + if (video_supported == IBMACPI_VIDEO_570) { ret = acpi_evalf(NULL, NULL, "\\_SB.PHS2", "vdd", 0x8b, status | 0x80); - } else if (video_supported == VIDEO_770) { + } else if (video_supported == IBMACPI_VIDEO_770) { int autosw = video_autosw(); if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) return -EIO; @@ -951,10 +935,10 @@ static int video_write(char *buf) enable |= 0x02; } else if (strlencmp(cmd, "crt_disable") == 0) { disable |= 0x02; - } else if (video_supported == VIDEO_NEW && + } else if (video_supported == IBMACPI_VIDEO_NEW && strlencmp(cmd, "dvi_enable") == 0) { enable |= 0x08; - } else if (video_supported == VIDEO_NEW && + } else if (video_supported == IBMACPI_VIDEO_NEW && strlencmp(cmd, "dvi_disable") == 0) { disable |= 0x08; } else if (strlencmp(cmd, "auto_enable") == 0) { @@ -1253,26 +1237,28 @@ static int cmos_write(char *buf) return 0; } -static int led_supported; - -#define LED_570 1 -#define LED_OLD 2 -#define LED_NEW 3 +enum led_access_mode { + IBMACPI_LED_NONE = 0, + IBMACPI_LED_570, /* 570 */ + IBMACPI_LED_OLD, /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ + IBMACPI_LED_NEW, /* all others */ +}; +static enum led_access_mode led_supported; static int led_init(void) { if (!led_handle) /* led not supported on R30, R31 */ - led_supported = 0; + led_supported = IBMACPI_LED_NONE; else if (strlencmp(led_path, "SLED") == 0) /* 570 */ - led_supported = LED_570; + led_supported = IBMACPI_LED_570; else if (strlencmp(led_path, "SYSL") == 0) /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ - led_supported = LED_OLD; + led_supported = IBMACPI_LED_OLD; else /* all others */ - led_supported = LED_NEW; + led_supported = IBMACPI_LED_NEW; return 0; } @@ -1289,7 +1275,7 @@ static int led_read(char *p) } len += sprintf(p + len, "status:\t\tsupported\n"); - if (led_supported == LED_570) { + if (led_supported == IBMACPI_LED_570) { /* 570 */ int i, status; for (i = 0; i < 8; i++) { @@ -1338,13 +1324,13 @@ static int led_write(char *buf) } else return -EINVAL; - if (led_supported == LED_570) { + if (led_supported == IBMACPI_LED_570) { /* 570 */ led = 1 << led; if (!acpi_evalf(led_handle, NULL, NULL, "vdd", led, led_sled_arg1[ind])) return -EIO; - } else if (led_supported == LED_OLD) { + } else if (led_supported == IBMACPI_LED_OLD) { /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ led = 1 << led; ret = ec_write(EC_HLMS, led); -- cgit v1.2.3-59-g8ed1b From f9ff43a6268d36acf8df18a76bb881a26a42dc1e Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 25 Nov 2006 16:37:38 -0200 Subject: ACPI: ibm-acpi: update version and copyright Bump up module version, add myself to copyright and MODULE_AUTHOR. Signed-off-by: Henrique de Moraes Holschuh --- drivers/acpi/ibm_acpi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 8bb41bd85cd3..92e7b6eb8f19 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -3,6 +3,7 @@ * * * Copyright (C) 2004-2005 Borislav Deianov + * Copyright (C) 2006 Henrique de Moraes Holschuh * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,10 +20,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define IBM_VERSION "0.12a" +#define IBM_VERSION "0.13" /* * Changelog: + * + * 2006-11-22 0.13 new maintainer + * changelog now lives in git commit history, and will + * not be updated further in-file. * * 2005-08-17 0.12 fix compilation on 2.6.13-rc kernels * 2005-03-17 0.11 support for 600e, 770x @@ -95,7 +100,7 @@ #define IBM_FILE "ibm_acpi" #define IBM_URL "http://ibm-acpi.sf.net/" -MODULE_AUTHOR("Borislav Deianov"); +MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); MODULE_DESCRIPTION(IBM_DESC); MODULE_VERSION(IBM_VERSION); MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From 671adbec210efc15cef81b4616adae8bcd667296 Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Mon, 4 Dec 2006 14:49:43 -0800 Subject: ACPI: dock: Make the dock station driver a platform device driver. Make the dock station driver a platform device driver so that we can create sysfs entries under /sys/device/platform. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Len Brown --- drivers/acpi/dock.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index bf5b79ed3613..336d94cdf2a0 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,8 @@ MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME); MODULE_LICENSE("GPL"); static struct atomic_notifier_head dock_notifier_list; +static struct platform_device dock_device; +static char dock_device_name[] = "dock"; struct dock_station { acpi_handle handle; @@ -629,6 +632,15 @@ static int dock_add(acpi_handle handle) spin_lock_init(&dock_station->hp_lock); ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); + /* initialize platform device stuff */ + dock_device.name = dock_device_name; + ret = platform_device_register(&dock_device); + if (ret) { + printk(KERN_ERR PREFIX "Error registering dock device\n", ret); + kfree(dock_station); + return ret; + } + /* Find dependent devices */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, find_dock_devices, dock_station, @@ -638,7 +650,8 @@ static int dock_add(acpi_handle handle) dd = alloc_dock_dependent_device(handle); if (!dd) { kfree(dock_station); - return -ENOMEM; + ret = -ENOMEM; + goto dock_add_err_unregister; } add_dock_dependent_device(dock_station, dd); @@ -658,8 +671,10 @@ static int dock_add(acpi_handle handle) return 0; dock_add_err: - kfree(dock_station); kfree(dd); +dock_add_err_unregister: + platform_device_unregister(&dock_device); + kfree(dock_station); return ret; } @@ -686,6 +701,9 @@ static int dock_remove(void) if (ACPI_FAILURE(status)) printk(KERN_ERR "Error removing notify handler\n"); + /* cleanup sysfs */ + platform_device_unregister(&dock_device); + /* free dock station memory */ kfree(dock_station); return 0; -- cgit v1.2.3-59-g8ed1b From e67beb37df7a9da9d5d1e59c5358654d007a97c5 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 7 Dec 2006 04:17:35 -0500 Subject: ACPI: dock: fix build warning drivers/acpi/dock.c:689: warning: too many arguments for format Signed-off-by: Len Brown --- drivers/acpi/dock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 336d94cdf2a0..2c2f28db9fb2 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -636,7 +636,7 @@ static int dock_add(acpi_handle handle) dock_device.name = dock_device_name; ret = platform_device_register(&dock_device); if (ret) { - printk(KERN_ERR PREFIX "Error registering dock device\n", ret); + printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret); kfree(dock_station); return ret; } -- cgit v1.2.3-59-g8ed1b From c80fdbe81a617c82e2f95233f8ddcf046ffe21b3 Mon Sep 17 00:00:00 2001 From: "brandon@ifup.org" Date: Mon, 4 Dec 2006 14:49:58 -0800 Subject: ACPI: dock: Add a docked sysfs file to the dock driver. Add 2 sysfs files for user interface. 1) docked - 1/0 (read only) - indicates whether the software believes the laptop is docked in a docking station. 2) undock - (write only) - writing to this file causes the software to initiate an undock request to the firmware. Signed-off-by: Brandon Philips Signed-off-by: Kristen Carlson Accardi Signed-off-by: Len Brown --- drivers/acpi/dock.c | 95 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 2c2f28db9fb2..e4c1a4ff4e31 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -514,6 +514,37 @@ void unregister_hotplug_dock_device(acpi_handle handle) EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); +/** + * handle_eject_request - handle an undock request checking for error conditions + * + * Check to make sure the dock device is still present, then undock and + * hotremove all the devices that may need removing. + */ +static int handle_eject_request(struct dock_station *ds, u32 event) +{ + if (!dock_present(ds)) + return -ENODEV; + + if (dock_in_progress(ds)) + return -EBUSY; + + /* + * here we need to generate the undock + * event prior to actually doing the undock + * so that the device struct still exists. + */ + dock_event(ds, event, UNDOCK_EVENT); + hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); + undock(ds); + eject_dock(ds); + if (dock_present(ds)) { + printk(KERN_ERR PREFIX "Unable to undock!\n"); + return -EBUSY; + } + + return 0; +} + /** * dock_notify - act upon an acpi dock notification * @handle: the dock station handle @@ -522,9 +553,7 @@ EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); * * If we are notified to dock, then check to see if the dock is * present and then dock. Notify all drivers of the dock event, - * and then hotplug and devices that may need hotplugging. For undock - * check to make sure the dock device is still present, then undock - * and hotremove all the devices that may need removing. + * and then hotplug and devices that may need hotplugging. */ static void dock_notify(acpi_handle handle, u32 event, void *data) { @@ -556,19 +585,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) * to the driver who wish to hotplug. */ case ACPI_NOTIFY_EJECT_REQUEST: - if (!dock_in_progress(ds) && dock_present(ds)) { - /* - * here we need to generate the undock - * event prior to actually doing the undock - * so that the device struct still exists. - */ - dock_event(ds, event, UNDOCK_EVENT); - hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); - undock(ds); - eject_dock(ds); - if (dock_present(ds)) - printk(KERN_ERR PREFIX "Unable to undock!\n"); - } + handle_eject_request(ds, event); break; default: printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); @@ -607,6 +624,33 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } +/* + * show_docked - read method for "docked" file in sysfs + */ +static ssize_t show_docked(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station)); + +} +DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); + +/* + * write_undock - write method for "undock" file in sysfs + */ +static ssize_t write_undock(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + + if (!count) + return -EINVAL; + + ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST); + return ret ? ret: count; +} +DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); + /** * dock_add - add a new dock station * @handle: the dock station handle @@ -640,6 +684,21 @@ static int dock_add(acpi_handle handle) kfree(dock_station); return ret; } + ret = device_create_file(&dock_device.dev, &dev_attr_docked); + if (ret) { + printk("Error %d adding sysfs file\n", ret); + platform_device_unregister(&dock_device); + kfree(dock_station); + return ret; + } + ret = device_create_file(&dock_device.dev, &dev_attr_undock); + if (ret) { + printk("Error %d adding sysfs file\n", ret); + device_remove_file(&dock_device.dev, &dev_attr_docked); + platform_device_unregister(&dock_device); + kfree(dock_station); + return ret; + } /* Find dependent devices */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, @@ -673,6 +732,8 @@ static int dock_add(acpi_handle handle) dock_add_err: kfree(dd); dock_add_err_unregister: + device_remove_file(&dock_device.dev, &dev_attr_docked); + device_remove_file(&dock_device.dev, &dev_attr_undock); platform_device_unregister(&dock_device); kfree(dock_station); return ret; @@ -702,6 +763,8 @@ static int dock_remove(void) printk(KERN_ERR "Error removing notify handler\n"); /* cleanup sysfs */ + device_remove_file(&dock_device.dev, &dev_attr_docked); + device_remove_file(&dock_device.dev, &dev_attr_undock); platform_device_unregister(&dock_device); /* free dock station memory */ -- cgit v1.2.3-59-g8ed1b From 2548c06b72396e28abdb5dd572ab589c3c22f4b9 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Mon, 4 Dec 2006 14:50:17 -0800 Subject: ACPI: dock: Fix symbol conflict between acpiphp and dock Fix bug which will cause acpiphp to not be able to load when dock.ko cannot load. Signed-off-by: Prarit Bhargava Signed-off-by: Kristen Carlson Accardi Signed-off-by: Len Brown --- drivers/acpi/dock.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index e4c1a4ff4e31..8c6828bee5d9 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -444,6 +444,9 @@ static int dock_in_progress(struct dock_station *ds) */ int register_dock_notifier(struct notifier_block *nb) { + if (!dock_station) + return -ENODEV; + return atomic_notifier_chain_register(&dock_notifier_list, nb); } @@ -455,6 +458,9 @@ EXPORT_SYMBOL_GPL(register_dock_notifier); */ void unregister_dock_notifier(struct notifier_block *nb) { + if (!dock_station) + return; + atomic_notifier_chain_unregister(&dock_notifier_list, nb); } @@ -807,7 +813,7 @@ static int __init dock_init(void) ACPI_UINT32_MAX, find_dock, &num, NULL); if (!num) - return -ENODEV; + printk(KERN_INFO "No dock devices found.\n"); return 0; } -- cgit v1.2.3-59-g8ed1b From d91df1aaa9e4c06f8ea10d4935888c4f1976ef56 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:16 +0300 Subject: ACPI: ec: Allow for write semantics in any command. Check for transaction attributes, not command index to decide on event to expect. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e6d4b084dca2..348a19e19b64 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -253,7 +253,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, acpi_ec_write_data(ec, *(wdata++)); } - if (command == ACPI_EC_COMMAND_WRITE) { + if (!rdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (result) return result; -- cgit v1.2.3-59-g8ed1b From 5d57a6a55ec0bdcb952dbcd3f8ffcde8a3ee9413 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:16 +0300 Subject: ACPI: ec: Enable EC GPE at beginning of transaction Temporary measure until resume sequence is right. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 348a19e19b64..3ffe172d1a88 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -290,6 +290,9 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, } down(&ec->sem); + /* Make sure GPE is enabled before doing transaction */ + acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (status) { printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); -- cgit v1.2.3-59-g8ed1b From 5c4064124a5720a2576eb4bd5b7200d70052e9b5 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:16 +0300 Subject: ACPI: ec: Increase timeout from 50 to 500 ms to handle old slow machines. http://bugzilla.kernel.org/show_bug.cgi?id=7466 Signed-off-by: Len Brown --- drivers/acpi/ec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 3ffe172d1a88..46a132d613bc 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -65,10 +65,10 @@ enum { ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ }; -#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ +#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ #define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ -#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ +#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 100ms max. during EC ops */ enum { EC_INTR = 1, /* Output buffer full */ -- cgit v1.2.3-59-g8ed1b From bec5a1e0604d1b829b87b4b7e85f71ccc43dda50 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:16 +0300 Subject: ACPI: ec: Read status register from check_status() function Signed-off-by: Len Brown --- drivers/acpi/ec.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 46a132d613bc..94b983b9cfba 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -134,8 +134,9 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) outb(data, ec->data_addr); } -static int acpi_ec_check_status(u8 status, u8 event) +static int acpi_ec_check_status(struct acpi_ec *ec, u8 event) { + u8 status = acpi_ec_read_status(ec); switch (event) { case ACPI_EC_EVENT_OBF_1: if (status & ACPI_EC_FLAG_OBF) @@ -158,7 +159,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, u8 event) long time_left; ec->expect_event = event; - if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { + if (acpi_ec_check_status(ec, event)) { ec->expect_event = 0; return 0; } @@ -175,7 +176,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, u8 event) return 0; } } - if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { + if (acpi_ec_check_status(ec, event)) { ec->expect_event = 0; return 0; } @@ -457,15 +458,15 @@ static u32 acpi_ec_gpe_handler(void *data) struct acpi_ec *ec = (struct acpi_ec *)data; acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); - value = acpi_ec_read_status(ec); if (acpi_ec_mode == EC_INTR) { - if (acpi_ec_check_status(value, ec->expect_event)) { + if (acpi_ec_check_status(ec, ec->expect_event)) { ec->expect_event = 0; wake_up(&ec->wait); } } + value = acpi_ec_read_status(ec); if (value & ACPI_EC_FLAG_SCI) { status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); return status == AE_OK ? -- cgit v1.2.3-59-g8ed1b From af3fd1404fd4f0f58ebbb52b22be4f1ca0794cda Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:16 +0300 Subject: ACPI: ec: Remove expect_event and all races around it. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 84 +++++++++++++++++++++++++------------------------------ 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 94b983b9cfba..1514e71b723d 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -46,6 +46,9 @@ ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" +#undef PREFIX +#define PREFIX "ACPI: EC: " + /* EC status register */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ @@ -101,7 +104,6 @@ struct acpi_ec { unsigned long data_addr; unsigned long global_lock; struct semaphore sem; - unsigned int expect_event; atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ wait_queue_head_t wait; } *ec_ecdt; @@ -155,34 +157,25 @@ static int acpi_ec_check_status(struct acpi_ec *ec, u8 event) static int acpi_ec_wait(struct acpi_ec *ec, u8 event) { - int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0; - long time_left; - - ec->expect_event = event; - if (acpi_ec_check_status(ec, event)) { - ec->expect_event = 0; - return 0; - } - - do { - if (acpi_ec_mode == EC_POLL) { - udelay(ACPI_EC_UDELAY); - } else { - time_left = wait_event_timeout(ec->wait, - !ec->expect_event, - msecs_to_jiffies(ACPI_EC_DELAY)); - if (time_left > 0) { - ec->expect_event = 0; + if (acpi_ec_mode == EC_POLL) { + int i; + for (i = 0; i < ACPI_EC_UDELAY_COUNT; ++i) { + if (acpi_ec_check_status(ec, event)) return 0; - } + udelay(ACPI_EC_UDELAY); } - if (acpi_ec_check_status(ec, event)) { - ec->expect_event = 0; + } else { + if (wait_event_timeout(ec->wait, + acpi_ec_check_status(ec, event), + msecs_to_jiffies(ACPI_EC_DELAY)) || + acpi_ec_check_status(ec, event)) { return 0; + } else { + printk(KERN_ERR PREFIX "acpi_ec_wait timeout," + " status = %d, expect_event = %d\n", + acpi_ec_read_status(ec), event); } - } while (--i > 0); - - ec->expect_event = 0; + } return -ETIME; } @@ -243,32 +236,41 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, const u8 *wdata, unsigned wdata_len, u8 *rdata, unsigned rdata_len) { - int result; + int result = 0; acpi_ec_write_cmd(ec, command); for (; wdata_len > 0; wdata_len --) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); - if (result) - return result; + if (result) { + printk(KERN_ERR PREFIX "write_cmd timeout, command = %d\n", + command); + goto end; + } acpi_ec_write_data(ec, *(wdata++)); } if (!rdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); - if (result) - return result; + if (result) { + printk(KERN_ERR PREFIX "finish-write timeout, command = %d\n", + command); + goto end; + } } for (; rdata_len > 0; rdata_len --) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); - if (result) - return result; + if (result) { + printk(KERN_ERR PREFIX "read timeout, command = %d\n", + command); + goto end; + } *(rdata++) = acpi_ec_read_data(ec); } - - return 0; + end: + return result; } static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, @@ -419,11 +421,6 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data) Event Management -------------------------------------------------------------------------- */ -struct acpi_ec_query_data { - acpi_handle handle; - u8 data; -}; - static void acpi_ec_gpe_query(void *ec_cxt) { struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; @@ -443,7 +440,7 @@ static void acpi_ec_gpe_query(void *ec_cxt) snprintf(object_name, 8, "_Q%2.2X", value); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); + printk(KERN_INFO PREFIX "evaluating %s\n", object_name); acpi_evaluate_object(ec->handle, object_name, NULL, NULL); @@ -460,17 +457,12 @@ static u32 acpi_ec_gpe_handler(void *data) acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); if (acpi_ec_mode == EC_INTR) { - if (acpi_ec_check_status(ec, ec->expect_event)) { - ec->expect_event = 0; - wake_up(&ec->wait); - } + wake_up(&ec->wait); } value = acpi_ec_read_status(ec); if (value & ACPI_EC_FLAG_SCI) { status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); - return status == AE_OK ? - ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; } acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); return status == AE_OK ? -- cgit v1.2.3-59-g8ed1b From e41334c0a6ef71458f255db25f011d15099e7cca Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:16 +0300 Subject: ACPI: ec: Remove calls to clear_gpe() and enable_gpe(), as these are handled at dispatch_gpe() level. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 1514e71b723d..acfe8830da14 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -428,24 +428,21 @@ static void acpi_ec_gpe_query(void *ec_cxt) static char object_name[8]; if (!ec) - goto end; + return; value = acpi_ec_read_status(ec); if (!(value & ACPI_EC_FLAG_SCI)) - goto end; + return; if (acpi_ec_query(ec, &value)) - goto end; + return; snprintf(object_name, 8, "_Q%2.2X", value); printk(KERN_INFO PREFIX "evaluating %s\n", object_name); acpi_evaluate_object(ec->handle, object_name, NULL, NULL); - - end: - acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); } static u32 acpi_ec_gpe_handler(void *data) @@ -454,7 +451,6 @@ static u32 acpi_ec_gpe_handler(void *data) u8 value; struct acpi_ec *ec = (struct acpi_ec *)data; - acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); if (acpi_ec_mode == EC_INTR) { wake_up(&ec->wait); @@ -464,7 +460,7 @@ static u32 acpi_ec_gpe_handler(void *data) if (value & ACPI_EC_FLAG_SCI) { status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); } - acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); + return status == AE_OK ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; } -- cgit v1.2.3-59-g8ed1b From 5d0c288b7362ad7ee235b59352ac2a89480e4757 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:16 +0300 Subject: ACPI: ec: Query only single query at a time. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index acfe8830da14..a85f795ab4ec 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -104,6 +104,7 @@ struct acpi_ec { unsigned long data_addr; unsigned long global_lock; struct semaphore sem; + atomic_t query_pending; atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ wait_queue_head_t wait; } *ec_ecdt; @@ -257,6 +258,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, command); goto end; } + } else if (command == ACPI_EC_COMMAND_QUERY) { + atomic_set(&ec->query_pending, 0); } for (; rdata_len > 0; rdata_len --) { @@ -425,17 +428,9 @@ static void acpi_ec_gpe_query(void *ec_cxt) { struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; u8 value = 0; - static char object_name[8]; + char object_name[8]; - if (!ec) - return; - - value = acpi_ec_read_status(ec); - - if (!(value & ACPI_EC_FLAG_SCI)) - return; - - if (acpi_ec_query(ec, &value)) + if (!ec || acpi_ec_query(ec, &value)) return; snprintf(object_name, 8, "_Q%2.2X", value); @@ -457,7 +452,8 @@ static u32 acpi_ec_gpe_handler(void *data) } value = acpi_ec_read_status(ec); - if (value & ACPI_EC_FLAG_SCI) { + if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { + atomic_set(&ec->query_pending, 1); status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); } @@ -652,6 +648,7 @@ static int acpi_ec_add(struct acpi_device *device) ec->handle = device->handle; ec->uid = -1; init_MUTEX(&ec->sem); + atomic_set(&ec->query_pending, 0); if (acpi_ec_mode == EC_INTR) { atomic_set(&ec->leaving_burst, 1); init_waitqueue_head(&ec->wait); -- cgit v1.2.3-59-g8ed1b From c787a8551e7fee85366962881e7a4f2fda656dfc Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:16 +0300 Subject: ACPI: ec: Change semaphore to mutex. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a85f795ab4ec..034a96372357 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -103,7 +103,7 @@ struct acpi_ec { unsigned long command_addr; unsigned long data_addr; unsigned long global_lock; - struct semaphore sem; + struct mutex lock; atomic_t query_pending; atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ wait_queue_head_t wait; @@ -294,7 +294,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, if (ACPI_FAILURE(status)) return -ENODEV; } - down(&ec->sem); + mutex_lock(&ec->lock); /* Make sure GPE is enabled before doing transaction */ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); @@ -310,7 +310,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, rdata, rdata_len); end: - up(&ec->sem); + mutex_unlock(&ec->lock); if (ec->global_lock) acpi_release_global_lock(glk); @@ -647,7 +647,7 @@ static int acpi_ec_add(struct acpi_device *device) ec->handle = device->handle; ec->uid = -1; - init_MUTEX(&ec->sem); + mutex_init(&ec->lock); atomic_set(&ec->query_pending, 0); if (acpi_ec_mode == EC_INTR) { atomic_set(&ec->leaving_burst, 1); @@ -830,7 +830,7 @@ acpi_fake_ecdt_callback(acpi_handle handle, { acpi_status status; - init_MUTEX(&ec_ecdt->sem); + mutex_init(&ec_ecdt->lock); if (acpi_ec_mode == EC_INTR) { init_waitqueue_head(&ec_ecdt->wait); } @@ -915,7 +915,7 @@ static int __init acpi_ec_get_real_ecdt(void) return -ENOMEM; memset(ec_ecdt, 0, sizeof(struct acpi_ec)); - init_MUTEX(&ec_ecdt->sem); + mutex_init(&ec_ecdt->lock); if (acpi_ec_mode == EC_INTR) { init_waitqueue_head(&ec_ecdt->wait); } -- cgit v1.2.3-59-g8ed1b From a86e277259b08be0f00cfcb182922da3ffc50f04 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:16 +0300 Subject: ACPI: ec: Rename gpe_bit to gpe Signed-off-by: Len Brown --- drivers/acpi/ec.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 034a96372357..722acafdf32e 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -99,7 +99,7 @@ static struct acpi_driver acpi_ec_driver = { struct acpi_ec { acpi_handle handle; unsigned long uid; - unsigned long gpe_bit; + unsigned long gpe; unsigned long command_addr; unsigned long data_addr; unsigned long global_lock; @@ -297,7 +297,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, mutex_lock(&ec->lock); /* Make sure GPE is enabled before doing transaction */ - acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); + acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (status) { @@ -563,14 +563,14 @@ static int acpi_ec_read_info(struct seq_file *seq, void *offset) if (!ec) goto end; - seq_printf(seq, "gpe bit: 0x%02x\n", - (u32) ec->gpe_bit); + seq_printf(seq, "gpe: 0x%02x\n", + (u32) ec->gpe); seq_printf(seq, "ports: 0x%02x, 0x%02x\n", (u32) ec->command_addr, (u32) ec->data_addr); seq_printf(seq, "use global lock: %s\n", ec->global_lock ? "yes" : "no"); - acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); + acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); end: return 0; @@ -668,7 +668,7 @@ static int acpi_ec_add(struct acpi_device *device) ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); - acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, + acpi_remove_gpe_handler(NULL, ec_ecdt->gpe, &acpi_ec_gpe_handler); kfree(ec_ecdt); @@ -678,7 +678,7 @@ static int acpi_ec_add(struct acpi_device *device) /* TODO: Add support for _GPE returning a package */ status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, - &ec->gpe_bit); + &ec->gpe); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment")); result = -ENODEV; @@ -691,7 +691,7 @@ static int acpi_ec_add(struct acpi_device *device) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", acpi_device_name(device), acpi_device_bid(device), - (u32) ec->gpe_bit)); + (u32) ec->gpe)); if (!first_ec) first_ec = device; @@ -771,26 +771,26 @@ static int acpi_ec_start(struct acpi_device *device) } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", - ec->gpe_bit, ec->command_addr, ec->data_addr)); + ec->gpe, ec->command_addr, ec->data_addr)); /* * Install GPE handler */ - status = acpi_install_gpe_handler(NULL, ec->gpe_bit, + status = acpi_install_gpe_handler(NULL, ec->gpe, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); if (ACPI_FAILURE(status)) { return -ENODEV; } - acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME); - acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); + acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); + acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); status = acpi_install_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, &acpi_ec_space_setup, ec); if (ACPI_FAILURE(status)) { - acpi_remove_gpe_handler(NULL, ec->gpe_bit, + acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); return -ENODEV; } @@ -816,7 +816,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type) return -ENODEV; status = - acpi_remove_gpe_handler(NULL, ec->gpe_bit, + acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); if (ACPI_FAILURE(status)) return -ENODEV; @@ -844,14 +844,14 @@ acpi_fake_ecdt_callback(acpi_handle handle, status = acpi_evaluate_integer(handle, "_GPE", NULL, - &ec_ecdt->gpe_bit); + &ec_ecdt->gpe); if (ACPI_FAILURE(status)) return status; ec_ecdt->global_lock = TRUE; ec_ecdt->handle = handle; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", - ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr)); + ec_ecdt->gpe, ec_ecdt->command_addr, ec_ecdt->data_addr)); return AE_CTRL_TERMINATE; } @@ -921,7 +921,7 @@ static int __init acpi_ec_get_real_ecdt(void) } ec_ecdt->command_addr = ecdt_ptr->ec_control.address; ec_ecdt->data_addr = ecdt_ptr->ec_data.address; - ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; + ec_ecdt->gpe = ecdt_ptr->gpe_bit; /* use the GL just to be safe */ ec_ecdt->global_lock = TRUE; ec_ecdt->uid = ecdt_ptr->uid; @@ -959,14 +959,14 @@ int __init acpi_ec_ecdt_probe(void) /* * Install GPE handler */ - status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit, + status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec_ecdt); if (ACPI_FAILURE(status)) { goto error; } - acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME); - acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR); + acpi_set_gpe_type(NULL, ec_ecdt->gpe, ACPI_GPE_TYPE_RUNTIME); + acpi_enable_gpe(NULL, ec_ecdt->gpe, ACPI_NOT_ISR); status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, @@ -974,7 +974,7 @@ int __init acpi_ec_ecdt_probe(void) &acpi_ec_space_setup, ec_ecdt); if (ACPI_FAILURE(status)) { - acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, + acpi_remove_gpe_handler(NULL, ec_ecdt->gpe, &acpi_ec_gpe_handler); goto error; } -- cgit v1.2.3-59-g8ed1b From 50c1e1138cb94f6aca0f8555777edbcefe0324e2 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:17 +0300 Subject: ACPI: ec: Drop udelay() from poll mode. Loop by reading status field instead. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 722acafdf32e..8ef74e7b3b91 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -70,8 +70,6 @@ enum { #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ -#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ -#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 100ms max. during EC ops */ enum { EC_INTR = 1, /* Output buffer full */ @@ -159,11 +157,10 @@ static int acpi_ec_check_status(struct acpi_ec *ec, u8 event) static int acpi_ec_wait(struct acpi_ec *ec, u8 event) { if (acpi_ec_mode == EC_POLL) { - int i; - for (i = 0; i < ACPI_EC_UDELAY_COUNT; ++i) { + unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); + while (time_before(jiffies, delay)) { if (acpi_ec_check_status(ec, event)) return 0; - udelay(ACPI_EC_UDELAY); } } else { if (wait_event_timeout(ec->wait, -- cgit v1.2.3-59-g8ed1b From 523953b41e52952347d7d50dcc4bfc27bc001dc8 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:17 +0300 Subject: ACPI: ec: Acquire Global Lock under EC mutex. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 8ef74e7b3b91..4d17777110ed 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -286,12 +286,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, if (rdata) memset(rdata, 0, rdata_len); + mutex_lock(&ec->lock); if (ec->global_lock) { status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); if (ACPI_FAILURE(status)) return -ENODEV; } - mutex_lock(&ec->lock); /* Make sure GPE is enabled before doing transaction */ acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); @@ -307,10 +307,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, rdata, rdata_len); end: - mutex_unlock(&ec->lock); if (ec->global_lock) acpi_release_global_lock(glk); + mutex_unlock(&ec->lock); return status; } -- cgit v1.2.3-59-g8ed1b From 78d0af3392cba6dfdd1dc1eab5a86ba8e4af8fff Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:17 +0300 Subject: ACPI: ec: Style changes. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 4d17777110ed..17a98aa734b8 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -135,20 +135,16 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) outb(data, ec->data_addr); } -static int acpi_ec_check_status(struct acpi_ec *ec, u8 event) +static inline int acpi_ec_check_status(struct acpi_ec *ec, u8 event) { u8 status = acpi_ec_read_status(ec); - switch (event) { - case ACPI_EC_EVENT_OBF_1: + + if (event == ACPI_EC_EVENT_OBF_1) { if (status & ACPI_EC_FLAG_OBF) return 1; - break; - case ACPI_EC_EVENT_IBF_0: + } else if (event == ACPI_EC_EVENT_IBF_0) { if (!(status & ACPI_EC_FLAG_IBF)) return 1; - break; - default: - break; } return 0; @@ -238,7 +234,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, acpi_ec_write_cmd(ec, command); - for (; wdata_len > 0; wdata_len --) { + for (; wdata_len > 0; --wdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (result) { printk(KERN_ERR PREFIX "write_cmd timeout, command = %d\n", @@ -259,7 +255,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, atomic_set(&ec->query_pending, 0); } - for (; rdata_len > 0; rdata_len --) { + for (; rdata_len > 0; --rdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); if (result) { printk(KERN_ERR PREFIX "read timeout, command = %d\n", -- cgit v1.2.3-59-g8ed1b From 3261ff4db3a33ac7e1b9ed98e905663845cadbc6 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:17 +0300 Subject: ACPI: ec: Change #define to enums there possible. Signed-off-by: Len Brown --- drivers/acpi/ec.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 17a98aa734b8..e05bb148754c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -56,14 +56,15 @@ ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ /* EC commands */ -#define ACPI_EC_COMMAND_READ 0x80 -#define ACPI_EC_COMMAND_WRITE 0x81 -#define ACPI_EC_BURST_ENABLE 0x82 -#define ACPI_EC_BURST_DISABLE 0x83 -#define ACPI_EC_COMMAND_QUERY 0x84 - +enum ec_command { + ACPI_EC_COMMAND_READ = 0x80, + ACPI_EC_COMMAND_WRITE = 0x81, + ACPI_EC_BURST_ENABLE = 0x82, + ACPI_EC_BURST_DISABLE = 0x83, + ACPI_EC_COMMAND_QUERY = 0x84, +}; /* EC events */ -enum { +enum ec_event { ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ }; @@ -71,10 +72,10 @@ enum { #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ -enum { +static enum ec_mode { EC_INTR = 1, /* Output buffer full */ EC_POLL, /* Input buffer empty */ -}; +} acpi_ec_mode = EC_INTR; static int acpi_ec_remove(struct acpi_device *device, int type); static int acpi_ec_start(struct acpi_device *device); @@ -109,7 +110,6 @@ struct acpi_ec { /* External interfaces use first EC only, so remember */ static struct acpi_device *first_ec; -static int acpi_ec_mode = EC_INTR; /* -------------------------------------------------------------------------- Transaction Management @@ -135,7 +135,7 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) outb(data, ec->data_addr); } -static inline int acpi_ec_check_status(struct acpi_ec *ec, u8 event) +static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event) { u8 status = acpi_ec_read_status(ec); @@ -150,7 +150,7 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, u8 event) return 0; } -static int acpi_ec_wait(struct acpi_ec *ec, u8 event) +static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event) { if (acpi_ec_mode == EC_POLL) { unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); -- cgit v1.2.3-59-g8ed1b From 6ccedb10e39c34a4cb68f6c8dae67ecdd3e0b138 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 7 Dec 2006 18:42:17 +0300 Subject: ACPI: ec: Lindent once again Signed-off-by: Len Brown --- drivers/acpi/ec.c | 171 ++++++++++++++++++++++++------------------------------ 1 file changed, 76 insertions(+), 95 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e05bb148754c..d713f769b72d 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -45,36 +45,33 @@ ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" - #undef PREFIX #define PREFIX "ACPI: EC: " - /* EC status register */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ - /* EC commands */ enum ec_command { - ACPI_EC_COMMAND_READ = 0x80, - ACPI_EC_COMMAND_WRITE = 0x81, - ACPI_EC_BURST_ENABLE = 0x82, - ACPI_EC_BURST_DISABLE = 0x83, - ACPI_EC_COMMAND_QUERY = 0x84, + ACPI_EC_COMMAND_READ = 0x80, + ACPI_EC_COMMAND_WRITE = 0x81, + ACPI_EC_BURST_ENABLE = 0x82, + ACPI_EC_BURST_DISABLE = 0x83, + ACPI_EC_COMMAND_QUERY = 0x84, }; /* EC events */ enum ec_event { ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ - ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ + ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ }; #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ static enum ec_mode { - EC_INTR = 1, /* Output buffer full */ - EC_POLL, /* Input buffer empty */ + EC_INTR = 1, /* Output buffer full */ + EC_POLL, /* Input buffer empty */ } acpi_ec_mode = EC_INTR; static int acpi_ec_remove(struct acpi_device *device, int type); @@ -167,7 +164,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event) } else { printk(KERN_ERR PREFIX "acpi_ec_wait timeout," " status = %d, expect_event = %d\n", - acpi_ec_read_status(ec), event); + acpi_ec_read_status(ec), event); } } @@ -184,7 +181,6 @@ int acpi_ec_enter_burst_mode(struct acpi_ec *ec) u8 tmp = 0; u8 status = 0; - status = acpi_ec_read_status(ec); if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); @@ -200,7 +196,7 @@ int acpi_ec_enter_burst_mode(struct acpi_ec *ec) atomic_set(&ec->leaving_burst, 0); return 0; - end: + end: ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode")); return -1; } @@ -209,26 +205,25 @@ int acpi_ec_leave_burst_mode(struct acpi_ec *ec) { u8 status = 0; - status = acpi_ec_read_status(ec); - if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ + if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) { status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); - if(status) + if (status) goto end; acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE); acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); } atomic_set(&ec->leaving_burst, 1); return 0; - end: + end: ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode")); return -1; } -#endif /* ACPI_FUTURE_USAGE */ +#endif /* ACPI_FUTURE_USAGE */ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, - const u8 *wdata, unsigned wdata_len, - u8 *rdata, unsigned rdata_len) + const u8 * wdata, unsigned wdata_len, + u8 * rdata, unsigned rdata_len) { int result = 0; @@ -237,8 +232,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, for (; wdata_len > 0; --wdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (result) { - printk(KERN_ERR PREFIX "write_cmd timeout, command = %d\n", - command); + printk(KERN_ERR PREFIX + "write_cmd timeout, command = %d\n", command); goto end; } acpi_ec_write_data(ec, *(wdata++)); @@ -247,8 +242,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, if (!rdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (result) { - printk(KERN_ERR PREFIX "finish-write timeout, command = %d\n", - command); + printk(KERN_ERR PREFIX + "finish-write timeout, command = %d\n", command); goto end; } } else if (command == ACPI_EC_COMMAND_QUERY) { @@ -259,7 +254,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); if (result) { printk(KERN_ERR PREFIX "read timeout, command = %d\n", - command); + command); goto end; } @@ -270,8 +265,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, } static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, - const u8 *wdata, unsigned wdata_len, - u8 *rdata, unsigned rdata_len) + const u8 * wdata, unsigned wdata_len, + u8 * rdata, unsigned rdata_len) { int status; u32 glk; @@ -279,8 +274,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) return -EINVAL; - if (rdata) - memset(rdata, 0, rdata_len); + if (rdata) + memset(rdata, 0, rdata_len); mutex_lock(&ec->lock); if (ec->global_lock) { @@ -294,15 +289,16 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (status) { - printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); + printk(KERN_DEBUG PREFIX + "input buffer is not empty, aborting transaction\n"); goto end; } - status = acpi_ec_transaction_unlocked(ec, command, - wdata, wdata_len, - rdata, rdata_len); + status = acpi_ec_transaction_unlocked(ec, command, + wdata, wdata_len, + rdata, rdata_len); -end: + end: if (ec->global_lock) acpi_release_global_lock(glk); @@ -311,7 +307,7 @@ end: return status; } -static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) +static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) { int result; u8 d; @@ -324,15 +320,15 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) { - u8 wdata[2] = { address, data }; - return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, + u8 wdata[2] = { address, data }; + return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, wdata, 2, NULL, 0); } /* * Externally callable EC access functions. For now, assume 1 EC only */ -int ec_read(u8 addr, u8 *val) +int ec_read(u8 addr, u8 * val) { struct acpi_ec *ec; int err; @@ -372,8 +368,8 @@ int ec_write(u8 addr, u8 val) EXPORT_SYMBOL(ec_write); extern int ec_transaction(u8 command, - const u8 *wdata, unsigned wdata_len, - u8 *rdata, unsigned rdata_len) + const u8 * wdata, unsigned wdata_len, + u8 * rdata, unsigned rdata_len) { struct acpi_ec *ec; @@ -388,29 +384,29 @@ extern int ec_transaction(u8 command, EXPORT_SYMBOL(ec_transaction); -static int acpi_ec_query(struct acpi_ec *ec, u8 *data) +static int acpi_ec_query(struct acpi_ec *ec, u8 * data) { int result; - u8 d; + u8 d; - if (!ec || !data) - return -EINVAL; + if (!ec || !data) + return -EINVAL; - /* - * Query the EC to find out which _Qxx method we need to evaluate. - * Note that successful completion of the query causes the ACPI_EC_SCI - * bit to be cleared (and thus clearing the interrupt source). - */ + /* + * Query the EC to find out which _Qxx method we need to evaluate. + * Note that successful completion of the query causes the ACPI_EC_SCI + * bit to be cleared (and thus clearing the interrupt source). + */ - result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1); - if (result) - return result; + result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1); + if (result) + return result; - if (!d) - return -ENODATA; + if (!d) + return -ENODATA; - *data = d; - return 0; + *data = d; + return 0; } /* -------------------------------------------------------------------------- @@ -439,7 +435,6 @@ static u32 acpi_ec_gpe_handler(void *data) u8 value; struct acpi_ec *ec = (struct acpi_ec *)data; - if (acpi_ec_mode == EC_INTR) { wake_up(&ec->wait); } @@ -447,7 +442,9 @@ static u32 acpi_ec_gpe_handler(void *data) value = acpi_ec_read_status(ec); if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { atomic_set(&ec->query_pending, 1); - status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); + status = + acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, + ec); } return status == AE_OK ? @@ -485,7 +482,6 @@ acpi_ec_space_handler(u32 function, acpi_integer f_v = 0; int i = 0; - if ((address > 0xFF) || !value || !handler_context) return AE_BAD_PARAMETER; @@ -499,7 +495,7 @@ acpi_ec_space_handler(u32 function, switch (function) { case ACPI_READ: temp = 0; - result = acpi_ec_read(ec, (u8) address, (u8 *) &temp); + result = acpi_ec_read(ec, (u8) address, (u8 *) & temp); break; case ACPI_WRITE: result = acpi_ec_write(ec, (u8) address, (u8) temp); @@ -552,15 +548,12 @@ static int acpi_ec_read_info(struct seq_file *seq, void *offset) { struct acpi_ec *ec = (struct acpi_ec *)seq->private; - if (!ec) goto end; - seq_printf(seq, "gpe: 0x%02x\n", - (u32) ec->gpe); + seq_printf(seq, "gpe: 0x%02x\n", (u32) ec->gpe); seq_printf(seq, "ports: 0x%02x, 0x%02x\n", - (u32) ec->command_addr, - (u32) ec->data_addr); + (u32) ec->command_addr, (u32) ec->data_addr); seq_printf(seq, "use global lock: %s\n", ec->global_lock ? "yes" : "no"); acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); @@ -586,7 +579,6 @@ static int acpi_ec_add_fs(struct acpi_device *device) { struct proc_dir_entry *entry = NULL; - if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_ec_dir); @@ -629,7 +621,6 @@ static int acpi_ec_add(struct acpi_device *device) acpi_status status = AE_OK; struct acpi_ec *ec = NULL; - if (!device) return -EINVAL; @@ -651,8 +642,7 @@ static int acpi_ec_add(struct acpi_device *device) acpi_driver_data(device) = ec; /* Use the global lock for all EC transactions? */ - acpi_evaluate_integer(ec->handle, "_GLK", NULL, - &ec->global_lock); + acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock); /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ @@ -669,11 +659,10 @@ static int acpi_ec_add(struct acpi_device *device) /* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ - status = - acpi_evaluate_integer(ec->handle, "_GPE", NULL, - &ec->gpe); + status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment")); + ACPI_EXCEPTION((AE_INFO, status, + "Obtaining GPE bit assignment")); result = -ENODEV; goto end; } @@ -683,13 +672,13 @@ static int acpi_ec_add(struct acpi_device *device) goto end; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", - acpi_device_name(device), acpi_device_bid(device), - (u32) ec->gpe)); + acpi_device_name(device), acpi_device_bid(device), + (u32) ec->gpe)); if (!first_ec) first_ec = device; - end: + end: if (result) kfree(ec); @@ -700,7 +689,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type) { struct acpi_ec *ec = NULL; - if (!device) return -EINVAL; @@ -743,7 +731,6 @@ static int acpi_ec_start(struct acpi_device *device) acpi_status status = AE_OK; struct acpi_ec *ec = NULL; - if (!device) return -EINVAL; @@ -783,8 +770,7 @@ static int acpi_ec_start(struct acpi_device *device) &acpi_ec_space_handler, &acpi_ec_space_setup, ec); if (ACPI_FAILURE(status)) { - acpi_remove_gpe_handler(NULL, ec->gpe, - &acpi_ec_gpe_handler); + acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); return -ENODEV; } @@ -796,7 +782,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type) acpi_status status = AE_OK; struct acpi_ec *ec = NULL; - if (!device) return -EINVAL; @@ -808,9 +793,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type) if (ACPI_FAILURE(status)) return -ENODEV; - status = - acpi_remove_gpe_handler(NULL, ec->gpe, - &acpi_ec_gpe_handler); + status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); if (ACPI_FAILURE(status)) return -ENODEV; @@ -835,16 +818,15 @@ acpi_fake_ecdt_callback(acpi_handle handle, ec_ecdt->uid = -1; acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); - status = - acpi_evaluate_integer(handle, "_GPE", NULL, - &ec_ecdt->gpe); + status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe); if (ACPI_FAILURE(status)) return status; ec_ecdt->global_lock = TRUE; ec_ecdt->handle = handle; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", - ec_ecdt->gpe, ec_ecdt->command_addr, ec_ecdt->data_addr)); + ec_ecdt->gpe, ec_ecdt->command_addr, + ec_ecdt->data_addr)); return AE_CTRL_TERMINATE; } @@ -883,7 +865,7 @@ static int __init acpi_ec_fake_ecdt(void) goto error; } return 0; - error: + error: return ret; } @@ -919,14 +901,13 @@ static int __init acpi_ec_get_real_ecdt(void) ec_ecdt->global_lock = TRUE; ec_ecdt->uid = ecdt_ptr->uid; - status = - acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); + status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); if (ACPI_FAILURE(status)) { goto error; } return 0; - error: + error: ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); kfree(ec_ecdt); ec_ecdt = NULL; @@ -986,7 +967,6 @@ static int __init acpi_ec_init(void) { int result = 0; - if (acpi_disabled) return 0; @@ -1039,7 +1019,8 @@ static int __init acpi_ec_set_intr_mode(char *str) acpi_ec_mode = EC_POLL; } acpi_ec_driver.ops.add = acpi_ec_add; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling")); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", + intr ? "interrupt" : "polling")); return 1; } -- cgit v1.2.3-59-g8ed1b From 8ea86e0ba7c9d16ae0f35cb0c4165194fa573f7a Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Mon, 11 Dec 2006 12:05:08 -0800 Subject: ACPI: dock: add uevent to indicate change in device status Send a uevent to indicate a device change whenever we dock or undock, so that userspace may now check the dock status via sysfs. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Holger Macht Signed-off-by: Len Brown --- drivers/acpi/dock.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 8c6828bee5d9..215f5b30a1f1 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -326,10 +326,12 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) static void dock_event(struct dock_station *ds, u32 event, int num) { + struct device *dev = &dock_device.dev; /* - * we don't do events until someone tells me that - * they would like to have them. + * Indicate that the status of the dock station has + * changed. */ + kobject_uevent(&dev->kobj, KOBJ_CHANGE); } /** -- cgit v1.2.3-59-g8ed1b From 25c68a33b7b74b37793b1250007e5e21d621a7fc Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 8 Dec 2006 04:43:41 -0500 Subject: ACPI: ibm_acpi: respond to workqueue update Signed-off-by: Len Brown --- drivers/acpi/ibm_acpi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 92e7b6eb8f19..ab1800735346 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1825,9 +1825,9 @@ static enum fan_control_commands fan_control_commands; static int fan_control_status_known; static u8 fan_control_initial_status; -static void fan_watchdog_fire(void *ignored); +static void fan_watchdog_fire(struct work_struct *ignored); static int fan_watchdog_maxinterval; -static DECLARE_WORK(fan_watchdog_task, fan_watchdog_fire, NULL); +static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire); static int fan_init(void) { @@ -2284,7 +2284,7 @@ static int fan_write(char *buf) return rc; } -static void fan_watchdog_fire(void *ignored) +static void fan_watchdog_fire(struct work_struct *ignored) { printk(IBM_NOTICE "fan watchdog: enabling fan\n"); if (fan_set_enable()) { -- cgit v1.2.3-59-g8ed1b From 7e244322cd4ea361ef9ee623b3fcb4d9f4ff841c Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 16 Dec 2006 00:59:38 -0500 Subject: ACPI: fix git automerge failure Signed-off-by: Len Brown --- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 39bc16bec5aa..18f4715c655d 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -569,7 +569,6 @@ static int sw_any_bug_found(struct dmi_system_id *d) return 0; } -#ifdef CONFIG_SMP static struct dmi_system_id sw_any_bug_dmi_table[] = { { .callback = sw_any_bug_found, -- cgit v1.2.3-59-g8ed1b From 4afaf54b3b97fa8cf2d1d9bcd7612b195acb53ae Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Mon, 18 Dec 2006 14:53:33 -0300 Subject: ACPI: ibm_acpi: allow clean removal Allow clean removal by setting notify_installed in the right place. Signed-off-by: Alexey Starikovskiy Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/acpi/ibm_acpi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 92e7b6eb8f19..1397efb71341 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -2503,7 +2503,7 @@ static int __init setup_notify(struct ibm_struct *ibm) ibm->name, status); return -ENODEV; } - + ibm->notify_installed = 1; return 0; } @@ -2580,7 +2580,6 @@ static int __init ibm_init(struct ibm_struct *ibm) ret = setup_notify(ibm); if (ret < 0) return ret; - ibm->notify_installed = 1; } return 0; -- cgit v1.2.3-59-g8ed1b From f10bb2544bab75b3e8df15a7b51a833c78cbd77f Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Tue, 19 Dec 2006 12:56:09 -0800 Subject: ACPI: fix single linked list manipulation Fix single linked list manipulation for sub_driver. If the remving entry is not on the head of the sub_driver list, it goes into infinate loop. Though that infinite loop doesn't happen. Because the only user of acpi_pci_register_dirver() is acpiphp. Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/pci_root.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 0984a1ee24ed..c92c144d6c58 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -98,11 +98,12 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) struct acpi_pci_driver **pptr = &sub_driver; while (*pptr) { - if (*pptr != driver) - continue; - *pptr = (*pptr)->next; - break; + if (*pptr == driver) + break; + pptr = &(*pptr)->next; } + BUG_ON(!*pptr); + *pptr = (*pptr)->next; if (!driver->remove) return; -- cgit v1.2.3-59-g8ed1b From 83822fc9e6ad2e0f3799174f7c6ad3aa285b9488 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Tue, 19 Dec 2006 12:56:10 -0800 Subject: ACPI: prevent processor module from loading on failures Make loading processor.ko fail when an error happens. Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/processor_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 1908e0d20222..22eb05efa64c 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -901,13 +901,13 @@ static int __init acpi_processor_init(void) acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); if (!acpi_processor_dir) - return 0; + return -ENOMEM; acpi_processor_dir->owner = THIS_MODULE; result = acpi_bus_register_driver(&acpi_processor_driver); if (result < 0) { remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); - return 0; + return result; } acpi_processor_install_hotplug_notify(); -- cgit v1.2.3-59-g8ed1b From a854e08a5a4f57d54991b3a40a80823dd548339d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 19 Dec 2006 12:56:12 -0800 Subject: ACPI: make drivers/acpi/ec.c:ec_ecdt static Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/ec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d713f769b72d..e2cfc9e078e9 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -92,7 +92,7 @@ static struct acpi_driver acpi_ec_driver = { }; /* If we find an EC via the ECDT, we need to keep a ptr to its context */ -struct acpi_ec { +static struct acpi_ec { acpi_handle handle; unsigned long uid; unsigned long gpe; -- cgit v1.2.3-59-g8ed1b From a6fdbf90b94fa4e2f5f7cbb526c71160b6c561c8 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 19 Dec 2006 12:56:13 -0800 Subject: ACPI: fix NULL check in drivers/acpi/osl.c Spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/osl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index c84286cbbe25..e10679ce1e0e 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1032,7 +1032,7 @@ acpi_status acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) { *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL); - if (cache == NULL) + if (*cache == NULL) return AE_ERROR; else return AE_OK; -- cgit v1.2.3-59-g8ed1b From 6796a1204cfeac6dab1c2dd682d1138454eca661 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 19 Dec 2006 12:56:13 -0800 Subject: ACPI: Kconfig - depend on PM rather than selecting it Make ACPI depend on PM rather than selecting it. Otherwise it's a nightmare working out why CONFIG_PM keeps getting set. Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 0f9d4be7ed75..6382f6477aca 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 -- cgit v1.2.3-59-g8ed1b From f4715189dfb1c381ad36b7e02e3716fb7a7f84db Mon Sep 17 00:00:00 2001 From: Thomas Tuttle Date: Tue, 19 Dec 2006 12:56:14 -0800 Subject: ACPI: Implement acpi_video_get_next_level() acpi_video_get_next_level was supposed to implement an algorithm to select a new brightness level based on the old brightness level of an ACPI video device, but it simply says "/* Fix me */" and returns the current brightness. This patch implements acpi_video_get_next_level properly. It had to change a few constants at the top of the file because they were (apparently) wrong, but it appears to work on my Dell Inspiron e1405 (with BIOS A05 only--BIOS A04 doesn't seem to send ACPI video hotkey events). [akpm@osdl.org: cleanups] Signed-off-by: Thomas Tuttle Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/video.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 56666a982476..9200a46c38bd 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -3,6 +3,7 @@ * * Copyright (C) 2004 Luming Yu * Copyright (C) 2004 Bruno Ducrot + * Copyright (C) 2006 Thomas Tuttle * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @@ -47,11 +48,11 @@ #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 -#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 -#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 -#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 -#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 -#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 +#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85 +#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 +#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 +#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 +#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) #define ACPI_VIDEO_HEAD_END (~0u) @@ -1509,8 +1510,34 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event) { - /*Fix me */ - return level_current; + int min, max, min_above, max_below, i, l; + max = max_below = 0; + min = min_above = 255; + for (i = 0; i < device->brightness->count; i++) { + l = device->brightness->levels[i]; + if (l < min) + min = l; + if (l > max) + max = l; + if (l < min_above && l > level_current) + min_above = l; + if (l > max_below && l < level_current) + max_below = l; + } + + switch (event) { + case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: + return (level_current < max) ? min_above : min; + case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: + return (level_current < max) ? min_above : max; + case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: + return (level_current > min) ? max_below : min; + case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: + case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: + return 0; + default: + return level_current; + } } static void -- cgit v1.2.3-59-g8ed1b From 519ab5f2be65b72cf12ae99c89752bbe79b44df6 Mon Sep 17 00:00:00 2001 From: Yu Luming Date: Tue, 19 Dec 2006 12:56:15 -0800 Subject: ACPI: video: Add dev argument for backlight_device_register This patch set adds generic abstract layer support for acpi video driver to have generic user interface to control backlight and output switch control by leveraging the existing backlight sysfs class driver, and by adding a new video output sysfs class driver. This patch: Add dev argument for backlight_device_register to link the class device to real device object. The platform specific driver should find a way to get the real device object for their video device. [akpm@osdl.org: build fix] [akpm@osdl.org: fix msi-laptop.c] Signed-off-by: Luming Yu Cc: "Antonino A. Daplas" Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/asus_acpi.c | 2 +- drivers/acpi/ibm_acpi.c | 2 +- drivers/acpi/toshiba_acpi.c | 3 ++- drivers/misc/msi-laptop.c | 3 ++- drivers/usb/misc/appledisplay.c | 2 +- drivers/video/backlight/backlight.c | 7 +++++-- include/linux/backlight.h | 2 +- 7 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index bf7bc25e680e..11468e46253c 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -1402,7 +1402,7 @@ static int __init asus_acpi_init(void) return result; } - asus_backlight_device = backlight_device_register("asus", NULL, + 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"); diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 1397efb71341..da08b9c62ffc 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1714,7 +1714,7 @@ static struct backlight_properties ibm_backlight_data = { static int brightness_init(void) { - ibm_backlight_device = backlight_device_register("ibm", NULL, + ibm_backlight_device = backlight_device_register("ibm", NULL, NULL, &ibm_backlight_data); if (IS_ERR(ibm_backlight_device)) { printk(IBM_ERR "Could not register backlight device\n"); diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 2f35f891593f..88aeccbafaaf 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c @@ -590,7 +590,8 @@ static int __init toshiba_acpi_init(void) remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); } - toshiba_backlight_device = backlight_device_register("toshiba", NULL, + toshiba_backlight_device = backlight_device_register("toshiba",NULL, + NULL, &toshiba_backlight_data); if (IS_ERR(toshiba_backlight_device)) { printk(KERN_ERR "Could not register toshiba backlight device\n"); diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c index fdb7153f4426..8e5e07e4c1cf 100644 --- a/drivers/misc/msi-laptop.c +++ b/drivers/misc/msi-laptop.c @@ -317,7 +317,8 @@ static int __init msi_init(void) /* Register backlight stuff */ - msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props); + msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL, + &msibl_props); if (IS_ERR(msibl_device)) return PTR_ERR(msibl_device); diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 6b23a1def9fe..a4522e6c31ec 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -283,7 +283,7 @@ static int appledisplay_probe(struct usb_interface *iface, /* Register backlight device */ snprintf(bl_name, sizeof(bl_name), "appledisplay%d", atomic_inc_return(&count_displays) - 1); - pdata->bd = backlight_device_register(bl_name, pdata, + pdata->bd = backlight_device_register(bl_name, NULL, NULL, &appledisplay_bl_data); if (IS_ERR(pdata->bd)) { err("appledisplay: Backlight registration failed"); diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 27597c576eff..1d97cdf6f382 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -190,8 +190,10 @@ static int fb_notifier_callback(struct notifier_block *self, * Creates and registers new backlight class_device. Returns either an * ERR_PTR() or a pointer to the newly allocated device. */ -struct backlight_device *backlight_device_register(const char *name, void *devdata, - struct backlight_properties *bp) +struct backlight_device *backlight_device_register(const char *name, + struct device *dev, + void *devdata, + struct backlight_properties *bp) { int i, rc; struct backlight_device *new_bd; @@ -206,6 +208,7 @@ struct backlight_device *backlight_device_register(const char *name, void *devda new_bd->props = bp; memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev)); new_bd->class_dev.class = &backlight_class; + new_bd->class_dev.dev = dev; strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN); class_set_devdata(&new_bd->class_dev, devdata); diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 75e91f5b6a04..a5cf1beacb44 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -54,7 +54,7 @@ struct backlight_device { }; extern struct backlight_device *backlight_device_register(const char *name, - void *devdata, struct backlight_properties *bp); + struct device *dev,void *devdata,struct backlight_properties *bp); extern void backlight_device_unregister(struct backlight_device *bd); #define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev) -- cgit v1.2.3-59-g8ed1b From a8274d57afb83e4954ddcb3f8b7dd1c03a379bd4 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 19 Dec 2006 12:56:16 -0800 Subject: fbdev: update after backlight argument change Update the frambuffer drivers to the backlight_device_registers changes. Signed-off-by: James Simmons Cc: Luming Yu Cc: "Antonino A. Daplas" Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/video/aty/aty128fb.c | 2 +- drivers/video/aty/atyfb_base.c | 2 +- drivers/video/aty/radeon_backlight.c | 2 +- drivers/video/nvidia/nv_backlight.c | 2 +- drivers/video/riva/fbdev.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 276a21530b95..5341462b6b48 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -1829,7 +1829,7 @@ static void aty128_bl_init(struct aty128fb_par *par) snprintf(name, sizeof(name), "aty128bl%d", info->node); - bd = backlight_device_register(name, par, &aty128_bl_data); + bd = backlight_device_register(name, info->dev, par, &aty128_bl_data); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "aty128: Backlight registration failed\n"); diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index b77b30923928..cc4bd8089fe2 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -2221,7 +2221,7 @@ static void aty_bl_init(struct atyfb_par *par) snprintf(name, sizeof(name), "atybl%d", info->node); - bd = backlight_device_register(name, par, &aty_bl_data); + bd = backlight_device_register(name, info->dev, par, &aty_bl_data); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "aty: Backlight registration failed\n"); diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 585eb7b9e636..3abfd4a380cc 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c @@ -163,7 +163,7 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node); - bd = backlight_device_register(name, pdata, &radeon_bl_data); + bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data); if (IS_ERR(bd)) { rinfo->info->bl_dev = NULL; printk("radeonfb: Backlight registration failed\n"); diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c index 5b75ae4e9457..df934bd21899 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/nvidia/nv_backlight.c @@ -141,7 +141,7 @@ void nvidia_bl_init(struct nvidia_par *par) snprintf(name, sizeof(name), "nvidiabl%d", info->node); - bd = backlight_device_register(name, par, &nvidia_bl_data); + bd = backlight_device_register(name, info->dev, par, &nvidia_bl_data); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "nvidia: Backlight registration failed\n"); diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index a433cc78ef90..a160c4de2ca2 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -383,7 +383,7 @@ static void riva_bl_init(struct riva_par *par) snprintf(name, sizeof(name), "rivabl%d", info->node); - bd = backlight_device_register(name, par, &riva_bl_data); + bd = backlight_device_register(name, info->dev, par, &riva_bl_data); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "riva: Backlight registration failed\n"); -- cgit v1.2.3-59-g8ed1b From 0f0fe1a08aa421266060ac67e50453a06d9ceb63 Mon Sep 17 00:00:00 2001 From: John Keller Date: Tue, 19 Dec 2006 12:56:19 -0800 Subject: ACPI: Add support for acpi_load_table/acpi_unload_table_id Make acpi_load_table() available for use by removing it from the #ifdef ACPI_FUTURE_USAGE. Also add a new routine used to unload an ACPI table of a given type and "id" - acpi_unload_table_id(). The implementation of this new routine was almost a direct copy of existing routine acpi_unload_table() - only difference being that it only removes a specific table id instead of ALL tables of a given type. The SN hotplug driver (sgi_hotplug.c) now uses both of these interfaces to dynamically load and unload SSDT ACPI tables. Also, a few other ACPI routines now used by the SN hotplug driver are exported (since the driver can be a loadable module): acpi_ns_map_handle_to_node acpi_ns_convert_entry_to_handle acpi_ns_get_next_node Signed-off-by: Aaron Young Cc: Greg KH Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/namespace/nsxfobj.c | 44 ++++++++++++++++++++++++++++++++ drivers/acpi/tables/tbxface.c | 54 +++++++++++++++++++++++++++++++++++++++- include/acpi/acpixf.h | 7 ++++-- 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c index a163e1d3708d..a18b1c223129 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/namespace/nsxfobj.c @@ -48,6 +48,50 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsxfobj") +/******************************************************************************* + * + * FUNCTION: acpi_get_id + * + * PARAMETERS: Handle - Handle of object whose id is desired + * ret_id - Where the id will be placed + * + * RETURN: Status + * + * DESCRIPTION: This routine returns the owner id associated with a handle + * + ******************************************************************************/ +acpi_status acpi_get_id(acpi_handle handle, acpi_owner_id * ret_id) +{ + struct acpi_namespace_node *node; + acpi_status status; + + /* Parameter Validation */ + + if (!ret_id) { + return (AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Convert and validate the handle */ + + node = acpi_ns_map_handle_to_node(handle); + if (!node) { + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return (AE_BAD_PARAMETER); + } + + *ret_id = node->owner_id; + + status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return (status); +} + +ACPI_EXPORT_SYMBOL(acpi_get_id) + /******************************************************************************* * * FUNCTION: acpi_get_type diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 7767987be15a..5ba9303293ad 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -123,7 +123,6 @@ acpi_status acpi_load_tables(void) ACPI_EXPORT_SYMBOL(acpi_load_tables) -#ifdef ACPI_FUTURE_USAGE /******************************************************************************* * * FUNCTION: acpi_load_table @@ -219,6 +218,59 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr) ACPI_EXPORT_SYMBOL(acpi_load_table) +/******************************************************************************* + * + * FUNCTION: acpi_unload_table_id + * + * PARAMETERS: table_type - Type of table to be unloaded + * id - Owner ID of the table to be removed. + * + * RETURN: Status + * + * DESCRIPTION: This routine is used to force the unload of a table (by id) + * + ******************************************************************************/ +acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id) +{ + struct acpi_table_desc *table_desc; + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_unload_table); + + /* Parameter validation */ + if (table_type > ACPI_TABLE_ID_MAX) + return_ACPI_STATUS(AE_BAD_PARAMETER); + + /* Find table from the requested type list */ + table_desc = acpi_gbl_table_lists[table_type].next; + while (table_desc && table_desc->owner_id != id) + table_desc = table_desc->next; + + if (!table_desc) + return_ACPI_STATUS(AE_NOT_EXIST); + + /* + * Delete all namespace objects owned by this table. Note that these + * objects can appear anywhere in the namespace by virtue of the AML + * "Scope" operator. Thus, we need to track ownership by an ID, not + * simply a position within the hierarchy + */ + acpi_ns_delete_namespace_by_owner(table_desc->owner_id); + + status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + + (void)acpi_tb_uninstall_table(table_desc); + + (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + + return_ACPI_STATUS(AE_OK); +} + +ACPI_EXPORT_SYMBOL(acpi_unload_table_id) + +#ifdef ACPI_FUTURE_USAGE /******************************************************************************* * * FUNCTION: acpi_unload_table diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 049e9aa1b867..81458767a90e 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -97,11 +97,12 @@ acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address); acpi_status acpi_load_tables(void); -#ifdef ACPI_FUTURE_USAGE acpi_status acpi_load_table(struct acpi_table_header *table_ptr); -acpi_status acpi_unload_table(acpi_table_type table_type); +acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id); +#ifdef ACPI_FUTURE_USAGE +acpi_status acpi_unload_table(acpi_table_type table_type); acpi_status acpi_get_table_header(acpi_table_type table_type, u32 instance, struct acpi_table_header *out_table_header); @@ -180,6 +181,8 @@ acpi_get_next_object(acpi_object_type type, acpi_status acpi_get_type(acpi_handle object, acpi_object_type * out_type); +acpi_status acpi_get_id(acpi_handle object, acpi_owner_id * out_type); + acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle); /* -- cgit v1.2.3-59-g8ed1b From 36bcbec7ce21e2e8b3143b11a05747330abeca70 Mon Sep 17 00:00:00 2001 From: Burman Yan Date: Tue, 19 Dec 2006 12:56:11 -0800 Subject: ACPI: replace kmalloc+memset with kzalloc Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- arch/ia64/kernel/cpufreq/acpi-cpufreq.c | 4 +--- drivers/acpi/ac.c | 3 +-- drivers/acpi/acpi_memhotplug.c | 3 +-- drivers/acpi/asus_acpi.c | 3 +-- drivers/acpi/battery.c | 9 +++------ drivers/acpi/container.c | 3 +-- drivers/acpi/ec.c | 9 +++------ drivers/acpi/fan.c | 3 +-- drivers/acpi/i2c_ec.c | 6 ++---- drivers/acpi/ibm_acpi.c | 3 +-- drivers/acpi/pci_bind.c | 16 +++++----------- drivers/acpi/pci_irq.c | 9 +++------ drivers/acpi/pci_link.c | 6 ++---- drivers/acpi/pci_root.c | 3 +-- drivers/acpi/power.c | 3 +-- drivers/acpi/processor_core.c | 3 +-- drivers/acpi/sbs.c | 3 +-- drivers/acpi/scan.c | 3 +-- drivers/acpi/thermal.c | 7 ++----- drivers/acpi/utils.c | 6 ++---- drivers/acpi/video.c | 10 +++------- drivers/pci/hotplug/acpiphp_ibm.c | 3 +-- 22 files changed, 38 insertions(+), 80 deletions(-) diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index 088f130197ae..15c08d52f09f 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -276,12 +276,10 @@ acpi_cpufreq_cpu_init ( dprintk("acpi_cpufreq_cpu_init\n"); - data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); + data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); if (!data) return (-ENOMEM); - memset(data, 0, sizeof(struct cpufreq_acpi_io)); - acpi_io_data[cpu] = data; result = acpi_processor_register_performance(&data->acpi_data, cpu); diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 46e58663dcb5..6daeace796a8 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -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); diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 150112ae48ed..cd946ed192d3 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; diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index 7cc54aacd4c0..396140bbbe57 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -1264,10 +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 = 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); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index f47c78a10656..5f43e0d14899 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -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)) { @@ -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)) { @@ -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); diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index a15381789462..0a1863ec91f3 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -96,11 +96,10 @@ static int acpi_container_add(struct acpi_device *device) return -EINVAL; } - container = kmalloc(sizeof(struct acpi_container), GFP_KERNEL); + container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL); if (!container) return -ENOMEM; - memset(container, 0, sizeof(struct acpi_container)); container->handle = device->handle; strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS); diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 08c12588af69..9c52d87d6f04 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -624,10 +624,9 @@ static int acpi_ec_add(struct acpi_device *device) if (!device) return -EINVAL; - ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); if (!ec) return -ENOMEM; - memset(ec, 0, sizeof(struct acpi_ec)); ec->handle = device->handle; ec->uid = -1; @@ -848,12 +847,11 @@ static int __init acpi_ec_fake_ecdt(void) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT")); - ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); if (!ec_ecdt) { ret = -ENOMEM; goto error; } - memset(ec_ecdt, 0, sizeof(struct acpi_ec)); status = acpi_get_devices(ACPI_EC_HID, acpi_fake_ecdt_callback, NULL, NULL); @@ -885,10 +883,9 @@ static int __init acpi_ec_get_real_ecdt(void) /* * Generate a temporary ec context to use until the namespace is scanned */ - ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); if (!ec_ecdt) return -ENOMEM; - memset(ec_ecdt, 0, sizeof(struct acpi_ec)); mutex_init(&ec_ecdt->lock); if (acpi_ec_mode == EC_INTR) { diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index c413e69fea8e..f305a826ca2d 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -186,10 +186,9 @@ static int acpi_fan_add(struct acpi_device *device) if (!device) return -EINVAL; - fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL); + fan = kzalloc(sizeof(struct acpi_fan), GFP_KERNEL); if (!fan) return -ENOMEM; - memset(fan, 0, sizeof(struct acpi_fan)); fan->device = device; strcpy(acpi_device_name(device), "Fan"); diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c index 82e3e64483fb..8338be0990bc 100644 --- a/drivers/acpi/i2c_ec.c +++ b/drivers/acpi/i2c_ec.c @@ -309,18 +309,16 @@ static int acpi_ec_hc_add(struct acpi_device *device) return -EINVAL; } - ec_hc = kmalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL); + ec_hc = kzalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL); if (!ec_hc) { return -ENOMEM; } - memset(ec_hc, 0, sizeof(struct acpi_ec_hc)); - smbus = kmalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL); + smbus = kzalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL); if (!smbus) { kfree(ec_hc); return -ENOMEM; } - memset(smbus, 0, sizeof(struct acpi_ec_smbus)); ec_hc->handle = device->handle; strcpy(acpi_device_name(device), ACPI_EC_HC_DEVICE_NAME); diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 130cc8c37e22..0e7682a88aa8 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -2516,13 +2516,12 @@ static int __init register_driver(struct ibm_struct *ibm) { int ret; - ibm->driver = kmalloc(sizeof(struct acpi_driver), GFP_KERNEL); + ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); if (!ibm->driver) { printk(IBM_ERR "kmalloc(ibm->driver) failed\n"); return -1; } - memset(ibm->driver, 0, sizeof(struct acpi_driver)); sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name); ibm->driver->ids = ibm->hid; ibm->driver->ops.add = &ibm_device_add; diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 70b440f3f262..55f57a61c55e 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c @@ -122,19 +122,17 @@ int acpi_pci_bind(struct acpi_device *device) if (!device || !device->parent) return -EINVAL; - pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; - memset(pathname, 0, ACPI_PATHNAME_MAX); buffer.length = ACPI_PATHNAME_MAX; buffer.pointer = pathname; - data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); + data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); if (!data) { kfree(pathname); return -ENOMEM; } - memset(data, 0, sizeof(struct acpi_pci_data)); acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", @@ -281,10 +279,9 @@ int acpi_pci_unbind(struct acpi_device *device) if (!device || !device->parent) return -EINVAL; - pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; - memset(pathname, 0, ACPI_PATHNAME_MAX); buffer.length = ACPI_PATHNAME_MAX; buffer.pointer = pathname; @@ -331,11 +328,9 @@ acpi_pci_bind_root(struct acpi_device *device, char *pathname = NULL; struct acpi_buffer buffer = { 0, NULL }; - - pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; - memset(pathname, 0, ACPI_PATHNAME_MAX); buffer.length = ACPI_PATHNAME_MAX; buffer.pointer = pathname; @@ -345,12 +340,11 @@ acpi_pci_bind_root(struct acpi_device *device, return -EINVAL; } - data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); + data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); if (!data) { kfree(pathname); return -ENOMEM; } - memset(data, 0, sizeof(struct acpi_pci_data)); data->id = *id; data->bus = bus; diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 226892eaf987..fe7d007833ad 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -89,10 +89,9 @@ acpi_pci_irq_add_entry(acpi_handle handle, if (!prt) return -EINVAL; - entry = kmalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); + entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); if (!entry) return -ENOMEM; - memset(entry, 0, sizeof(struct acpi_prt_entry)); entry->id.segment = segment; entry->id.bus = bus; @@ -161,10 +160,9 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) static int first_time = 1; - pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kzalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; - memset(pathname, 0, ACPI_PATHNAME_MAX); if (first_time) { acpi_prt.count = 0; @@ -198,11 +196,10 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) return -ENODEV; } - prt = kmalloc(buffer.length, GFP_KERNEL); + prt = kzalloc(buffer.length, GFP_KERNEL); if (!prt) { return -ENOMEM; } - memset(prt, 0, buffer.length); buffer.pointer = prt; status = acpi_get_irq_routing_table(handle, &buffer); diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 812d733fe816..481e633bbf41 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -307,11 +307,10 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) if (!link || !irq) return -EINVAL; - resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); + resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); if (!resource) return -ENOMEM; - memset(resource, 0, sizeof(*resource) + 1); buffer.length = sizeof(*resource) + 1; buffer.pointer = resource; @@ -718,10 +717,9 @@ static int acpi_pci_link_add(struct acpi_device *device) if (!device) return -EINVAL; - link = kmalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); + link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); if (!link) return -ENOMEM; - memset(link, 0, sizeof(struct acpi_pci_link)); link->device = device; strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME); diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index b9c52cdbf658..a860efa2c562 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -165,10 +165,9 @@ static int acpi_pci_root_add(struct acpi_device *device) if (!device) return -EINVAL; - root = kmalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); + root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) return -ENOMEM; - memset(root, 0, sizeof(struct acpi_pci_root)); INIT_LIST_HEAD(&root->node); root->device = device; diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 23a8a9295578..0ba7dfbbb2ee 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -532,10 +532,9 @@ static int acpi_power_add(struct acpi_device *device) if (!device) return -EINVAL; - resource = kmalloc(sizeof(struct acpi_power_resource), GFP_KERNEL); + resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL); if (!resource) return -ENOMEM; - memset(resource, 0, sizeof(struct acpi_power_resource)); resource->device = device; strcpy(resource->name, device->pnp.bus_id); diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 89b3610feb47..25718fed39f1 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -615,10 +615,9 @@ static int acpi_processor_add(struct acpi_device *device) if (!device) return -EINVAL; - pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL); + pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); if (!pr) return -ENOMEM; - memset(pr, 0, sizeof(struct acpi_processor)); pr->handle = device->handle; strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 2fb7533314cd..f58fc7447ab4 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -1576,12 +1576,11 @@ static int acpi_sbs_add(struct acpi_device *device) int id, cnt; acpi_status status = AE_OK; - sbs = kmalloc(sizeof(struct acpi_sbs), GFP_KERNEL); + sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL); if (!sbs) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n")); return -ENOMEM; } - memset(sbs, 0, sizeof(struct acpi_sbs)); cnt = 0; while (cnt < 10) { diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 698a1540e303..283d87522c5d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -984,12 +984,11 @@ acpi_add_single_object(struct acpi_device **child, if (!child) return -EINVAL; - device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL); + device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); if (!device) { printk(KERN_ERR PREFIX "Memory allocation error\n"); return -ENOMEM; } - memset(device, 0, sizeof(struct acpi_device)); device->handle = handle; device->parent = parent; diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 4d75085ca2d2..40ddb4dd9631 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -902,12 +902,10 @@ acpi_thermal_write_trip_points(struct file *file, int i = 0; - limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL); + limit_string = kzalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL); if (!limit_string) return -ENOMEM; - memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN); - active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL); if (!active) { kfree(limit_string); @@ -1271,10 +1269,9 @@ static int acpi_thermal_add(struct acpi_device *device) if (!device) return -EINVAL; - tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL); + tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); if (!tz) return -ENOMEM; - memset(tz, 0, sizeof(struct acpi_thermal)); tz->device = device; strcpy(tz->name, device->pnp.bus_id); diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 91fed70a65a6..68a809fa7b19 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -262,11 +262,10 @@ acpi_evaluate_integer(acpi_handle handle, if (!data) return AE_BAD_PARAMETER; - element = kmalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); + element = kzalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); if (!element) return AE_NO_MEMORY; - memset(element, 0, sizeof(union acpi_object)); buffer.length = sizeof(union acpi_object); buffer.pointer = element; status = acpi_evaluate_object(handle, pathname, arguments, &buffer); @@ -321,12 +320,11 @@ acpi_evaluate_string(acpi_handle handle, return AE_BAD_DATA; } - *data = kmalloc(element->string.length + 1, GFP_KERNEL); + *data = kzalloc(element->string.length + 1, GFP_KERNEL); if (!data) { printk(KERN_ERR PREFIX "Memory allocation\n"); return -ENOMEM; } - memset(*data, 0, element->string.length + 1); memcpy(*data, element->string.pointer, element->string.length); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index eb5141f9ef8f..36b37d755dbc 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -533,11 +533,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) int count = 0; union acpi_object *o; - br = kmalloc(sizeof(*br), GFP_KERNEL); + br = kzalloc(sizeof(*br), GFP_KERNEL); if (!br) { printk(KERN_ERR "can't allocate memory\n"); } else { - memset(br, 0, sizeof(*br)); br->levels = kmalloc(obj->package.count * sizeof *(br->levels), GFP_KERNEL); if (!br->levels) @@ -1260,12 +1259,10 @@ acpi_video_bus_get_one_device(struct acpi_device *device, acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); if (ACPI_SUCCESS(status)) { - data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL); + data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); if (!data) return -ENOMEM; - memset(data, 0, sizeof(struct acpi_video_device)); - strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); acpi_driver_data(device) = data; @@ -1718,10 +1715,9 @@ static int acpi_video_bus_add(struct acpi_device *device) if (!device) return -EINVAL; - video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); + video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); if (!video) return -ENOMEM; - memset(video, 0, sizeof(struct acpi_video_bus)); video->device = device; strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index bd40aee10e16..7f03881a8b68 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -319,13 +319,12 @@ static int ibm_get_table_from_acpi(char **bufp) if (bufp == NULL) goto read_table_done; - lbuf = kmalloc(size, GFP_KERNEL); + lbuf = kzalloc(size, GFP_KERNEL); dbg("%s: element count: %i, ASL table size: %i, &table = 0x%p\n", __FUNCTION__, package->package.count, size, lbuf); if (lbuf) { *bufp = lbuf; - memset(lbuf, 0, size); } else { size = -ENOMEM; goto read_table_done; -- cgit v1.2.3-59-g8ed1b