From f22ff5523af8b365167cb79189f8b91470d57c8c Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 29 Jun 2013 00:24:34 +0800 Subject: ACPI / dock: avoid initializing acpi_dock_notifier_list multiple times Function dock_add() will be called multiple times if there are multiple dock stations, which causes acpi_dock_notifier_list to be initialized multiple times. To avoid that, move the initialization of acpi_dock_notifier_list from dock_add() to acpi_dock_init(). [rjw: Changelog] Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 82656075338..c36de862fd5 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -1007,7 +1007,6 @@ static int __init dock_add(acpi_handle handle) mutex_init(&dock_station->hp_lock); spin_lock_init(&dock_station->dd_lock); INIT_LIST_HEAD(&dock_station->sibling); - ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); INIT_LIST_HEAD(&dock_station->dependent_devices); /* we want the dock device to send uevents */ @@ -1078,6 +1077,7 @@ void __init acpi_dock_init(void) return; } + ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); register_acpi_bus_notifier(&dock_acpi_notifier); pr_info(PREFIX "%s: %d docks/bays found\n", ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); -- cgit v1.2.3-70-g09d2 From ed633e709fa633c6bc24f4d6ecb55ad0c14fd335 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 29 Jun 2013 00:24:35 +0800 Subject: ACPI / dock: drop redundant spin lock in dock station object All dock station objects are created during initialization and don't change at runtime, so drop the redundant spin lock from struct dock_station. [rjw: Changelog] Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index c36de862fd5..750f958ef0b 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -63,7 +63,6 @@ struct dock_station { acpi_handle handle; unsigned long last_dock_time; u32 flags; - spinlock_t dd_lock; struct mutex hp_lock; struct list_head dependent_devices; @@ -112,10 +111,7 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) dd->handle = handle; INIT_LIST_HEAD(&dd->list); - - spin_lock(&ds->dd_lock); list_add_tail(&dd->list, &ds->dependent_devices); - spin_unlock(&ds->dd_lock); return 0; } @@ -220,14 +216,10 @@ find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) { struct dock_dependent_device *dd; - spin_lock(&ds->dd_lock); - list_for_each_entry(dd, &ds->dependent_devices, list) { - if (handle == dd->handle) { - spin_unlock(&ds->dd_lock); + list_for_each_entry(dd, &ds->dependent_devices, list) + if (handle == dd->handle) return dd; - } - } - spin_unlock(&ds->dd_lock); + return NULL; } @@ -1005,7 +997,6 @@ static int __init dock_add(acpi_handle handle) dock_station->last_dock_time = jiffies - HZ; mutex_init(&dock_station->hp_lock); - spin_lock_init(&dock_station->dd_lock); INIT_LIST_HEAD(&dock_station->sibling); INIT_LIST_HEAD(&dock_station->dependent_devices); -- cgit v1.2.3-70-g09d2 From d423c083ff3b3adc1e42a2f2c03c8430a6e0220f Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 29 Jun 2013 00:24:36 +0800 Subject: ACPI / dock: mark initialization functions with __init Mark all initialization functions with __init to reduce runtime memory consumption. Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 750f958ef0b..f3ec722ae85 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -100,7 +100,7 @@ struct dock_dependent_device { * * Add the dependent device to the dock's dependent device list. */ -static int +static int __init add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) { struct dock_dependent_device *dd; @@ -244,7 +244,7 @@ static int is_dock(acpi_handle handle) return 1; } -static int is_ejectable(acpi_handle handle) +static int __init is_ejectable(acpi_handle handle) { acpi_status status; acpi_handle tmp; @@ -255,7 +255,7 @@ static int is_ejectable(acpi_handle handle) return 1; } -static int is_ata(acpi_handle handle) +static int __init is_ata(acpi_handle handle) { acpi_handle tmp; @@ -268,7 +268,7 @@ static int is_ata(acpi_handle handle) return 0; } -static int is_battery(acpi_handle handle) +static int __init is_battery(acpi_handle handle) { struct acpi_device_info *info; int ret = 1; @@ -284,7 +284,7 @@ static int is_battery(acpi_handle handle) return ret; } -static int is_ejectable_bay(acpi_handle handle) +static int __init is_ejectable_bay(acpi_handle handle) { acpi_handle phandle; @@ -848,7 +848,7 @@ static struct notifier_block dock_acpi_notifier = { * check to see if an object has an _EJD method. If it does, then it * will see if it is dependent on the dock station. */ -static acpi_status +static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; -- cgit v1.2.3-70-g09d2 From 472d963befe28b8614ea2789757b27536c8d79eb Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 29 Jun 2013 00:24:37 +0800 Subject: ACPI / dock: simplify dock_create_acpi_device() The return value of dock_create_acpi_device() is not used at all, so change its signature to return void and simplify the implementation of it. Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index f3ec722ae85..1bdb1facc17 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -351,10 +351,8 @@ static int dock_present(struct dock_station *ds) * handle if one does not exist already. This should cause * acpi to scan for drivers for the given devices, and call * matching driver's add routine. - * - * Returns a pointer to the acpi_device corresponding to the handle. */ -static struct acpi_device * dock_create_acpi_device(acpi_handle handle) +static void dock_create_acpi_device(acpi_handle handle) { struct acpi_device *device; int ret; @@ -367,10 +365,7 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle) ret = acpi_bus_scan(handle); if (ret) pr_debug("error adding bus, %x\n", -ret); - - acpi_bus_get_device(handle, &device); } - return device; } /** -- cgit v1.2.3-70-g09d2 From 952c63e9512b63220886105cfc791507046fa39a Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 29 Jun 2013 00:24:38 +0800 Subject: ACPI: introduce helper function acpi_has_method() Introduce helper function acpi_has_method() and use it in a number of places to simplify code. [rjw: Changelog] Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 11 ++--- drivers/acpi/ec.c | 4 +- drivers/acpi/processor_perflib.c | 22 +++------ drivers/acpi/resource.c | 4 +- drivers/acpi/scan.c | 99 ++++++++++++---------------------------- drivers/acpi/utils.c | 15 ++++++ drivers/acpi/video.c | 39 +++++----------- drivers/acpi/video_detect.c | 19 ++++---- include/acpi/acpi_bus.h | 3 ++ 9 files changed, 80 insertions(+), 136 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 082b4dd252a..a7627166e18 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -548,12 +548,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) static int acpi_battery_init_alarm(struct acpi_battery *battery) { - acpi_status status = AE_OK; - acpi_handle handle = NULL; - /* See if alarms are supported, and if so, set default */ - status = acpi_get_handle(battery->device->handle, "_BTP", &handle); - if (ACPI_FAILURE(status)) { + if (!acpi_has_method(battery->device->handle, "_BTP")) { clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); return 0; } @@ -1066,7 +1062,7 @@ static int acpi_battery_add(struct acpi_device *device) { int result = 0; struct acpi_battery *battery = NULL; - acpi_handle handle; + if (!device) return -EINVAL; battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); @@ -1078,8 +1074,7 @@ static int acpi_battery_add(struct acpi_device *device) device->driver_data = battery; mutex_init(&battery->lock); mutex_init(&battery->sysfs_lock); - if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, - "_BIX", &handle))) + if (acpi_has_method(battery->device->handle, "_BIX")) set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); result = acpi_battery_update(battery); if (result) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 80403c1a89f..84bf06cec1f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1049,10 +1049,8 @@ int __init acpi_ec_ecdt_probe(void) * which needs it, has fake EC._INI method, so use it as flag. * Keep boot_ec struct as it will be needed soon. */ - acpi_handle dummy; if (!dmi_name_in_vendors("ASUS") || - ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", - &dummy))) + !acpi_has_method(boot_ec->handle, "_INI")) return -ENODEV; } install: diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 1e9732d809b..51d7948611d 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -164,17 +164,12 @@ static void acpi_processor_ppc_ost(acpi_handle handle, int status) {.type = ACPI_TYPE_INTEGER,}, }; struct acpi_object_list arg_list = {2, params}; - acpi_handle temp; - params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE; - params[1].integer.value = status; - - /* when there is no _OST , skip it */ - if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp))) - return; - - acpi_evaluate_object(handle, "_OST", &arg_list, NULL); - return; + if (acpi_has_method(handle, "_OST")) { + params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE; + params[1].integer.value = status; + acpi_evaluate_object(handle, "_OST", &arg_list, NULL); + } } int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) @@ -468,14 +463,11 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) int acpi_processor_get_performance_info(struct acpi_processor *pr) { int result = 0; - acpi_status status = AE_OK; - acpi_handle handle = NULL; if (!pr || !pr->performance || !pr->handle) return -EINVAL; - status = acpi_get_handle(pr->handle, "_PCT", &handle); - if (ACPI_FAILURE(status)) { + if (!acpi_has_method(pr->handle, "_PCT")) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI-based processor performance control unavailable\n")); return -ENODEV; @@ -501,7 +493,7 @@ int acpi_processor_get_performance_info(struct acpi_processor *pr) */ update_bios: #ifdef CONFIG_X86 - if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){ + if (acpi_has_method(pr->handle, "_PPC")) { if(boot_cpu_has(X86_FEATURE_EST)) printk(KERN_WARNING FW_BUG "BIOS needs update for CPU " "frequency support\n"); diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 3322b47ab7c..b7201fc6f1e 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -505,14 +505,12 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list, void *preproc_data) { struct res_proc_context c; - acpi_handle not_used; acpi_status status; if (!adev || !adev->handle || !list_empty(list)) return -EINVAL; - status = acpi_get_handle(adev->handle, METHOD_NAME__CRS, ¬_used); - if (ACPI_FAILURE(status)) + if (!acpi_has_method(adev->handle, METHOD_NAME__CRS)) return 0; c.list = list; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 10985573aaa..ada0b4cf2ba 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -193,7 +193,6 @@ static acpi_status acpi_bus_online_companions(acpi_handle handle, u32 lvl, static int acpi_scan_hot_remove(struct acpi_device *device) { acpi_handle handle = device->handle; - acpi_handle not_used; struct acpi_object_list arg_list; union acpi_object arg; struct device *errdev; @@ -258,7 +257,7 @@ static int acpi_scan_hot_remove(struct acpi_device *device) put_device(&device->dev); device = NULL; - if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", ¬_used))) { + if (acpi_has_method(handle, "_LCK")) { arg_list.count = 1; arg_list.pointer = &arg; arg.type = ACPI_TYPE_INTEGER; @@ -652,7 +651,6 @@ static int acpi_device_setup_files(struct acpi_device *dev) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; acpi_status status; - acpi_handle temp; unsigned long long sun; int result = 0; @@ -678,8 +676,7 @@ static int acpi_device_setup_files(struct acpi_device *dev) /* * If device has _STR, 'description' file is created */ - status = acpi_get_handle(dev->handle, "_STR", &temp); - if (ACPI_SUCCESS(status)) { + if (acpi_has_method(dev->handle, "_STR")) { status = acpi_evaluate_object(dev->handle, "_STR", NULL, &buffer); if (ACPI_FAILURE(status)) @@ -709,8 +706,7 @@ static int acpi_device_setup_files(struct acpi_device *dev) * If device has _EJ0, 'eject' file is created that is used to trigger * hot-removal function from userland. */ - status = acpi_get_handle(dev->handle, "_EJ0", &temp); - if (ACPI_SUCCESS(status)) { + if (acpi_has_method(dev->handle, "_EJ0")) { result = device_create_file(&dev->dev, &dev_attr_eject); if (result) return result; @@ -732,9 +728,6 @@ end: static void acpi_device_remove_files(struct acpi_device *dev) { - acpi_status status; - acpi_handle temp; - if (dev->flags.power_manageable) { device_remove_file(&dev->dev, &dev_attr_power_state); if (dev->power.flags.power_resources) @@ -745,20 +738,17 @@ static void acpi_device_remove_files(struct acpi_device *dev) /* * If device has _STR, remove 'description' file */ - status = acpi_get_handle(dev->handle, "_STR", &temp); - if (ACPI_SUCCESS(status)) { + if (acpi_has_method(dev->handle, "_STR")) { kfree(dev->pnp.str_obj); device_remove_file(&dev->dev, &dev_attr_description); } /* * If device has _EJ0, remove 'eject' file. */ - status = acpi_get_handle(dev->handle, "_EJ0", &temp); - if (ACPI_SUCCESS(status)) + if (acpi_has_method(dev->handle, "_EJ0")) device_remove_file(&dev->dev, &dev_attr_eject); - status = acpi_get_handle(dev->handle, "_SUN", &temp); - if (ACPI_SUCCESS(status)) + if (acpi_has_method(dev->handle, "_SUN")) device_remove_file(&dev->dev, &dev_attr_sun); if (dev->pnp.unique_id) @@ -1334,13 +1324,10 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) { - acpi_handle temp; - acpi_status status = 0; int err; /* Presence of _PRW indicates wake capable */ - status = acpi_get_handle(device->handle, "_PRW", &temp); - if (ACPI_FAILURE(status)) + if (!acpi_has_method(device->handle, "_PRW")) return; err = acpi_bus_extract_wakeup_device_power_package(device->handle, @@ -1370,7 +1357,6 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state) struct acpi_device_power_state *ps = &device->power.states[state]; char pathname[5] = { '_', 'P', 'R', '0' + state, '\0' }; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - acpi_handle handle; acpi_status status; INIT_LIST_HEAD(&ps->resources); @@ -1393,8 +1379,7 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state) /* Evaluate "_PSx" to see if we can do explicit sets */ pathname[2] = 'S'; - status = acpi_get_handle(device->handle, pathname, &handle); - if (ACPI_SUCCESS(status)) + if (acpi_has_method(device->handle, pathname)) ps->flags.explicit_set = 1; /* @@ -1413,28 +1398,21 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state) static void acpi_bus_get_power_flags(struct acpi_device *device) { - acpi_status status; - acpi_handle handle; u32 i; /* Presence of _PS0|_PR0 indicates 'power manageable' */ - status = acpi_get_handle(device->handle, "_PS0", &handle); - if (ACPI_FAILURE(status)) { - status = acpi_get_handle(device->handle, "_PR0", &handle); - if (ACPI_FAILURE(status)) - return; - } + if (!acpi_has_method(device->handle, "_PS0") && + !acpi_has_method(device->handle, "_PR0")) + return; device->flags.power_manageable = 1; /* * Power Management Flags */ - status = acpi_get_handle(device->handle, "_PSC", &handle); - if (ACPI_SUCCESS(status)) + if (acpi_has_method(device->handle, "_PSC")) device->power.flags.explicit_get = 1; - status = acpi_get_handle(device->handle, "_IRC", &handle); - if (ACPI_SUCCESS(status)) + if (acpi_has_method(device->handle, "_IRC")) device->power.flags.inrush_current = 1; /* @@ -1468,28 +1446,18 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) static void acpi_bus_get_flags(struct acpi_device *device) { - acpi_status status = AE_OK; - acpi_handle temp = NULL; - /* Presence of _STA indicates 'dynamic_status' */ - status = acpi_get_handle(device->handle, "_STA", &temp); - if (ACPI_SUCCESS(status)) + if (acpi_has_method(device->handle, "_STA")) device->flags.dynamic_status = 1; /* Presence of _RMV indicates 'removable' */ - status = acpi_get_handle(device->handle, "_RMV", &temp); - if (ACPI_SUCCESS(status)) + if (acpi_has_method(device->handle, "_RMV")) device->flags.removable = 1; /* Presence of _EJD|_EJ0 indicates 'ejectable' */ - status = acpi_get_handle(device->handle, "_EJD", &temp); - if (ACPI_SUCCESS(status)) + if (acpi_has_method(device->handle, "_EJD") || + acpi_has_method(device->handle, "_EJ0")) device->flags.ejectable = 1; - else { - status = acpi_get_handle(device->handle, "_EJ0", &temp); - if (ACPI_SUCCESS(status)) - device->flags.ejectable = 1; - } } static void acpi_device_get_busid(struct acpi_device *device) @@ -1538,27 +1506,24 @@ static void acpi_device_get_busid(struct acpi_device *device) */ static int acpi_bay_match(acpi_handle handle) { - acpi_status status; - acpi_handle tmp; acpi_handle phandle; - status = acpi_get_handle(handle, "_EJ0", &tmp); - if (ACPI_FAILURE(status)) + if (!acpi_has_method(handle, "_EJ0")) return -ENODEV; - if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) + if (acpi_has_method(handle, "_GTF") || + acpi_has_method(handle, "_GTM") || + acpi_has_method(handle, "_STM") || + acpi_has_method(handle, "_SDD")) return 0; if (acpi_get_parent(handle, &phandle)) return -ENODEV; - if ((ACPI_SUCCESS(acpi_get_handle(phandle, "_GTF", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(phandle, "_GTM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(phandle, "_STM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(phandle, "_SDD", &tmp)))) + if (acpi_has_method(phandle, "_GTF") || + acpi_has_method(phandle, "_GTM") || + acpi_has_method(phandle, "_STM") || + acpi_has_method(phandle, "_SDD")) return 0; return -ENODEV; @@ -1610,7 +1575,6 @@ static void acpi_add_id(struct acpi_device_pnp *pnp, const char *dev_id) */ static int acpi_ibm_smbus_match(acpi_handle handle) { - acpi_handle h_dummy; struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; int result; @@ -1629,9 +1593,9 @@ static int acpi_ibm_smbus_match(acpi_handle handle) /* Does it have the necessary (but misnamed) methods? */ result = -ENODEV; - if (ACPI_SUCCESS(acpi_get_handle(handle, "SBI", &h_dummy)) && - ACPI_SUCCESS(acpi_get_handle(handle, "SBR", &h_dummy)) && - ACPI_SUCCESS(acpi_get_handle(handle, "SBW", &h_dummy))) + if (acpi_has_method(handle, "SBI") && + acpi_has_method(handle, "SBR") && + acpi_has_method(handle, "SBW")) result = 0; out: kfree(path.pointer); @@ -1898,7 +1862,6 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, struct acpi_device *device = NULL; int type; unsigned long long sta; - acpi_status status; int result; acpi_bus_get_device(handle, &device); @@ -1919,10 +1882,8 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, if (!(sta & ACPI_STA_DEVICE_PRESENT) && !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { struct acpi_device_wakeup wakeup; - acpi_handle temp; - status = acpi_get_handle(handle, "_PRW", &temp); - if (ACPI_SUCCESS(status)) { + if (acpi_has_method(handle, "_PRW")) { acpi_bus_extract_wakeup_device_power_package(handle, &wakeup); acpi_power_resources_list_free(&wakeup.resources); diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 74437130431..b08d97376f8 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -495,3 +495,18 @@ acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) kfree(buffer.pointer); } EXPORT_SYMBOL(acpi_handle_printk); + +/** + * acpi_has_method: Check whether @handle has a method named @name + * @handle: ACPI device handle + * @name: name of object or method + * + * Check whether @handle has a method named @name. + */ +bool acpi_has_method(acpi_handle handle, char *name) +{ + acpi_handle tmp; + + return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp)); +} +EXPORT_SYMBOL(acpi_has_method); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5d7075d2570..a84533e67b9 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -875,28 +875,21 @@ out: static void acpi_video_device_find_cap(struct acpi_video_device *device) { - acpi_handle h_dummy1; - - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { + if (acpi_has_method(device->dev->handle, "_ADR")) device->cap._ADR = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) { + if (acpi_has_method(device->dev->handle, "_BCL")) device->cap._BCL = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { + if (acpi_has_method(device->dev->handle, "_BCM")) device->cap._BCM = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) + if (acpi_has_method(device->dev->handle, "_BQC")) { device->cap._BQC = 1; - else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ", - &h_dummy1))) { + } else if (acpi_has_method(device->dev->handle, "_BCQ")) { printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n"); device->cap._BCQ = 1; } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { + if (acpi_has_method(device->dev->handle, "_DDC")) device->cap._DDC = 1; - } if (acpi_video_backlight_support()) { struct backlight_properties props; @@ -984,26 +977,18 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) static void acpi_video_bus_find_cap(struct acpi_video_bus *video) { - acpi_handle h_dummy1; - - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { + if (acpi_has_method(video->device->handle, "_DOS")) video->cap._DOS = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) { + if (acpi_has_method(video->device->handle, "_DOD")) video->cap._DOD = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) { + if (acpi_has_method(video->device->handle, "_ROM")) video->cap._ROM = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) { + if (acpi_has_method(video->device->handle, "_GPD")) video->cap._GPD = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) { + if (acpi_has_method(video->device->handle, "_SPD")) video->cap._SPD = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) { + if (acpi_has_method(video->device->handle, "_VPO")) video->cap._VPO = 1; - } } /* diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index e6bd910bc6e..ddefa5f954e 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -51,14 +51,13 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, void **retyurn_value) { long *cap = context; - acpi_handle h_dummy; - if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) && - ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) { + if (acpi_has_method(handle, "_BCM") && + acpi_has_method(handle, "_BCL")) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " "support\n")); *cap |= ACPI_VIDEO_BACKLIGHT; - if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) + if (!acpi_has_method(handle, "_BQC")) printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, " "cannot determine initial brightness\n"); /* We have backlight support, no need to scan further */ @@ -77,22 +76,20 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, */ long acpi_is_video_device(acpi_handle handle) { - acpi_handle h_dummy; long video_caps = 0; /* Is this device able to support video switching ? */ - if (ACPI_SUCCESS(acpi_get_handle(handle, "_DOD", &h_dummy)) || - ACPI_SUCCESS(acpi_get_handle(handle, "_DOS", &h_dummy))) + if (acpi_has_method(handle, "_DOD") || acpi_has_method(handle, "_DOS")) video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; /* Is this device able to retrieve a video ROM ? */ - if (ACPI_SUCCESS(acpi_get_handle(handle, "_ROM", &h_dummy))) + if (acpi_has_method(handle, "_ROM")) video_caps |= ACPI_VIDEO_ROM_AVAILABLE; /* Is this device able to configure which video head to be POSTed ? */ - if (ACPI_SUCCESS(acpi_get_handle(handle, "_VPO", &h_dummy)) && - ACPI_SUCCESS(acpi_get_handle(handle, "_GPD", &h_dummy)) && - ACPI_SUCCESS(acpi_get_handle(handle, "_SPD", &h_dummy))) + if (acpi_has_method(handle, "_VPO") && + acpi_has_method(handle, "_GPD") && + acpi_has_method(handle, "_SPD")) video_caps |= ACPI_VIDEO_DEVICE_POSTING; /* Only check for backlight functionality if one of the above hit. */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 56e6b68c8d2..62b2811bade 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -56,6 +56,9 @@ acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, acpi_status acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld); + +bool acpi_has_method(acpi_handle handle, char *name); + #ifdef CONFIG_ACPI #include -- cgit v1.2.3-70-g09d2 From 0db98202605c3d32e023d43c30b5bd878f520976 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 29 Jun 2013 00:24:39 +0800 Subject: ACPI: introduce helper function acpi_execute_simple_method() Introduce helper function acpi_execute_simple_method() and use it in a number of places to simplify code. [rjw: Changelog] Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 8 ++------ drivers/acpi/bus.c | 6 +----- drivers/acpi/power.c | 4 +--- drivers/acpi/sleep.c | 7 ++----- drivers/acpi/thermal.c | 18 ++++-------------- drivers/acpi/utils.c | 12 ++++++++++++ drivers/acpi/video.c | 17 +++++------------ include/acpi/acpi_bus.h | 2 ++ 8 files changed, 29 insertions(+), 45 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index a7627166e18..74669ac4c61 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -525,18 +525,14 @@ static int acpi_battery_get_state(struct acpi_battery *battery) static int acpi_battery_set_alarm(struct acpi_battery *battery) { acpi_status status = 0; - union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; - struct acpi_object_list arg_list = { 1, &arg0 }; if (!acpi_battery_present(battery) || !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) return -ENODEV; - arg0.integer.value = battery->alarm; - mutex_lock(&battery->lock); - status = acpi_evaluate_object(battery->device->handle, "_BTP", - &arg_list, NULL); + status = acpi_execute_simple_method(battery->device->handle, "_BTP", + battery->alarm); mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a5bb33bab44..a5a032e2344 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -593,8 +593,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) static int __init acpi_bus_init_irq(void) { acpi_status status; - union acpi_object arg = { ACPI_TYPE_INTEGER }; - struct acpi_object_list arg_list = { 1, &arg }; char *message = NULL; @@ -623,9 +621,7 @@ static int __init acpi_bus_init_irq(void) printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message); - arg.integer.value = acpi_irq_model; - - status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL); + status = acpi_execute_simple_method(NULL, "\\_PIC", acpi_irq_model); if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC")); return -ENODEV; diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 5c28c894c0f..1460c88a7c0 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -637,9 +637,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev, } /* Execute _PSW */ - arg_list.count = 1; - in_arg[0].integer.value = enable; - status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL); + status = acpi_execute_simple_method(dev->handle, "_PSW", enable); if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { printk(KERN_ERR PREFIX "_PSW execution failed\n"); dev->wakeup.flags.valid = 0; diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 187ab61889e..81b0f03d97d 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -31,12 +31,9 @@ static u8 sleep_states[ACPI_S_STATE_COUNT]; static void acpi_sleep_tts_switch(u32 acpi_state) { - union acpi_object in_arg = { ACPI_TYPE_INTEGER }; - struct acpi_object_list arg_list = { 1, &in_arg }; - acpi_status status = AE_OK; + acpi_status status; - in_arg.integer.value = acpi_state; - status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL); + status = acpi_execute_simple_method(NULL, "\\_TTS", acpi_state); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { /* * OS can't evaluate the _TTS object correctly. Some warning diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index a33821ca389..94523c79dc5 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -239,26 +239,16 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) { - acpi_status status = AE_OK; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list arg_list = { 1, &arg0 }; - acpi_handle handle = NULL; - - if (!tz) return -EINVAL; - status = acpi_get_handle(tz->device->handle, "_SCP", &handle); - if (ACPI_FAILURE(status)) { + if (!acpi_has_method(tz->device->handle, "_SCP")) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); return -ENODEV; - } - - arg0.integer.value = mode; - - status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); - if (ACPI_FAILURE(status)) + } else if (ACPI_FAILURE(acpi_execute_simple_method(tz->device->handle, + "_SCP", mode))) { return -ENODEV; + } return 0; } diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index b08d97376f8..87b85882b5d 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -510,3 +510,15 @@ bool acpi_has_method(acpi_handle handle, char *name) return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp)); } EXPORT_SYMBOL(acpi_has_method); + +acpi_status acpi_execute_simple_method(acpi_handle handle, char *method, + u64 arg) +{ + union acpi_object obj = { .type = ACPI_TYPE_INTEGER }; + struct acpi_object_list arg_list = { .count = 1, .pointer = &obj, }; + + obj.integer.value = arg; + + return acpi_evaluate_object(handle, method, &arg_list, NULL); +} +EXPORT_SYMBOL(acpi_execute_simple_method); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a84533e67b9..b862c7f7494 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -353,14 +353,10 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) { int status; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list args = { 1, &arg0 }; int state; - arg0.integer.value = level; - - status = acpi_evaluate_object(device->dev->handle, "_BCM", - &args, NULL); + status = acpi_execute_simple_method(device->dev->handle, + "_BCM", level); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Evaluating _BCM failed")); return -EIO; @@ -628,18 +624,15 @@ static int acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) { acpi_status status; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list args = { 1, &arg0 }; if (!video->cap._DOS) return 0; if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) return -EINVAL; - arg0.integer.value = (lcd_flag << 2) | bios_flag; - video->dos_setting = arg0.integer.value; - status = acpi_evaluate_object(video->device->handle, "_DOS", - &args, NULL); + video->dos_setting = (lcd_flag << 2) | bios_flag; + status = acpi_execute_simple_method(video->device->handle, "_DOS", + (lcd_flag << 2) | bios_flag); if (ACPI_FAILURE(status)) return -EIO; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 62b2811bade..e3862587b9d 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -58,6 +58,8 @@ acpi_status acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld); bool acpi_has_method(acpi_handle handle, char *name); +acpi_status acpi_execute_simple_method(acpi_handle handle, char *method, + u64 arg); #ifdef CONFIG_ACPI -- cgit v1.2.3-70-g09d2 From 7d2421f84b445dc48c68d33911f1fd6ce6853ee3 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 29 Jun 2013 00:24:40 +0800 Subject: ACPI: introduce two helper functions for _EJ0 and _LCK Introduce two helper functions, acpi_evaluate_ej0() and acpi_evaluate_lck(), that will execute the _EJ0 and _LCK ACPI control methods, respectively, and use them to simplify the ACPI scan code. [rjw: Changelog] Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 31 ++++++------------------------- drivers/acpi/utils.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/acpi/acpi_bus.h | 2 ++ 3 files changed, 51 insertions(+), 25 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ada0b4cf2ba..4c25c3b7ef8 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -193,8 +193,6 @@ static acpi_status acpi_bus_online_companions(acpi_handle handle, u32 lvl, static int acpi_scan_hot_remove(struct acpi_device *device) { acpi_handle handle = device->handle; - struct acpi_object_list arg_list; - union acpi_object arg; struct device *errdev; acpi_status status; unsigned long long sta; @@ -257,32 +255,15 @@ static int acpi_scan_hot_remove(struct acpi_device *device) put_device(&device->dev); device = NULL; - if (acpi_has_method(handle, "_LCK")) { - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 0; - acpi_evaluate_object(handle, "_LCK", &arg_list, NULL); - } - - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 1; - + acpi_evaluate_lck(handle, 0); /* * TBD: _EJD support. */ - status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); - if (ACPI_FAILURE(status)) { - if (status == AE_NOT_FOUND) { - return -ENODEV; - } else { - acpi_handle_warn(handle, "Eject failed (0x%x)\n", - status); - return -EIO; - } - } + status = acpi_evaluate_ej0(handle); + if (status == AE_NOT_FOUND) + return -ENODEV; + else if (ACPI_FAILURE(status)) + return -EIO; /* * Verify if eject was indeed successful. If not, log an error diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 87b85882b5d..552248b0005 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -522,3 +522,46 @@ acpi_status acpi_execute_simple_method(acpi_handle handle, char *method, return acpi_evaluate_object(handle, method, &arg_list, NULL); } EXPORT_SYMBOL(acpi_execute_simple_method); + +/** + * acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations + * @handle: ACPI device handle + * + * Evaluate device's _EJ0 method for hotplug operations. + */ +acpi_status acpi_evaluate_ej0(acpi_handle handle) +{ + acpi_status status; + + status = acpi_execute_simple_method(handle, "_EJ0", 1); + if (status == AE_NOT_FOUND) + acpi_handle_warn(handle, "No _EJ0 support for device\n"); + else if (ACPI_FAILURE(status)) + acpi_handle_warn(handle, "Eject failed (0x%x)\n", status); + + return status; +} + +/** + * acpi_evaluate_lck: Evaluate _LCK method to lock/unlock device + * @handle: ACPI device handle + * @lock: lock device if non-zero, otherwise unlock device + * + * Evaluate device's _LCK method if present to lock/unlock device + */ +acpi_status acpi_evaluate_lck(acpi_handle handle, int lock) +{ + acpi_status status; + + status = acpi_execute_simple_method(handle, "_LCK", !!lock); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + if (lock) + acpi_handle_warn(handle, + "Locking device failed (0x%x)\n", status); + else + acpi_handle_warn(handle, + "Unlocking device failed (0x%x)\n", status); + } + + return status; +} diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index e3862587b9d..f499157b04e 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -60,6 +60,8 @@ acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld bool acpi_has_method(acpi_handle handle, char *name); acpi_status acpi_execute_simple_method(acpi_handle handle, char *method, u64 arg); +acpi_status acpi_evaluate_ej0(acpi_handle handle); +acpi_status acpi_evaluate_lck(acpi_handle handle, int lock); #ifdef CONFIG_ACPI -- cgit v1.2.3-70-g09d2 From ebf4df8db0e7e5db9f7fca5fcd0c2b90ac954385 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 29 Jun 2013 00:24:41 +0800 Subject: ACPI: Export acpi_(bay)|(dock)_match() from scan.c Functions acpi_dock_match() and acpi_bay_match() in scan.c can be shared with dock.c to reduce code duplication, so export them as global functions. Also add a new function acpi_ata_match() to check whether an ACPI device object represents an ATA device. [rjw: Changelog] Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 77 +++++++++++++++++++++++-------------------------- include/acpi/acpi_bus.h | 3 ++ 2 files changed, 39 insertions(+), 41 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 4c25c3b7ef8..62e2055e880 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1479,44 +1479,46 @@ static void acpi_device_get_busid(struct acpi_device *device) } } +/* + * acpi_ata_match - see if an acpi object is an ATA device + * + * If an acpi object has one of the ACPI ATA methods defined, + * then we can safely call it an ATA device. + */ +bool acpi_ata_match(acpi_handle handle) +{ + return acpi_has_method(handle, "_GTF") || + acpi_has_method(handle, "_GTM") || + acpi_has_method(handle, "_STM") || + acpi_has_method(handle, "_SDD"); +} + /* * acpi_bay_match - see if an acpi object is an ejectable driver bay * * If an acpi object is ejectable and has one of the ACPI ATA methods defined, * then we can safely call it an ejectable drive bay */ -static int acpi_bay_match(acpi_handle handle) +bool acpi_bay_match(acpi_handle handle) { acpi_handle phandle; if (!acpi_has_method(handle, "_EJ0")) - return -ENODEV; + return false; + if (acpi_ata_match(handle)) + return true; + if (ACPI_FAILURE(acpi_get_parent(handle, &phandle))) + return false; - if (acpi_has_method(handle, "_GTF") || - acpi_has_method(handle, "_GTM") || - acpi_has_method(handle, "_STM") || - acpi_has_method(handle, "_SDD")) - return 0; - - if (acpi_get_parent(handle, &phandle)) - return -ENODEV; - - if (acpi_has_method(phandle, "_GTF") || - acpi_has_method(phandle, "_GTM") || - acpi_has_method(phandle, "_STM") || - acpi_has_method(phandle, "_SDD")) - return 0; - - return -ENODEV; + return acpi_ata_match(phandle); } /* * acpi_dock_match - see if an acpi object has a _DCK method */ -static int acpi_dock_match(acpi_handle handle) +bool acpi_dock_match(acpi_handle handle) { - acpi_handle tmp; - return acpi_get_handle(handle, "_DCK", &tmp); + return acpi_has_method(handle, "_DCK"); } const char *acpi_device_hid(struct acpi_device *device) @@ -1554,33 +1556,26 @@ static void acpi_add_id(struct acpi_device_pnp *pnp, const char *dev_id) * lacks the SMBUS01 HID and the methods do not have the necessary "_" * prefix. Work around this. */ -static int acpi_ibm_smbus_match(acpi_handle handle) +static bool acpi_ibm_smbus_match(acpi_handle handle) { - struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; - int result; + char node_name[ACPI_PATH_SEGMENT_LENGTH]; + struct acpi_buffer path = { sizeof(node_name), node_name }; if (!dmi_name_in_vendors("IBM")) - return -ENODEV; + return false; /* Look for SMBS object */ - result = acpi_get_name(handle, ACPI_SINGLE_NAME, &path); - if (result) - return result; - - if (strcmp("SMBS", path.pointer)) { - result = -ENODEV; - goto out; - } + if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &path)) || + strcmp("SMBS", path.pointer)) + return false; /* Does it have the necessary (but misnamed) methods? */ - result = -ENODEV; if (acpi_has_method(handle, "SBI") && acpi_has_method(handle, "SBR") && acpi_has_method(handle, "SBW")) - result = 0; -out: - kfree(path.pointer); - return result; + return true; + + return false; } static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, @@ -1628,11 +1623,11 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, */ if (acpi_is_video_device(handle)) acpi_add_id(pnp, ACPI_VIDEO_HID); - else if (ACPI_SUCCESS(acpi_bay_match(handle))) + else if (acpi_bay_match(handle)) acpi_add_id(pnp, ACPI_BAY_HID); - else if (ACPI_SUCCESS(acpi_dock_match(handle))) + else if (acpi_dock_match(handle)) acpi_add_id(pnp, ACPI_DOCK_HID); - else if (!acpi_ibm_smbus_match(handle)) + else if (acpi_ibm_smbus_match(handle)) acpi_add_id(pnp, ACPI_SMBUS_IBM_HID); else if (list_empty(&pnp->ids) && handle == ACPI_ROOT_OBJECT) { acpi_add_id(pnp, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f499157b04e..facc0ba6dd2 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -62,6 +62,9 @@ acpi_status acpi_execute_simple_method(acpi_handle handle, char *method, u64 arg); acpi_status acpi_evaluate_ej0(acpi_handle handle); acpi_status acpi_evaluate_lck(acpi_handle handle, int lock); +bool acpi_ata_match(acpi_handle handle); +bool acpi_bay_match(acpi_handle handle); +bool acpi_dock_match(acpi_handle handle); #ifdef CONFIG_ACPI -- cgit v1.2.3-70-g09d2 From c9b5471f8866956919955b70ab27b4737b8bce30 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 29 Jun 2013 00:24:42 +0800 Subject: ACPI: simplify dock driver with new helper functions Use helper functions introduced previously to simplify the ACPI dock driver. [rjw: Changelog] Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 122 ++++++---------------------------------------------- 1 file changed, 12 insertions(+), 110 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 1bdb1facc17..810d1d720b1 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -226,48 +226,6 @@ find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) /***************************************************************************** * Dock functions * *****************************************************************************/ -/** - * is_dock - see if a device is a dock station - * @handle: acpi handle of the device - * - * If an acpi object has a _DCK method, then it is by definition a dock - * station, so return true. - */ -static int is_dock(acpi_handle handle) -{ - acpi_status status; - acpi_handle tmp; - - status = acpi_get_handle(handle, "_DCK", &tmp); - if (ACPI_FAILURE(status)) - return 0; - return 1; -} - -static int __init is_ejectable(acpi_handle handle) -{ - acpi_status status; - acpi_handle tmp; - - status = acpi_get_handle(handle, "_EJ0", &tmp); - if (ACPI_FAILURE(status)) - return 0; - return 1; -} - -static int __init is_ata(acpi_handle handle) -{ - acpi_handle tmp; - - if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || - (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) - return 1; - - return 0; -} - static int __init is_battery(acpi_handle handle) { struct acpi_device_info *info; @@ -284,17 +242,13 @@ static int __init is_battery(acpi_handle handle) return ret; } -static int __init is_ejectable_bay(acpi_handle handle) +/* Check whether ACPI object is an ejectable battery or disk bay */ +static bool __init is_ejectable_bay(acpi_handle handle) { - acpi_handle phandle; + if (acpi_has_method(handle, "_EJ0") && is_battery(handle)) + return true; - if (!is_ejectable(handle)) - return 0; - if (is_battery(handle) || is_ata(handle)) - return 1; - if (!acpi_get_parent(handle, &phandle) && is_ata(phandle)) - return 1; - return 0; + return acpi_bay_match(handle); } /** @@ -312,7 +266,7 @@ int is_dock_device(acpi_handle handle) if (!dock_station_count) return 0; - if (is_dock(handle)) + if (acpi_dock_match(handle)) return 1; list_for_each_entry(dock_station, &dock_stations, sibling) @@ -446,37 +400,6 @@ static void dock_event(struct dock_station *ds, u32 event, int num) kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); } -/** - * eject_dock - respond to a dock eject request - * @ds: the dock station - * - * This is called after _DCK is called, to execute the dock station's - * _EJ0 method. - */ -static void eject_dock(struct dock_station *ds) -{ - struct acpi_object_list arg_list; - union acpi_object arg; - acpi_status status; - acpi_handle tmp; - - /* all dock devices should have _EJ0, but check anyway */ - status = acpi_get_handle(ds->handle, "_EJ0", &tmp); - if (ACPI_FAILURE(status)) { - pr_debug("No _EJ0 support for dock device\n"); - return; - } - - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 1; - - status = acpi_evaluate_object(ds->handle, "_EJ0", &arg_list, NULL); - if (ACPI_FAILURE(status)) - pr_debug("Failed to evaluate _EJ0!\n"); -} - /** * handle_dock - handle a dock event * @ds: the dock station @@ -537,27 +460,6 @@ static inline void complete_undock(struct dock_station *ds) ds->flags &= ~(DOCK_UNDOCKING); } -static void dock_lock(struct dock_station *ds, int lock) -{ - struct acpi_object_list arg_list; - union acpi_object arg; - acpi_status status; - - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = !!lock; - status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - if (lock) - acpi_handle_warn(ds->handle, - "Locking device failed (0x%x)\n", status); - else - acpi_handle_warn(ds->handle, - "Unlocking device failed (0x%x)\n", status); - } -} - /** * dock_in_progress - see if we are in the middle of handling a dock event * @ds: the dock station @@ -692,8 +594,8 @@ static int handle_eject_request(struct dock_station *ds, u32 event) hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); undock(ds); - dock_lock(ds, 0); - eject_dock(ds); + acpi_evaluate_lck(ds->handle, 0); + acpi_evaluate_ej0(ds->handle); if (dock_present(ds)) { acpi_handle_err(ds->handle, "Unable to undock!\n"); return -EBUSY; @@ -752,7 +654,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) hotplug_dock_devices(ds, event); complete_dock(ds); dock_event(ds, event, DOCK_EVENT); - dock_lock(ds, 1); + acpi_evaluate_lck(ds->handle, 1); acpi_update_all_gpes(); break; } @@ -998,9 +900,9 @@ static int __init dock_add(acpi_handle handle) /* we want the dock device to send uevents */ dev_set_uevent_suppress(&dd->dev, 0); - if (is_dock(handle)) + if (acpi_dock_match(handle)) dock_station->flags |= DOCK_IS_DOCK; - if (is_ata(handle)) + if (acpi_ata_match(handle)) dock_station->flags |= DOCK_IS_ATA; if (is_battery(handle)) dock_station->flags |= DOCK_IS_BAT; @@ -1043,7 +945,7 @@ err_unregister: static __init acpi_status find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) { - if (is_dock(handle) || is_ejectable_bay(handle)) + if (acpi_dock_match(handle) || is_ejectable_bay(handle)) dock_add(handle); return AE_OK; -- cgit v1.2.3-70-g09d2 From d460acebd7959cc91e7edc594d90adb9b72a0b05 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 30 Jun 2013 23:42:51 +0200 Subject: ACPI / dock: Drop the hp_lock mutex from struct dock_station The only existing user of the hp_lock mutex in struct dock_station, hotplug_dock_devices(), is always called under acpi_scan_lock and cannot race with another instance of itself, so drop the mutex which is not necessary. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 810d1d720b1..c10761533d6 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -63,7 +63,6 @@ struct dock_station { acpi_handle handle; unsigned long last_dock_time; u32 flags; - struct mutex hp_lock; struct list_head dependent_devices; struct list_head sibling; @@ -351,8 +350,6 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) { struct dock_dependent_device *dd; - mutex_lock(&ds->hp_lock); - /* * First call driver specific hotplug functions */ @@ -371,7 +368,6 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) else dock_create_acpi_device(dd->handle); } - mutex_unlock(&ds->hp_lock); } static void dock_event(struct dock_station *ds, u32 event, int num) @@ -893,7 +889,6 @@ static int __init dock_add(acpi_handle handle) dock_station->dock_device = dd; dock_station->last_dock_time = jiffies - HZ; - mutex_init(&dock_station->hp_lock); INIT_LIST_HEAD(&dock_station->sibling); INIT_LIST_HEAD(&dock_station->dependent_devices); -- cgit v1.2.3-70-g09d2 From 96c0a4d4902c3d5f56bde95d3e2d96689ca64b6d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 30 Jun 2013 23:46:02 +0200 Subject: ACPI / dock: Rework and simplify find_dock_devices() Since acpi_walk_namespace() calls find_dock_devices() during tree pre-order visit, the latter doesn't need to add devices whose parents have _EJD pointing to the docking station to the list of that station's dependent devices, because those parents are going to be added to that list anyway and the removal of a parent will take care of the removal of its children in those cases. For this reason, rework find_dock_devices() to only call add_dock_dependent_device() for devices whose _EJD point directy to the docking station represented by its context argument and simplify it slightly. Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu --- drivers/acpi/dock.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index c10761533d6..7c86d01346e 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -741,29 +741,16 @@ static struct notifier_block dock_acpi_notifier = { * check to see if an object has an _EJD method. If it does, then it * will see if it is dependent on the dock station. */ -static acpi_status __init -find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) +static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl, + void *context, void **rv) { - acpi_status status; - acpi_handle tmp, parent; struct dock_station *ds = context; + acpi_handle ejd = NULL; - status = acpi_bus_get_ejd(handle, &tmp); - if (ACPI_FAILURE(status)) { - /* try the parent device as well */ - status = acpi_get_parent(handle, &parent); - if (ACPI_FAILURE(status)) - goto fdd_out; - /* see if parent is dependent on dock */ - status = acpi_bus_get_ejd(parent, &tmp); - if (ACPI_FAILURE(status)) - goto fdd_out; - } - - if (tmp == ds->handle) + acpi_bus_get_ejd(handle, &ejd); + if (ejd == ds->handle) add_dock_dependent_device(ds, handle); -fdd_out: return AE_OK; } -- cgit v1.2.3-70-g09d2 From 37f908778f20bbcc35ab9a98a5b584329c6abf08 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 30 Jun 2013 23:46:42 +0200 Subject: ACPI / dock: Walk list in reverse order during removal of devices If there are indirect dependencies between devices in a dock station's dependent devices list, they may be broken if the devices are removed in the same order in which they have been added. For this reason, make the code in handle_eject_request() walk the list of dependent devices in reverse order. Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu --- drivers/acpi/dock.c | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 7c86d01346e..41c5d04a89c 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -337,9 +337,29 @@ static void dock_remove_acpi_device(acpi_handle handle) } /** - * hotplug_dock_devices - insert or remove devices on the dock station + * hot_remove_dock_devices - Remove dock station devices. + * @ds: Dock station. + */ +static void hot_remove_dock_devices(struct dock_station *ds) +{ + struct dock_dependent_device *dd; + + /* + * Walk the list in reverse order so that devices that have been added + * last are removed first (in case there are some indirect dependencies + * between them). + */ + list_for_each_entry_reverse(dd, &ds->dependent_devices, list) + dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false); + + list_for_each_entry_reverse(dd, &ds->dependent_devices, list) + dock_remove_acpi_device(dd->handle); +} + +/** + * hotplug_dock_devices - Insert devices on a dock station. * @ds: the dock station - * @event: either bus check or eject request + * @event: either bus check or device check request * * Some devices on the dock station need to have drivers called * to perform hotplug operations after a dock event has occurred. @@ -350,24 +370,17 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) { struct dock_dependent_device *dd; - /* - * First call driver specific hotplug functions - */ + /* Call driver specific hotplug functions. */ list_for_each_entry(dd, &ds->dependent_devices, list) dock_hotplug_event(dd, event, false); /* - * Now make sure that an acpi_device is created for each - * dependent device, or removed if this is an eject request. - * This will cause acpi_drivers to be stopped/started if they - * exist + * Now make sure that an acpi_device is created for each dependent + * device. That will cause scan handlers to be attached to device + * objects or acpi_drivers to be stopped/started if they are present. */ - list_for_each_entry(dd, &ds->dependent_devices, list) { - if (event == ACPI_NOTIFY_EJECT_REQUEST) - dock_remove_acpi_device(dd->handle); - else - dock_create_acpi_device(dd->handle); - } + list_for_each_entry(dd, &ds->dependent_devices, list) + dock_create_acpi_device(dd->handle); } static void dock_event(struct dock_station *ds, u32 event, int num) @@ -588,7 +601,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event) */ dock_event(ds, event, UNDOCK_EVENT); - hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); + hot_remove_dock_devices(ds); undock(ds); acpi_evaluate_lck(ds->handle, 0); acpi_evaluate_ej0(ds->handle); -- cgit v1.2.3-70-g09d2 From 4ec24065a65b4debfdeb591cc01a4aa092651f53 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 30 Jun 2013 23:47:14 +0200 Subject: ACPI / dock: Simplify dock_init_hotplug() and dock_release_hotplug() Make dock_init_hotplug() and dock_release_hotplug() slightly simpler and move some checks in those functions to the code paths where they are needed. Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu --- drivers/acpi/dock.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 41c5d04a89c..b1170d60a83 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -130,19 +130,16 @@ static int dock_init_hotplug(struct dock_dependent_device *dd, int ret = 0; mutex_lock(&hotplug_lock); - - if (dd->hp_context) { + if (WARN_ON(dd->hp_context)) { ret = -EEXIST; } else { dd->hp_refcount = 1; dd->hp_ops = ops; dd->hp_context = context; dd->hp_release = release; + if (init) + init(context); } - - if (!WARN_ON(ret) && init) - init(context); - mutex_unlock(&hotplug_lock); return ret; } @@ -157,22 +154,17 @@ static int dock_init_hotplug(struct dock_dependent_device *dd, */ static void dock_release_hotplug(struct dock_dependent_device *dd) { - void (*release)(void *) = NULL; - void *context = NULL; - mutex_lock(&hotplug_lock); - if (dd->hp_context && !--dd->hp_refcount) { + void (*release)(void *) = dd->hp_release; + void *context = dd->hp_context; + dd->hp_ops = NULL; - context = dd->hp_context; dd->hp_context = NULL; - release = dd->hp_release; dd->hp_release = NULL; + if (release) + release(context); } - - if (release && context) - release(context); - mutex_unlock(&hotplug_lock); } -- cgit v1.2.3-70-g09d2 From 59401ccce8729e5c43f9781cc5570da5ca470e27 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 30 Jun 2013 23:48:49 +0200 Subject: ACPI / dock: Rework the handling of notifications The ACPI dock driver uses register_acpi_bus_notifier() which installs a notifier triggered globally for all system notifications. That first of all is inefficient, because the dock driver is only interested in notifications associated with the devices it handles, but it has to handle all system notifies for all devices. Moreover, it does that even if no docking stations are present in the system (CONFIG_ACPI_DOCK set is sufficient for that to happen). Besides, that is inconvenient, because it requires the driver to do extra work for each notification to find the target dock station object. For these reasons, rework the dock driver to install a notify handler individually for each dock station in the system using acpi_install_notify_handler(). This allows the dock station object to be passed directly to the notify handler and makes it possible to simplify the dock driver quite a bit. It also reduces the overhead related to the handling of all system notifies when CONFIG_ACPI_DOCK is set. Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu --- drivers/acpi/dock.c | 67 +++++++++++++++++++---------------------------------- 1 file changed, 24 insertions(+), 43 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index b1170d60a83..a326c7993f4 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -607,18 +607,17 @@ static int handle_eject_request(struct dock_station *ds, u32 event) /** * dock_notify - act upon an acpi dock notification - * @handle: the dock station handle + * @ds: dock station * @event: the acpi event - * @data: our driver data struct * * 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. */ -static void dock_notify(acpi_handle handle, u32 event, void *data) +static void dock_notify(struct dock_station *ds, u32 event) { - struct dock_station *ds = data; - struct acpi_device *tmp; + acpi_handle handle = ds->handle; + struct acpi_device *ad; int surprise_removal = 0; /* @@ -641,8 +640,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) switch (event) { case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: - if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle, - &tmp)) { + if (!dock_in_progress(ds) && acpi_bus_get_device(handle, &ad)) { begin_dock(ds); dock(ds); if (!dock_present(ds)) { @@ -679,9 +677,8 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) } struct dock_data { - acpi_handle handle; - unsigned long event; struct dock_station *ds; + u32 event; }; static void acpi_dock_deferred_cb(void *context) @@ -689,52 +686,31 @@ static void acpi_dock_deferred_cb(void *context) struct dock_data *data = context; acpi_scan_lock_acquire(); - dock_notify(data->handle, data->event, data->ds); + dock_notify(data->ds, data->event); acpi_scan_lock_release(); kfree(data); } -static int acpi_dock_notifier_call(struct notifier_block *this, - unsigned long event, void *data) +static void dock_notify_handler(acpi_handle handle, u32 event, void *data) { - struct dock_station *dock_station; - acpi_handle handle = data; + struct dock_data *dd; if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK && event != ACPI_NOTIFY_EJECT_REQUEST) - return 0; - - acpi_scan_lock_acquire(); - - list_for_each_entry(dock_station, &dock_stations, sibling) { - if (dock_station->handle == handle) { - struct dock_data *dd; - acpi_status status; - - dd = kmalloc(sizeof(*dd), GFP_KERNEL); - if (!dd) - break; + return; - dd->handle = handle; - dd->event = event; - dd->ds = dock_station; - status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, - dd); - if (ACPI_FAILURE(status)) - kfree(dd); + dd = kmalloc(sizeof(*dd), GFP_KERNEL); + if (dd) { + acpi_status status; - break; - } + dd->ds = data; + dd->event = event; + status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); + if (ACPI_FAILURE(status)) + kfree(dd); } - - acpi_scan_lock_release(); - return 0; } -static struct notifier_block dock_acpi_notifier = { - .notifier_call = acpi_dock_notifier_call, -}; - /** * find_dock_devices - find devices on the dock station * @handle: the handle of the device we are examining @@ -868,6 +844,7 @@ static int __init dock_add(acpi_handle handle) int ret, id; struct dock_station ds, *dock_station; struct platform_device *dd; + acpi_status status; id = dock_station_count; memset(&ds, 0, sizeof(ds)); @@ -908,6 +885,11 @@ static int __init dock_add(acpi_handle handle) if (ret) goto err_rmgroup; + status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + dock_notify_handler, dock_station); + if (ACPI_FAILURE(status)) + goto err_rmgroup; + dock_station_count++; list_add(&dock_station->sibling, &dock_stations); return 0; @@ -953,7 +935,6 @@ void __init acpi_dock_init(void) } ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); - register_acpi_bus_notifier(&dock_acpi_notifier); pr_info(PREFIX "%s: %d docks/bays found\n", ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); } -- cgit v1.2.3-70-g09d2 From f716fc2ac037c45a6c641eb9f20ec602e8d04e14 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 30 Jun 2013 23:49:55 +0200 Subject: ACPI: Drop ACPI bus notifier call chain There are no users of the ACPI bus notifier call chain, acpi_bus_notify_list, any more, so drop it. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 16 ---------------- include/acpi/acpi_bus.h | 2 -- 2 files changed, 18 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a5a032e2344..6fd27a9abcd 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -499,19 +499,6 @@ static void acpi_bus_check_scope(acpi_handle handle) */ } -static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list); -int register_acpi_bus_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&acpi_bus_notify_list, nb); -} -EXPORT_SYMBOL_GPL(register_acpi_bus_notifier); - -void unregister_acpi_bus_notifier(struct notifier_block *nb) -{ - blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb); -} -EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier); - /** * acpi_bus_notify * --------------- @@ -525,9 +512,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", type, handle)); - blocking_notifier_call_chain(&acpi_bus_notify_list, - type, (void *)handle); - switch (type) { case ACPI_NOTIFY_BUS_CHECK: diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index facc0ba6dd2..71f3fd429fd 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -366,8 +366,6 @@ extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); extern int register_acpi_notifier(struct notifier_block *); extern int unregister_acpi_notifier(struct notifier_block *); -extern int register_acpi_bus_notifier(struct notifier_block *nb); -extern void unregister_acpi_bus_notifier(struct notifier_block *nb); /* * External Functions */ -- cgit v1.2.3-70-g09d2 From a30c4c5ee85680bb66ed8a6c0b0bf4921125c378 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 30 Jun 2013 23:50:24 +0200 Subject: ACPI / dock: Do not leak memory on falilures to add a dock station The function creating and registering dock station objects, dock_add(), leaks memory if there's an error after it's walked the ACPI namespace calling find_dock_devices(), because it doesn't free the list of dependent devices it's just created in those cases. Fix that issue by adding the missing code to free the list of dependent devices on errors. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index a326c7993f4..3e20b13fa27 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -115,6 +115,16 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) return 0; } +static void remove_dock_dependent_devices(struct dock_station *ds) +{ + struct dock_dependent_device *dd, *aux; + + list_for_each_entry_safe(dd, aux, &ds->dependent_devices, list) { + list_del(&dd->list); + kfree(dd); + } +} + /** * dock_init_hotplug - Initialize a hotplug device on a docking station. * @dd: Dock-dependent device. @@ -895,6 +905,7 @@ static int __init dock_add(acpi_handle handle) return 0; err_rmgroup: + remove_dock_dependent_devices(dock_station); sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); err_unregister: platform_device_unregister(dd); -- cgit v1.2.3-70-g09d2 From f09ce741a03ad7de591aa47e760fbeee28567b63 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 5 Jul 2013 03:03:25 +0200 Subject: ACPI / dock / PCI: Drop ACPI dock notifier chain The only user of the ACPI dock notifier chain is the ACPI-based PCI hotplug (acpiphp) driver that uses it to carry out post-dock fixups needed by some systems with broken _DCK. However, it is not necessary to use a separate notifier chain for that, as it can be simply replaced with a new callback in struct acpi_dock_ops. For this reason, add a new .fixup() callback to struct acpi_dock_ops and make hotplug_dock_devices() execute it for all dock devices with hotplug operations registered. Accordingly, make acpiphp point that callback to the function carrying out the post-dock fixups and do not register a separate dock notifier for each device registering dock operations. Finally, drop the ACPI dock notifier chain that has no more users. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 66 +++++++++++++++----------------------- drivers/pci/hotplug/acpiphp.h | 1 - drivers/pci/hotplug/acpiphp_glue.c | 18 +++-------- include/acpi/acpi_drivers.h | 10 +----- 4 files changed, 30 insertions(+), 65 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 3e20b13fa27..c89a9c3b48b 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -51,8 +51,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " " the driver to wait for userspace to write the undock sysfs file " " before undocking"); -static struct atomic_notifier_head dock_notifier_list; - static const struct acpi_device_id dock_device_ids[] = { {"LNXDOCK", 0}, {"", 0}, @@ -89,6 +87,12 @@ struct dock_dependent_device { #define DOCK_EVENT 3 #define UNDOCK_EVENT 2 +enum dock_callback_type { + DOCK_CALL_HANDLER, + DOCK_CALL_FIXUP, + DOCK_CALL_UEVENT, +}; + /***************************************************************************** * Dock Dependent device functions * *****************************************************************************/ @@ -179,7 +183,7 @@ static void dock_release_hotplug(struct dock_dependent_device *dd) } static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, - bool uevent) + enum dock_callback_type cb_type) { acpi_notify_handler cb = NULL; bool run = false; @@ -189,8 +193,18 @@ static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, if (dd->hp_context) { run = true; dd->hp_refcount++; - if (dd->hp_ops) - cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler; + if (dd->hp_ops) { + switch (cb_type) { + case DOCK_CALL_FIXUP: + cb = dd->hp_ops->fixup; + break; + case DOCK_CALL_UEVENT: + cb = dd->hp_ops->uevent; + break; + default: + cb = dd->hp_ops->handler; + } + } } mutex_unlock(&hotplug_lock); @@ -372,9 +386,13 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) { struct dock_dependent_device *dd; + /* Call driver specific post-dock fixups. */ + list_for_each_entry(dd, &ds->dependent_devices, list) + dock_hotplug_event(dd, event, DOCK_CALL_FIXUP); + /* Call driver specific hotplug functions. */ list_for_each_entry(dd, &ds->dependent_devices, list) - dock_hotplug_event(dd, event, false); + dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); /* * Now make sure that an acpi_device is created for each dependent @@ -405,7 +423,7 @@ static void dock_event(struct dock_station *ds, u32 event, int num) kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); list_for_each_entry(dd, &ds->dependent_devices, list) - dock_hotplug_event(dd, event, true); + dock_hotplug_event(dd, event, DOCK_CALL_UEVENT); if (num != DOCK_EVENT) kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); @@ -487,37 +505,6 @@ static int dock_in_progress(struct dock_station *ds) return 0; } -/** - * register_dock_notifier - add yourself to the dock notifier list - * @nb: the callers notifier block - * - * If a driver wishes to be notified about dock events, they can - * use this function to put a notifier block on the dock notifier list. - * this notifier call chain will be called after a dock event, but - * before hotplugging any new devices. - */ -int register_dock_notifier(struct notifier_block *nb) -{ - if (!dock_station_count) - return -ENODEV; - - return atomic_notifier_chain_register(&dock_notifier_list, nb); -} -EXPORT_SYMBOL_GPL(register_dock_notifier); - -/** - * unregister_dock_notifier - remove yourself from the dock notifier list - * @nb: the callers notifier block - */ -void unregister_dock_notifier(struct notifier_block *nb) -{ - if (!dock_station_count) - return; - - atomic_notifier_chain_unregister(&dock_notifier_list, nb); -} -EXPORT_SYMBOL_GPL(unregister_dock_notifier); - /** * register_hotplug_dock_device - register a hotplug function * @handle: the handle of the device @@ -658,8 +645,6 @@ static void dock_notify(struct dock_station *ds, u32 event) complete_dock(ds); break; } - atomic_notifier_call_chain(&dock_notifier_list, - event, NULL); hotplug_dock_devices(ds, event); complete_dock(ds); dock_event(ds, event, DOCK_EVENT); @@ -945,7 +930,6 @@ void __init acpi_dock_init(void) return; } - ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); pr_info(PREFIX "%s: %d docks/bays found\n", ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); } diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 6fdd49c6f0b..6c781edabcc 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -122,7 +122,6 @@ struct acpiphp_func { struct acpiphp_slot *slot; /* parent */ struct list_head sibling; - struct notifier_block nb; acpi_handle handle; u8 function; /* pci function# */ diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a0a7133a1d1..8bfad0dc29a 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -119,15 +119,14 @@ static void free_bridge(struct kref *kref) * TBD - figure out a way to only call fixups for * systems that require them. */ -static int post_dock_fixups(struct notifier_block *nb, unsigned long val, - void *v) +static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) { - struct acpiphp_func *func = container_of(nb, struct acpiphp_func, nb); + struct acpiphp_func *func = data; struct pci_bus *bus = func->slot->bridge->pci_bus; u32 buses; if (!bus->self) - return NOTIFY_OK; + return; /* fixup bad _DCK function that rewrites * secondary bridge on slot @@ -143,11 +142,11 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, | ((unsigned int)(bus->busn_res.end) << 16); pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); } - return NOTIFY_OK; } static const struct acpi_dock_ops acpiphp_dock_ops = { + .fixup = post_dock_fixups, .handler = hotplug_event_func, }; @@ -315,14 +314,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) &acpiphp_dock_ops, newfunc, acpiphp_dock_init, acpiphp_dock_release)) dbg("failed to register dock device\n"); - - /* we need to be notified when dock events happen - * outside of the hotplug operation, since we may - * need to do fixups before we can hotplug. - */ - newfunc->nb.notifier_call = post_dock_fixups; - if (register_dock_notifier(&newfunc->nb)) - dbg("failed to register a dock notifier"); } /* install notify handler */ @@ -472,7 +463,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) list_for_each_entry(func, &slot->funcs, sibling) { if (is_dock_device(func->handle)) { unregister_hotplug_dock_device(func->handle); - unregister_dock_notifier(&func->nb); } if (!(func->flags & FUNC_HAS_DCK)) { status = acpi_remove_notify_handler(func->handle, diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 0cf85786ed2..1cedfcb1bd8 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -113,14 +113,13 @@ void pci_acpi_crs_quirks(void); Dock Station -------------------------------------------------------------------------- */ struct acpi_dock_ops { + acpi_notify_handler fixup; acpi_notify_handler handler; acpi_notify_handler uevent; }; #ifdef CONFIG_ACPI_DOCK extern int is_dock_device(acpi_handle handle); -extern int register_dock_notifier(struct notifier_block *nb); -extern void unregister_dock_notifier(struct notifier_block *nb); extern int register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops, void *context, @@ -132,13 +131,6 @@ static inline int is_dock_device(acpi_handle handle) { return 0; } -static inline int register_dock_notifier(struct notifier_block *nb) -{ - return -ENODEV; -} -static inline void unregister_dock_notifier(struct notifier_block *nb) -{ -} static inline int register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops, void *context, -- cgit v1.2.3-70-g09d2 From 2efbca4dfc7b43951de6dd1647f9eebda9d4372b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 5 Jul 2013 03:23:36 +0200 Subject: ACPI / dock: Drop unnecessary local variable from dock_add() The local variable id in dock_add() is not necessary, so drop it. While we're at it, use an initializer to clear the local variable ds and drop the memset() used for this purpose. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index c89a9c3b48b..f601658a4ad 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -836,14 +836,13 @@ static struct attribute_group dock_attribute_group = { */ static int __init dock_add(acpi_handle handle) { - int ret, id; - struct dock_station ds, *dock_station; + struct dock_station *dock_station, ds = { NULL, }; struct platform_device *dd; acpi_status status; + int ret; - id = dock_station_count; - memset(&ds, 0, sizeof(ds)); - dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds)); + dd = platform_device_register_data(NULL, "dock", dock_station_count, + &ds, sizeof(ds)); if (IS_ERR(dd)) return PTR_ERR(dd); -- cgit v1.2.3-70-g09d2 From 1696d9dc57e062ce5200f6a42a6aaada15b434bb Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 15 Jul 2013 10:15:09 +0200 Subject: ACPI: Remove the old /proc/acpi/event interface It is quite some time that this one has been deprecated. Get rid of it. Should some really important user be overseen, it may be reverted and the userspace program worked on first, but it is time to do something to get rid of this old stuff... Signed-off-by: Thomas Renninger Acked-by: Matthew Garrett Acked-by: Henrique de Moraes Holschuh Signed-off-by: Rafael J. Wysocki --- Documentation/laptops/asus-laptop.txt | 8 +-- Documentation/laptops/sony-laptop.txt | 8 +-- drivers/acpi/Kconfig | 18 ------ drivers/acpi/ac.c | 1 - drivers/acpi/acpi_pad.c | 1 - drivers/acpi/battery.c | 2 - drivers/acpi/bus.c | 98 ----------------------------- drivers/acpi/button.c | 2 - drivers/acpi/event.c | 106 -------------------------------- drivers/acpi/processor_driver.c | 4 -- drivers/acpi/sbs.c | 15 +---- drivers/acpi/thermal.c | 3 - drivers/acpi/video.c | 10 --- drivers/char/sonypi.c | 5 -- drivers/pci/hotplug/acpiphp_ibm.c | 1 - drivers/platform/x86/asus-laptop.c | 1 - drivers/platform/x86/eeepc-laptop.c | 1 - drivers/platform/x86/fujitsu-laptop.c | 4 -- drivers/platform/x86/panasonic-laptop.c | 3 - drivers/platform/x86/sony-laptop.c | 4 -- drivers/platform/x86/thinkpad_acpi.c | 11 ---- include/acpi/acpi_bus.h | 9 --- 22 files changed, 10 insertions(+), 305 deletions(-) (limited to 'drivers/acpi') diff --git a/Documentation/laptops/asus-laptop.txt b/Documentation/laptops/asus-laptop.txt index 69f9fb3701e..79a1bc675a8 100644 --- a/Documentation/laptops/asus-laptop.txt +++ b/Documentation/laptops/asus-laptop.txt @@ -8,8 +8,8 @@ http://acpi4asus.sf.net/ This driver provides support for extra features of ACPI-compatible ASUS laptops. It may also support some MEDION, JVC or VICTOR laptops (such as MEDION 9675 or - VICTOR XP7210 for example). It makes all the extra buttons generate standard - ACPI events that go through /proc/acpi/events and input events (like keyboards). + VICTOR XP7210 for example). It makes all the extra buttons generate input + events (like keyboards). On some models adds support for changing the display brightness and output, switching the LCD backlight on and off, and most importantly, allows you to blink those fancy LEDs intended for reporting mail and wireless status. @@ -55,8 +55,8 @@ Usage DSDT) to me. That's all, now, all the events generated by the hotkeys of your laptop - should be reported in your /proc/acpi/event entry. You can check with - "acpi_listen". + should be reported via netlink events. You can check with + "acpi_genl monitor" (part of the acpica project). Hotkeys are also reported as input keys (like keyboards) you can check which key are supported using "xev" under X11. diff --git a/Documentation/laptops/sony-laptop.txt b/Documentation/laptops/sony-laptop.txt index 0d5ac7f5287..978b1e61515 100644 --- a/Documentation/laptops/sony-laptop.txt +++ b/Documentation/laptops/sony-laptop.txt @@ -12,10 +12,10 @@ Fn keys (hotkeys): ------------------ Some models report hotkeys through the SNC or SPIC devices, such events are reported both through the ACPI subsystem as acpi events and through the INPUT -subsystem. See the logs of acpid or /proc/acpi/event and -/proc/bus/input/devices to find out what those events are and which input -devices are created by the driver. Additionally, loading the driver with the -debug option will report all events in the kernel log. +subsystem. See the logs of /proc/bus/input/devices to find out what those +events are and which input devices are created by the driver. +Additionally, loading the driver with the debug option will report all events +in the kernel log. The "scancodes" passed to the input system (that can be remapped with udev) are indexes to the table "sony_laptop_input_keycode_map" in the sony-laptop.c diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 100bd724f64..3278a210c43 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -91,24 +91,6 @@ config ACPI_EC_DEBUGFS Thus this option is a debug option that helps to write ACPI drivers and can be used to identify ACPI code or EC firmware bugs. -config ACPI_PROC_EVENT - bool "Deprecated /proc/acpi/event support" - depends on PROC_FS - default y - help - A user-space daemon, acpid, typically reads /proc/acpi/event - and handles all ACPI-generated events. - - These events are now delivered to user-space either - via the input layer or as netlink events. - - This build option enables the old code for legacy - user-space implementation. After some time, this will - be moved under CONFIG_ACPI_PROCFS, and then deleted. - - Say Y here to retain the old behaviour. Say N if your - user-space is newer than kernel 2.6.23 (September 2007). - config ACPI_AC tristate "AC Adapter" depends on X86 diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 4f4e741d34b..f37beaa3275 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -267,7 +267,6 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) msleep(ac_sleep_before_get_state_ms); acpi_ac_get_state(ac); - acpi_bus_generate_proc_event(device, event, (u32) ac->state); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, (u32) ac->state); diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 27bb6a91de5..6230637054c 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -452,7 +452,6 @@ static void acpi_pad_notify(acpi_handle handle, u32 event, switch (event) { case ACPI_PROCESSOR_AGGREGATOR_NOTIFY: acpi_pad_handle_notify(handle); - acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); break; diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 082b4dd252a..33dfa851899 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1034,8 +1034,6 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) if (event == ACPI_BATTERY_NOTIFY_INFO) acpi_battery_refresh(battery); acpi_battery_update(battery); - acpi_bus_generate_proc_event(device, event, - acpi_battery_present(battery)); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, acpi_battery_present(battery)); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a5bb33bab44..b6e9a3786e2 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -345,104 +345,6 @@ static void acpi_bus_osc_support(void) /* do we need to check other returned cap? Sounds no */ } -/* -------------------------------------------------------------------------- - Event Management - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI_PROC_EVENT -static DEFINE_SPINLOCK(acpi_bus_event_lock); - -LIST_HEAD(acpi_bus_event_list); -DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); - -extern int event_is_open; - -int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data) -{ - struct acpi_bus_event *event; - unsigned long flags; - - /* drop event on the floor if no one's listening */ - if (!event_is_open) - return 0; - - event = kzalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC); - if (!event) - return -ENOMEM; - - strcpy(event->device_class, device_class); - strcpy(event->bus_id, bus_id); - event->type = type; - event->data = data; - - spin_lock_irqsave(&acpi_bus_event_lock, flags); - list_add_tail(&event->node, &acpi_bus_event_list); - spin_unlock_irqrestore(&acpi_bus_event_lock, flags); - - wake_up_interruptible(&acpi_bus_event_queue); - - return 0; - -} - -EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4); - -int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) -{ - if (!device) - return -EINVAL; - return acpi_bus_generate_proc_event4(device->pnp.device_class, - device->pnp.bus_id, type, data); -} - -EXPORT_SYMBOL(acpi_bus_generate_proc_event); - -int acpi_bus_receive_event(struct acpi_bus_event *event) -{ - unsigned long flags; - struct acpi_bus_event *entry = NULL; - - DECLARE_WAITQUEUE(wait, current); - - - if (!event) - return -EINVAL; - - if (list_empty(&acpi_bus_event_list)) { - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&acpi_bus_event_queue, &wait); - - if (list_empty(&acpi_bus_event_list)) - schedule(); - - remove_wait_queue(&acpi_bus_event_queue, &wait); - set_current_state(TASK_RUNNING); - - if (signal_pending(current)) - return -ERESTARTSYS; - } - - spin_lock_irqsave(&acpi_bus_event_lock, flags); - if (!list_empty(&acpi_bus_event_list)) { - entry = list_entry(acpi_bus_event_list.next, - struct acpi_bus_event, node); - list_del(&entry->node); - } - spin_unlock_irqrestore(&acpi_bus_event_lock, flags); - - if (!entry) - return -ENODEV; - - memcpy(event, entry, sizeof(struct acpi_bus_event)); - - kfree(entry); - - return 0; -} - -#endif /* CONFIG_ACPI_PROC_EVENT */ - /* -------------------------------------------------------------------------- Notification Handling -------------------------------------------------------------------------- */ diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index d2e617b5b3f..a55773801c5 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -303,8 +303,6 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) pm_wakeup_event(&device->dev, 0); } - - acpi_bus_generate_proc_event(device, event, ++button->pushed); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index 1442737cede..8247fcdde07 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c @@ -21,100 +21,6 @@ #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("event"); -#ifdef CONFIG_ACPI_PROC_EVENT -/* Global vars for handling event proc entry */ -static DEFINE_SPINLOCK(acpi_system_event_lock); -int event_is_open = 0; -extern struct list_head acpi_bus_event_list; -extern wait_queue_head_t acpi_bus_event_queue; - -static int acpi_system_open_event(struct inode *inode, struct file *file) -{ - spin_lock_irq(&acpi_system_event_lock); - - if (event_is_open) - goto out_busy; - - event_is_open = 1; - - spin_unlock_irq(&acpi_system_event_lock); - return 0; - - out_busy: - spin_unlock_irq(&acpi_system_event_lock); - return -EBUSY; -} - -static ssize_t -acpi_system_read_event(struct file *file, char __user * buffer, size_t count, - loff_t * ppos) -{ - int result = 0; - struct acpi_bus_event event; - static char str[ACPI_MAX_STRING]; - static int chars_remaining = 0; - static char *ptr; - - if (!chars_remaining) { - memset(&event, 0, sizeof(struct acpi_bus_event)); - - if ((file->f_flags & O_NONBLOCK) - && (list_empty(&acpi_bus_event_list))) - return -EAGAIN; - - result = acpi_bus_receive_event(&event); - if (result) - return result; - - chars_remaining = sprintf(str, "%s %s %08x %08x\n", - event.device_class ? event. - device_class : "", - event.bus_id ? event. - bus_id : "", event.type, - event.data); - ptr = str; - } - - if (chars_remaining < count) { - count = chars_remaining; - } - - if (copy_to_user(buffer, ptr, count)) - return -EFAULT; - - *ppos += count; - chars_remaining -= count; - ptr += count; - - return count; -} - -static int acpi_system_close_event(struct inode *inode, struct file *file) -{ - spin_lock_irq(&acpi_system_event_lock); - event_is_open = 0; - spin_unlock_irq(&acpi_system_event_lock); - return 0; -} - -static unsigned int acpi_system_poll_event(struct file *file, poll_table * wait) -{ - poll_wait(file, &acpi_bus_event_queue, wait); - if (!list_empty(&acpi_bus_event_list)) - return POLLIN | POLLRDNORM; - return 0; -} - -static const struct file_operations acpi_system_event_ops = { - .owner = THIS_MODULE, - .open = acpi_system_open_event, - .read = acpi_system_read_event, - .release = acpi_system_close_event, - .poll = acpi_system_poll_event, - .llseek = default_llseek, -}; -#endif /* CONFIG_ACPI_PROC_EVENT */ - /* ACPI notifier chain */ static BLOCKING_NOTIFIER_HEAD(acpi_chain_head); @@ -280,9 +186,6 @@ static int acpi_event_genetlink_init(void) static int __init acpi_event_init(void) { -#ifdef CONFIG_ACPI_PROC_EVENT - struct proc_dir_entry *entry; -#endif int error = 0; if (acpi_disabled) @@ -293,15 +196,6 @@ static int __init acpi_event_init(void) if (error) printk(KERN_WARNING PREFIX "Failed to create genetlink family for ACPI event\n"); - -#ifdef CONFIG_ACPI_PROC_EVENT - /* 'event' [R] */ - entry = proc_create("event", S_IRUSR, acpi_root_dir, - &acpi_system_event_ops); - if (!entry) - return -ENODEV; -#endif - return 0; } diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 823be116619..94b7b3b5559 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -91,21 +91,17 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) acpi_processor_ppc_has_changed(pr, 1); if (saved == pr->performance_platform_limit) break; - acpi_bus_generate_proc_event(device, event, - pr->performance_platform_limit); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, pr->performance_platform_limit); break; case ACPI_PROCESSOR_NOTIFY_POWER: acpi_processor_cst_has_changed(pr); - acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); break; case ACPI_PROCESSOR_NOTIFY_THROTTLING: acpi_processor_tstate_has_changed(pr); - acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); break; diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index b6241eeb113..aef7e1cd1e5 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -873,14 +873,9 @@ static void acpi_sbs_callback(void *context) u8 saved_charger_state = sbs->charger_present; u8 saved_battery_state; acpi_ac_get_present(sbs); - if (sbs->charger_present != saved_charger_state) { -#ifdef CONFIG_ACPI_PROC_EVENT - acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME, - ACPI_SBS_NOTIFY_STATUS, - sbs->charger_present); -#endif + if (sbs->charger_present != saved_charger_state) kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); - } + if (sbs->manager_present) { for (id = 0; id < MAX_SBS_BAT; ++id) { if (!(sbs->batteries_supported & (1 << id))) @@ -890,12 +885,6 @@ static void acpi_sbs_callback(void *context) acpi_battery_read(bat); if (saved_battery_state == bat->present) continue; -#ifdef CONFIG_ACPI_PROC_EVENT - acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS, - bat->name, - ACPI_SBS_NOTIFY_STATUS, - bat->present); -#endif kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); } } diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index a33821ca389..547a906a766 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -769,7 +769,6 @@ static int thermal_notify(struct thermal_zone_device *thermal, int trip, else return 0; - acpi_bus_generate_proc_event(tz->device, type, 1); acpi_bus_generate_netlink_event(tz->device->pnp.device_class, dev_name(&tz->device->dev), type, 1); @@ -980,14 +979,12 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event) case ACPI_THERMAL_NOTIFY_THRESHOLDS: acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); acpi_thermal_check(tz); - acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); break; case ACPI_THERMAL_NOTIFY_DEVICES: acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); acpi_thermal_check(tz); - acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); break; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5d7075d2570..8f91a378319 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1556,7 +1556,6 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) switch (event) { case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, * most likely via hotkey. */ - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_SWITCHVIDEOMODE; break; @@ -1564,20 +1563,16 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) * connector. */ acpi_video_device_enumerate(video); acpi_video_device_rebind(video); - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_SWITCHVIDEOMODE; break; case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_SWITCHVIDEOMODE; break; case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_VIDEO_NEXT; break; case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_VIDEO_PREV; break; @@ -1620,31 +1615,26 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ if (brightness_switch_enabled) acpi_video_switch_brightness(video_device, event); - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESS_CYCLE; break; case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ if (brightness_switch_enabled) acpi_video_switch_brightness(video_device, event); - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESSUP; break; case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ if (brightness_switch_enabled) acpi_video_switch_brightness(video_device, event); - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESSDOWN; break; case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ if (brightness_switch_enabled) acpi_video_switch_brightness(video_device, event); - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESS_ZERO; break; case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ if (brightness_switch_enabled) acpi_video_switch_brightness(video_device, event); - acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_DISPLAY_OFF; break; default: diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index bf2349dbbf7..7cc1fe2241f 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -876,11 +876,6 @@ found: if (useinput) sonypi_report_input_event(event); -#ifdef CONFIG_ACPI - if (sonypi_acpi_device) - acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); -#endif - kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event, sizeof(event), &sonypi_device.fifo_lock); kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index c35e8ad6db0..5394fffdf16 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -270,7 +270,6 @@ static void ibm_handle_events(acpi_handle handle, u32 event, void *context) if (subevent == 0x80) { dbg("%s: generationg bus event\n", __func__); - acpi_bus_generate_proc_event(note->device, note->event, detail); acpi_bus_generate_netlink_event(note->device->pnp.device_class, dev_name(¬e->device->dev), note->event, detail); diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 8e268da6fdb..0e9c169b42f 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1543,7 +1543,6 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event) /* TODO Find a better way to handle events count. */ count = asus->event_count[event % 128]++; - acpi_bus_generate_proc_event(asus->device, event, count); acpi_bus_generate_netlink_event(asus->device->pnp.device_class, dev_name(&asus->device->dev), event, count); diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 5d26e70bed6..a6afd4108be 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1269,7 +1269,6 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event) if (event > ACPI_MAX_SYS_NOTIFY) return; count = eeepc->event_count[event % 128]++; - acpi_bus_generate_proc_event(device, event, count); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, count); diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 1c9386e7c58..52b8a97efde 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -773,8 +773,6 @@ static void acpi_fujitsu_notify(struct acpi_device *device, u32 event) else set_lcd_level(newb); } - acpi_bus_generate_proc_event(fujitsu->dev, - ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0); keycode = KEY_BRIGHTNESSUP; } else if (oldb > newb) { if (disable_brightness_adjust != 1) { @@ -783,8 +781,6 @@ static void acpi_fujitsu_notify(struct acpi_device *device, u32 event) else set_lcd_level(newb); } - acpi_bus_generate_proc_event(fujitsu->dev, - ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0); keycode = KEY_BRIGHTNESSDOWN; } break; diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 4add9a31bf6..984253da365 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -464,9 +464,6 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) "error getting hotkey status\n")); return; } - - acpi_bus_generate_proc_event(pcc->device, HKEY_NOTIFY, result); - if (!sparse_keymap_report_event(hotk_input_dev, result & 0xf, result & 0x80, false)) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 2ac045f27f1..069821b1fc2 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1275,9 +1275,6 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) ev_type = HOTKEY; sony_laptop_report_input_event(real_ev); } - - acpi_bus_generate_proc_event(sony_nc_acpi_device, ev_type, real_ev); - acpi_bus_generate_netlink_event(sony_nc_acpi_device->pnp.device_class, dev_name(&sony_nc_acpi_device->dev), ev_type, real_ev); } @@ -4243,7 +4240,6 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) found: sony_laptop_report_input_event(device_event); - acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event); sonypi_compat_report_event(device_event); return IRQ_HANDLED; } diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 54d31c0a984..e946c0d58a9 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2282,10 +2282,6 @@ static struct tp_acpi_drv_struct ibm_hotkey_acpidriver; static void tpacpi_hotkey_send_key(unsigned int scancode) { tpacpi_input_send_key_masked(scancode); - if (hotkey_report_mode < 2) { - acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device, - 0x80, TP_HKEY_EV_HOTKEY_BASE + scancode); - } } static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m) @@ -3737,13 +3733,6 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) "event happened to %s\n", TPACPI_MAIL); } - /* Legacy events */ - if (!ignore_acpi_ev && - (send_acpi_ev || hotkey_report_mode < 2)) { - acpi_bus_generate_proc_event(ibm->acpi->device, - event, hkey); - } - /* netlink events */ if (!ignore_acpi_ev && send_acpi_ev) { acpi_bus_generate_netlink_event( diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 56e6b68c8d2..2650d1f19e4 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -383,15 +383,6 @@ bool acpi_bus_can_wakeup(acpi_handle handle); static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; } #endif -#ifdef CONFIG_ACPI_PROC_EVENT -int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); -int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data); -int acpi_bus_receive_event(struct acpi_bus_event *event); -#else -static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) - { return 0; } -#endif - void acpi_scan_lock_acquire(void); void acpi_scan_lock_release(void); int acpi_scan_add_handler(struct acpi_scan_handler *handler); -- cgit v1.2.3-70-g09d2 From a7d5caf6d21814a855422df75c2d8c093cb2019a Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 17 Jul 2013 09:48:15 +0800 Subject: ACPICA: Update comments about behavior when _STA does not exist No functional change. Add some comments concerning behavior when the _STA method does not exist. According to the ACPI specification, in this case the device should be assumed to be present, functional, and enabled. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsxfname.c | 7 ++++++- drivers/acpi/acpica/uteval.c | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index f3a4d95899f..21a2ef363ad 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -379,9 +379,14 @@ acpi_get_object_info(acpi_handle handle, * Get extra info for ACPI Device/Processor objects only: * Run the _STA, _ADR and, sx_w, and _sx_d methods. * - * Note: none of these methods are required, so they may or may + * Notes: none of these methods are required, so they may or may * not be present for this device. The Info->Valid bitfield is used * to indicate which methods were found and run successfully. + * + * For _STA, if the method does not exist, then (as per the ACPI + * specification), the returned current_status flags will indicate + * that the device is present/functional/enabled. Otherwise, the + * current_status flags reflect the value returned from _STA. */ /* Execute the Device._STA method */ diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index ee83adb97b1..4fd68971019 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -239,7 +239,8 @@ acpi_ut_evaluate_numeric_object(char *object_name, * RETURN: Status * * DESCRIPTION: Executes _STA for selected device and stores results in - * *Flags. + * *Flags. If _STA does not exist, then the device is assumed + * to be present/functional/enabled (as per the ACPI spec). * * NOTE: Internal function, no parameter validation * @@ -257,6 +258,11 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) ACPI_BTYPE_INTEGER, &obj_desc); if (ACPI_FAILURE(status)) { if (AE_NOT_FOUND == status) { + /* + * if _STA does not exist, then (as per the ACPI specification), + * the returned flags will indicate that the device is present, + * functional, and enabled. + */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "_STA on %4.4s was not found, assuming device is present\n", acpi_ut_get_node_name(device_node))); -- cgit v1.2.3-70-g09d2 From 57987ca2b7c3b16aeeaeacb69b52372181cb7c58 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 17 Jul 2013 09:48:27 +0800 Subject: ACPICA: TableManager: Export acpi_tb_scan_memory_for_rsdp() This patch exports this function to be used by other ACPICA utilities. Chao Guan, Bob Moore. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/actables.h | 5 +++++ drivers/acpi/acpica/tbxfroot.c | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 7755e915a00..917315ec21d 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -46,6 +46,11 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count); +/* + * tbxfroot - Root pointer utilities + */ +u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); + /* * tbfadt - FADT parse/convert/validate */ diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index 7c2ecfb7c2c..e76ed0f0782 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -49,8 +49,6 @@ ACPI_MODULE_NAME("tbxfroot") /* Local prototypes */ -static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); - static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); /******************************************************************************* @@ -231,7 +229,7 @@ acpi_status acpi_find_root_pointer(acpi_size *table_address) * DESCRIPTION: Search a block of memory for the RSDP signature * ******************************************************************************/ -static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) +u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length) { acpi_status status; u8 *mem_rover; -- cgit v1.2.3-70-g09d2 From 0fb3adf8099160c0a1b1952b6ccf7ac05c218d38 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 17 Jul 2013 09:48:40 +0800 Subject: ACPICA: Disassembler: Expand maximum output string length to 64K Was 256 bytes max. The original purpose of this constraint was to limit the amount of debug output. However, the string function in question (UtPrintString) is now used for the disassembler also, where 256 bytes is insufficient. Reported by RehabMan@GitHub. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acutils.h | 2 +- drivers/acpi/acpica/utstring.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 3c76edea680..4c081c43608 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -616,7 +616,7 @@ int acpi_ut_stricmp(char *string1, char *string2); acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer); -void acpi_ut_print_string(char *string, u8 max_length); +void acpi_ut_print_string(char *string, u16 max_length); void ut_convert_backslashes(char *pathname); diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index c53759b76a3..cb1e9cc32d5 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c @@ -333,7 +333,8 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) * FUNCTION: acpi_ut_print_string * * PARAMETERS: string - Null terminated ASCII string - * max_length - Maximum output length + * max_length - Maximum output length. Used to constrain the + * length of strings during debug output only. * * RETURN: None * @@ -342,7 +343,7 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) * ******************************************************************************/ -void acpi_ut_print_string(char *string, u8 max_length) +void acpi_ut_print_string(char *string, u16 max_length) { u32 i; -- cgit v1.2.3-70-g09d2 From 2c48e3eacb0998dc483860e63da47909313c314e Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 17 Jul 2013 09:48:50 +0800 Subject: ACPICA: Remove restriction of 256 maximum GPEs in any GPE block The FADT can support over 1000 GPEs, so remove any restriction on the GPE numbers. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/evgpeinit.c | 11 ----------- include/acpi/actypes.h | 7 ------- 2 files changed, 18 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 9037f17c960..7842700346a 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -125,7 +125,6 @@ acpi_status acpi_ev_gpe_initialize(void) /* GPE block 0 exists (has both length and address > 0) */ register_count0 = (u16)(acpi_gbl_FADT.gpe0_block_length / 2); - gpe_number_max = (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; @@ -204,16 +203,6 @@ acpi_status acpi_ev_gpe_initialize(void) goto cleanup; } - /* Check for Max GPE number out-of-range */ - - if (gpe_number_max > ACPI_GPE_MAX) { - ACPI_ERROR((AE_INFO, - "Maximum GPE number from FADT is too large: 0x%X", - gpe_number_max)); - status = AE_BAD_VALUE; - goto cleanup; - } - cleanup: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return_ACPI_STATUS(AE_OK); diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 22b03c9286e..787a977ece9 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -668,13 +668,6 @@ typedef u32 acpi_event_status; #define ACPI_EVENT_FLAG_SET (acpi_event_status) 0x04 #define ACPI_EVENT_FLAG_HANDLE (acpi_event_status) 0x08 -/* - * General Purpose Events (GPE) - */ -#define ACPI_GPE_INVALID 0xFF -#define ACPI_GPE_MAX 0xFF -#define ACPI_NUM_GPE 256 - /* Actions for acpi_set_gpe, acpi_gpe_wakeup, acpi_hw_low_set_gpe */ #define ACPI_GPE_ENABLE 0 -- cgit v1.2.3-70-g09d2 From bbe707eddca7f5d03613f38ad8d6b0253a47f5a8 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 17 Jul 2013 09:48:58 +0800 Subject: ACPICA: Fix compiler warnings for casting issues (only some compilers) Fixes compiler warnings from GCC 4.2 and perhaps other compilers. Jung-uk Kim Signed-off-by: Jung-uk Kim Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exdump.c | 6 +++--- drivers/acpi/acpica/nsxfname.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index c740f24e310..4d046faac48 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -338,6 +338,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, { u8 *target; char *name; + const char *reference_name; u8 count; if (!info) { @@ -426,10 +427,9 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, case ACPI_EXD_REFERENCE: + reference_name = acpi_ut_get_reference_name(obj_desc); acpi_ex_out_string("Class Name", - ACPI_CAST_PTR(char, - acpi_ut_get_reference_name - (obj_desc))); + ACPI_CAST_PTR(char, reference_name)); acpi_ex_dump_reference_obj(obj_desc); break; diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 21a2ef363ad..83c16443458 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -158,6 +158,7 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) { acpi_status status; struct acpi_namespace_node *node; + char *node_name; /* Parameter validation */ @@ -202,7 +203,8 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) /* Just copy the ACPI name from the Node and zero terminate it */ - ACPI_MOVE_NAME(buffer->pointer, acpi_ut_get_node_name(node)); + node_name = acpi_ut_get_node_name(node); + ACPI_MOVE_NAME(buffer->pointer, node_name); ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; status = AE_OK; -- cgit v1.2.3-70-g09d2 From be1c9de98d8904c75a5ab8b2a0d97bea0f7c07cc Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 13 Jul 2013 23:27:23 +0200 Subject: ACPI / PCI: Make bus registration and unregistration symmetric Since acpi_pci_slot_enumerate() and acpiphp_enumerate_slots() can get the ACPI device handle they need from bus->bridge, it is not necessary to pass that handle to them as an argument. Drop the second argument of acpi_pci_slot_enumerate() and acpiphp_enumerate_slots(), rework them to obtain the ACPI handle from bus->bridge and make acpi_pci_add_bus() and acpi_pci_remove_bus() entirely symmetrical. Tested-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu --- drivers/acpi/pci_slot.c | 14 +++++++++----- drivers/pci/hotplug/acpiphp_glue.c | 6 ++++-- drivers/pci/pci-acpi.c | 16 ++++------------ include/linux/pci-acpi.h | 10 ++++------ 4 files changed, 21 insertions(+), 25 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 033d1179bdb..d678a180ca2 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c @@ -159,12 +159,16 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle) +void acpi_pci_slot_enumerate(struct pci_bus *bus) { - mutex_lock(&slot_list_lock); - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, - register_slot, NULL, bus, NULL); - mutex_unlock(&slot_list_lock); + acpi_handle handle = ACPI_HANDLE(bus->bridge); + + if (handle) { + mutex_lock(&slot_list_lock); + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, + register_slot, NULL, bus, NULL); + mutex_unlock(&slot_list_lock); + } } void acpi_pci_slot_remove(struct pci_bus *bus) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 8bfad0dc29a..a203ba529fe 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -1147,14 +1147,16 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, * Create hotplug slots for the PCI bus. * It should always return 0 to avoid skipping following notifiers. */ -void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle) +void acpiphp_enumerate_slots(struct pci_bus *bus) { + acpi_handle handle; struct acpiphp_bridge *bridge; if (acpiphp_disabled) return; - if (detect_ejectable_slots(handle) <= 0) + handle = ACPI_HANDLE(bus->bridge); + if (!handle || detect_ejectable_slots(handle) <= 0) return; bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index dbdc5f7e2b2..c78cc432eda 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -290,24 +290,16 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { void acpi_pci_add_bus(struct pci_bus *bus) { - acpi_handle handle = NULL; - - if (bus->bridge) - handle = ACPI_HANDLE(bus->bridge); - if (acpi_pci_disabled || handle == NULL) + if (acpi_pci_disabled || !bus->bridge) return; - acpi_pci_slot_enumerate(bus, handle); - acpiphp_enumerate_slots(bus, handle); + acpi_pci_slot_enumerate(bus); + acpiphp_enumerate_slots(bus); } void acpi_pci_remove_bus(struct pci_bus *bus) { - /* - * bus->bridge->acpi_node.handle has already been reset to NULL - * when acpi_pci_remove_bus() is called, so don't check ACPI handle. - */ - if (acpi_pci_disabled) + if (acpi_pci_disabled || !bus->bridge) return; acpiphp_remove_slots(bus); diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 17044797727..d006f0ca60f 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -47,24 +47,22 @@ void acpi_pci_remove_bus(struct pci_bus *bus); #ifdef CONFIG_ACPI_PCI_SLOT void acpi_pci_slot_init(void); -void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle); +void acpi_pci_slot_enumerate(struct pci_bus *bus); void acpi_pci_slot_remove(struct pci_bus *bus); #else static inline void acpi_pci_slot_init(void) { } -static inline void acpi_pci_slot_enumerate(struct pci_bus *bus, - acpi_handle handle) { } +static inline void acpi_pci_slot_enumerate(struct pci_bus *bus) { } static inline void acpi_pci_slot_remove(struct pci_bus *bus) { } #endif #ifdef CONFIG_HOTPLUG_PCI_ACPI void acpiphp_init(void); -void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle); +void acpiphp_enumerate_slots(struct pci_bus *bus); void acpiphp_remove_slots(struct pci_bus *bus); void acpiphp_check_host_bridge(acpi_handle handle); #else static inline void acpiphp_init(void) { } -static inline void acpiphp_enumerate_slots(struct pci_bus *bus, - acpi_handle handle) { } +static inline void acpiphp_enumerate_slots(struct pci_bus *bus) { } static inline void acpiphp_remove_slots(struct pci_bus *bus) { } static inline void acpiphp_check_host_bridge(acpi_handle handle) { } #endif -- cgit v1.2.3-70-g09d2 From 2cf9f5bcc8d8cb31d6ea7baebac5056f39fb4f40 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Mon, 22 Jul 2013 16:08:16 +0800 Subject: ACPICA: Add acpi_update_interfaces() public interface Add new API to allow OSPM to disable/enable specific types of _OSI interface strings. ACPICA does not have the knowledge about whether an _OSI interface string is an OS vendor string or a feature group string and there isn't any API interface to allow OSPM to install a new interface string as a feature group string. This patch simply adds all feature group strings defined by ACPI specification into the acpi_default_supported_interfaces with ACPI_OSI_FEATURE flag set to fix this gap. This patch also adds codes to keep their default states as ACPI_OSI_INVALID before the initialization and after the termination. Signed-off-by: Lv Zheng Reviewed-by: Zhang Rui Signed-off-by: Bob Moore Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki Conflicts: include/acpi/actypes.h (with commit 242b228) --- drivers/acpi/acpica/aclocal.h | 3 ++ drivers/acpi/acpica/acutils.h | 2 ++ drivers/acpi/acpica/utosi.c | 77 +++++++++++++++++++++++++++++++++++-------- drivers/acpi/acpica/utxface.c | 29 ++++++++++++++++ include/acpi/acpixf.h | 2 ++ include/acpi/actypes.h | 14 ++++++++ 6 files changed, 114 insertions(+), 13 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index d4a4901637c..b0e3d15cfe9 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -942,6 +942,9 @@ struct acpi_interface_info { #define ACPI_OSI_INVALID 0x01 #define ACPI_OSI_DYNAMIC 0x02 +#define ACPI_OSI_FEATURE 0x04 +#define ACPI_OSI_DEFAULT_INVALID 0x08 +#define ACPI_OSI_OPTIONAL_FEATURE (ACPI_OSI_FEATURE | ACPI_OSI_DEFAULT_INVALID | ACPI_OSI_INVALID) struct acpi_port_info { char *name; diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 4c081c43608..d5a62a6182b 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -470,6 +470,8 @@ acpi_status acpi_ut_install_interface(acpi_string interface_name); acpi_status acpi_ut_remove_interface(acpi_string interface_name); +acpi_status acpi_ut_update_interfaces(u8 action); + struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name); acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state); diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 7e807725c63..8856bd37bc7 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c @@ -77,21 +77,20 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = { /* Feature Group Strings */ - {"Extended Address Space Descriptor", NULL, 0, 0} + {"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0}, /* * All "optional" feature group strings (features that are implemented - * by the host) should be dynamically added by the host via - * acpi_install_interface and should not be manually added here. - * - * Examples of optional feature group strings: - * - * "Module Device" - * "Processor Device" - * "3.0 Thermal Model" - * "3.0 _SCP Extensions" - * "Processor Aggregator Device" + * by the host) should be dynamically modified to VALID by the host via + * acpi_install_interface or acpi_update_interfaces. Such optional feature + * group strings are set as INVALID by default here. */ + + {"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, + {"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, + {"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, + {"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}, + {"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0} }; /******************************************************************************* @@ -158,11 +157,20 @@ acpi_status acpi_ut_interface_terminate(void) while (next_interface) { acpi_gbl_supported_interfaces = next_interface->next; - /* Only interfaces added at runtime can be freed */ - if (next_interface->flags & ACPI_OSI_DYNAMIC) { + + /* Only interfaces added at runtime can be freed */ + ACPI_FREE(next_interface->name); ACPI_FREE(next_interface); + } else { + /* Interface is in static list. Reset it to invalid or valid. */ + + if (next_interface->flags & ACPI_OSI_DEFAULT_INVALID) { + next_interface->flags |= ACPI_OSI_INVALID; + } else { + next_interface->flags &= ~ACPI_OSI_INVALID; + } } next_interface = acpi_gbl_supported_interfaces; @@ -276,6 +284,49 @@ acpi_status acpi_ut_remove_interface(acpi_string interface_name) return (AE_NOT_EXIST); } +/******************************************************************************* + * + * FUNCTION: acpi_ut_update_interfaces + * + * PARAMETERS: action - Actions to be performed during the + * update + * + * RETURN: Status + * + * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor + * strings or/and feature group strings. + * Caller MUST hold acpi_gbl_osi_mutex + * + ******************************************************************************/ + +acpi_status acpi_ut_update_interfaces(u8 action) +{ + struct acpi_interface_info *next_interface; + + next_interface = acpi_gbl_supported_interfaces; + while (next_interface) { + if (((next_interface->flags & ACPI_OSI_FEATURE) && + (action & ACPI_FEATURE_STRINGS)) || + (!(next_interface->flags & ACPI_OSI_FEATURE) && + (action & ACPI_VENDOR_STRINGS))) { + if (action & ACPI_DISABLE_INTERFACES) { + + /* Mark the interfaces as invalid */ + + next_interface->flags |= ACPI_OSI_INVALID; + } else { + /* Mark the interfaces as valid */ + + next_interface->flags &= ~ACPI_OSI_INVALID; + } + } + + next_interface = next_interface->next; + } + + return (AE_OK); +} + /******************************************************************************* * * FUNCTION: acpi_ut_get_interface diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 6505774f223..03a211e6e26 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -387,6 +387,34 @@ acpi_status acpi_install_interface_handler(acpi_interface_handler handler) ACPI_EXPORT_SYMBOL(acpi_install_interface_handler) +/***************************************************************************** + * + * FUNCTION: acpi_update_interfaces + * + * PARAMETERS: action - Actions to be performed during the + * update + * + * RETURN: Status + * + * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor + * string or/and feature group strings. + * + ****************************************************************************/ +acpi_status acpi_update_interfaces(u8 action) +{ + acpi_status status; + + status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE(status)) { + return (status); + } + + status = acpi_ut_update_interfaces(action); + + acpi_os_release_mutex(acpi_gbl_osi_mutex); + return (status); +} + /***************************************************************************** * * FUNCTION: acpi_check_address_range @@ -402,6 +430,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_interface_handler) * ASL operation region address ranges. * ****************************************************************************/ + u32 acpi_check_address_range(acpi_adr_space_type space_id, acpi_physical_address address, diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 292af0c0b89..0dd03f226a6 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -147,6 +147,8 @@ acpi_status acpi_install_interface(acpi_string interface_name); acpi_status acpi_remove_interface(acpi_string interface_name); +acpi_status acpi_update_interfaces(u8 action); + u32 acpi_check_address_range(acpi_adr_space_type space_id, acpi_physical_address address, diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 787a977ece9..eae55fb7490 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -1152,4 +1152,18 @@ struct acpi_memory_list { #define ACPI_OSI_WIN_7 0x0B #define ACPI_OSI_WIN_8 0x0C +/* _OSI update actions */ + +#define ACPI_VENDOR_STRINGS 0x01 +#define ACPI_FEATURE_STRINGS 0x02 +#define ACPI_ENABLE_INTERFACES 0x00 +#define ACPI_DISABLE_INTERFACES 0x04 + +#define ACPI_DISABLE_ALL_VENDOR_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_VENDOR_STRINGS) +#define ACPI_DISABLE_ALL_FEATURE_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_FEATURE_STRINGS) +#define ACPI_DISABLE_ALL_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS) +#define ACPI_ENABLE_ALL_VENDOR_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS) +#define ACPI_ENABLE_ALL_FEATURE_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_FEATURE_STRINGS) +#define ACPI_ENABLE_ALL_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS) + #endif /* __ACTYPES_H__ */ -- cgit v1.2.3-70-g09d2 From 5dc17986fdc3d2425838cb8d699152c3c30d1208 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Mon, 22 Jul 2013 16:08:25 +0800 Subject: ACPI: Add facility to disable all _OSI OS vendor strings This patch introduces "acpi_osi=!" command line to force Linux replying "UNSUPPORTED" to all of the _OSI strings. This patch is based on an ACPICA enhancement - the new API acpi_update_interfaces(). The _OSI object provides the platform with the ability to query OSPM to determine the set of ACPI related interfaces, behaviors, or features that the operating system supports. The argument passed to the _OSI is a string like the followings: 1. Feature Group String, examples include Module Device Processor Device 3.0 _SCP Extensions Processor Aggregator Device ... 2. OS Vendor String, examples include Linux FreeBSD Windows ... There are AML codes provided in the ACPI namespace written in the following style to determine OSPM interfaces / features: Method(OSCK) { if (CondRefOf(_OSI, Local0)) { if (\_OSI("Windows")) { Return (One) } if (\_OSI("Windows 2006")) { Return (Ones) } Return (Zero) } Return (Zero) } There is a debugging facility implemented in Linux. Users can pass "acpi_osi=" boot parameters to the kernel to tune the _OSI evaluation result so that certain AML codes can be executed. Current implementation includes: 1. 'acpi_osi=' - this makes CondRefOf(_OSI, Local0) TRUE 2. 'acpi_osi="Windows"' - this makes \_OSI("Windows") TRUE 3. 'acpi_osi="!Windows"' - this makes \_OSI("Windows") FALSE The function to implement this feature is also used as a quirk mechanism in the Linux ACPI subystem. When _OSI is evaluatated by the AML codes, ACPICA replies "SUPPORTED" to all Windows operating system vendor strings. This is because Windows operating systems return "SUPPORTED" if the argument to the _OSI method specifies an earlier version of Windows. Please refer to the following MSDN document: How to Identify the Windows Version in ACPI by Using _OSI http://msdn.microsoft.com/en-us/library/hardware/gg463275.aspx This adds difficulties when developers want to feed specific Windows operating system vendor string to the BIOS codes for debugging purpose, multiple acpi_osi="!xxx" have to be specified in the command line to force Linux replying "UNSUPPORTED" to the Windows OS vendor strings listed in the AML codes. Signed-off-by: Lv Zheng Reviewed-by: Zhang Rui Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki --- Documentation/kernel-parameters.txt | 29 +++++++++++++++++++++++++++-- drivers/acpi/osl.c | 14 +++++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 15356aca938..d0d9cf278ae 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -235,10 +235,35 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Format: To spoof as Windows 98: ="Microsoft Windows" acpi_osi= [HW,ACPI] Modify list of supported OS interface strings - acpi_osi="string1" # add string1 -- only one string - acpi_osi="!string2" # remove built-in string2 + acpi_osi="string1" # add string1 + acpi_osi="!string2" # remove string2 + acpi_osi=! # disable all built-in OS vendor + strings acpi_osi= # disable all strings + 'acpi_osi=!' can be used in combination with single or + multiple 'acpi_osi="string1"' to support specific OS + vendor string(s). Note that such command can only + affect the default state of the OS vendor strings, thus + it cannot affect the default state of the feature group + strings and the current state of the OS vendor strings, + specifying it multiple times through kernel command line + is meaningless. + Examples: + 1. 'acpi_osi=! acpi_osi="Windows 2000"' is equivalent + to 'acpi_osi="Windows 2000" acpi_osi=!', they all + can make '_OSI("Windows 2000")' TRUE. + + 'acpi_osi=' cannot be used in combination with other + 'acpi_osi=' command lines, the _OSI method will not + exist in the ACPI namespace. NOTE that such command can + only affect the _OSI support state, thus specifying it + multiple times through kernel command line is also + meaningless. + Examples: + 1. 'acpi_osi=' can make 'CondRefOf(_OSI, Local1)' + FALSE. + acpi_pm_good [X86] Override the pmtimer bug detection: force the kernel to assume that this machine's pmtimer latches its value diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6ab2c350552..e8baa408fae 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -140,7 +140,8 @@ static struct osi_linux { unsigned int enable:1; unsigned int dmi:1; unsigned int cmdline:1; -} osi_linux = {0, 0, 0}; + unsigned int default_disabling:1; +} osi_linux = {0, 0, 0, 0}; static u32 acpi_osi_handler(acpi_string interface, u32 supported) { @@ -1376,6 +1377,10 @@ void __init acpi_osi_setup(char *str) if (*str == '!') { str++; + if (*str == '\0') { + osi_linux.default_disabling = 1; + return; + } enable = false; } @@ -1441,6 +1446,13 @@ static void __init acpi_osi_setup_late(void) int i; acpi_status status; + if (osi_linux.default_disabling) { + status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS); + + if (ACPI_SUCCESS(status)) + printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n"); + } + for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { osi = &osi_setup_entries[i]; str = osi->string; -- cgit v1.2.3-70-g09d2 From 741d81280ad2b31fc3d76c49fa5c1fe09f3a6f68 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Mon, 22 Jul 2013 16:08:36 +0800 Subject: ACPI: Add facility to remove all _OSI strings This patch changes the "acpi_osi=" boot parameter implementation so that: 1. "acpi_osi=!" can be used to disable all _OSI OS vendor strings by default. It is meaningless to specify "acpi_osi=!" multiple times as it can only affect the default state of the target _OSI strings. 2. "acpi_osi=!*" can be used to remove all _OSI OS vendor strings and all _OSI feature group strings. It is useful to specify "acpi_osi=!*" multiple times through kernel command line to override the current state of the target _OSI strings. Signed-off-by: Lv Zheng Reviewed-by: Zhang Rui Acked-by: Len Brown Signed-off-by: Rafael J. Wysocki --- Documentation/kernel-parameters.txt | 28 +++++++++++++++++++++++++++- drivers/acpi/osl.c | 7 +++++++ 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index d0d9cf278ae..5ec77aad177 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -237,6 +237,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. acpi_osi= [HW,ACPI] Modify list of supported OS interface strings acpi_osi="string1" # add string1 acpi_osi="!string2" # remove string2 + acpi_osi=!* # remove all strings acpi_osi=! # disable all built-in OS vendor strings acpi_osi= # disable all strings @@ -248,7 +249,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. it cannot affect the default state of the feature group strings and the current state of the OS vendor strings, specifying it multiple times through kernel command line - is meaningless. + is meaningless. This command is useful when one do not + care about the state of the feature group strings which + should be controlled by the OSPM. Examples: 1. 'acpi_osi=! acpi_osi="Windows 2000"' is equivalent to 'acpi_osi="Windows 2000" acpi_osi=!', they all @@ -264,6 +267,29 @@ bytes respectively. Such letter suffixes can also be entirely omitted. 1. 'acpi_osi=' can make 'CondRefOf(_OSI, Local1)' FALSE. + 'acpi_osi=!*' can be used in combination with single or + multiple 'acpi_osi="string1"' to support specific + string(s). Note that such command can affect the + current state of both the OS vendor strings and the + feature group strings, thus specifying it multiple times + through kernel command line is meaningful. But it may + still not able to affect the final state of a string if + there are quirks related to this string. This command + is useful when one want to control the state of the + feature group strings to debug BIOS issues related to + the OSPM features. + Examples: + 1. 'acpi_osi="Module Device" acpi_osi=!*' can make + '_OSI("Module Device")' FALSE. + 2. 'acpi_osi=!* acpi_osi="Module Device"' can make + '_OSI("Module Device")' TRUE. + 3. 'acpi_osi=! acpi_osi=!* acpi_osi="Windows 2000"' is + equivalent to + 'acpi_osi=!* acpi_osi=! acpi_osi="Windows 2000"' + and + 'acpi_osi=!* acpi_osi="Windows 2000" acpi_osi=!', + they all will make '_OSI("Windows 2000")' TRUE. + acpi_pm_good [X86] Override the pmtimer bug detection: force the kernel to assume that this machine's pmtimer latches its value diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e8baa408fae..cc1ed12d0b8 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1380,6 +1380,13 @@ void __init acpi_osi_setup(char *str) if (*str == '\0') { osi_linux.default_disabling = 1; return; + } else if (*str == '*') { + acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS); + for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { + osi = &osi_setup_entries[i]; + osi->enable = false; + } + return; } enable = false; } -- cgit v1.2.3-70-g09d2 From 0177f29fea534ef5e6af2d76e9a9be0fdd325c4d Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 17 Jul 2013 08:33:25 +0800 Subject: ACPI / dock: fix error return code in dock_add() Fix to return -ENODEV in the acpi notify handler install error handling case instead of 0, as done elsewhere in this function. Signed-off-by: Wei Yongjun Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index f601658a4ad..b527c1bd8bb 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -881,8 +881,10 @@ static int __init dock_add(acpi_handle handle) status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, dock_notify_handler, dock_station); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)) { + ret = -ENODEV; goto err_rmgroup; + } dock_station_count++; list_add(&dock_station->sibling, &dock_stations); -- cgit v1.2.3-70-g09d2 From 1129c92faa069581bf3acf34cae92477bd6161d8 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 23 Jul 2013 16:11:55 +0800 Subject: ACPI: Cleanup sparse warning on acpi_os_initialize1() This patch cleans up the following sparse warning: # make C=2 drivers/acpi/osl.o ... drivers/acpi/osl.c:1775:20: warning: symbol 'acpi_os_initialize1' was not declared. Should it be static? ... CC drivers/acpi/osl.o Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 1 - drivers/acpi/internal.h | 1 + drivers/acpi/osl.c | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index b6e9a3786e2..25b289ff429 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -617,7 +617,6 @@ static int __init acpi_bus_init(void) { int result; acpi_status status; - extern acpi_status acpi_os_initialize1(void); acpi_os_initialize1(); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 3a50a34fe17..b636b7481f3 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -23,6 +23,7 @@ #define PREFIX "ACPI: " +acpi_status acpi_os_initialize1(void); int init_acpi_device_notify(void); int acpi_scan_init(void); #ifdef CONFIG_ACPI_PCI_SLOT diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6ab2c350552..605718f6664 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -52,6 +52,7 @@ #include #include #include +#include "internal.h" #define _COMPONENT ACPI_OS_SERVICES ACPI_MODULE_NAME("osl"); -- cgit v1.2.3-70-g09d2 From 2c7d132a589077b31493b3ea82ac83b1f72c93e1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 30 Jul 2013 14:34:00 +0200 Subject: ACPI / PM: Only set power states of devices that are power manageable Make acpi_device_set_power() check if the given device is power manageable before checking if the given power state is valid for that device. Otherwise it will print that "Device does not support" that power state into the kernel log, which may not make sense for some power states (D0 and D3cold are supported by all devices by definition). Tested-by: Yinghai Lu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 4ab807dc851..63324b87363 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -159,7 +159,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) int result = 0; bool cut_power = false; - if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) + if (!device || !device->flags.power_manageable + || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) return -EINVAL; /* Make sure this is a valid target state */ -- cgit v1.2.3-70-g09d2 From b69137a74b7a9451b3da504d1ef9ead7cb393922 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 30 Jul 2013 14:34:55 +0200 Subject: ACPI / PM: Make messages in acpi_device_set_power() print device names Modify acpi_device_set_power() so that diagnostic messages printed by it to the kernel log always contain the name of the device concerned to make it possible to identify the device that triggered the message if need be. Also replace printk(KERN_WARNING ) with dev_warn() everywhere in that function. Signed-off-by: Rafael J. Wysocki Reviewed-by: Aaron Lu --- drivers/acpi/device_pm.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 63324b87363..8234e1f8c79 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -166,20 +166,20 @@ int acpi_device_set_power(struct acpi_device *device, int state) /* Make sure this is a valid target state */ if (state == device->power.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at %s\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already in %s\n", + device->pnp.bus_id, acpi_power_state_string(state))); return 0; } if (!device->power.states[state].flags.valid) { - printk(KERN_WARNING PREFIX "Device does not support %s\n", - acpi_power_state_string(state)); + dev_warn(&device->dev, "Power state %s not supported\n", + acpi_power_state_string(state)); return -ENODEV; } if (device->parent && (state < device->parent->power.state)) { - printk(KERN_WARNING PREFIX - "Cannot set device to a higher-powered" - " state than parent\n"); + dev_warn(&device->dev, + "Cannot transition to a higher-powered state than parent\n"); return -ENODEV; } @@ -192,8 +192,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) if (state < device->power.state && state != ACPI_STATE_D0 && device->power.state >= ACPI_STATE_D3_HOT) { - printk(KERN_WARNING PREFIX - "Cannot transition to non-D0 state from D3\n"); + dev_warn(&device->dev, + "Cannot transition to non-D0 state from D3\n"); return -ENODEV; } @@ -220,10 +220,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) end: if (result) { - printk(KERN_WARNING PREFIX - "Device [%s] failed to transition to %s\n", - device->pnp.bus_id, - acpi_power_state_string(state)); + dev_warn(&device->dev, "Failed to change power state to %s\n", + acpi_power_state_string(state)); } else { device->power.state = state; ACPI_DEBUG_PRINT((ACPI_DB_INFO, -- cgit v1.2.3-70-g09d2 From 8ad928d52e63a9b7d69f0873d7318c4561e2f8cd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 30 Jul 2013 14:36:20 +0200 Subject: ACPI / PM: Use ACPI_STATE_D3_COLD instead of ACPI_STATE_D3 everywhere There are several places in the tree where ACPI_STATE_D3 is used instead of ACPI_STATE_D3_COLD which should be used instead for clarity. Modify them all to use ACPI_STATE_D3_COLD as appropriate. [The definition of ACPI_STATE_D3 itself cannot go away at this point as it is part of ACPICA.] Signed-off-by: Rafael J. Wysocki Reviewed-by: Aaron Lu --- drivers/acpi/fan.c | 4 ++-- drivers/acpi/power.c | 2 +- drivers/acpi/scan.c | 4 ++-- drivers/ata/libata-acpi.c | 4 ++-- drivers/ide/ide-acpi.c | 5 +++-- drivers/pnp/pnpacpi/core.c | 6 +++--- include/acpi/acpi_bus.h | 3 ++- 7 files changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 5b02a0aa540..41ade6570bc 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -93,7 +93,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long if (result) return result; - *state = (acpi_state == ACPI_STATE_D3 ? 0 : + *state = (acpi_state == ACPI_STATE_D3_COLD ? 0 : (acpi_state == ACPI_STATE_D0 ? 1 : -1)); return 0; } @@ -108,7 +108,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) return -EINVAL; result = acpi_bus_set_power(device->handle, - state ? ACPI_STATE_D0 : ACPI_STATE_D3); + state ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD); return result; } diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 5c28c894c0f..4cdcc0cf0c5 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -786,7 +786,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state) } } - *state = ACPI_STATE_D3; + *state = ACPI_STATE_D3_COLD; return 0; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 8a46c924eff..c30df3ad2d7 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1450,8 +1450,8 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) /* Set defaults for D0 and D3 states (always valid) */ device->power.states[ACPI_STATE_D0].flags.valid = 1; device->power.states[ACPI_STATE_D0].power = 100; - device->power.states[ACPI_STATE_D3].flags.valid = 1; - device->power.states[ACPI_STATE_D3].power = 0; + device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; + device->power.states[ACPI_STATE_D3_COLD].power = 0; /* Set D3cold's explicit_set flag if _PS3 exists. */ if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index cf4e7020ada..da8170dfc90 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -947,11 +947,11 @@ static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state) continue; acpi_bus_set_power(dev_handle, state.event & PM_EVENT_RESUME ? - ACPI_STATE_D0 : ACPI_STATE_D3); + ACPI_STATE_D0 : ACPI_STATE_D3_COLD); } if (!(state.event & PM_EVENT_RESUME)) - acpi_bus_set_power(port_handle, ACPI_STATE_D3); + acpi_bus_set_power(port_handle, ACPI_STATE_D3_COLD); } /** diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index f1a6796b165..140c8ef5052 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -520,11 +520,12 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) ide_port_for_each_present_dev(i, drive, hwif) { if (drive->acpidata->obj_handle) acpi_bus_set_power(drive->acpidata->obj_handle, - on ? ACPI_STATE_D0 : ACPI_STATE_D3); + on ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD); } if (!on) - acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3); + acpi_bus_set_power(hwif->acpidata->obj_handle, + ACPI_STATE_D3_COLD); } /** diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 55cd459a390..34049b0b4c7 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -131,7 +131,7 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ ret = 0; if (acpi_bus_power_manageable(handle)) - acpi_bus_set_power(handle, ACPI_STATE_D3); + acpi_bus_set_power(handle, ACPI_STATE_D3_COLD); /* continue even if acpi_bus_set_power() fails */ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL))) ret = -ENODEV; @@ -174,10 +174,10 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) if (acpi_bus_power_manageable(handle)) { int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL, - ACPI_STATE_D3); + ACPI_STATE_D3_COLD); if (power_state < 0) power_state = (state.event == PM_EVENT_ON) ? - ACPI_STATE_D0 : ACPI_STATE_D3; + ACPI_STATE_D0 : ACPI_STATE_D3_COLD; /* * acpi_bus_set_power() often fails (keyboard port can't be diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 56e6b68c8d2..916b1893387 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -478,7 +478,8 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) if (p) *p = ACPI_STATE_D0; - return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3) ? m : ACPI_STATE_D0; + return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3_COLD) ? + m : ACPI_STATE_D0; } static inline void acpi_dev_pm_add_dependent(acpi_handle handle, struct device *depdev) {} -- cgit v1.2.3-70-g09d2 From 7b4e0c4ac1809eab6fcfe6818ec8b70be79b41bc Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Wed, 31 Jul 2013 14:07:15 +0200 Subject: ACPI / PM: Remove redundant power manageable check from acpi_bus_set_power() Now that acpi_device_set_power() checks whether or not the given device is power manageable, it is not necessary to do this check in acpi_bus_set_power() any more, so remove it. Signed-off-by: Aaron Lu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 8234e1f8c79..beb9625e845 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -243,13 +243,6 @@ int acpi_bus_set_power(acpi_handle handle, int state) if (result) return result; - if (!device->flags.power_manageable) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Device [%s] is not power manageable\n", - dev_name(&device->dev))); - return -ENODEV; - } - return acpi_device_set_power(device, state); } EXPORT_SYMBOL(acpi_bus_set_power); -- cgit v1.2.3-70-g09d2 From d6b47b122473885abc882e337ac2d321bbcfb378 Mon Sep 17 00:00:00 2001 From: Ben Guthro Date: Tue, 30 Jul 2013 08:24:52 -0400 Subject: ACPI / sleep: Introduce acpi_os_prepare_extended_sleep() for extended sleep path Like acpi_os_prepare_sleep(), register a callback for use in systems like tboot, and xen, which have system specific requirements outside of ACPICA. This mirrors the functionality in acpi_os_prepare_sleep(), called from acpi_hw_sleep() Signed-off-by: Ben Guthro Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/hwesleep.c | 9 +++++++++ drivers/acpi/osl.c | 24 ++++++++++++++++++++++++ include/linux/acpi.h | 7 +++++++ 3 files changed, 40 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index 5e5f76230f5..414076818d4 100644 --- a/drivers/acpi/acpica/hwesleep.c +++ b/drivers/acpi/acpica/hwesleep.c @@ -43,6 +43,7 @@ */ #include +#include #include "accommon.h" #define _COMPONENT ACPI_HARDWARE @@ -128,6 +129,14 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state) ACPI_FLUSH_CPU_CACHE(); + status = acpi_os_prepare_extended_sleep(sleep_state, + acpi_gbl_sleep_type_a, + acpi_gbl_sleep_type_b); + if (ACPI_SKIP(status)) + return_ACPI_STATUS(AE_OK); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + /* * Set the SLP_TYP and SLP_EN bits. * diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6ab2c350552..a934950ff7a 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -79,6 +79,8 @@ extern char line_buf[80]; static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl, u32 pm1b_ctrl); +static int (*__acpi_os_prepare_extended_sleep)(u8 sleep_state, u32 val_a, + u32 val_b); static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; @@ -1779,6 +1781,28 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, __acpi_os_prepare_sleep = func; } +acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a, + u32 val_b) +{ + int rc = 0; + if (__acpi_os_prepare_extended_sleep) + rc = __acpi_os_prepare_extended_sleep(sleep_state, + val_a, val_b); + if (rc < 0) + return AE_ERROR; + else if (rc > 0) + return AE_CTRL_SKIP; + + return AE_OK; +} + +void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state, + u32 val_a, u32 val_b)) +{ + __acpi_os_prepare_extended_sleep = func; +} + + void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context, void (*func)(struct work_struct *work)) { diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 353ba256f36..a5db4aeefa3 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -481,6 +481,13 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control); + +void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state, + u32 val_a, u32 val_b)); + +acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, + u32 val_a, u32 val_b); + #ifdef CONFIG_X86 void arch_reserve_mem_area(acpi_physical_address addr, size_t size); #else -- cgit v1.2.3-70-g09d2 From 593298e68a3a53bd2fe942244250dfef4d68d477 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Sat, 3 Aug 2013 21:13:22 +0200 Subject: ACPI / PM: Add state information to error message in acpi_device_set_power() The state information can be useful to know what the problem is when an error message about a device can not being set to a higher power state than its parent appeared, so this patch adds such state information for both the target state of the device and the current state of its parent. Signed-off-by: Aaron Lu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index beb9625e845..59d3202f6b3 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -179,7 +179,9 @@ int acpi_device_set_power(struct acpi_device *device, int state) } if (device->parent && (state < device->parent->power.state)) { dev_warn(&device->dev, - "Cannot transition to a higher-powered state than parent\n"); + "Cannot transition to power state %s for parent in %s\n", + acpi_power_state_string(state), + acpi_power_state_string(device->parent->power.state)); return -ENODEV; } -- cgit v1.2.3-70-g09d2 From 21fcb34e28e99291e91d83422f2824f11b3c9ce9 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Thu, 1 Aug 2013 18:43:59 -0500 Subject: ACPI / video: trivial costmetic cleanups Fix whitespace and comments in several places in drivers/acpi/video.c. [rjw: Changelog] Signed-off-by: Felipe Contreras Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 114 +++++++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 53 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 0ec434d2586..f021bf4d930 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1,5 +1,5 @@ /* - * video.c - ACPI Video Driver ($Revision:$) + * video.c - ACPI Video Driver * * Copyright (C) 2004 Luming Yu * Copyright (C) 2004 Bruno Ducrot @@ -118,26 +118,26 @@ struct acpi_video_bus_flags { }; struct acpi_video_bus_cap { - u8 _DOS:1; /*Enable/Disable output switching */ - u8 _DOD:1; /*Enumerate all devices attached to display adapter */ - u8 _ROM:1; /*Get ROM Data */ - u8 _GPD:1; /*Get POST Device */ - u8 _SPD:1; /*Set POST Device */ - u8 _VPO:1; /*Video POST Options */ + u8 _DOS:1; /* Enable/Disable output switching */ + u8 _DOD:1; /* Enumerate all devices attached to display adapter */ + u8 _ROM:1; /* Get ROM Data */ + u8 _GPD:1; /* Get POST Device */ + u8 _SPD:1; /* Set POST Device */ + u8 _VPO:1; /* Video POST Options */ u8 reserved:2; }; struct acpi_video_device_attrib { u32 display_index:4; /* A zero-based instance of the Display */ - u32 display_port_attachment:4; /*This field differentiates the display type */ - u32 display_type:4; /*Describe the specific type in use */ - u32 vendor_specific:4; /*Chipset Vendor Specific */ - u32 bios_can_detect:1; /*BIOS can detect the device */ - u32 depend_on_vga:1; /*Non-VGA output device whose power is related to + u32 display_port_attachment:4; /* This field differentiates the display type */ + u32 display_type:4; /* Describe the specific type in use */ + u32 vendor_specific:4; /* Chipset Vendor Specific */ + u32 bios_can_detect:1; /* BIOS can detect the device */ + u32 depend_on_vga:1; /* Non-VGA output device whose power is related to the VGA device. */ - u32 pipe_id:3; /*For VGA multiple-head devices. */ - u32 reserved:10; /*Must be 0 */ - u32 device_id_scheme:1; /*Device ID Scheme */ + u32 pipe_id:3; /* For VGA multiple-head devices. */ + u32 reserved:10; /* Must be 0 */ + u32 device_id_scheme:1; /* Device ID Scheme */ }; struct acpi_video_enumerated_device { @@ -174,17 +174,17 @@ struct acpi_video_device_flags { }; struct acpi_video_device_cap { - u8 _ADR:1; /*Return the unique ID */ - u8 _BCL:1; /*Query list of brightness control levels supported */ - u8 _BCM:1; /*Set the brightness level */ + u8 _ADR:1; /* Return the unique ID */ + u8 _BCL:1; /* Query list of brightness control levels supported */ + u8 _BCM:1; /* Set the brightness level */ u8 _BQC:1; /* Get current brightness level */ u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ - u8 _DDC:1; /*Return the EDID for this device */ + u8 _DDC:1; /* Return the EDID for this device */ }; struct acpi_video_brightness_flags { u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */ - u8 _BCL_reversed:1; /* _BCL package is in a reversed order*/ + u8 _BCL_reversed:1; /* _BCL package is in a reversed order */ u8 _BCL_use_index:1; /* levels in _BCL are index values */ u8 _BCM_use_index:1; /* input of _BCM is an index value */ u8 _BQC_use_index:1; /* _BQC returns an index value */ @@ -231,7 +231,7 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, static int acpi_video_switch_brightness(struct acpi_video_device *device, int event); -/*backlight device sysfs support*/ +/* backlight device sysfs support */ static int acpi_video_get_brightness(struct backlight_device *bd) { unsigned long long cur_level; @@ -243,8 +243,10 @@ static int acpi_video_get_brightness(struct backlight_device *bd) return -EINVAL; for (i = 2; i < vd->brightness->count; i++) { if (vd->brightness->levels[i] == cur_level) - /* The first two entries are special - see page 575 - of the ACPI spec 3.0 */ + /* + * The first two entries are special - see page 575 + * of the ACPI spec 3.0 + */ return i-2; } return 0; @@ -316,9 +318,11 @@ static const struct thermal_cooling_device_ops video_cooling_ops = { .set_cur_state = video_set_cur_state, }; -/* -------------------------------------------------------------------------- - Video Management - -------------------------------------------------------------------------- */ +/* + * -------------------------------------------------------------------------- + * Video Management + * -------------------------------------------------------------------------- + */ static int acpi_video_device_lcd_query_levels(struct acpi_video_device *device, @@ -556,7 +560,8 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, buf)); device->cap._BQC = device->cap._BCQ = 0; } else { - /* Fixme: + /* + * Fixme: * should we return an error or ignore this failure? * dev->brightness->curr is a cached value which stores * the correct current backlight level in most cases. @@ -615,8 +620,8 @@ acpi_video_device_EDID(struct acpi_video_device *device, /* * Arg: - * video : video bus device pointer - * bios_flag : + * video : video bus device pointer + * bios_flag : * 0. The system BIOS should NOT automatically switch(toggle) * the active display output. * 1. The system BIOS should automatically switch (toggle) the @@ -628,9 +633,9 @@ acpi_video_device_EDID(struct acpi_video_device *device, * lcd_flag : * 0. The system BIOS should automatically control the brightness level * of the LCD when the power changes from AC to DC - * 1. The system BIOS should NOT automatically control the brightness + * 1. The system BIOS should NOT automatically control the brightness * level of the LCD when the power changes from AC to DC. - * Return Value: + * Return Value: * -EINVAL wrong arg. */ @@ -717,8 +722,8 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device, /* - * Arg: - * device : video output device (LCD, CRT, ..) + * Arg: + * device : video output device (LCD, CRT, ..) * * Return Value: * Maximum brightness level @@ -877,7 +882,7 @@ out: * device : video output device (LCD, CRT, ..) * * Return Value: - * None + * None * * Find out all required AML methods defined under the output * device. @@ -988,11 +993,11 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) } /* - * Arg: - * device : video output device (VGA) + * Arg: + * device : video output device (VGA) * * Return Value: - * None + * None * * Find out all required AML methods defined under the video bus device. */ @@ -1039,7 +1044,8 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) return -ENODEV; pci_dev_put(dev); - /* Since there is no HID, CID and so on for VGA driver, we have + /* + * Since there is no HID, CID and so on for VGA driver, we have * to check well known required nodes. */ @@ -1069,9 +1075,11 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) return status; } -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ +/* + * -------------------------------------------------------------------------- + * Driver Interface + * -------------------------------------------------------------------------- + */ /* device interface */ static struct acpi_video_device_attrib* @@ -1192,12 +1200,12 @@ acpi_video_bus_get_one_device(struct acpi_device *device, /* * Arg: - * video : video bus device + * video : video bus device * * Return: - * none - * - * Enumerate the video device list of the video bus, + * none + * + * Enumerate the video device list of the video bus, * bind the ids with the corresponding video devices * under the video bus. */ @@ -1216,13 +1224,13 @@ static void acpi_video_device_rebind(struct acpi_video_bus *video) /* * Arg: - * video : video bus device - * device : video output device under the video - * bus + * video : video bus device + * device : video output device under the video + * bus * * Return: - * none - * + * none + * * Bind the ids with the corresponding video devices * under the video bus. */ @@ -1245,11 +1253,11 @@ acpi_video_device_bind(struct acpi_video_bus *video, /* * Arg: - * video : video bus device + * video : video bus device * * Return: - * < 0 : error - * + * < 0 : error + * * Call _DOD to enumerate all devices attached to display adapter * */ -- cgit v1.2.3-70-g09d2 From 915ea7e41439efa7793814cdf4338cb6b003538a Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sat, 3 Aug 2013 22:12:50 +0200 Subject: ACPI / video: trivial style cleanups Fix several coding style defects in drivers/acpi/video.c: - Initialization of static variables. - Whitespace in expressions, variable definitions, function headers, etc. - Positioning of labels. - Braces around single statements. [rjw: Changelog] Signed-off-by: Felipe Contreras Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 80 +++++++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 45 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index f021bf4d930..fff5bb3ffda 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -88,7 +88,7 @@ module_param(allow_duplicates, bool, 0644); static bool use_bios_initial_backlight = 1; module_param(use_bios_initial_backlight, bool, 0644); -static int register_count = 0; +static int register_count; static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_remove(struct acpi_device *device); static void acpi_video_bus_notify(struct acpi_device *device, u32 event); @@ -247,7 +247,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd) * The first two entries are special - see page 575 * of the ACPI spec 3.0 */ - return i-2; + return i - 2; } return 0; } @@ -304,11 +304,11 @@ video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long st struct acpi_video_device *video = acpi_driver_data(device); int level; - if ( state >= video->brightness->count - 2) + if (state >= video->brightness->count - 2) return -EINVAL; state = video->brightness->count - state; - level = video->brightness->levels[state -1]; + level = video->brightness->levels[state - 1]; return acpi_video_device_lcd_set_level(video, level); } @@ -349,7 +349,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device, return 0; - err: +err: kfree(buffer.pointer); return status; @@ -550,7 +550,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, if (device->brightness->levels[i] == *level) { device->brightness->curr = *level; return 0; - } + } /* * BQC returned an invalid level. * Stop using it. @@ -892,16 +892,13 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) { acpi_handle h_dummy1; - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) device->cap._ADR = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) device->cap._BCL = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) device->cap._BCM = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) + if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BQC", &h_dummy1))) device->cap._BQC = 1; else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ", &h_dummy1))) { @@ -909,9 +906,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) device->cap._BCQ = 1; } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) device->cap._DDC = 1; - } if (acpi_video_init_brightness(device)) return; @@ -922,7 +918,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) acpi_handle acpi_parent; struct device *parent = NULL; int result; - static int count = 0; + static int count; char *name; name = kasprintf(GFP_KERNEL, "acpi_video%d", count); @@ -1006,24 +1002,18 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) { acpi_handle h_dummy1; - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) video->cap._DOS = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) video->cap._DOD = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) video->cap._ROM = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) video->cap._GPD = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) video->cap._SPD = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) { + if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) video->cap._VPO = 1; - } } /* @@ -1082,7 +1072,7 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) */ /* device interface */ -static struct acpi_video_device_attrib* +static struct acpi_video_device_attrib * acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) { struct acpi_video_enumerated_device *ids; @@ -1120,7 +1110,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, unsigned long long device_id; int status, device_type; struct acpi_video_device *data; - struct acpi_video_device_attrib* attribute; + struct acpi_video_device_attrib *attribute; status = acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); @@ -1142,7 +1132,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, attribute = acpi_video_get_device_attr(video, device_id); - if((attribute != NULL) && attribute->device_id_scheme) { + if (attribute && attribute->device_id_scheme) { switch (attribute->display_type) { case ACPI_VIDEO_DISPLAY_CRT: data->flags.crt = 1; @@ -1160,24 +1150,24 @@ acpi_video_bus_get_one_device(struct acpi_device *device, data->flags.unknown = 1; break; } - if(attribute->bios_can_detect) + if (attribute->bios_can_detect) data->flags.bios = 1; } else { /* Check for legacy IDs */ device_type = acpi_video_get_device_type(video, device_id); /* Ignore bits 16 and 18-20 */ switch (device_type & 0xffe2ffff) { - case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: - data->flags.crt = 1; - break; - case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: - data->flags.lcd = 1; - break; - case ACPI_VIDEO_DISPLAY_LEGACY_TV: - data->flags.tvout = 1; - break; - default: - data->flags.unknown = 1; + case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: + data->flags.crt = 1; + break; + case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: + data->flags.lcd = 1; + break; + case ACPI_VIDEO_DISPLAY_LEGACY_TV: + data->flags.tvout = 1; + break; + default: + data->flags.unknown = 1; } } @@ -1318,7 +1308,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) video->attached_array = active_list; video->attached_count = count; - out: +out: kfree(buffer.pointer); return status; } @@ -1773,7 +1763,7 @@ static int acpi_video_bus_add(struct acpi_device *device) if (!strcmp(device->pnp.bus_id, "VID")) { if (instance) device->pnp.bus_id[3] = '0' + instance; - instance ++; + instance++; } /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ if (!strcmp(device->pnp.bus_id, "VGA")) { -- cgit v1.2.3-70-g09d2 From 7c364e79aab6246675436bfc8e50e1ffba15dd63 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sat, 3 Aug 2013 22:15:21 +0200 Subject: ACPI / video: remove unnecessary type casting Remove type casting from assignments involving void pointers in two places in drivers/acpi/video.c. [rjw: Changelog] Signed-off-by: Felipe Contreras Reviewed-by: Aaron Lu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index fff5bb3ffda..8681727e318 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -236,8 +236,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd) { unsigned long long cur_level; int i; - struct acpi_video_device *vd = - (struct acpi_video_device *)bl_get_data(bd); + struct acpi_video_device *vd = bl_get_data(bd); if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false)) return -EINVAL; @@ -255,8 +254,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd) static int acpi_video_set_brightness(struct backlight_device *bd) { int request_level = bd->props.brightness + 2; - struct acpi_video_device *vd = - (struct acpi_video_device *)bl_get_data(bd); + struct acpi_video_device *vd = bl_get_data(bd); return acpi_video_device_lcd_set_level(vd, vd->brightness->levels[request_level]); -- cgit v1.2.3-70-g09d2 From d8648caf55051c7c7609cc3538174930cef205ac Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sat, 3 Aug 2013 22:28:09 +0200 Subject: ACPI / video: drop unused fields from struct acpi_video_brightness_flags The _BCM_use_index and _BCL_use_index fields in struct acpi_video_brightness_flags are not used, so drop them. [rjw: Changelog] Signed-off-by: Felipe Contreras Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 8681727e318..159c935eaac 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -185,8 +185,6 @@ struct acpi_video_device_cap { struct acpi_video_brightness_flags { u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */ u8 _BCL_reversed:1; /* _BCL package is in a reversed order */ - u8 _BCL_use_index:1; /* levels in _BCL are index values */ - u8 _BCM_use_index:1; /* input of _BCM is an index value */ u8 _BQC_use_index:1; /* _BQC returns an index value */ }; @@ -809,16 +807,6 @@ acpi_video_init_brightness(struct acpi_video_device *device) br->count = count; device->brightness = br; - /* Check the input/output of _BQC/_BCL/_BCM */ - if ((max_level < 100) && (max_level <= (count - 2))) - br->flags._BCL_use_index = 1; - - /* - * _BCM is always consistent with _BCL, - * at least for all the laptops we have ever seen. - */ - br->flags._BCM_use_index = br->flags._BCL_use_index; - /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ br->curr = level = max_level; -- cgit v1.2.3-70-g09d2 From cb7a386c6c25e85c2710cdb1a498a73794cda660 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Mon, 29 Jul 2013 14:20:58 -0500 Subject: ACPI: blacklist win8 OSI for ASUS Zenbook Prime UX31A Since v3.7 the ACPI backlight driver doesn't work at all on this machine, because presumably the backlight AML code in the ACPI tables contains a code path that triggers when the OS identifies itself as compatible with Windows 8 (which the kernel started to do in 3.7). That code path is never used by Windows and on this particular machine it turns out to be unusable at all. Work around this problem by blacklisting the win8 OSI, so we are back to v3.6 behavior (that is, we don't tell the BIOS that we are compatible with Windows 8). Since v3.7, users have been forced to work around the initial regression by modifying the boot arguments [1]. [1] https://wiki.archlinux.org/index.php/ASUS_Zenbook_Prime_UX31A [rjw: Changelog] Signed-off-by: Felipe Contreras Signed-off-by: Rafael J. Wysocki --- drivers/acpi/blacklist.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index cb9629638de..a4041277680 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -192,6 +192,12 @@ static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) acpi_osi_setup("!Windows 2009"); return 0; } +static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) +{ + printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); + acpi_osi_setup("!Windows 2012"); + return 0; +} static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { { @@ -267,6 +273,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), }, }, + { + .callback = dmi_disable_osi_win8, + .ident = "ASUS Zenbook Prime UX31A", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"), + }, + }, /* * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. -- cgit v1.2.3-70-g09d2 From 62eb4b07f0803d0426eb695bfe6755dd6a2cafb2 Mon Sep 17 00:00:00 2001 From: Kuppuswamy Sathyanarayanan Date: Mon, 22 Jul 2013 16:51:20 -0700 Subject: ACPI / scan: Allow platform device creation without any IO resources Currently, ACPI platform device creation is aborted when there are no valid IO resources for the device. This approach will not work if the device has only GPIO as its resource or some custom resources. Remove zero resource check and allow platform device creation even without any valid IO resources. [rjw: Changelog] Signed-off-by: Kuppuswamy Sathyanarayanan Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_platform.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index fafec5ddf17..32136b85196 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -52,7 +52,7 @@ int acpi_create_platform_device(struct acpi_device *adev, struct platform_device_info pdevinfo; struct resource_list_entry *rentry; struct list_head resource_list; - struct resource *resources; + struct resource *resources = NULL; int count; /* If the ACPI node already has a physical device attached, skip it. */ @@ -61,9 +61,12 @@ int acpi_create_platform_device(struct acpi_device *adev, INIT_LIST_HEAD(&resource_list); count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); - if (count <= 0) + if (count < 0) return 0; + if (!count) + goto create_dev; + resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); if (!resources) { dev_err(&adev->dev, "No memory for resources\n"); @@ -76,6 +79,7 @@ int acpi_create_platform_device(struct acpi_device *adev, acpi_dev_free_resource_list(&resource_list); +create_dev: memset(&pdevinfo, 0, sizeof(pdevinfo)); /* * If the ACPI node has a parent and that parent has a physical device -- cgit v1.2.3-70-g09d2 From caf5c03f17c33a14ef0e7033000f89e4d0910f5a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 30 Jul 2013 14:38:34 +0200 Subject: ACPI: Move acpi_bus_get_device() from bus.c to scan.c Move acpi_bus_get_device() from bus.c to scan.c which allows acpi_bus_data_handler() to become static and clean up the latter. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 21 --------------------- drivers/acpi/scan.c | 30 ++++++++++++++++++++++-------- include/acpi/acpi_bus.h | 1 - 3 files changed, 22 insertions(+), 30 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 25b289ff429..7df97d27754 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -89,27 +89,6 @@ static struct dmi_system_id dsdt_dmi_table[] __initdata = { Device Management -------------------------------------------------------------------------- */ -int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) -{ - acpi_status status; - - if (!device) - return -EINVAL; - - /* TBD: Support fixed-feature devices */ - - status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device); - if (ACPI_FAILURE(status) || !*device) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", - handle)); - return -ENODEV; - } - - return 0; -} - -EXPORT_SYMBOL(acpi_bus_get_device); - acpi_status acpi_bus_get_status_handle(acpi_handle handle, unsigned long long *sta) { diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 10985573aaa..4b2679342e8 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -997,6 +997,28 @@ struct bus_type acpi_bus_type = { .uevent = acpi_device_uevent, }; +static void acpi_bus_data_handler(acpi_handle handle, void *context) +{ + /* Intentionally empty. */ +} + +int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) +{ + acpi_status status; + + if (!device) + return -EINVAL; + + status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device); + if (ACPI_FAILURE(status) || !*device) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", + handle)); + return -ENODEV; + } + return 0; +} +EXPORT_SYMBOL_GPL(acpi_bus_get_device); + int acpi_device_add(struct acpi_device *device, void (*release)(struct device *)) { @@ -1208,14 +1230,6 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) } EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); -void acpi_bus_data_handler(acpi_handle handle, void *context) -{ - - /* TBD */ - - return; -} - static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, struct acpi_device_wakeup *wakeup) { diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 2650d1f19e4..2a42cb36d23 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -363,7 +363,6 @@ extern void unregister_acpi_bus_notifier(struct notifier_block *nb); */ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); -void acpi_bus_data_handler(acpi_handle handle, void *context); acpi_status acpi_bus_get_status_handle(acpi_handle handle, unsigned long long *sta); int acpi_bus_get_status(struct acpi_device *device); -- cgit v1.2.3-70-g09d2 From d2fe7251a36012bc552a4c95246d486a8e284043 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Aug 2013 01:11:33 +0200 Subject: ACPI / scan: Drop unnecessary label from acpi_create_platform_device() The create_dev label in acpi_create_platform_device() is not necessary, because the if statement causing the jump to it to happen may be rearranged to avoid that jump. Rework the code accordingly (no functional changes should result drom that). Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_platform.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 32136b85196..1bde12708f9 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -61,25 +61,23 @@ int acpi_create_platform_device(struct acpi_device *adev, INIT_LIST_HEAD(&resource_list); count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); - if (count < 0) + if (count < 0) { return 0; + } else if (count > 0) { + resources = kmalloc(count * sizeof(struct resource), + GFP_KERNEL); + if (!resources) { + dev_err(&adev->dev, "No memory for resources\n"); + acpi_dev_free_resource_list(&resource_list); + return -ENOMEM; + } + count = 0; + list_for_each_entry(rentry, &resource_list, node) + resources[count++] = rentry->res; - if (!count) - goto create_dev; - - resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); - if (!resources) { - dev_err(&adev->dev, "No memory for resources\n"); acpi_dev_free_resource_list(&resource_list); - return -ENOMEM; } - count = 0; - list_for_each_entry(rentry, &resource_list, node) - resources[count++] = rentry->res; - - acpi_dev_free_resource_list(&resource_list); -create_dev: memset(&pdevinfo, 0, sizeof(pdevinfo)); /* * If the ACPI node has a parent and that parent has a physical device -- cgit v1.2.3-70-g09d2 From 3fe444ad7e3a6951fa0c9b552c5afe6f6df0d571 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Aug 2013 01:15:25 +0200 Subject: ACPI: Do not fail acpi_bind_one() if device is already bound correctly Modify acpi_bind_one() so that it doesn't fail if the device represented by its first argument has already been bound to the given ACPI handle (second argument), because that is not a good enough reason for returning an error code. Signed-off-by: Rafael J. Wysocki Reviewed-by: Lan Tianyu Acked-by: Toshi Kani --- drivers/acpi/glue.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 408f6b2a5fa..48cc4c98e18 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -217,7 +217,10 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) /* Sanity check. */ if (pn->dev == dev) { dev_warn(dev, "Already associated with ACPI node\n"); - goto err_free; + if (ACPI_HANDLE(dev) == handle) + retval = 0; + + goto out_free; } if (pn->node_id == node_id) { physnode_list = &pn->node; @@ -255,10 +258,14 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) put_device(dev); return retval; - err_free: + out_free: mutex_unlock(&acpi_dev->physical_node_lock); kfree(physical_node); - goto err; + if (retval) + goto err; + + put_device(dev); + return 0; } EXPORT_SYMBOL_GPL(acpi_bind_one); -- cgit v1.2.3-70-g09d2 From bdbdbf91081250657d018fc66d7cd0c07f337070 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Aug 2013 01:19:23 +0200 Subject: ACPI: Reduce acpi_bind_one()/acpi_unbind_one() code duplication Move some duplicated code from acpi_bind_one() and acpi_unbind_one() into a separate function and make that function use snprintf() instead of sprintf() for extra safety. Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Acked-by: Yasuaki Ishimatsu --- drivers/acpi/glue.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 48cc4c98e18..92cacb12ef5 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -173,6 +173,15 @@ acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge) } EXPORT_SYMBOL_GPL(acpi_find_child); +static void acpi_physnode_link_name(char *buf, unsigned int node_id) +{ + if (node_id > 0) + snprintf(buf, PHYSICAL_NODE_NAME_SIZE, + PHYSICAL_NODE_STRING "%u", node_id); + else + strcpy(buf, PHYSICAL_NODE_STRING); +} + int acpi_bind_one(struct device *dev, acpi_handle handle) { struct acpi_device *acpi_dev; @@ -238,11 +247,7 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) if (!ACPI_HANDLE(dev)) ACPI_HANDLE_SET(dev, acpi_dev->handle); - if (!physical_node->node_id) - strcpy(physical_node_name, PHYSICAL_NODE_STRING); - else - sprintf(physical_node_name, - "physical_node%d", physical_node->node_id); + acpi_physnode_link_name(physical_node_name, node_id); retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, physical_node_name); retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, @@ -296,12 +301,7 @@ int acpi_unbind_one(struct device *dev) acpi_dev->physical_node_count--; - if (!entry->node_id) - strcpy(physical_node_name, PHYSICAL_NODE_STRING); - else - sprintf(physical_node_name, - "physical_node%d", entry->node_id); - + acpi_physnode_link_name(physical_node_name, entry->node_id); sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name); sysfs_remove_link(&dev->kobj, "firmware_node"); ACPI_HANDLE_SET(dev, NULL); -- cgit v1.2.3-70-g09d2 From 4005520648c7d6cf28e74addb52bc4a793eea3eb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Aug 2013 01:19:37 +0200 Subject: ACPI: Create symlinks in acpi_bind_one() under physical_node_lock Put the creation of symlinks in acpi_bind_one() under the physical_node_lock mutex of the given ACPI device object, because that is part of the binding operation logically (those links are already removed under that mutex too). Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Acked-by: Yasuaki Ishimatsu --- drivers/acpi/glue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 92cacb12ef5..914a3460123 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -242,8 +242,6 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) list_add(&physical_node->node, physnode_list); acpi_dev->physical_node_count++; - mutex_unlock(&acpi_dev->physical_node_lock); - if (!ACPI_HANDLE(dev)) ACPI_HANDLE_SET(dev, acpi_dev->handle); @@ -253,6 +251,8 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, "firmware_node"); + mutex_unlock(&acpi_dev->physical_node_lock); + if (acpi_dev->wakeup.flags.valid) device_set_wakeup_capable(dev, true); -- cgit v1.2.3-70-g09d2 From f501b6ec290f59b9c444bc061acf0e422347fb55 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Aug 2013 01:19:52 +0200 Subject: ACPI: acpi_bind_one()/acpi_unbind_one() whitespace cleanups Clean up some inconsistent use of whitespace in acpi_bind_one() and acpi_unbind_one(). Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Acked-by: Yasuaki Ishimatsu --- drivers/acpi/glue.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 914a3460123..69641c06161 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -247,9 +247,9 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) acpi_physnode_link_name(physical_node_name, node_id); retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, - physical_node_name); + physical_node_name); retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, - "firmware_node"); + "firmware_node"); mutex_unlock(&acpi_dev->physical_node_lock); @@ -293,12 +293,11 @@ int acpi_unbind_one(struct device *dev) char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; entry = list_entry(node, struct acpi_device_physical_node, - node); + node); if (entry->dev != dev) continue; list_del(node); - acpi_dev->physical_node_count--; acpi_physnode_link_name(physical_node_name, entry->node_id); -- cgit v1.2.3-70-g09d2 From 3e3327837c180781960188563b4e4d5c004c2b29 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Aug 2013 01:22:08 +0200 Subject: ACPI: Use list_for_each_entry() in acpi_unbind_one() Since acpi_unbind_one() walks physical_node_list under the ACPI device object's physical_node_lock mutex and the walk may be terminated as soon as the matching entry has been found, it is not necessary to use list_for_each_safe() for that walk, so use list_for_each_entry() instead and make the code slightly more straightforward. Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Acked-by: Yasuaki Ishimatsu --- drivers/acpi/glue.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 69641c06161..570628e1def 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -279,7 +279,6 @@ int acpi_unbind_one(struct device *dev) struct acpi_device_physical_node *entry; struct acpi_device *acpi_dev; acpi_status status; - struct list_head *node, *next; if (!ACPI_HANDLE(dev)) return 0; @@ -289,25 +288,24 @@ int acpi_unbind_one(struct device *dev) goto err; mutex_lock(&acpi_dev->physical_node_lock); - list_for_each_safe(node, next, &acpi_dev->physical_node_list) { - char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; - - entry = list_entry(node, struct acpi_device_physical_node, - node); - if (entry->dev != dev) - continue; - - list_del(node); - acpi_dev->physical_node_count--; - - acpi_physnode_link_name(physical_node_name, entry->node_id); - sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name); - sysfs_remove_link(&dev->kobj, "firmware_node"); - ACPI_HANDLE_SET(dev, NULL); - /* acpi_bind_one increase refcnt by one */ - put_device(dev); - kfree(entry); - } + + list_for_each_entry(entry, &acpi_dev->physical_node_list, node) + if (entry->dev == dev) { + char physnode_name[PHYSICAL_NODE_NAME_SIZE]; + + list_del(&entry->node); + acpi_dev->physical_node_count--; + + acpi_physnode_link_name(physnode_name, entry->node_id); + sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name); + sysfs_remove_link(&dev->kobj, "firmware_node"); + ACPI_HANDLE_SET(dev, NULL); + /* acpi_bind_one() increase refcnt by one. */ + put_device(dev); + kfree(entry); + break; + } + mutex_unlock(&acpi_dev->physical_node_lock); return 0; -- cgit v1.2.3-70-g09d2 From 38e88839eff8a3d2e8d3bcc2ad833fe51cca0496 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Aug 2013 01:22:51 +0200 Subject: ACPI: Clean up error code path in acpi_unbind_one() The error code path in acpi_unbind_one() is unnecessarily complicated (in particular, the err label is not really necessary) and the error message printed by it is inaccurate (there's nothing called 'acpi_handle' in that function), so clean up those things. Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani Acked-by: Yasuaki Ishimatsu --- drivers/acpi/glue.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 570628e1def..dcba319ac3f 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -284,8 +284,10 @@ int acpi_unbind_one(struct device *dev) return 0; status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev); - if (ACPI_FAILURE(status)) - goto err; + if (ACPI_FAILURE(status)) { + dev_err(dev, "Oops, ACPI handle corrupt in %s()\n", __func__); + return -EINVAL; + } mutex_lock(&acpi_dev->physical_node_lock); @@ -307,12 +309,7 @@ int acpi_unbind_one(struct device *dev) } mutex_unlock(&acpi_dev->physical_node_lock); - return 0; - -err: - dev_err(dev, "Oops, 'acpi_handle' corrupt\n"); - return -EINVAL; } EXPORT_SYMBOL_GPL(acpi_unbind_one); -- cgit v1.2.3-70-g09d2 From 6cef74970186797c45b3add1e73a14aa71d338d1 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 7 Aug 2013 17:16:55 +0530 Subject: ACPI / EC: Fix incorrect placement of __initdata __initdata should be placed between the variable name and equal sign for the variable to be placed in the intended section. Signed-off-by: Sachin Kamat Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 80403c1a89f..34448038724 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -948,7 +948,7 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) return 0; } -static struct dmi_system_id __initdata ec_dmi_table[] = { +static struct dmi_system_id ec_dmi_table[] __initdata = { { ec_skip_dsdt_scan, "Compal JFL92", { DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), -- cgit v1.2.3-70-g09d2 From 8ef9fc78911ef64df98feba8ad12e406e8fa479b Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 7 Aug 2013 17:16:56 +0530 Subject: ACPI / processor: Fix incorrect placement of __initdata __initdata should be placed between the variable name and equal sign for the variable to be placed in the intended section. Signed-off-by: Sachin Kamat Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 164d49569ae..210079c3ad8 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -28,7 +28,7 @@ static int __init set_no_mwait(const struct dmi_system_id *id) return 0; } -static struct dmi_system_id __initdata processor_idle_dmi_table[] = { +static struct dmi_system_id processor_idle_dmi_table[] __initdata = { { set_no_mwait, "Extensa 5220", { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), -- cgit v1.2.3-70-g09d2 From 3e4376ffcec8e51091bd8ea54da8323e7b912971 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 7 Aug 2013 17:16:57 +0530 Subject: ACPI / Sleep: Fix incorrect placement of __initdata __initdata should be placed between the variable name and equal sign for the variable to be placed in the intended section. Signed-off-by: Sachin Kamat Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 187ab61889e..72554fd3104 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -141,7 +141,7 @@ static int __init init_nvs_nosave(const struct dmi_system_id *d) return 0; } -static struct dmi_system_id __initdata acpisleep_dmi_table[] = { +static struct dmi_system_id acpisleep_dmi_table[] __initdata = { { .callback = init_old_suspend_ordering, .ident = "Abit KN9 (nForce4 variant)", -- cgit v1.2.3-70-g09d2 From 38f7c5a11e8ec0f770d8850ca8442528a959f9f3 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 8 Aug 2013 15:29:22 +0800 Subject: ACPICA: Export acpi_tb_validate_rsdp(). This patch exports acpi_tb_validate_rsdp(), so that code duplication in some ACPICA utilities can be reduced. This patch also includes lint changes. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/actables.h | 2 ++ drivers/acpi/acpica/tbxfroot.c | 8 ++------ 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 917315ec21d..c54f42c64fe 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -49,6 +49,8 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count); /* * tbxfroot - Root pointer utilities */ +acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); + u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); /* diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index e76ed0f0782..948c95e80d4 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -48,9 +48,6 @@ #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbxfroot") -/* Local prototypes */ -static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); - /******************************************************************************* * * FUNCTION: acpi_tb_validate_rsdp @@ -62,8 +59,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); * DESCRIPTION: Validate the RSDP (ptr) * ******************************************************************************/ - -static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) +acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) { /* @@ -72,7 +68,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) * Note: Sometimes there exists more than one RSDP in memory; the valid * RSDP has a valid checksum, all others have an invalid checksum. */ - if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, + if (ACPI_STRNCMP((char *)rsdp->signature, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1) != 0) { /* Nope, BAD Signature */ -- cgit v1.2.3-70-g09d2 From b268cee867ed193379762fdf94005c5bb79317a8 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 8 Aug 2013 15:29:27 +0800 Subject: ACPICA: Emit all unresolved method externals in a text block Put all of the unresolved external method declarations in a single block, since they are important and may cause the resulting disassembled ASL file to not compile. This patch only affects ACPICA utilities and is necessary to avoid adding source code divergences between Linux and ACPICA upstream. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/aclocal.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index b0e3d15cfe9..0ed00669cd2 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -1033,6 +1033,7 @@ struct acpi_external_list { u8 type; u8 flags; u8 resolved; + u8 emitted; }; /* Values for Flags field above */ -- cgit v1.2.3-70-g09d2 From 63660e05ec719613b518547b40a1c501c10f0bc4 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 8 Aug 2013 15:29:32 +0800 Subject: ACPICA: DeRefOf operator: Update to fully resolve FieldUnit and BufferField refs. Previously, references to these objects were resolved only to the actual FieldUnit or BufferField object. The correct behavior is to resolve these references to an actual value. The problem is that DerefOf did not resolve these objects to actual values. An "Integer" object is simple, return the value. But a field in an operation region will require a read operation. For a BufferField, the appropriate data must be extracted from the parent buffer. NOTE: It appears that this issues is present in Windows7 but not Windows8. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exoparg1.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 814b4a3d656..3482df4a69f 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -990,11 +990,40 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) acpi_namespace_node *) return_desc); - } + if (!return_desc) { + break; + } + + /* + * June 2013: + * buffer_fields/field_units require additional resolution + */ + switch (return_desc->common.type) { + case ACPI_TYPE_BUFFER_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + + status = + acpi_ex_read_data_from_field + (walk_state, return_desc, + &temp_desc); + if (ACPI_FAILURE(status)) { + goto cleanup; + } - /* Add another reference to the object! */ + return_desc = temp_desc; + break; - acpi_ut_add_reference(return_desc); + default: + + /* Add another reference to the object */ + + acpi_ut_add_reference + (return_desc); + break; + } + } break; default: -- cgit v1.2.3-70-g09d2 From 3342c753bdeb29ec29d721c7ce38d283cc969174 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 8 Aug 2013 16:19:10 +0200 Subject: ACPI: Drop unnecessary label from acpi_bind_one() The out_free label in acpi_bind_one() is only jumped to from one place, so in fact it is not necessary, because the code below it can be moved to that place directly. Move that code and drop the label. Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani --- drivers/acpi/glue.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index dcba319ac3f..f3ead0ce37a 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -225,11 +225,15 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) list_for_each_entry(pn, &acpi_dev->physical_node_list, node) { /* Sanity check. */ if (pn->dev == dev) { + mutex_unlock(&acpi_dev->physical_node_lock); + dev_warn(dev, "Already associated with ACPI node\n"); - if (ACPI_HANDLE(dev) == handle) - retval = 0; + kfree(physical_node); + if (ACPI_HANDLE(dev) != handle) + goto err; - goto out_free; + put_device(dev); + return 0; } if (pn->node_id == node_id) { physnode_list = &pn->node; @@ -262,15 +266,6 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) ACPI_HANDLE_SET(dev, NULL); put_device(dev); return retval; - - out_free: - mutex_unlock(&acpi_dev->physical_node_lock); - kfree(physical_node); - if (retval) - goto err; - - put_device(dev); - return 0; } EXPORT_SYMBOL_GPL(acpi_bind_one); -- cgit v1.2.3-70-g09d2 From 464c114717ae221202ebdbd9aa216035b4626f18 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 8 Aug 2013 16:19:19 +0200 Subject: ACPI: Print diagnostic messages if device links cannot be created Although the device links created by acpi_bind_one() are not essential from the kernel functionality point of view, user space may be confused when they are missing, so print diagnostic messages to the kernel log if they can't be created. Signed-off-by: Rafael J. Wysocki Acked-by: Toshi Kani --- drivers/acpi/glue.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index f3ead0ce37a..94672297e1b 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -252,8 +252,15 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) acpi_physnode_link_name(physical_node_name, node_id); retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, physical_node_name); + if (retval) + dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n", + physical_node_name, retval); + retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, "firmware_node"); + if (retval) + dev_err(dev, "Failed to create link firmware_node (%d)\n", + retval); mutex_unlock(&acpi_dev->physical_node_lock); -- cgit v1.2.3-70-g09d2 From 22e7551eb6fd58352930306039a98313c011e615 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Tue, 13 Aug 2013 12:11:22 +0200 Subject: ACPI / processor: Remove acpi_processor_get_limit_info() acpi_processor_get_limit_info() is only called in the __acpi_processor_start() and what it does actually is just to check pr->flags.throttling and set limit. The pr pointer has been checked in the __acpi_processor_start() before acpi_processor_get_limit_info() being called. It doesn't make sense still to keep it as a function. So move code to __acpi_processor_start() and remove acpi_processor_get_limit_info(). Signed-off-by: Lan Tianyu Acked-by: Zhang Rui Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_driver.c | 4 +++- drivers/acpi/processor_thermal.c | 12 ------------ 2 files changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 870eaf5fa54..f0a4d0c0f96 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -179,7 +179,9 @@ static int __acpi_processor_start(struct acpi_device *device) acpi_processor_load_module(pr); #endif acpi_processor_get_throttling_info(pr); - acpi_processor_get_limit_info(pr); + + if (pr->flags.throttling) + pr->flags.limit = 1; if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) acpi_processor_power_init(pr); diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index e8e652710e6..d1d2e7fb5b3 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -186,18 +186,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) #endif -int acpi_processor_get_limit_info(struct acpi_processor *pr) -{ - - if (!pr) - return -EINVAL; - - if (pr->flags.throttling) - pr->flags.limit = 1; - - return 0; -} - /* thermal coolign device callbacks */ static int acpi_processor_max_state(struct acpi_processor *pr) { -- cgit v1.2.3-70-g09d2 From b9d10be7a8e88fdcb12540387c219cdde87b0795 Mon Sep 17 00:00:00 2001 From: Toshi Kani Date: Mon, 12 Aug 2013 09:45:53 -0600 Subject: ACPI / processor: Acquire writer lock to update CPU maps CPU system maps are protected with reader/writer locks. The reader lock, get_online_cpus(), assures that the maps are not updated while holding the lock. The writer lock, cpu_hotplug_begin(), is used to udpate the cpu maps along with cpu_maps_update_begin(). However, the ACPI processor handler updates the cpu maps without holding the the writer lock. acpi_map_lsapic() is called from acpi_processor_hotadd_init() to update cpu_possible_mask and cpu_present_mask. acpi_unmap_lsapic() is called from acpi_processor_remove() to update cpu_possible_mask. Currently, they are either unprotected or protected with the reader lock, which is not correct. For example, the get_online_cpus() below is supposed to assure that cpu_possible_mask is not changed while the code is iterating with for_each_possible_cpu(). get_online_cpus(); for_each_possible_cpu(cpu) { : } put_online_cpus(); However, this lock has no protection with CPU hotplug since the ACPI processor handler does not use the writer lock when it updates cpu_possible_mask. The reader lock does not serialize within the readers. This patch protects them with the writer lock with cpu_hotplug_begin() along with cpu_maps_update_begin(), which must be held before calling cpu_hotplug_begin(). It also protects arch_register_cpu() / arch_unregister_cpu(), which creates / deletes a sysfs cpu device interface. For this purpose it changes cpu_hotplug_begin() and cpu_hotplug_done() to global and exports them in cpu.h. Signed-off-by: Toshi Kani Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_processor.c | 21 ++++++++++++++++----- include/linux/cpu.h | 4 ++++ kernel/cpu.c | 9 +++------ 3 files changed, 23 insertions(+), 11 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 5a74a9c1e42..f29e06efa47 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -178,14 +178,17 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) return -ENODEV; + cpu_maps_update_begin(); + cpu_hotplug_begin(); + ret = acpi_map_lsapic(pr->handle, &pr->id); if (ret) - return ret; + goto out; ret = arch_register_cpu(pr->id); if (ret) { acpi_unmap_lsapic(pr->id); - return ret; + goto out; } /* @@ -195,7 +198,11 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) */ pr_info("CPU%d has been hot-added\n", pr->id); pr->flags.need_hotplug_init = 1; - return 0; + +out: + cpu_hotplug_done(); + cpu_maps_update_done(); + return ret; } #else static inline int acpi_processor_hotadd_init(struct acpi_processor *pr) @@ -452,11 +459,15 @@ static void acpi_processor_remove(struct acpi_device *device) per_cpu(processor_device_array, pr->id) = NULL; per_cpu(processors, pr->id) = NULL; + cpu_maps_update_begin(); + cpu_hotplug_begin(); + /* Remove the CPU. */ - get_online_cpus(); arch_unregister_cpu(pr->id); acpi_unmap_lsapic(pr->id); - put_online_cpus(); + + cpu_hotplug_done(); + cpu_maps_update_done(); try_offline_node(cpu_to_node(pr->id)); diff --git a/include/linux/cpu.h b/include/linux/cpu.h index ab0eade7303..956c0a16566 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -172,6 +172,8 @@ extern struct bus_type cpu_subsys; #ifdef CONFIG_HOTPLUG_CPU /* Stop CPUs going up and down. */ +extern void cpu_hotplug_begin(void); +extern void cpu_hotplug_done(void); extern void get_online_cpus(void); extern void put_online_cpus(void); extern void cpu_hotplug_disable(void); @@ -197,6 +199,8 @@ static inline void cpu_hotplug_driver_unlock(void) #else /* CONFIG_HOTPLUG_CPU */ +static inline void cpu_hotplug_begin(void) {} +static inline void cpu_hotplug_done(void) {} #define get_online_cpus() do { } while (0) #define put_online_cpus() do { } while (0) #define cpu_hotplug_disable() do { } while (0) diff --git a/kernel/cpu.c b/kernel/cpu.c index b2b227b8212..d7f07a2da5a 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -113,7 +113,7 @@ EXPORT_SYMBOL_GPL(put_online_cpus); * get_online_cpus() not an api which is called all that often. * */ -static void cpu_hotplug_begin(void) +void cpu_hotplug_begin(void) { cpu_hotplug.active_writer = current; @@ -127,7 +127,7 @@ static void cpu_hotplug_begin(void) } } -static void cpu_hotplug_done(void) +void cpu_hotplug_done(void) { cpu_hotplug.active_writer = NULL; mutex_unlock(&cpu_hotplug.lock); @@ -154,10 +154,7 @@ void cpu_hotplug_enable(void) cpu_maps_update_done(); } -#else /* #if CONFIG_HOTPLUG_CPU */ -static void cpu_hotplug_begin(void) {} -static void cpu_hotplug_done(void) {} -#endif /* #else #if CONFIG_HOTPLUG_CPU */ +#endif /* CONFIG_HOTPLUG_CPU */ /* Need to know about CPUs going up/down? */ int __ref register_cpu_notifier(struct notifier_block *nb) -- cgit v1.2.3-70-g09d2 From 027951e5650eefffa4d9fffad561468ea77ededa Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Tue, 13 Aug 2013 18:31:13 +0800 Subject: ACPI / dock: Fix __init attribute location in find_dock_and_bay() __init belongs after the return type on functions, not before it. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 82656075338..c90112ceb57 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -1055,7 +1055,7 @@ err_unregister: * * This is called by acpi_walk_namespace to look for dock stations and bays. */ -static __init acpi_status +static acpi_status __init find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) { if (is_dock(handle) || is_ejectable_bay(handle)) -- cgit v1.2.3-70-g09d2 From 40e318563c3748fd5c6712d163e5d663af8b22ae Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Tue, 13 Aug 2013 18:31:14 +0800 Subject: ACPI / numa: Fix __init attribute location in slit_valid() __init belongs after the return type on functions, not before it. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/numa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 33e609f6358..2e82e5d7693 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -159,7 +159,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) * distance than the others. * Do some quick checks here and only use the SLIT if it passes. */ -static __init int slit_valid(struct acpi_table_slit *slit) +static int __init slit_valid(struct acpi_table_slit *slit) { int i, j; int d = slit->locality_count; -- cgit v1.2.3-70-g09d2 From e73d3136355f511d3e1c2ef21acf02b19bd2b650 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Tue, 13 Aug 2013 18:31:15 +0800 Subject: ACPI / osl: Fix osi_setup_entries[] __initdata attribute location __initdata should come after the variable name being declared and nowhere else, in this way the variable will be placed in the intended section. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 605718f6664..eb95978854a 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1352,8 +1352,8 @@ struct osi_setup_entry { bool enable; }; -static struct osi_setup_entry __initdata - osi_setup_entries[OSI_STRING_ENTRIES_MAX] = { +static struct osi_setup_entry + osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { {"Module Device", true}, {"Processor Device", true}, {"3.0 _SCP Extensions", true}, -- cgit v1.2.3-70-g09d2 From bf0dd264b1207b090858e7847919af5f2e367d7c Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 8 Aug 2013 15:29:38 +0800 Subject: ACPICA: Fix possible fault for methods that optionally have no return value. Currently applies to the _WAK method only. If the method has no return value and slack mode is not enabled, the return value validation code can fault. Also improves the error message when an expected return value is missing (for any predefined name/method). The problem fixed here cannot happen on Linux unless acpi=strict is added to the kernel command line. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nspredef.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 24b71a01bf9..098e7666cbc 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -150,6 +150,15 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node, goto exit; } + /* + * + * 4) If there is no return value and it is optional, just return + * AE_OK (_WAK). + */ + if (!(*return_object_ptr)) { + goto exit; + } + /* * For returned Package objects, check the type of all sub-objects. * Note: Package may have been newly created by call above. @@ -268,7 +277,12 @@ acpi_ns_check_object_type(struct acpi_evaluate_info *info, acpi_ut_get_expected_return_types(type_buffer, expected_btypes); - if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { + if (!return_object) { + ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, + info->node_flags, + "Expected return object of type %s", + type_buffer)); + } else if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags, "Return type mismatch - found %s, expected %s", -- cgit v1.2.3-70-g09d2 From 2641f540800b47a1b9e9d8ce9d682fc15df088e2 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 8 Aug 2013 15:29:46 +0800 Subject: ACPICA: Fix divergences of the commit - ACPICA: Expose OSI version. The original commit 242b2287cd7f27521c8b54a4101d569e53e7a0ca "ACPICA: expose OSI version" triggers build errors in ACPICA when it is back ported. The patch removes the divergences between Linux and upstream ACPICA resulting from that. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 7 ++++++- drivers/acpi/acpica/utglobal.c | 1 - include/acpi/actypes.h | 28 +++++++++++++--------------- 3 files changed, 19 insertions(+), 17 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index b8d38117a20..90e846f985f 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -138,6 +138,12 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_auto_repair, FALSE); */ u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_ssdt_table_load, FALSE); +/* + * We keep track of the latest version of Windows that has been requested by + * the BIOS. + */ +u8 ACPI_INIT_GLOBAL(acpi_gbl_osi_data, 0); + /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ struct acpi_table_fadt acpi_gbl_FADT; @@ -285,7 +291,6 @@ ACPI_EXTERN u8 acpi_gbl_debugger_configuration; ACPI_EXTERN u8 acpi_gbl_step_to_next_call; ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; ACPI_EXTERN u8 acpi_gbl_events_initialized; -ACPI_EXTERN u8 acpi_gbl_osi_data; ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces; ACPI_EXTERN struct acpi_address_range *acpi_gbl_address_range_list[ACPI_ADDRESS_RANGE_MAX]; diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index f736448a860..d6f26bf8a06 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -336,7 +336,6 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_trace_dbg_layer = 0; acpi_gbl_debugger_configuration = DEBUGGER_THREADING; acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; - acpi_gbl_osi_data = 0; acpi_gbl_osi_mutex = NULL; acpi_gbl_reg_methods_executed = FALSE; diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index eae55fb7490..b748aefce92 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -1137,7 +1137,19 @@ struct acpi_memory_list { #endif }; -/* Definitions for _OSI support */ +/* Definitions of _OSI support */ + +#define ACPI_VENDOR_STRINGS 0x01 +#define ACPI_FEATURE_STRINGS 0x02 +#define ACPI_ENABLE_INTERFACES 0x00 +#define ACPI_DISABLE_INTERFACES 0x04 + +#define ACPI_DISABLE_ALL_VENDOR_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_VENDOR_STRINGS) +#define ACPI_DISABLE_ALL_FEATURE_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_FEATURE_STRINGS) +#define ACPI_DISABLE_ALL_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS) +#define ACPI_ENABLE_ALL_VENDOR_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS) +#define ACPI_ENABLE_ALL_FEATURE_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_FEATURE_STRINGS) +#define ACPI_ENABLE_ALL_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS) #define ACPI_OSI_WIN_2000 0x01 #define ACPI_OSI_WIN_XP 0x02 @@ -1152,18 +1164,4 @@ struct acpi_memory_list { #define ACPI_OSI_WIN_7 0x0B #define ACPI_OSI_WIN_8 0x0C -/* _OSI update actions */ - -#define ACPI_VENDOR_STRINGS 0x01 -#define ACPI_FEATURE_STRINGS 0x02 -#define ACPI_ENABLE_INTERFACES 0x00 -#define ACPI_DISABLE_INTERFACES 0x04 - -#define ACPI_DISABLE_ALL_VENDOR_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_VENDOR_STRINGS) -#define ACPI_DISABLE_ALL_FEATURE_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_FEATURE_STRINGS) -#define ACPI_DISABLE_ALL_STRINGS (ACPI_DISABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS) -#define ACPI_ENABLE_ALL_VENDOR_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS) -#define ACPI_ENABLE_ALL_FEATURE_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_FEATURE_STRINGS) -#define ACPI_ENABLE_ALL_STRINGS (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS) - #endif /* __ACTYPES_H__ */ -- cgit v1.2.3-70-g09d2 From 1d82980c99ef2a91459ea39627d8114befb2c895 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 8 Aug 2013 15:29:51 +0800 Subject: ACPICA: Make ACPI Power Management Timer (PM Timer) optional. PM Timer is now optional. This support is already in Windows8 and "SHOULD" come out in ACPI 5.0A (if all goes well). The change doesn't affect Linux directly, because it does not rely on the presence of the PM timer. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/hwtimer.c | 13 ++++++++++++- drivers/acpi/acpica/tbfadt.c | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 0c1a8bbd05d..2d7d22ebc78 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -100,8 +100,13 @@ acpi_status acpi_get_timer(u32 * ticks) return_ACPI_STATUS(AE_BAD_PARAMETER); } - status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); + /* ACPI 5.0A: PM Timer is optional */ + + if (!acpi_gbl_FADT.xpm_timer_block.address) { + return_ACPI_STATUS(AE_SUPPORT); + } + status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); return_ACPI_STATUS(status); } @@ -148,6 +153,12 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) return_ACPI_STATUS(AE_BAD_PARAMETER); } + /* ACPI 5.0A: PM Timer is optional */ + + if (!acpi_gbl_FADT.xpm_timer_block.address) { + return_ACPI_STATUS(AE_SUPPORT); + } + /* * Compute Tick Delta: * Handle (max one) timer rollovers on 24-bit versus 32-bit timers. diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 33b00d22300..9d99f218969 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -117,7 +117,7 @@ static struct acpi_fadt_info fadt_info_table[] = { ACPI_FADT_OFFSET(pm_timer_block), ACPI_FADT_OFFSET(pm_timer_length), ACPI_PM_TIMER_WIDTH, - ACPI_FADT_REQUIRED}, + ACPI_FADT_SEPARATE_LENGTH}, /* ACPI 5.0A: Timer is optional */ {"Gpe0Block", ACPI_FADT_OFFSET(xgpe0_block), @@ -574,7 +574,7 @@ static void acpi_tb_validate_fadt(void) if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { /* - * Field is required (Pm1a_event, Pm1a_control, pm_timer). + * Field is required (Pm1a_event, Pm1a_control). * Both the address and length must be non-zero. */ if (!address64->address || !length) { -- cgit v1.2.3-70-g09d2 From a50abf4842dd7d603a2ad6dcc7f1467fd2a66f03 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 8 Aug 2013 15:29:58 +0800 Subject: ACPICA: Return error if DerefOf resolves to a null package element. Disallow the dereference of a reference (via index) to an uninitialized package element. Provides compatibility with other ACPI implementations. ACPICA BZ 1003. References: https://bugs.acpica.org/show_bug.cgi?id=431 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exoparg1.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 3482df4a69f..2cdd41d8ade 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -962,10 +962,17 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) */ return_desc = *(operand[0]->reference.where); - if (return_desc) { - acpi_ut_add_reference - (return_desc); + if (!return_desc) { + /* + * Element is NULL, do not allow the dereference. + * This provides compatibility with other ACPI + * implementations. + */ + return_ACPI_STATUS + (AE_AML_UNINITIALIZED_ELEMENT); } + + acpi_ut_add_reference(return_desc); break; default: -- cgit v1.2.3-70-g09d2 From 4ef17507834d19ba4fc24c4c1c61e8f68df356a6 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 8 Aug 2013 15:30:05 +0800 Subject: ACPICA: Update names for walk_namespace callbacks to clarify usage. Use of "preorder" and "postorder" was incorrect. The callbacks are simply invoked during tree ascent and descent during the depth-first walk. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acnamesp.h | 4 ++-- drivers/acpi/acpica/nswalk.c | 26 +++++++++++++------------- drivers/acpi/acpica/nsxfeval.c | 16 ++++++++-------- include/acpi/acpixf.h | 4 ++-- 4 files changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index b83dc32a5ae..40b04bd5579 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -104,8 +104,8 @@ acpi_ns_walk_namespace(acpi_object_type type, acpi_handle start_object, u32 max_depth, u32 flags, - acpi_walk_callback pre_order_visit, - acpi_walk_callback post_order_visit, + acpi_walk_callback descending_callback, + acpi_walk_callback ascending_callback, void *context, void **return_value); struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index e70911a9e44..e81f15ef659 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -156,9 +156,9 @@ struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, * max_depth - Depth to which search is to reach * flags - Whether to unlock the NS before invoking * the callback routine - * pre_order_visit - Called during tree pre-order visit + * descending_callback - Called during tree descent * when an object of "Type" is found - * post_order_visit - Called during tree post-order visit + * ascending_callback - Called during tree ascent * when an object of "Type" is found * context - Passed to user function(s) above * return_value - from the user_function if terminated @@ -185,8 +185,8 @@ acpi_ns_walk_namespace(acpi_object_type type, acpi_handle start_node, u32 max_depth, u32 flags, - acpi_walk_callback pre_order_visit, - acpi_walk_callback post_order_visit, + acpi_walk_callback descending_callback, + acpi_walk_callback ascending_callback, void *context, void **return_value) { acpi_status status; @@ -255,22 +255,22 @@ acpi_ns_walk_namespace(acpi_object_type type, } /* - * Invoke the user function, either pre-order or post-order + * Invoke the user function, either descending, ascending, * or both. */ if (!node_previously_visited) { - if (pre_order_visit) { + if (descending_callback) { status = - pre_order_visit(child_node, level, - context, - return_value); + descending_callback(child_node, + level, context, + return_value); } } else { - if (post_order_visit) { + if (ascending_callback) { status = - post_order_visit(child_node, level, - context, - return_value); + ascending_callback(child_node, + level, context, + return_value); } } diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index f553cfdb71d..b38b4b07f86 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -533,9 +533,9 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) * PARAMETERS: type - acpi_object_type to search for * start_object - Handle in namespace where search begins * max_depth - Depth to which search is to reach - * pre_order_visit - Called during tree pre-order visit + * descending_callback - Called during tree descent * when an object of "Type" is found - * post_order_visit - Called during tree post-order visit + * ascending_callback - Called during tree ascent * when an object of "Type" is found * context - Passed to user function(s) above * return_value - Location where return value of @@ -563,8 +563,8 @@ acpi_status acpi_walk_namespace(acpi_object_type type, acpi_handle start_object, u32 max_depth, - acpi_walk_callback pre_order_visit, - acpi_walk_callback post_order_visit, + acpi_walk_callback descending_callback, + acpi_walk_callback ascending_callback, void *context, void **return_value) { acpi_status status; @@ -574,7 +574,7 @@ acpi_walk_namespace(acpi_object_type type, /* Parameter validation */ if ((type > ACPI_TYPE_LOCAL_MAX) || - (!max_depth) || (!pre_order_visit && !post_order_visit)) { + (!max_depth) || (!descending_callback && !ascending_callback)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -606,9 +606,9 @@ acpi_walk_namespace(acpi_object_type type, } status = acpi_ns_walk_namespace(type, start_object, max_depth, - ACPI_NS_WALK_UNLOCK, pre_order_visit, - post_order_visit, context, - return_value); + ACPI_NS_WALK_UNLOCK, + descending_callback, ascending_callback, + context, return_value); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 0dd03f226a6..e53f16a0723 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -212,8 +212,8 @@ acpi_status acpi_walk_namespace(acpi_object_type type, acpi_handle start_object, u32 max_depth, - acpi_walk_callback pre_order_visit, - acpi_walk_callback post_order_visit, + acpi_walk_callback descending_callback, + acpi_walk_callback ascending_callback, void *context, void **return_value); acpi_status -- cgit v1.2.3-70-g09d2 From 8a6036b92620a4ea0a1285d5c134ac9610ff4b32 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Wed, 14 Aug 2013 21:00:37 +0800 Subject: ACPI / thermal: Remove the unused lock of struct acpi_thermal The acpi_thermal->lock now just is initialized when a thermal zone device is added and destroyed when the thermal zone is removed. It is never used in any other places, so remove it. Signed-off-by: Lan Tianyu Acked-by: Zhang Rui Acked-by: Durgadoss R Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 547a906a766..dc1ba6c9ef5 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -190,7 +190,6 @@ struct acpi_thermal { struct thermal_zone_device *thermal_zone; int tz_enabled; int kelvin_offset; - struct mutex lock; }; /* -------------------------------------------------------------------------- @@ -1098,8 +1097,6 @@ static int acpi_thermal_add(struct acpi_device *device) strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); device->driver_data = tz; - mutex_init(&tz->lock); - result = acpi_thermal_get_info(tz); if (result) @@ -1132,7 +1129,6 @@ static int acpi_thermal_remove(struct acpi_device *device) tz = acpi_driver_data(device); acpi_thermal_unregister_thermal_zone(tz); - mutex_destroy(&tz->lock); kfree(tz); return 0; } -- cgit v1.2.3-70-g09d2 From b22131c254a9a3cfe0184b234ab8bd737b4c8ba2 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Wed, 14 Aug 2013 21:00:38 +0800 Subject: ACPI / thermal: Remove unused macros in the driver/acpi/thermal.c The ACPI_THERMAL_FILE* macros are not used now, so remove them. Signed-off-by: Lan Tianyu Acked-by: Zhang Rui Acked-by: Durgadoss R Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index dc1ba6c9ef5..eccd22dfa03 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -50,11 +50,6 @@ #define ACPI_THERMAL_CLASS "thermal_zone" #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" -#define ACPI_THERMAL_FILE_STATE "state" -#define ACPI_THERMAL_FILE_TEMPERATURE "temperature" -#define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points" -#define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode" -#define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency" #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 -- cgit v1.2.3-70-g09d2 From 70f2903b506100396dbdb301ae1ead74842a6894 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Wed, 14 Aug 2013 21:00:39 +0800 Subject: ACPI / thermal: Use THERMAL_TRIPS_NONE macro to replace number It's unreadable to pass "-1" as trip parameter directly to thermal_zone_bind_cooling_device(). Use THERMAL_TRIPS_NONE instead. Signed-off-by: Lan Tianyu Acked-by: Zhang Rui Acked-by: Durgadoss R Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index eccd22dfa03..ccf9527d7ed 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -843,12 +843,13 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, if (ACPI_SUCCESS(status) && (dev == device)) { if (bind) result = thermal_zone_bind_cooling_device - (thermal, -1, cdev, - THERMAL_NO_LIMIT, + (thermal, THERMAL_TRIPS_NONE, + cdev, THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); else result = thermal_zone_unbind_cooling_device - (thermal, -1, cdev); + (thermal, THERMAL_TRIPS_NONE, + cdev); if (result) goto failed; } -- cgit v1.2.3-70-g09d2 From 7702ae0dd9b40930931914866999a2ac9734d3eb Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Wed, 14 Aug 2013 17:37:08 +0800 Subject: ACPI / osl: Kill macro INVALID_TABLE(). The macro INVALID_TABLE() is defined like this: #define INVALID_TABLE(x, path, name) \ { pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); continue; } And it is used like this: for (...) { ... if (...) INVALID_TABLE() ... } The "continue" in the macro makes the code hard to understand. And also, this macro is only used several times in a single file. As suggested by Joe Perches , we can remote it and use pr_err directly. So after this patch, this macro is removed, and pr_err() is used like this: for (...) { ... if (...) { pr_err("ACPI OVERRIDE: ......"); continue; } ... } Signed-off-by: Tang Chen Suggested-by: Joe Perches Acked-by: Tejun Heo Acked-by: Toshi Kani Reviewed-by: Zhang Yanfei Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index eb95978854a..6bc08272f05 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -564,10 +564,6 @@ static const char * const table_sigs[] = { ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT, ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL }; -/* Non-fatal errors: Affected tables/files are ignored */ -#define INVALID_TABLE(x, path, name) \ - { pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); continue; } - #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) /* Must not increase 10 or needs code modification below */ @@ -594,9 +590,11 @@ void __init acpi_initrd_override(void *data, size_t size) data += offset; size -= offset; - if (file.size < sizeof(struct acpi_table_header)) - INVALID_TABLE("Table smaller than ACPI header", - cpio_path, file.name); + if (file.size < sizeof(struct acpi_table_header)) { + pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]\n", + cpio_path, file.name); + continue; + } table = file.data; @@ -604,15 +602,21 @@ void __init acpi_initrd_override(void *data, size_t size) if (!memcmp(table->signature, table_sigs[sig], 4)) break; - if (!table_sigs[sig]) - INVALID_TABLE("Unknown signature", - cpio_path, file.name); - if (file.size != table->length) - INVALID_TABLE("File length does not match table length", - cpio_path, file.name); - if (acpi_table_checksum(file.data, table->length)) - INVALID_TABLE("Bad table checksum", - cpio_path, file.name); + if (!table_sigs[sig]) { + pr_err("ACPI OVERRIDE: Unknown signature [%s%s]\n", + cpio_path, file.name); + continue; + } + if (file.size != table->length) { + pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]\n", + cpio_path, file.name); + continue; + } + if (acpi_table_checksum(file.data, table->length)) { + pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n", + cpio_path, file.name); + continue; + } pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n", table->signature, cpio_path, file.name, table->length); -- cgit v1.2.3-70-g09d2 From ad07277e82dedabacc52c82746633680a3187d25 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 20 Aug 2013 01:42:32 +0200 Subject: ACPI / PM: Hold acpi_scan_lock over system PM transitions Bad things happen if ACPI hotplug events are handled during system PM transitions, especially if devices are removed as a result. To prevent those bad things from happening, acquire acpi_scan_lock when a PM transition is started and release it when that transition is complete or has been aborted. This fixes resume lockup on my test-bed Acer Aspire S5 that happens when Thunderbolt devices are disconnected from the machine while suspended. Also fixes the analogous problem for Mika Westerberg on an Intel DZ77RE-75K board. Signed-off-by: Rafael J. Wysocki Tested-by: Mika Westerberg Acked-by: Toshi Kani --- drivers/acpi/sleep.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 81b0f03d97d..1dec53decff 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -420,10 +420,21 @@ static void acpi_pm_finish(void) } /** - * acpi_pm_end - Finish up suspend sequence. + * acpi_pm_start - Start system PM transition. + */ +static void acpi_pm_start(u32 acpi_state) +{ + acpi_target_sleep_state = acpi_state; + acpi_sleep_tts_switch(acpi_target_sleep_state); + acpi_scan_lock_acquire(); +} + +/** + * acpi_pm_end - Finish up system PM transition. */ static void acpi_pm_end(void) { + acpi_scan_lock_release(); /* * This is necessary in case acpi_pm_finish() is not called during a * failing transition to a sleep state. @@ -451,21 +462,19 @@ static u32 acpi_suspend_states[] = { static int acpi_suspend_begin(suspend_state_t pm_state) { u32 acpi_state = acpi_suspend_states[pm_state]; - int error = 0; + int error; error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc(); if (error) return error; - if (sleep_states[acpi_state]) { - acpi_target_sleep_state = acpi_state; - acpi_sleep_tts_switch(acpi_target_sleep_state); - } else { - printk(KERN_ERR "ACPI does not support this state: %d\n", - pm_state); - error = -ENOSYS; + if (!sleep_states[acpi_state]) { + pr_err("ACPI does not support sleep state S%u\n", acpi_state); + return -ENOSYS; } - return error; + + acpi_pm_start(acpi_state); + return 0; } /** @@ -631,10 +640,8 @@ static int acpi_hibernation_begin(void) int error; error = nvs_nosave ? 0 : suspend_nvs_alloc(); - if (!error) { - acpi_target_sleep_state = ACPI_STATE_S4; - acpi_sleep_tts_switch(acpi_target_sleep_state); - } + if (!error) + acpi_pm_start(ACPI_STATE_S4); return error; } @@ -713,8 +720,10 @@ static int acpi_hibernation_begin_old(void) if (!error) { if (!nvs_nosave) error = suspend_nvs_alloc(); - if (!error) + if (!error) { acpi_target_sleep_state = ACPI_STATE_S4; + acpi_scan_lock_acquire(); + } } return error; } -- cgit v1.2.3-70-g09d2 From 94fb9823a7c478bf88b99b8da4fc3e540608ece5 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sun, 25 Aug 2013 12:37:33 -0500 Subject: ACPI: blacklist win8 OSI for buggy laptops Since v3.7 the acpi backlight driver doesn't work correctly in several machines because ACPI code has different code for Windows 8, and the rest. The commit ea45ea7 (in v3.11-rc2) tried to fix this problem by using the intel backlight driver, however it introduced several other issues in different machines. This patch fixes both regressions by blacklisting the win8 OSI, so we are back to v3.6 behavior, and it should remain that way until the intel backlight driver is fixed. Since v3.7, users have been forced to fix the initial regression by modifying the boot arguments (acpi_osi="!Windows 2012"). Once the Intel backlight driver works correctly for all machines, this blacklist can be removed and that driver can be used instead. References: https://bugzilla.kernel.org/show_bug.cgi?id=60682 Reported-by: Danny Baumann Reported-by: Philipp Richter Signed-off-by: Felipe Contreras Signed-off-by: Rafael J. Wysocki --- drivers/acpi/blacklist.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index a4041277680..9515f18898b 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -281,6 +281,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"), }, }, + { + .callback = dmi_disable_osi_win8, + .ident = "Dell Inspiron 15R SE", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad Edge E530", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"), + }, + }, /* * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. -- cgit v1.2.3-70-g09d2 From 668e02004462487df8ec6c65c665ddb8af78dc12 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Tue, 27 Aug 2013 16:29:31 +0800 Subject: ACPI / thermal: Add check of "_TZD" availability and evaluating result Some machines don't provide _TZD, so check the availability of it before carrying out futher operations. If _TZD is present, also check the result of its evaluation. [rjw: Changelog] Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index ccf9527d7ed..0055c83c26c 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -485,14 +485,14 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) break; } - if (flag & ACPI_TRIPS_DEVICES) { - memset(&devices, 0, sizeof(struct acpi_handle_list)); + if ((flag & ACPI_TRIPS_DEVICES) + && acpi_has_method(tz->device->handle, "_TZD")) { + memset(&devices, 0, sizeof(devices)); status = acpi_evaluate_reference(tz->device->handle, "_TZD", NULL, &devices); - if (memcmp(&tz->devices, &devices, - sizeof(struct acpi_handle_list))) { - memcpy(&tz->devices, &devices, - sizeof(struct acpi_handle_list)); + if (ACPI_SUCCESS(status) + && memcmp(&tz->devices, &devices, sizeof(devices))) { + tz->devices = devices; ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); } } -- cgit v1.2.3-70-g09d2 From 524f42fab787a9510be826ce3d736b56d454ac6d Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Mon, 26 Aug 2013 10:19:18 +0800 Subject: ACPI / EC: Add ASUSTEK L4R to quirk list in order to validate ECDT The ECDT of ASUSTEK L4R doesn't provide correct command and data I/O ports. The DSDT provides the correct information instead. For this reason, add this machine to quirk list for ECDT validation and use the EC information from the DSDT. [rjw: Changelog] References: https://bugzilla.kernel.org/show_bug.cgi?id=60765 Reported-and-tested-by: Daniele Esposti Signed-off-by: Lan Tianyu Cc: All Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 34448038724..81b1331554f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -987,6 +987,10 @@ static struct dmi_system_id ec_dmi_table[] __initdata = { ec_skip_dsdt_scan, "HP Folio 13", { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL}, + { + ec_validate_ecdt, "ASUS hardware", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, {}, }; -- cgit v1.2.3-70-g09d2 From f943db40c29f3c82a56956e9ca36f21d6d855db9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 28 Aug 2013 21:41:07 +0200 Subject: ACPI / hotplug: Remove containers synchronously The current protocol for handling hot remove of containers is very fragile and causes acpi_eject_store() to acquire acpi_scan_lock which may deadlock with the removal of the device that it is called for (the reason is that device sysfs attributes cannot be removed while their callbacks are being executed and ACPI device objects are removed under acpi_scan_lock). The problem is related to the fact that containers are handled by acpi_bus_device_eject() in a special way, which is to emit an offline uevent instead of just removing the container. Then, user space is expected to handle that uevent and use the container's "eject" attribute to actually remove it. That is fragile, because user space may fail to complete the ejection (for example, by not using the container's "eject" attribute at all) leaving the BIOS kind of in a limbo. Moreover, if the eject event is not signaled for a container itself, but for its parent device object (or generally, for an ancestor above it in the ACPI namespace), the container will be removed straight away without doing that whole dance. For this reason, modify acpi_bus_device_eject() to remove containers synchronously like any other objects (user space will get its uevent anyway in case it does some other things in response to it) and remove the eject_pending ACPI device flag that is not used any more. This way acpi_eject_store() doesn't have a reason to acquire acpi_scan_lock any more and one possible deadlock scenario goes away (plus the code is simplified a bit). Reported-and-tested-by: Gu Zheng Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman Acked-by: Toshi Kani --- drivers/acpi/scan.c | 49 +++++++++++++++---------------------------------- include/acpi/acpi_bus.h | 3 +-- 2 files changed, 16 insertions(+), 36 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 8a46c924eff..e2f6d9dbdf0 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -307,6 +307,7 @@ static void acpi_bus_device_eject(void *context) struct acpi_device *device = NULL; struct acpi_scan_handler *handler; u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; + int error; mutex_lock(&acpi_scan_lock); @@ -321,17 +322,13 @@ static void acpi_bus_device_eject(void *context) } acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); - if (handler->hotplug.mode == AHM_CONTAINER) { - device->flags.eject_pending = true; + if (handler->hotplug.mode == AHM_CONTAINER) kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); - } else { - int error; - get_device(&device->dev); - error = acpi_scan_hot_remove(device); - if (error) - goto err_out; - } + get_device(&device->dev); + error = acpi_scan_hot_remove(device); + if (error) + goto err_out; out: mutex_unlock(&acpi_scan_lock); @@ -516,7 +513,6 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, struct acpi_eject_event *ej_event; acpi_object_type not_used; acpi_status status; - u32 ost_source; int ret; if (!count || buf[0] != '1') @@ -530,43 +526,28 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) return -ENODEV; - mutex_lock(&acpi_scan_lock); - - if (acpi_device->flags.eject_pending) { - /* ACPI eject notification event. */ - ost_source = ACPI_NOTIFY_EJECT_REQUEST; - acpi_device->flags.eject_pending = 0; - } else { - /* Eject initiated by user space. */ - ost_source = ACPI_OST_EC_OSPM_EJECT; - } ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); if (!ej_event) { ret = -ENOMEM; goto err_out; } - acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source, + acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); ej_event->device = acpi_device; - ej_event->event = ost_source; + ej_event->event = ACPI_OST_EC_OSPM_EJECT; get_device(&acpi_device->dev); status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); - if (ACPI_FAILURE(status)) { - put_device(&acpi_device->dev); - kfree(ej_event); - ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; - goto err_out; - } - ret = count; + if (ACPI_SUCCESS(status)) + return count; - out: - mutex_unlock(&acpi_scan_lock); - return ret; + put_device(&acpi_device->dev); + kfree(ej_event); + ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; err_out: - acpi_evaluate_hotplug_ost(acpi_device->handle, ost_source, + acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); - goto out; + return ret; } static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 94383a70c1a..6ff9510718d 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -157,9 +157,8 @@ struct acpi_device_flags { u32 removable:1; u32 ejectable:1; u32 power_manageable:1; - u32 eject_pending:1; u32 match_driver:1; - u32 reserved:26; + u32 reserved:27; }; /* File System */ -- cgit v1.2.3-70-g09d2