From f1b1dc845cb1418b2b0de35491b0da87498ea6a8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 7 Jul 2014 14:07:38 +0200 Subject: ACPI / PNP: do ACPI binding directly PNPACPI uses acpi_bus_type to do ACPI binding for the PNPACPI devices. This is overkill because PNPACPI code already knows which ACPI device object to bind during PNPACPI device enumeration. This patch removes acpi_pnp_bus and does the binding by invoking acpi_bind_one() directly after device enumerated. This also fixes a bug in the previous code that some PNPACPI devices failed to be bound because 1. the ACPI device _HID is not pnpid, e.g. "MSFT0001", but its _CID is, e.g. "PNP0303", thus ACPI _CID is used as the pnp device device id. 2. device is bound only if the pnp device id matches the ACPI device _HID. Tested-by: Prigent Christophe Signed-off-by: Zhang Rui Signed-off-by: Rafael J. Wysocki diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 7de5b60..151f3e7 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -84,8 +84,6 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, int type, unsigned long long sta); void acpi_device_add_finalize(struct acpi_device *device); void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); -int acpi_bind_one(struct device *dev, struct acpi_device *adev); -int acpi_unbind_one(struct device *dev); bool acpi_device_is_present(struct acpi_device *adev); bool acpi_device_is_battery(struct acpi_device *adev); diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index b81448b..3bebeda 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -295,9 +295,11 @@ static int __init pnpacpi_add_device(struct acpi_device *device) return error; } + error = acpi_bind_one(&dev->dev, device); + num++; - return 0; + return error; } static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, @@ -313,41 +315,6 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, return AE_OK; } -static int __init acpi_pnp_match(struct device *dev, void *_pnp) -{ - struct acpi_device *acpi = to_acpi_device(dev); - struct pnp_dev *pnp = _pnp; - - /* true means it matched */ - return !acpi->physical_node_count - && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); -} - -static struct acpi_device * __init acpi_pnp_find_companion(struct device *dev) -{ - dev = bus_find_device(&acpi_bus_type, NULL, to_pnp_dev(dev), - acpi_pnp_match); - if (!dev) - return NULL; - - put_device(dev); - return to_acpi_device(dev); -} - -/* complete initialization of a PNPACPI device includes having - * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling. - */ -static bool acpi_pnp_bus_match(struct device *dev) -{ - return dev->bus == &pnp_bus_type; -} - -static struct acpi_bus_type __initdata acpi_pnp_bus = { - .name = "PNP", - .match = acpi_pnp_bus_match, - .find_companion = acpi_pnp_find_companion, -}; - int pnpacpi_disabled __initdata; static int __init pnpacpi_init(void) { @@ -357,10 +324,8 @@ static int __init pnpacpi_init(void) } printk(KERN_INFO "pnp: PnP ACPI init\n"); pnp_register_protocol(&pnpacpi_protocol); - register_acpi_bus_type(&acpi_pnp_bus); acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); printk(KERN_INFO "pnp: PnP ACPI: found %d devices\n", num); - unregister_acpi_bus_type(&acpi_pnp_bus); pnp_platform_devices = 1; return 0; } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index b571458..4bcbb94 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -487,6 +487,8 @@ struct acpi_bus_type { }; int register_acpi_bus_type(struct acpi_bus_type *); int unregister_acpi_bus_type(struct acpi_bus_type *); +int acpi_bind_one(struct device *dev, struct acpi_device *adev); +int acpi_unbind_one(struct device *dev); struct acpi_pci_root { struct acpi_device * device; -- cgit v0.10.2 From e70dba6020eaaceb1d3619dfb535c719900c7091 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 23 Jul 2014 01:03:06 +0200 Subject: ACPI / PNP: Use ACPI_COMPANION() instead of ACPI_HANDLE() The ACPI_HANDLE() macro evaluates ACPI_COMPANION() internally to return the handle of the device's ACPI companion, so it is much more straightforward and efficient to use ACPI_COMPANION() directly to obtain the device's ACPI companion object instead of using ACPI_HANDLE() and acpi_bus_get_device() on the returned handle for the same thing. Do that in several places in the ACPI PNP core code. Also use acpi_device_set_power() and acpi_device_power_manageable() instead of acpi_bus_set_power() and acpi_bus_power_manageable(), respectively, because the former two are more efficient if the ACPI device object is already available. Signed-off-by: Rafael J. Wysocki diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 3bebeda..d2b780a 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -67,8 +67,8 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) pnp_dbg(&dev->dev, "set resources\n"); - handle = ACPI_HANDLE(&dev->dev); - if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { + acpi_dev = ACPI_COMPANION(&dev->dev); + if (!acpi_dev) { dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); return -ENODEV; } @@ -76,6 +76,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) if (WARN_ON_ONCE(acpi_dev != dev->data)) dev->data = acpi_dev; + handle = acpi_dev->handle; if (acpi_has_method(handle, METHOD_NAME__SRS)) { struct acpi_buffer buffer; @@ -93,8 +94,8 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) } kfree(buffer.pointer); } - if (!ret && acpi_bus_power_manageable(handle)) - ret = acpi_bus_set_power(handle, ACPI_STATE_D0); + if (!ret && acpi_device_power_manageable(acpi_dev)) + ret = acpi_device_set_power(acpi_dev, ACPI_STATE_D0); return ret; } @@ -102,23 +103,22 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) static int pnpacpi_disable_resources(struct pnp_dev *dev) { struct acpi_device *acpi_dev; - acpi_handle handle; acpi_status status; dev_dbg(&dev->dev, "disable resources\n"); - handle = ACPI_HANDLE(&dev->dev); - if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { + acpi_dev = ACPI_COMPANION(&dev->dev); + if (!acpi_dev) { dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); return 0; } /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ - if (acpi_bus_power_manageable(handle)) - acpi_bus_set_power(handle, ACPI_STATE_D3_COLD); + if (acpi_device_power_manageable(acpi_dev)) + acpi_device_set_power(acpi_dev, ACPI_STATE_D3_COLD); - /* continue even if acpi_bus_set_power() fails */ - status = acpi_evaluate_object(handle, "_DIS", NULL, NULL); + /* continue even if acpi_device_set_power() fails */ + status = acpi_evaluate_object(acpi_dev->handle, "_DIS", NULL, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) return -ENODEV; @@ -128,26 +128,22 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) #ifdef CONFIG_ACPI_SLEEP static bool pnpacpi_can_wakeup(struct pnp_dev *dev) { - struct acpi_device *acpi_dev; - acpi_handle handle; + struct acpi_device *acpi_dev = ACPI_COMPANION(&dev->dev); - handle = ACPI_HANDLE(&dev->dev); - if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { + if (!acpi_dev) { dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); return false; } - return acpi_bus_can_wakeup(handle); + return acpi_bus_can_wakeup(acpi_dev->handle); } static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) { - struct acpi_device *acpi_dev; - acpi_handle handle; + struct acpi_device *acpi_dev = ACPI_COMPANION(&dev->dev); int error = 0; - handle = ACPI_HANDLE(&dev->dev); - if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { + if (!acpi_dev) { dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); return 0; } @@ -159,7 +155,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) return error; } - if (acpi_bus_power_manageable(handle)) { + if (acpi_device_power_manageable(acpi_dev)) { int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL, ACPI_STATE_D3_COLD); if (power_state < 0) @@ -167,12 +163,12 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) ACPI_STATE_D0 : ACPI_STATE_D3_COLD; /* - * acpi_bus_set_power() often fails (keyboard port can't be + * acpi_device_set_power() can fail (keyboard port can't be * powered-down?), and in any case, our return value is ignored * by pnp_bus_suspend(). Hence we don't revert the wakeup * setting if the set_power fails. */ - error = acpi_bus_set_power(handle, power_state); + error = acpi_device_set_power(acpi_dev, power_state); } return error; @@ -180,11 +176,10 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) static int pnpacpi_resume(struct pnp_dev *dev) { - struct acpi_device *acpi_dev; - acpi_handle handle = ACPI_HANDLE(&dev->dev); + struct acpi_device *acpi_dev = ACPI_COMPANION(&dev->dev); int error = 0; - if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { + if (!acpi_dev) { dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); return -ENODEV; } @@ -192,8 +187,8 @@ static int pnpacpi_resume(struct pnp_dev *dev) if (device_may_wakeup(&dev->dev)) acpi_pm_device_sleep_wake(&dev->dev, false); - if (acpi_bus_power_manageable(handle)) - error = acpi_bus_set_power(handle, ACPI_STATE_D0); + if (acpi_device_power_manageable(acpi_dev)) + error = acpi_device_set_power(acpi_dev, ACPI_STATE_D0); return error; } -- cgit v0.10.2 From 85dbb3d05ec6d063f6f8ad4d6dfc13793d566374 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 24 Jul 2014 01:18:53 +0200 Subject: ACPI / PCI: Use ACPI_COMPANION() instead of ACPI_HANDLE() The ACPI_HANDLE() macro evaluates ACPI_COMPANION() internally to return the handle of the device's ACPI companion, so it is much more straightforward and efficient to use ACPI_COMPANION() directly to obtain the device's ACPI companion object instead of using ACPI_HANDLE() and acpi_bus_get_device() on the returned handle for the same thing. Use ACPI_COMPANION() instead of ACPI_HANDLE() in the PCI ACPI support code. Signed-off-by: Rafael J. Wysocki diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index ca4927b..740efa8 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -170,14 +170,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) static bool acpi_pci_power_manageable(struct pci_dev *dev) { - acpi_handle handle = ACPI_HANDLE(&dev->dev); - - return handle ? acpi_bus_power_manageable(handle) : false; + struct acpi_device *adev = ACPI_COMPANION(&dev->dev); + return adev ? acpi_device_power_manageable(adev) : false; } static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) { - acpi_handle handle = ACPI_HANDLE(&dev->dev); + struct acpi_device *adev = ACPI_COMPANION(&dev->dev); static const u8 state_conv[] = { [PCI_D0] = ACPI_STATE_D0, [PCI_D1] = ACPI_STATE_D1, @@ -188,7 +187,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) int error = -EINVAL; /* If the ACPI device has _EJ0, ignore the device */ - if (!handle || acpi_has_method(handle, "_EJ0")) + if (!adev || acpi_has_method(adev->handle, "_EJ0")) return -ENODEV; switch (state) { @@ -202,7 +201,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) case PCI_D1: case PCI_D2: case PCI_D3hot: - error = acpi_bus_set_power(handle, state_conv[state]); + error = acpi_device_set_power(adev, state_conv[state]); } if (!error) @@ -214,9 +213,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) static bool acpi_pci_can_wakeup(struct pci_dev *dev) { - acpi_handle handle = ACPI_HANDLE(&dev->dev); - - return handle ? acpi_bus_can_wakeup(handle) : false; + struct acpi_device *adev = ACPI_COMPANION(&dev->dev); + return adev ? acpi_device_can_wakeup(adev) : false; } static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) -- cgit v0.10.2