Commit f4cb707e7ad9727a046b463232f2de166e327d3e
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'pm+acpi-3.17-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from Rafael Wysocki: "These are regression fixes (ACPI hotplug, cpufreq, hibernation, ACPI LPSS driver), fixes for stuff that never worked correctly (ACPI GPIO support in some cases and a wrong sign of an error code in the ACPI core in one place), and one blacklist item for ACPI backlight handling. Specifics: - Revert of a recent hibernation core commit that introduced a NULL pointer dereference during resume for at least one user (Rafael J Wysocki). - Fix for the ACPI LPSS (Low-Power Subsystem) driver to disable asynchronous PM callback execution for LPSS devices during system suspend/resume (introduced in 3.16) which turns out to break ordering expectations on some systems. From Fu Zhonghui. - cpufreq core fix related to the handling of sysfs nodes during system suspend/resume that has been broken for intel_pstate since 3.15 from Lan Tianyu. - Restore the generation of "online" uevents for ACPI container devices that was removed in 3.14, but some user space utilities turn out to need them (Rafael J Wysocki). - The cpufreq core fails to release a lock in an error code path after changes made in 3.14. Fix from Prarit Bhargava. - ACPICA and ACPI/GPIO fixes to make the handling of ACPI GPIO operation regions (which means AML using GPIOs) work correctly in all cases from Bob Moore and Srinivas Pandruvada. - Fix for a wrong sign of the ACPI core's create_modalias() return value in case of an error from Mika Westerberg. - ACPI backlight blacklist entry for ThinkPad X201s from Aaron Lu" * tag 'pm+acpi-3.17-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: Revert "PM / Hibernate: Iterate over set bits instead of PFNs in swsusp_free()" gpio / ACPI: Use pin index and bit length ACPICA: Update to GPIO region handler interface. ACPI / platform / LPSS: disable async suspend/resume of LPSS devices cpufreq: release policy->rwsem on error cpufreq: fix cpufreq suspend/resume for intel_pstate ACPI / scan: Correct error return value of create_modalias() ACPI / video: disable native backlight for ThinkPad X201s ACPI / hotplug: Generate online uevents for ACPI containers
Showing 14 changed files Side-by-side Diff
- drivers/acpi/acpi_lpss.c
- drivers/acpi/acpica/aclocal.h
- drivers/acpi/acpica/acobject.h
- drivers/acpi/acpica/dsfield.c
- drivers/acpi/acpica/evregion.c
- drivers/acpi/acpica/exfield.c
- drivers/acpi/acpica/exprep.c
- drivers/acpi/container.c
- drivers/acpi/scan.c
- drivers/acpi/video.c
- drivers/cpufreq/cpufreq.c
- drivers/gpio/gpiolib-acpi.c
- include/acpi/acpi_bus.h
- kernel/power/snapshot.c
drivers/acpi/acpi_lpss.c
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/acobject.h
... | ... | @@ -264,6 +264,7 @@ |
264 | 264 | ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO u16 resource_length; |
265 | 265 | union acpi_operand_object *region_obj; /* Containing op_region object */ |
266 | 266 | u8 *resource_buffer; /* resource_template for serial regions/fields */ |
267 | + u16 pin_number_index; /* Index relative to previous Connection/Template */ | |
267 | 268 | }; |
268 | 269 | |
269 | 270 | struct acpi_object_bank_field { |
drivers/acpi/acpica/dsfield.c
... | ... | @@ -360,6 +360,7 @@ |
360 | 360 | */ |
361 | 361 | info->resource_buffer = NULL; |
362 | 362 | info->connection_node = NULL; |
363 | + info->pin_number_index = 0; | |
363 | 364 | |
364 | 365 | /* |
365 | 366 | * A Connection() is either an actual resource descriptor (buffer) |
... | ... | @@ -437,6 +438,7 @@ |
437 | 438 | } |
438 | 439 | |
439 | 440 | info->field_bit_position += info->field_bit_length; |
441 | + info->pin_number_index++; /* Index relative to previous Connection() */ | |
440 | 442 | break; |
441 | 443 | |
442 | 444 | default: |
drivers/acpi/acpica/evregion.c
... | ... | @@ -142,6 +142,7 @@ |
142 | 142 | union acpi_operand_object *region_obj2; |
143 | 143 | void *region_context = NULL; |
144 | 144 | struct acpi_connection_info *context; |
145 | + acpi_physical_address address; | |
145 | 146 | |
146 | 147 | ACPI_FUNCTION_TRACE(ev_address_space_dispatch); |
147 | 148 | |
148 | 149 | |
149 | 150 | |
150 | 151 | |
... | ... | @@ -231,25 +232,23 @@ |
231 | 232 | /* We have everything we need, we can invoke the address space handler */ |
232 | 233 | |
233 | 234 | handler = handler_desc->address_space.handler; |
235 | + address = (region_obj->region.address + region_offset); | |
234 | 236 | |
235 | - ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | |
236 | - "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", | |
237 | - ®ion_obj->region.handler->address_space, handler, | |
238 | - ACPI_FORMAT_NATIVE_UINT(region_obj->region.address + | |
239 | - region_offset), | |
240 | - acpi_ut_get_region_name(region_obj->region. | |
241 | - space_id))); | |
242 | - | |
243 | 237 | /* |
244 | 238 | * Special handling for generic_serial_bus and general_purpose_io: |
245 | 239 | * There are three extra parameters that must be passed to the |
246 | 240 | * handler via the context: |
247 | - * 1) Connection buffer, a resource template from Connection() op. | |
248 | - * 2) Length of the above buffer. | |
249 | - * 3) Actual access length from the access_as() op. | |
241 | + * 1) Connection buffer, a resource template from Connection() op | |
242 | + * 2) Length of the above buffer | |
243 | + * 3) Actual access length from the access_as() op | |
244 | + * | |
245 | + * In addition, for general_purpose_io, the Address and bit_width fields | |
246 | + * are defined as follows: | |
247 | + * 1) Address is the pin number index of the field (bit offset from | |
248 | + * the previous Connection) | |
249 | + * 2) bit_width is the actual bit length of the field (number of pins) | |
250 | 250 | */ |
251 | - if (((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) || | |
252 | - (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO)) && | |
251 | + if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) && | |
253 | 252 | context && field_obj) { |
254 | 253 | |
255 | 254 | /* Get the Connection (resource_template) buffer */ |
256 | 255 | |
... | ... | @@ -258,7 +257,25 @@ |
258 | 257 | context->length = field_obj->field.resource_length; |
259 | 258 | context->access_length = field_obj->field.access_length; |
260 | 259 | } |
260 | + if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && | |
261 | + context && field_obj) { | |
261 | 262 | |
263 | + /* Get the Connection (resource_template) buffer */ | |
264 | + | |
265 | + context->connection = field_obj->field.resource_buffer; | |
266 | + context->length = field_obj->field.resource_length; | |
267 | + context->access_length = field_obj->field.access_length; | |
268 | + address = field_obj->field.pin_number_index; | |
269 | + bit_width = field_obj->field.bit_length; | |
270 | + } | |
271 | + | |
272 | + ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | |
273 | + "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", | |
274 | + ®ion_obj->region.handler->address_space, handler, | |
275 | + ACPI_FORMAT_NATIVE_UINT(address), | |
276 | + acpi_ut_get_region_name(region_obj->region. | |
277 | + space_id))); | |
278 | + | |
262 | 279 | if (!(handler_desc->address_space.handler_flags & |
263 | 280 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { |
264 | 281 | /* |
... | ... | @@ -271,9 +288,7 @@ |
271 | 288 | |
272 | 289 | /* Call the handler */ |
273 | 290 | |
274 | - status = handler(function, | |
275 | - (region_obj->region.address + region_offset), | |
276 | - bit_width, value, context, | |
291 | + status = handler(function, address, bit_width, value, context, | |
277 | 292 | region_obj2->extra.region_context); |
278 | 293 | |
279 | 294 | if (ACPI_FAILURE(status)) { |
drivers/acpi/acpica/exfield.c
... | ... | @@ -253,6 +253,37 @@ |
253 | 253 | buffer = &buffer_desc->integer.value; |
254 | 254 | } |
255 | 255 | |
256 | + if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && | |
257 | + (obj_desc->field.region_obj->region.space_id == | |
258 | + ACPI_ADR_SPACE_GPIO)) { | |
259 | + /* | |
260 | + * For GPIO (general_purpose_io), the Address will be the bit offset | |
261 | + * from the previous Connection() operator, making it effectively a | |
262 | + * pin number index. The bit_length is the length of the field, which | |
263 | + * is thus the number of pins. | |
264 | + */ | |
265 | + ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | |
266 | + "GPIO FieldRead [FROM]: Pin %u Bits %u\n", | |
267 | + obj_desc->field.pin_number_index, | |
268 | + obj_desc->field.bit_length)); | |
269 | + | |
270 | + /* Lock entire transaction if requested */ | |
271 | + | |
272 | + acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); | |
273 | + | |
274 | + /* Perform the write */ | |
275 | + | |
276 | + status = acpi_ex_access_region(obj_desc, 0, | |
277 | + (u64 *)buffer, ACPI_READ); | |
278 | + acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | |
279 | + if (ACPI_FAILURE(status)) { | |
280 | + acpi_ut_remove_reference(buffer_desc); | |
281 | + } else { | |
282 | + *ret_buffer_desc = buffer_desc; | |
283 | + } | |
284 | + return_ACPI_STATUS(status); | |
285 | + } | |
286 | + | |
256 | 287 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
257 | 288 | "FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n", |
258 | 289 | obj_desc, obj_desc->common.type, buffer, |
... | ... | @@ -412,6 +443,42 @@ |
412 | 443 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
413 | 444 | |
414 | 445 | *result_desc = buffer_desc; |
446 | + return_ACPI_STATUS(status); | |
447 | + } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && | |
448 | + (obj_desc->field.region_obj->region.space_id == | |
449 | + ACPI_ADR_SPACE_GPIO)) { | |
450 | + /* | |
451 | + * For GPIO (general_purpose_io), we will bypass the entire field | |
452 | + * mechanism and handoff the bit address and bit width directly to | |
453 | + * the handler. The Address will be the bit offset | |
454 | + * from the previous Connection() operator, making it effectively a | |
455 | + * pin number index. The bit_length is the length of the field, which | |
456 | + * is thus the number of pins. | |
457 | + */ | |
458 | + if (source_desc->common.type != ACPI_TYPE_INTEGER) { | |
459 | + return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | |
460 | + } | |
461 | + | |
462 | + ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | |
463 | + "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X [TO]: Pin %u Bits %u\n", | |
464 | + acpi_ut_get_type_name(source_desc->common. | |
465 | + type), | |
466 | + source_desc->common.type, | |
467 | + (u32)source_desc->integer.value, | |
468 | + obj_desc->field.pin_number_index, | |
469 | + obj_desc->field.bit_length)); | |
470 | + | |
471 | + buffer = &source_desc->integer.value; | |
472 | + | |
473 | + /* Lock entire transaction if requested */ | |
474 | + | |
475 | + acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); | |
476 | + | |
477 | + /* Perform the write */ | |
478 | + | |
479 | + status = acpi_ex_access_region(obj_desc, 0, | |
480 | + (u64 *)buffer, ACPI_WRITE); | |
481 | + acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | |
415 | 482 | return_ACPI_STATUS(status); |
416 | 483 | } |
417 | 484 |
drivers/acpi/acpica/exprep.c
... | ... | @@ -484,6 +484,8 @@ |
484 | 484 | obj_desc->field.resource_length = info->resource_length; |
485 | 485 | } |
486 | 486 | |
487 | + obj_desc->field.pin_number_index = info->pin_number_index; | |
488 | + | |
487 | 489 | /* Allow full data read from EC address space */ |
488 | 490 | |
489 | 491 | if ((obj_desc->field.region_obj->region.space_id == |
drivers/acpi/container.c
... | ... | @@ -99,6 +99,13 @@ |
99 | 99 | device_unregister(dev); |
100 | 100 | } |
101 | 101 | |
102 | +static void container_device_online(struct acpi_device *adev) | |
103 | +{ | |
104 | + struct device *dev = acpi_driver_data(adev); | |
105 | + | |
106 | + kobject_uevent(&dev->kobj, KOBJ_ONLINE); | |
107 | +} | |
108 | + | |
102 | 109 | static struct acpi_scan_handler container_handler = { |
103 | 110 | .ids = container_device_ids, |
104 | 111 | .attach = container_device_attach, |
... | ... | @@ -106,6 +113,7 @@ |
106 | 113 | .hotplug = { |
107 | 114 | .enabled = true, |
108 | 115 | .demand_offline = true, |
116 | + .notify_online = container_device_online, | |
109 | 117 | }, |
110 | 118 | }; |
111 | 119 |
drivers/acpi/scan.c
... | ... | @@ -130,7 +130,7 @@ |
130 | 130 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { |
131 | 131 | count = snprintf(&modalias[len], size, "%s:", id->id); |
132 | 132 | if (count < 0) |
133 | - return EINVAL; | |
133 | + return -EINVAL; | |
134 | 134 | if (count >= size) |
135 | 135 | return -ENOMEM; |
136 | 136 | len += count; |
... | ... | @@ -2189,6 +2189,9 @@ |
2189 | 2189 | ok: |
2190 | 2190 | list_for_each_entry(child, &device->children, node) |
2191 | 2191 | acpi_bus_attach(child); |
2192 | + | |
2193 | + if (device->handler && device->handler->hotplug.notify_online) | |
2194 | + device->handler->hotplug.notify_online(device); | |
2192 | 2195 | } |
2193 | 2196 | |
2194 | 2197 | /** |
drivers/acpi/video.c
... | ... | @@ -750,6 +750,14 @@ |
750 | 750 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"), |
751 | 751 | }, |
752 | 752 | }, |
753 | + { | |
754 | + .callback = video_disable_native_backlight, | |
755 | + .ident = "ThinkPad X201s", | |
756 | + .matches = { | |
757 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
758 | + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"), | |
759 | + }, | |
760 | + }, | |
753 | 761 | |
754 | 762 | /* The native backlight controls do not work on some older machines */ |
755 | 763 | { |
drivers/cpufreq/cpufreq.c
... | ... | @@ -1289,6 +1289,8 @@ |
1289 | 1289 | per_cpu(cpufreq_cpu_data, j) = NULL; |
1290 | 1290 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1291 | 1291 | |
1292 | + up_write(&policy->rwsem); | |
1293 | + | |
1292 | 1294 | if (cpufreq_driver->exit) |
1293 | 1295 | cpufreq_driver->exit(policy); |
1294 | 1296 | err_set_policy_cpu: |
... | ... | @@ -1656,6 +1658,8 @@ |
1656 | 1658 | if (!cpufreq_driver) |
1657 | 1659 | return; |
1658 | 1660 | |
1661 | + cpufreq_suspended = true; | |
1662 | + | |
1659 | 1663 | if (!has_target()) |
1660 | 1664 | return; |
1661 | 1665 | |
... | ... | @@ -1670,8 +1674,6 @@ |
1670 | 1674 | pr_err("%s: Failed to suspend driver: %p\n", __func__, |
1671 | 1675 | policy); |
1672 | 1676 | } |
1673 | - | |
1674 | - cpufreq_suspended = true; | |
1675 | 1677 | } |
1676 | 1678 | |
1677 | 1679 | /** |
1678 | 1680 | |
... | ... | @@ -1687,12 +1689,12 @@ |
1687 | 1689 | if (!cpufreq_driver) |
1688 | 1690 | return; |
1689 | 1691 | |
1692 | + cpufreq_suspended = false; | |
1693 | + | |
1690 | 1694 | if (!has_target()) |
1691 | 1695 | return; |
1692 | 1696 | |
1693 | 1697 | pr_debug("%s: Resuming Governors\n", __func__); |
1694 | - | |
1695 | - cpufreq_suspended = false; | |
1696 | 1698 | |
1697 | 1699 | list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { |
1698 | 1700 | if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) |
drivers/gpio/gpiolib-acpi.c
... | ... | @@ -377,8 +377,10 @@ |
377 | 377 | struct gpio_chip *chip = achip->chip; |
378 | 378 | struct acpi_resource_gpio *agpio; |
379 | 379 | struct acpi_resource *ares; |
380 | + int pin_index = (int)address; | |
380 | 381 | acpi_status status; |
381 | 382 | bool pull_up; |
383 | + int length; | |
382 | 384 | int i; |
383 | 385 | |
384 | 386 | status = acpi_buffer_to_resource(achip->conn_info.connection, |
... | ... | @@ -400,7 +402,8 @@ |
400 | 402 | return AE_BAD_PARAMETER; |
401 | 403 | } |
402 | 404 | |
403 | - for (i = 0; i < agpio->pin_table_length; i++) { | |
405 | + length = min(agpio->pin_table_length, (u16)(pin_index + bits)); | |
406 | + for (i = pin_index; i < length; ++i) { | |
404 | 407 | unsigned pin = agpio->pin_table[i]; |
405 | 408 | struct acpi_gpio_connection *conn; |
406 | 409 | struct gpio_desc *desc; |
include/acpi/acpi_bus.h
kernel/power/snapshot.c
... | ... | @@ -725,14 +725,6 @@ |
725 | 725 | clear_bit(bit, addr); |
726 | 726 | } |
727 | 727 | |
728 | -static void memory_bm_clear_current(struct memory_bitmap *bm) | |
729 | -{ | |
730 | - int bit; | |
731 | - | |
732 | - bit = max(bm->cur.node_bit - 1, 0); | |
733 | - clear_bit(bit, bm->cur.node->data); | |
734 | -} | |
735 | - | |
736 | 728 | static int memory_bm_test_bit(struct memory_bitmap *bm, unsigned long pfn) |
737 | 729 | { |
738 | 730 | void *addr; |
739 | 731 | |
740 | 732 | |
741 | 733 | |
... | ... | @@ -1341,35 +1333,23 @@ |
1341 | 1333 | |
1342 | 1334 | void swsusp_free(void) |
1343 | 1335 | { |
1344 | - unsigned long fb_pfn, fr_pfn; | |
1336 | + struct zone *zone; | |
1337 | + unsigned long pfn, max_zone_pfn; | |
1345 | 1338 | |
1346 | - memory_bm_position_reset(forbidden_pages_map); | |
1347 | - memory_bm_position_reset(free_pages_map); | |
1339 | + for_each_populated_zone(zone) { | |
1340 | + max_zone_pfn = zone_end_pfn(zone); | |
1341 | + for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) | |
1342 | + if (pfn_valid(pfn)) { | |
1343 | + struct page *page = pfn_to_page(pfn); | |
1348 | 1344 | |
1349 | -loop: | |
1350 | - fr_pfn = memory_bm_next_pfn(free_pages_map); | |
1351 | - fb_pfn = memory_bm_next_pfn(forbidden_pages_map); | |
1352 | - | |
1353 | - /* | |
1354 | - * Find the next bit set in both bitmaps. This is guaranteed to | |
1355 | - * terminate when fb_pfn == fr_pfn == BM_END_OF_MAP. | |
1356 | - */ | |
1357 | - do { | |
1358 | - if (fb_pfn < fr_pfn) | |
1359 | - fb_pfn = memory_bm_next_pfn(forbidden_pages_map); | |
1360 | - if (fr_pfn < fb_pfn) | |
1361 | - fr_pfn = memory_bm_next_pfn(free_pages_map); | |
1362 | - } while (fb_pfn != fr_pfn); | |
1363 | - | |
1364 | - if (fr_pfn != BM_END_OF_MAP && pfn_valid(fr_pfn)) { | |
1365 | - struct page *page = pfn_to_page(fr_pfn); | |
1366 | - | |
1367 | - memory_bm_clear_current(forbidden_pages_map); | |
1368 | - memory_bm_clear_current(free_pages_map); | |
1369 | - __free_page(page); | |
1370 | - goto loop; | |
1345 | + if (swsusp_page_is_forbidden(page) && | |
1346 | + swsusp_page_is_free(page)) { | |
1347 | + swsusp_unset_page_forbidden(page); | |
1348 | + swsusp_unset_page_free(page); | |
1349 | + __free_page(page); | |
1350 | + } | |
1351 | + } | |
1371 | 1352 | } |
1372 | - | |
1373 | 1353 | nr_copy_pages = 0; |
1374 | 1354 | nr_meta_pages = 0; |
1375 | 1355 | restore_pblist = NULL; |