summaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2013-01-10 11:18:41 -0700
committerBjorn Helgaas <bhelgaas@google.com>2013-01-10 11:18:41 -0700
commit295a7f6235bfa21be3454aebc1bea1eaf0b74fb7 (patch)
treeae253b12eb331e1d093a3f348b4f8045e80f5e53 /drivers/acpi
parentb3e65e1f9185a2eb034defe4270ba178ba70b9a9 (diff)
parentf95988de06ea62ef5bd861f06e9ef56cea405ed1 (diff)
downloadop-kernel-dev-295a7f6235bfa21be3454aebc1bea1eaf0b74fb7.zip
op-kernel-dev-295a7f6235bfa21be3454aebc1bea1eaf0b74fb7.tar.gz
Merge branch 'acpi-scan' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm into pci/yinghai-survey-resources+acpi-scan
* 'acpi-scan' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / scan: Treat power resources in a special way ACPI: Remove unused struct acpi_pci_root.id member ACPI: Drop ACPI device .bind() and .unbind() callbacks ACPI / PCI: Move the _PRT setup and cleanup code to pci-acpi.c ACPI / PCI: Rework the setup and cleanup of device wakeup ACPI: Add .setup() and .cleanup() callbacks to struct acpi_bus_type ACPI: Make acpi_bus_scan() and acpi_bus_add() take only one argument ACPI: Replace ACPI device add_type field with a match_driver flag ACPI: Drop the second argument of acpi_bus_scan() ACPI: Remove the arguments of acpi_bus_add() that are not used ACPI: Remove acpi_start_single_object() and acpi_bus_start() ACPI / PCI: Fold acpi_pci_root_start() into acpi_pci_root_add() ACPI: Change the ordering of acpi_bus_check_add() ACPI: Replace struct acpi_bus_ops with enum type ACPI: Reduce the usage of struct acpi_bus_ops ACPI: Make acpi_bus_add() and acpi_bus_start() visibly different ACPI: Change the ordering of PCI root bridge driver registrarion ACPI: Separate adding ACPI device objects from probing ACPI drivers Conflicts: drivers/acpi/pci_root.c
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/acpi_memhotplug.c24
-rw-r--r--drivers/acpi/container.c31
-rw-r--r--drivers/acpi/device_pm.c2
-rw-r--r--drivers/acpi/dock.c15
-rw-r--r--drivers/acpi/glue.c50
-rw-r--r--drivers/acpi/internal.h1
-rw-r--r--drivers/acpi/pci_bind.c122
-rw-r--r--drivers/acpi/pci_root.c67
-rw-r--r--drivers/acpi/processor_driver.c30
-rw-r--r--drivers/acpi/scan.c208
11 files changed, 149 insertions, 403 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 2a4502b..4ee2e75 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -37,7 +37,7 @@ acpi-y += resource.o
acpi-y += processor_core.o
acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.o
-acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-y += pci_root.o pci_link.o pci_irq.o
acpi-y += acpi_platform.o
acpi-y += power.o
acpi-y += event.o
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index eb30e5a..327ab44 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -157,38 +157,26 @@ static int
acpi_memory_get_device(acpi_handle handle,
struct acpi_memory_device **mem_device)
{
- acpi_status status;
- acpi_handle phandle;
struct acpi_device *device = NULL;
- struct acpi_device *pdevice = NULL;
int result;
-
if (!acpi_bus_get_device(handle, &device) && device)
goto end;
- status = acpi_get_parent(handle, &phandle);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "Cannot find acpi parent"));
- return -EINVAL;
- }
-
- /* Get the parent device */
- result = acpi_bus_get_device(phandle, &pdevice);
- if (result) {
- acpi_handle_warn(phandle, "Cannot get acpi bus device\n");
- return -EINVAL;
- }
-
/*
* Now add the notified device. This creates the acpi_device
* and invokes .add function
*/
- result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
+ result = acpi_bus_add(handle);
if (result) {
acpi_handle_warn(handle, "Cannot add acpi bus\n");
return -EINVAL;
}
+ result = acpi_bus_get_device(handle, &device);
+ if (result) {
+ acpi_handle_warn(handle, "Missing device object\n");
+ return -EINVAL;
+ }
end:
*mem_device = acpi_driver_data(device);
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 811910b..f8fb228 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -135,30 +135,6 @@ static int acpi_container_remove(struct acpi_device *device, int type)
return status;
}
-static int container_device_add(struct acpi_device **device, acpi_handle handle)
-{
- acpi_handle phandle;
- struct acpi_device *pdev;
- int result;
-
-
- if (acpi_get_parent(handle, &phandle)) {
- return -ENODEV;
- }
-
- if (acpi_bus_get_device(phandle, &pdev)) {
- return -ENODEV;
- }
-
- if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_DEVICE)) {
- return -ENODEV;
- }
-
- result = acpi_bus_start(*device);
-
- return result;
-}
-
static void container_notify_cb(acpi_handle handle, u32 type, void *context)
{
struct acpi_device *device = NULL;
@@ -190,11 +166,16 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
if (!ACPI_FAILURE(status) || device)
break;
- result = container_device_add(&device, handle);
+ result = acpi_bus_add(handle);
if (result) {
acpi_handle_warn(handle, "Failed to add container\n");
break;
}
+ result = acpi_bus_get_device(handle, &device);
+ if (result) {
+ acpi_handle_warn(handle, "Missing device object\n");
+ break;
+ }
kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
ost_code = ACPI_OST_SC_SUCCESS;
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index f09dc98..e4f6ac9 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -353,7 +353,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
* acpi_dev_pm_get_node - Get ACPI device node for the given physical device.
* @dev: Device to get the ACPI node for.
*/
-static struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
+struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
{
acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
struct acpi_device *adev;
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index f32bd47..9e31b2b 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -310,8 +310,6 @@ static int dock_present(struct dock_station *ds)
static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
{
struct acpi_device *device;
- struct acpi_device *parent_device;
- acpi_handle parent;
int ret;
if (acpi_bus_get_device(handle, &device)) {
@@ -319,16 +317,11 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
* no device created for this object,
* so we should create one.
*/
- acpi_get_parent(handle, &parent);
- if (acpi_bus_get_device(parent, &parent_device))
- parent_device = NULL;
-
- ret = acpi_bus_add(&device, parent_device, handle,
- ACPI_BUS_TYPE_DEVICE);
- if (ret) {
+ ret = acpi_bus_add(handle);
+ if (ret)
pr_debug("error adding bus, %x\n", -ret);
- return NULL;
- }
+
+ acpi_bus_get_device(handle, &device);
}
return device;
}
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 0155184..ac00b88 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -63,6 +63,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
{
struct acpi_bus_type *tmp, *ret = NULL;
+ if (!type)
+ return NULL;
+
down_read(&bus_type_sem);
list_for_each_entry(tmp, &bus_type_list, list) {
if (tmp->bus == type) {
@@ -264,28 +267,39 @@ static int acpi_platform_notify(struct device *dev)
{
struct acpi_bus_type *type;
acpi_handle handle;
- int ret = -EINVAL;
+ int ret;
ret = acpi_bind_one(dev, NULL);
- if (!ret)
- goto out;
-
- if (!dev->bus || !dev->parent) {
+ if (ret && (!dev->bus || !dev->parent)) {
/* bridge devices genernally haven't bus or parent */
ret = acpi_find_bridge_device(dev, &handle);
- goto end;
+ if (!ret) {
+ ret = acpi_bind_one(dev, handle);
+ if (ret)
+ goto out;
+ }
}
+
type = acpi_get_bus_type(dev->bus);
- if (!type) {
- DBG("No ACPI bus support for %s\n", dev_name(dev));
- ret = -EINVAL;
- goto end;
+ if (ret) {
+ if (!type || !type->find_device) {
+ DBG("No ACPI bus support for %s\n", dev_name(dev));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = type->find_device(dev, &handle);
+ if (ret) {
+ DBG("Unable to get handle for %s\n", dev_name(dev));
+ goto out;
+ }
+ ret = acpi_bind_one(dev, handle);
+ if (ret)
+ goto out;
}
- if ((ret = type->find_device(dev, &handle)) != 0)
- DBG("Can't get handler for %s\n", dev_name(dev));
- end:
- if (!ret)
- acpi_bind_one(dev, handle);
+
+ if (type && type->setup)
+ type->setup(dev);
out:
#if ACPI_GLUE_DEBUG
@@ -304,6 +318,12 @@ static int acpi_platform_notify(struct device *dev)
static int acpi_platform_notify_remove(struct device *dev)
{
+ struct acpi_bus_type *type;
+
+ type = acpi_get_bus_type(dev->bus);
+ if (type && type->cleanup)
+ type->cleanup(dev);
+
acpi_unbind_one(dev);
return 0;
}
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 3c407cd..e050254 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -67,6 +67,7 @@ struct acpi_ec {
extern struct acpi_ec *first_ec;
+int acpi_pci_root_init(void);
int acpi_ec_init(void);
int acpi_ec_ecdt_probe(void);
int acpi_boot_ec_enable(void);
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
deleted file mode 100644
index a1dee29..0000000
--- a/drivers/acpi/pci_bind.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * pci_bind.c - ACPI PCI Device Binding ($Revision: 2 $)
- *
- * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci-acpi.h>
-#include <linux/acpi.h>
-#include <linux/pm_runtime.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-
-#define _COMPONENT ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_bind");
-
-static int acpi_pci_unbind(struct acpi_device *device)
-{
- struct pci_dev *dev;
-
- dev = acpi_get_pci_dev(device->handle);
- if (!dev)
- goto out;
-
- device_set_run_wake(&dev->dev, false);
- pci_acpi_remove_pm_notifier(device);
- acpi_power_resource_unregister_device(&dev->dev, device->handle);
-
- if (!dev->subordinate)
- goto out;
-
- acpi_pci_irq_del_prt(pci_domain_nr(dev->bus), dev->subordinate->number);
-
- device->ops.bind = NULL;
- device->ops.unbind = NULL;
-
-out:
- pci_dev_put(dev);
- return 0;
-}
-
-static int acpi_pci_bind(struct acpi_device *device)
-{
- acpi_status status;
- acpi_handle handle;
- unsigned char bus;
- struct pci_dev *dev;
-
- dev = acpi_get_pci_dev(device->handle);
- if (!dev)
- return 0;
-
- pci_acpi_add_pm_notifier(device, dev);
- acpi_power_resource_register_device(&dev->dev, device->handle);
- if (device->wakeup.flags.run_wake)
- device_set_run_wake(&dev->dev, true);
-
- /*
- * Install the 'bind' function to facilitate callbacks for
- * children of the P2P bridge.
- */
- if (dev->subordinate) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Device %04x:%02x:%02x.%d is a PCI bridge\n",
- pci_domain_nr(dev->bus), dev->bus->number,
- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)));
- device->ops.bind = acpi_pci_bind;
- device->ops.unbind = acpi_pci_unbind;
- }
-
- /*
- * Evaluate and parse _PRT, if exists. This code allows parsing of
- * _PRT objects within the scope of non-bridge devices. Note that
- * _PRTs within the scope of a PCI bridge assume the bridge's
- * subordinate bus number.
- *
- * TBD: Can _PRTs exist within the scope of non-bridge PCI devices?
- */
- status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
- if (ACPI_FAILURE(status))
- goto out;
-
- if (dev->subordinate)
- bus = dev->subordinate->number;
- else
- bus = dev->bus->number;
-
- acpi_pci_irq_add_prt(device->handle, pci_domain_nr(dev->bus), bus);
-
-out:
- pci_dev_put(dev);
- return 0;
-}
-
-int acpi_pci_bind_root(struct acpi_device *device)
-{
- device->ops.bind = acpi_pci_bind;
- device->ops.unbind = acpi_pci_unbind;
-
- return 0;
-}
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index dcbe966..471b2dc 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -47,7 +47,6 @@ ACPI_MODULE_NAME("pci_root");
#define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge"
static int acpi_pci_root_add(struct acpi_device *device);
static int acpi_pci_root_remove(struct acpi_device *device, int type);
-static int acpi_pci_root_start(struct acpi_device *device);
#define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \
| OSC_ACTIVE_STATE_PWR_SUPPORT \
@@ -67,7 +66,6 @@ static struct acpi_driver acpi_pci_root_driver = {
.ops = {
.add = acpi_pci_root_add,
.remove = acpi_pci_root_remove,
- .start = acpi_pci_root_start,
},
};
@@ -188,21 +186,6 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
return AE_OK;
}
-static void acpi_pci_bridge_scan(struct acpi_device *device)
-{
- int status;
- struct acpi_device *child = NULL;
-
- if (device->flags.bus_address)
- if (device->parent && device->parent->ops.bind) {
- status = device->parent->ops.bind(device);
- if (!status) {
- list_for_each_entry(child, &device->children, node)
- acpi_pci_bridge_scan(child);
- }
- }
-}
-
static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766";
static acpi_status acpi_pci_run_osc(acpi_handle handle,
@@ -452,7 +435,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
int result;
struct acpi_pci_root *root;
acpi_handle handle;
- struct acpi_device *child;
+ struct acpi_pci_driver *driver;
u32 flags, base_flags;
bool is_osc_granted = false;
@@ -603,21 +586,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
goto out_del_root;
}
- /*
- * Attach ACPI-PCI Context
- * -----------------------
- * Thus binding the ACPI and PCI devices.
- */
- result = acpi_pci_bind_root(device);
- if (result)
- goto out_del_root;
-
- /*
- * Scan and bind all _ADR-Based Devices
- */
- list_for_each_entry(child, &device->children, node)
- acpi_pci_bridge_scan(child);
-
/* ASPM setting */
if (is_osc_granted) {
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM)
@@ -632,24 +600,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
if (device->wakeup.flags.run_wake)
device_set_run_wake(root->bus->bridge, true);
- return 0;
-
-out_del_root:
- mutex_lock(&acpi_pci_root_lock);
- list_del(&root->node);
- mutex_unlock(&acpi_pci_root_lock);
-
- acpi_pci_irq_del_prt(root->segment, root->secondary.start);
-end:
- kfree(root);
- return result;
-}
-
-static int acpi_pci_root_start(struct acpi_device *device)
-{
- struct acpi_pci_root *root = acpi_driver_data(device);
- struct acpi_pci_driver *driver;
-
if (system_state != SYSTEM_BOOTING) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_bus_resources(root->bus);
@@ -666,8 +616,17 @@ static int acpi_pci_root_start(struct acpi_device *device)
pci_enable_bridges(root->bus);
pci_bus_add_devices(root->bus);
-
return 0;
+
+out_del_root:
+ mutex_lock(&acpi_pci_root_lock);
+ list_del(&root->node);
+ mutex_unlock(&acpi_pci_root_lock);
+
+ acpi_pci_irq_del_prt(root->segment, root->secondary.start);
+end:
+ kfree(root);
+ return result;
}
static int acpi_pci_root_remove(struct acpi_device *device, int type)
@@ -701,7 +660,7 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
return 0;
}
-static int __init acpi_pci_root_init(void)
+int __init acpi_pci_root_init(void)
{
acpi_hest_init();
@@ -714,5 +673,3 @@ static int __init acpi_pci_root_init(void)
return 0;
}
-
-subsys_initcall(acpi_pci_root_init);
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index e83311b..0777663 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -677,28 +677,6 @@ static int is_processor_present(acpi_handle handle)
return 0;
}
-static
-int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
-{
- acpi_handle phandle;
- struct acpi_device *pdev;
-
-
- if (acpi_get_parent(handle, &phandle)) {
- return -ENODEV;
- }
-
- if (acpi_bus_get_device(phandle, &pdev)) {
- return -ENODEV;
- }
-
- if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
- return -ENODEV;
- }
-
- return 0;
-}
-
static void acpi_processor_hotplug_notify(acpi_handle handle,
u32 event, void *data)
{
@@ -721,12 +699,16 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
if (!acpi_bus_get_device(handle, &device))
break;
- result = acpi_processor_device_add(handle, &device);
+ result = acpi_bus_add(handle);
if (result) {
acpi_handle_err(handle, "Unable to add the device\n");
break;
}
-
+ result = acpi_bus_get_device(handle, &device);
+ if (result) {
+ acpi_handle_err(handle, "Missing device object\n");
+ break;
+ }
ost_code = ACPI_OST_SC_SUCCESS;
break;
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 53502d1..e380345 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -494,7 +494,8 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
struct acpi_device *acpi_dev = to_acpi_device(dev);
struct acpi_driver *acpi_drv = to_acpi_driver(drv);
- return !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
+ return acpi_dev->flags.match_driver
+ && !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
}
static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
@@ -570,7 +571,6 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device)
}
static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
-static int acpi_start_single_object(struct acpi_device *);
static int acpi_device_probe(struct device * dev)
{
struct acpi_device *acpi_dev = to_acpi_device(dev);
@@ -579,9 +579,6 @@ static int acpi_device_probe(struct device * dev)
ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
if (!ret) {
- if (acpi_dev->bus_ops.acpi_op_start)
- acpi_start_single_object(acpi_dev);
-
if (acpi_drv->ops.notify) {
ret = acpi_device_install_notify_handler(acpi_dev);
if (ret) {
@@ -760,24 +757,6 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
return 0;
}
-static int acpi_start_single_object(struct acpi_device *device)
-{
- int result = 0;
- struct acpi_driver *driver;
-
-
- if (!(driver = device->driver))
- return 0;
-
- if (driver->ops.start) {
- result = driver->ops.start(device);
- if (result && driver->ops.remove)
- driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
- }
-
- return result;
-}
-
/**
* acpi_bus_register_driver - register a driver with the ACPI bus
* @driver: driver being registered
@@ -1406,13 +1385,6 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
if (!rmdevice)
return 0;
- /*
- * unbind _ADR-Based Devices when hot removal
- */
- if (dev->flags.bus_address) {
- if ((dev->parent) && (dev->parent->ops.unbind))
- dev->parent->ops.unbind(dev);
- }
acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
return 0;
@@ -1420,8 +1392,7 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
static int acpi_add_single_object(struct acpi_device **child,
acpi_handle handle, int type,
- unsigned long long sta,
- struct acpi_bus_ops *ops)
+ unsigned long long sta, bool match_driver)
{
int result;
struct acpi_device *device;
@@ -1437,7 +1408,6 @@ static int acpi_add_single_object(struct acpi_device **child,
device->device_type = type;
device->handle = handle;
device->parent = acpi_bus_get_parent(handle);
- device->bus_ops = *ops; /* workround for not call .start */
STRUCT_TO_INT(device->status) = sta;
acpi_device_get_busid(device);
@@ -1488,16 +1458,9 @@ static int acpi_add_single_object(struct acpi_device **child,
if ((result = acpi_device_set_context(device)))
goto end;
+ device->flags.match_driver = match_driver;
result = acpi_device_register(device);
- /*
- * Bind _ADR-Based Devices when hot add
- */
- if (device->flags.bus_address) {
- if (device->parent && device->parent->ops.bind)
- device->parent->ops.bind(device);
- }
-
end:
if (!result) {
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
@@ -1519,16 +1482,12 @@ end:
static void acpi_bus_add_power_resource(acpi_handle handle)
{
- struct acpi_bus_ops ops = {
- .acpi_op_add = 1,
- .acpi_op_start = 1,
- };
struct acpi_device *device = NULL;
acpi_bus_get_device(handle, &device);
if (!device)
acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER,
- ACPI_STA_DEFAULT, &ops);
+ ACPI_STA_DEFAULT, true);
}
static int acpi_bus_type_and_status(acpi_handle handle, int *type,
@@ -1570,16 +1529,19 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type,
return 0;
}
-static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
- void *context, void **return_value)
+static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
+ void *not_used, void **return_value)
{
- struct acpi_bus_ops *ops = context;
+ struct acpi_device *device = NULL;
int type;
unsigned long long sta;
- struct acpi_device *device;
acpi_status status;
int result;
+ acpi_bus_get_device(handle, &device);
+ if (device)
+ goto out;
+
result = acpi_bus_type_and_status(handle, &type, &sta);
if (result)
return AE_OK;
@@ -1596,97 +1558,89 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
return AE_CTRL_DEPTH;
}
- /*
- * We may already have an acpi_device from a previous enumeration. If
- * so, we needn't add it again, but we may still have to start it.
- */
- device = NULL;
- acpi_bus_get_device(handle, &device);
- if (ops->acpi_op_add && !device) {
- acpi_add_single_object(&device, handle, type, sta, ops);
- /* Is the device a known good platform device? */
- if (device
- && !acpi_match_device_ids(device, acpi_platform_device_ids))
- acpi_create_platform_device(device);
- }
-
+ acpi_add_single_object(&device, handle, type, sta,
+ type == ACPI_BUS_TYPE_POWER);
if (!device)
return AE_CTRL_DEPTH;
- if (ops->acpi_op_start && !(ops->acpi_op_add)) {
- status = acpi_start_single_object(device);
- if (ACPI_FAILURE(status))
- return AE_CTRL_DEPTH;
- }
+ device->flags.match_driver = true;
+ out:
if (!*return_value)
*return_value = device;
+
return AE_OK;
}
-static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops,
- struct acpi_device **child)
+static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
+ void *not_used, void **ret_not_used)
{
- acpi_status status;
- void *device = NULL;
+ acpi_status status = AE_OK;
+ struct acpi_device *device;
+ unsigned long long sta_not_used;
+ int type_not_used;
- status = acpi_bus_check_add(handle, 0, ops, &device);
- if (ACPI_SUCCESS(status))
- acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
- acpi_bus_check_add, NULL, ops, &device);
+ /*
+ * Ignore errors ignored by acpi_bus_check_add() to avoid terminating
+ * namespace walks prematurely.
+ */
+ if (acpi_bus_type_and_status(handle, &type_not_used, &sta_not_used))
+ return AE_OK;
- if (child)
- *child = device;
+ if (acpi_bus_get_device(handle, &device))
+ return AE_CTRL_DEPTH;
- if (device)
- return 0;
- else
- return -ENODEV;
+ if (!acpi_match_device_ids(device, acpi_platform_device_ids)) {
+ /* This is a known good platform device. */
+ acpi_create_platform_device(device);
+ } else if (device_attach(&device->dev)) {
+ status = AE_CTRL_DEPTH;
+ }
+ return status;
}
-/*
- * acpi_bus_add and acpi_bus_start
- *
- * scan a given ACPI tree and (probably recently hot-plugged)
- * create and add or starts found devices.
- *
- * If no devices were found -ENODEV is returned which does not
- * mean that this is a real error, there just have been no suitable
- * ACPI objects in the table trunk from which the kernel could create
- * a device and add/start an appropriate driver.
- */
-
-int
-acpi_bus_add(struct acpi_device **child,
- struct acpi_device *parent, acpi_handle handle, int type)
+static int acpi_bus_scan(acpi_handle handle)
{
- struct acpi_bus_ops ops;
+ void *device = NULL;
- memset(&ops, 0, sizeof(ops));
- ops.acpi_op_add = 1;
+ if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device)))
+ acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+ acpi_bus_check_add, NULL, NULL, &device);
- return acpi_bus_scan(handle, &ops, child);
-}
-EXPORT_SYMBOL(acpi_bus_add);
+ if (!device)
+ return -ENODEV;
-int acpi_bus_start(struct acpi_device *device)
-{
- struct acpi_bus_ops ops;
- int result;
+ if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL)))
+ acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+ acpi_bus_device_attach, NULL, NULL, NULL);
- if (!device)
- return -EINVAL;
+ return 0;
+}
- memset(&ops, 0, sizeof(ops));
- ops.acpi_op_start = 1;
+/**
+ * acpi_bus_add - Add ACPI device node objects in a given namespace scope.
+ * @handle: Root of the namespace scope to scan.
+ *
+ * Scan a given ACPI tree (probably recently hot-plugged) and create and add
+ * found devices.
+ *
+ * If no devices were found, -ENODEV is returned, but it does not mean that
+ * there has been a real error. There just have been no suitable ACPI objects
+ * in the table trunk from which the kernel could create a device and add an
+ * appropriate driver.
+ */
+int acpi_bus_add(acpi_handle handle)
+{
+ int err;
- result = acpi_bus_scan(device->handle, &ops, NULL);
+ err = acpi_bus_scan(handle);
+ if (err)
+ return err;
acpi_update_all_gpes();
-
- return result;
+ return 0;
}
-EXPORT_SYMBOL(acpi_bus_start);
+EXPORT_SYMBOL(acpi_bus_add);
int acpi_bus_trim(struct acpi_device *start, int rmdevice)
{
@@ -1747,11 +1701,6 @@ static int acpi_bus_scan_fixed(void)
{
int result = 0;
struct acpi_device *device = NULL;
- struct acpi_bus_ops ops;
-
- memset(&ops, 0, sizeof(ops));
- ops.acpi_op_add = 1;
- ops.acpi_op_start = 1;
/*
* Enumerate all fixed-feature devices.
@@ -1759,16 +1708,14 @@ static int acpi_bus_scan_fixed(void)
if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
result = acpi_add_single_object(&device, NULL,
ACPI_BUS_TYPE_POWER_BUTTON,
- ACPI_STA_DEFAULT,
- &ops);
+ ACPI_STA_DEFAULT, true);
device_init_wakeup(&device->dev, true);
}
if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
result = acpi_add_single_object(&device, NULL,
ACPI_BUS_TYPE_SLEEP_BUTTON,
- ACPI_STA_DEFAULT,
- &ops);
+ ACPI_STA_DEFAULT, true);
}
return result;
@@ -1777,11 +1724,6 @@ static int acpi_bus_scan_fixed(void)
int __init acpi_scan_init(void)
{
int result;
- struct acpi_bus_ops ops;
-
- memset(&ops, 0, sizeof(ops));
- ops.acpi_op_add = 1;
- ops.acpi_op_start = 1;
result = bus_register(&acpi_bus_type);
if (result) {
@@ -1790,12 +1732,16 @@ int __init acpi_scan_init(void)
}
acpi_power_init();
+ acpi_pci_root_init();
/*
* Enumerate devices in the ACPI namespace.
*/
- result = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root);
+ result = acpi_bus_scan(ACPI_ROOT_OBJECT);
+ if (result)
+ return result;
+ result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root);
if (!result)
result = acpi_bus_scan_fixed();
OpenPOWER on IntegriCloud