Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI: scan: Extend acpi_walk_dep_device_list()

The acpi_walk_dep_device_list() function is not as generic as its
name implies, serving only to decrement the dependency count for each
dependent device of the input.

Extend it to accept a callback which can be applied to all the
dependencies in acpi_dep_list.

Replace all existing calls to the function with calls to a wrapper,
passing a callback that applies the same dependency reduction.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Maximilian Luz <luzmaximilian@gmail.com> # for platform/surface parts
Signed-off-by: Daniel Scally <djrscally@gmail.com>
[ rjw: Changelog edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Daniel Scally and committed by
Rafael J. Wysocki
a9e10e58 6d279758

+90 -47
+1 -1
drivers/acpi/ec.c
··· 1627 1627 WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); 1628 1628 1629 1629 /* Reprobe devices depending on the EC */ 1630 - acpi_walk_dep_device_list(ec->handle); 1630 + acpi_dev_clear_dependencies(device); 1631 1631 1632 1632 acpi_handle_debug(ec->handle, "enumerated.\n"); 1633 1633 return 0;
+1 -1
drivers/acpi/pmic/intel_pmic_chtdc_ti.c
··· 117 117 return err; 118 118 119 119 /* Re-enumerate devices depending on PMIC */ 120 - acpi_walk_dep_device_list(ACPI_HANDLE(pdev->dev.parent)); 120 + acpi_dev_clear_dependencies(ACPI_COMPANION(pdev->dev.parent)); 121 121 return 0; 122 122 } 123 123
+51 -18
drivers/acpi/scan.c
··· 47 47 */ 48 48 static u64 spcr_uart_addr; 49 49 50 - struct acpi_dep_data { 51 - struct list_head node; 52 - acpi_handle supplier; 53 - acpi_handle consumer; 54 - }; 55 - 56 50 void acpi_scan_lock_acquire(void) 57 51 { 58 52 mutex_lock(&acpi_scan_lock); ··· 2101 2107 device->handler->hotplug.notify_online(device); 2102 2108 } 2103 2109 2104 - void acpi_walk_dep_device_list(acpi_handle handle) 2110 + static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data) 2111 + { 2112 + struct acpi_device *adev; 2113 + 2114 + acpi_bus_get_device(dep->consumer, &adev); 2115 + 2116 + if (adev) { 2117 + adev->dep_unmet--; 2118 + if (!adev->dep_unmet) 2119 + acpi_bus_attach(adev, true); 2120 + } 2121 + 2122 + list_del(&dep->node); 2123 + kfree(dep); 2124 + 2125 + return 0; 2126 + } 2127 + 2128 + /** 2129 + * acpi_walk_dep_device_list - Apply a callback to every entry in acpi_dep_list 2130 + * @handle: The ACPI handle of the supplier device 2131 + * @callback: Pointer to the callback function to apply 2132 + * @data: Pointer to some data to pass to the callback 2133 + * 2134 + * The return value of the callback determines this function's behaviour. If 0 2135 + * is returned we continue to iterate over acpi_dep_list. If a positive value 2136 + * is returned then the loop is broken but this function returns 0. If a 2137 + * negative value is returned by the callback then the loop is broken and that 2138 + * value is returned as the final error. 2139 + */ 2140 + int acpi_walk_dep_device_list(acpi_handle handle, 2141 + int (*callback)(struct acpi_dep_data *, void *), 2142 + void *data) 2105 2143 { 2106 2144 struct acpi_dep_data *dep, *tmp; 2107 - struct acpi_device *adev; 2145 + int ret; 2108 2146 2109 2147 mutex_lock(&acpi_dep_list_lock); 2110 2148 list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) { 2111 2149 if (dep->supplier == handle) { 2112 - acpi_bus_get_device(dep->consumer, &adev); 2113 - 2114 - if (adev) { 2115 - adev->dep_unmet--; 2116 - if (!adev->dep_unmet) 2117 - acpi_bus_attach(adev, true); 2118 - } 2119 - 2120 - list_del(&dep->node); 2121 - kfree(dep); 2150 + ret = callback(dep, data); 2151 + if (ret) 2152 + break; 2122 2153 } 2123 2154 } 2124 2155 mutex_unlock(&acpi_dep_list_lock); 2156 + 2157 + return ret > 0 ? 0 : ret; 2125 2158 } 2126 2159 EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list); 2160 + 2161 + /** 2162 + * acpi_dev_clear_dependencies - Inform consumers that the device is now active 2163 + * @supplier: Pointer to the supplier &struct acpi_device 2164 + * 2165 + * Clear dependencies on the given device. 2166 + */ 2167 + void acpi_dev_clear_dependencies(struct acpi_device *supplier) 2168 + { 2169 + acpi_walk_dep_device_list(supplier->handle, acpi_scan_clear_dep, NULL); 2170 + } 2171 + EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies); 2127 2172 2128 2173 /** 2129 2174 * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
+5 -5
drivers/gpio/gpiolib-acpi.c
··· 1233 1233 void acpi_gpiochip_add(struct gpio_chip *chip) 1234 1234 { 1235 1235 struct acpi_gpio_chip *acpi_gpio; 1236 - acpi_handle handle; 1236 + struct acpi_device *adev; 1237 1237 acpi_status status; 1238 1238 1239 1239 if (!chip || !chip->parent) 1240 1240 return; 1241 1241 1242 - handle = ACPI_HANDLE(chip->parent); 1243 - if (!handle) 1242 + adev = ACPI_COMPANION(chip->parent); 1243 + if (!adev) 1244 1244 return; 1245 1245 1246 1246 acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL); ··· 1254 1254 INIT_LIST_HEAD(&acpi_gpio->events); 1255 1255 INIT_LIST_HEAD(&acpi_gpio->deferred_req_irqs_list_entry); 1256 1256 1257 - status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio); 1257 + status = acpi_attach_data(adev->handle, acpi_gpio_chip_dh, acpi_gpio); 1258 1258 if (ACPI_FAILURE(status)) { 1259 1259 dev_err(chip->parent, "Failed to attach ACPI GPIO chip\n"); 1260 1260 kfree(acpi_gpio); ··· 1263 1263 1264 1264 acpi_gpiochip_request_regions(acpi_gpio); 1265 1265 acpi_gpiochip_scan_gpios(acpi_gpio); 1266 - acpi_walk_dep_device_list(handle); 1266 + acpi_dev_clear_dependencies(adev); 1267 1267 } 1268 1268 1269 1269 void acpi_gpiochip_remove(struct gpio_chip *chip)
+4 -4
drivers/i2c/i2c-core-acpi.c
··· 259 259 */ 260 260 void i2c_acpi_register_devices(struct i2c_adapter *adap) 261 261 { 262 + struct acpi_device *adev; 262 263 acpi_status status; 263 - acpi_handle handle; 264 264 265 265 if (!has_acpi_companion(&adap->dev)) 266 266 return; ··· 275 275 if (!adap->dev.parent) 276 276 return; 277 277 278 - handle = ACPI_HANDLE(adap->dev.parent); 279 - if (!handle) 278 + adev = ACPI_COMPANION(adap->dev.parent); 279 + if (!adev) 280 280 return; 281 281 282 - acpi_walk_dep_device_list(handle); 282 + acpi_dev_clear_dependencies(adev); 283 283 } 284 284 285 285 static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
+3 -3
drivers/platform/surface/aggregator/core.c
··· 621 621 622 622 static int ssam_serial_hub_probe(struct serdev_device *serdev) 623 623 { 624 + struct acpi_device *ssh = ACPI_COMPANION(&serdev->dev); 624 625 struct ssam_controller *ctrl; 625 - acpi_handle *ssh = ACPI_HANDLE(&serdev->dev); 626 626 acpi_status astatus; 627 627 int status; 628 628 ··· 652 652 if (status) 653 653 goto err_devopen; 654 654 655 - astatus = ssam_serdev_setup_via_acpi(ssh, serdev); 655 + astatus = ssam_serdev_setup_via_acpi(ssh->handle, serdev); 656 656 if (ACPI_FAILURE(astatus)) { 657 657 status = -ENXIO; 658 658 goto err_devinit; ··· 706 706 * For now let's thus default power/wakeup to false. 707 707 */ 708 708 device_set_wakeup_capable(&serdev->dev, true); 709 - acpi_walk_dep_device_list(ssh); 709 + acpi_dev_clear_dependencies(ssh); 710 710 711 711 return 0; 712 712
+11 -11
drivers/platform/surface/surface3_power.c
··· 446 446 447 447 static int mshw0011_install_space_handler(struct i2c_client *client) 448 448 { 449 - acpi_handle handle; 449 + struct acpi_device *adev; 450 450 struct mshw0011_handler_data *data; 451 451 acpi_status status; 452 452 453 - handle = ACPI_HANDLE(&client->dev); 454 - if (!handle) 453 + adev = ACPI_COMPANION(&client->dev); 454 + if (!adev) 455 455 return -ENODEV; 456 456 457 457 data = kzalloc(sizeof(struct mshw0011_handler_data), ··· 460 460 return -ENOMEM; 461 461 462 462 data->client = client; 463 - status = acpi_bus_attach_private_data(handle, (void *)data); 463 + status = acpi_bus_attach_private_data(adev->handle, (void *)data); 464 464 if (ACPI_FAILURE(status)) { 465 465 kfree(data); 466 466 return -ENOMEM; 467 467 } 468 468 469 - status = acpi_install_address_space_handler(handle, 470 - ACPI_ADR_SPACE_GSBUS, 471 - &mshw0011_space_handler, 472 - NULL, 473 - data); 469 + status = acpi_install_address_space_handler(adev->handle, 470 + ACPI_ADR_SPACE_GSBUS, 471 + &mshw0011_space_handler, 472 + NULL, 473 + data); 474 474 if (ACPI_FAILURE(status)) { 475 475 dev_err(&client->dev, "Error installing i2c space handler\n"); 476 - acpi_bus_detach_private_data(handle); 476 + acpi_bus_detach_private_data(adev->handle); 477 477 kfree(data); 478 478 return -ENOMEM; 479 479 } 480 480 481 - acpi_walk_dep_device_list(handle); 481 + acpi_dev_clear_dependencies(adev); 482 482 return 0; 483 483 } 484 484
+4 -3
drivers/platform/surface/surface_acpi_notify.c
··· 798 798 799 799 static int san_probe(struct platform_device *pdev) 800 800 { 801 - acpi_handle san = ACPI_HANDLE(&pdev->dev); 801 + struct acpi_device *san = ACPI_COMPANION(&pdev->dev); 802 802 struct ssam_controller *ctrl; 803 803 struct san_data *data; 804 804 acpi_status astatus; ··· 821 821 822 822 platform_set_drvdata(pdev, data); 823 823 824 - astatus = acpi_install_address_space_handler(san, ACPI_ADR_SPACE_GSBUS, 824 + astatus = acpi_install_address_space_handler(san->handle, 825 + ACPI_ADR_SPACE_GSBUS, 825 826 &san_opreg_handler, NULL, 826 827 &data->info); 827 828 if (ACPI_FAILURE(astatus)) ··· 836 835 if (status) 837 836 goto err_install_dev; 838 837 839 - acpi_walk_dep_device_list(san); 838 + acpi_dev_clear_dependencies(san); 840 839 return 0; 841 840 842 841 err_install_dev:
+7
include/acpi/acpi_bus.h
··· 280 280 struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */ 281 281 }; 282 282 283 + struct acpi_dep_data { 284 + struct list_head node; 285 + acpi_handle supplier; 286 + acpi_handle consumer; 287 + }; 288 + 283 289 /* Performance Management */ 284 290 285 291 struct acpi_device_perf_flags { ··· 691 685 692 686 bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2); 693 687 688 + void acpi_dev_clear_dependencies(struct acpi_device *supplier); 694 689 struct acpi_device * 695 690 acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv); 696 691 struct acpi_device *
+3 -1
include/linux/acpi.h
··· 666 666 const struct device_driver *drv); 667 667 int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *); 668 668 int acpi_device_modalias(struct device *, char *, int); 669 - void acpi_walk_dep_device_list(acpi_handle handle); 669 + int acpi_walk_dep_device_list(acpi_handle handle, 670 + int (*callback)(struct acpi_dep_data *, void *), 671 + void *data); 670 672 671 673 struct platform_device *acpi_create_platform_device(struct acpi_device *, 672 674 struct property_entry *);