Commit 6a8dd808 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'acpi-scan' into acpi-pm

The following commits depend on the 'acpi-scan' material.
parents 9931faca 5993c467
...@@ -37,7 +37,7 @@ acpi-y += resource.o ...@@ -37,7 +37,7 @@ acpi-y += resource.o
acpi-y += processor_core.o acpi-y += processor_core.o
acpi-y += ec.o acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.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 += acpi_platform.o
acpi-y += power.o acpi-y += power.o
acpi-y += event.o acpi-y += event.o
......
...@@ -157,38 +157,26 @@ static int ...@@ -157,38 +157,26 @@ static int
acpi_memory_get_device(acpi_handle handle, acpi_memory_get_device(acpi_handle handle,
struct acpi_memory_device **mem_device) struct acpi_memory_device **mem_device)
{ {
acpi_status status;
acpi_handle phandle;
struct acpi_device *device = NULL; struct acpi_device *device = NULL;
struct acpi_device *pdevice = NULL;
int result; int result;
if (!acpi_bus_get_device(handle, &device) && device) if (!acpi_bus_get_device(handle, &device) && device)
goto end; 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 * Now add the notified device. This creates the acpi_device
* and invokes .add function * and invokes .add function
*/ */
result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); result = acpi_bus_add(handle);
if (result) { if (result) {
acpi_handle_warn(handle, "Cannot add acpi bus\n"); acpi_handle_warn(handle, "Cannot add acpi bus\n");
return -EINVAL; return -EINVAL;
} }
result = acpi_bus_get_device(handle, &device);
if (result) {
acpi_handle_warn(handle, "Missing device object\n");
return -EINVAL;
}
end: end:
*mem_device = acpi_driver_data(device); *mem_device = acpi_driver_data(device);
...@@ -355,7 +343,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) ...@@ -355,7 +343,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
break; break;
} }
ej_event->handle = handle; ej_event->device = device;
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
acpi_os_hotplug_execute(acpi_bus_hot_remove_device, acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
(void *)ej_event); (void *)ej_event);
......
...@@ -135,30 +135,6 @@ static int acpi_container_remove(struct acpi_device *device, int type) ...@@ -135,30 +135,6 @@ static int acpi_container_remove(struct acpi_device *device, int type)
return status; 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) static void container_notify_cb(acpi_handle handle, u32 type, void *context)
{ {
struct acpi_device *device = NULL; struct acpi_device *device = NULL;
...@@ -190,11 +166,16 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) ...@@ -190,11 +166,16 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
if (!ACPI_FAILURE(status) || device) if (!ACPI_FAILURE(status) || device)
break; break;
result = container_device_add(&device, handle); result = acpi_bus_add(handle);
if (result) { if (result) {
acpi_handle_warn(handle, "Failed to add container\n"); acpi_handle_warn(handle, "Failed to add container\n");
break; 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); kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
ost_code = ACPI_OST_SC_SUCCESS; ost_code = ACPI_OST_SC_SUCCESS;
......
...@@ -353,7 +353,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) ...@@ -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. * acpi_dev_pm_get_node - Get ACPI device node for the given physical device.
* @dev: Device to get the ACPI node for. * @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); acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
struct acpi_device *adev; struct acpi_device *adev;
......
...@@ -310,8 +310,6 @@ static int dock_present(struct dock_station *ds) ...@@ -310,8 +310,6 @@ static int dock_present(struct dock_station *ds)
static struct acpi_device * dock_create_acpi_device(acpi_handle handle) static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
{ {
struct acpi_device *device; struct acpi_device *device;
struct acpi_device *parent_device;
acpi_handle parent;
int ret; int ret;
if (acpi_bus_get_device(handle, &device)) { if (acpi_bus_get_device(handle, &device)) {
...@@ -319,16 +317,11 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle) ...@@ -319,16 +317,11 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
* no device created for this object, * no device created for this object,
* so we should create one. * so we should create one.
*/ */
acpi_get_parent(handle, &parent); ret = acpi_bus_add(handle);
if (acpi_bus_get_device(parent, &parent_device)) if (ret)
parent_device = NULL;
ret = acpi_bus_add(&device, parent_device, handle,
ACPI_BUS_TYPE_DEVICE);
if (ret) {
pr_debug("error adding bus, %x\n", -ret); pr_debug("error adding bus, %x\n", -ret);
return NULL;
} acpi_bus_get_device(handle, &device);
} }
return device; return device;
} }
...@@ -346,7 +339,7 @@ static void dock_remove_acpi_device(acpi_handle handle) ...@@ -346,7 +339,7 @@ static void dock_remove_acpi_device(acpi_handle handle)
int ret; int ret;
if (!acpi_bus_get_device(handle, &device)) { if (!acpi_bus_get_device(handle, &device)) {
ret = acpi_bus_trim(device, 1); ret = acpi_bus_trim(device);
if (ret) if (ret)
pr_debug("error removing bus, %x\n", -ret); pr_debug("error removing bus, %x\n", -ret);
} }
......
...@@ -68,6 +68,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) ...@@ -68,6 +68,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
{ {
struct acpi_bus_type *tmp, *ret = NULL; struct acpi_bus_type *tmp, *ret = NULL;
if (!type)
return NULL;
down_read(&bus_type_sem); down_read(&bus_type_sem);
list_for_each_entry(tmp, &bus_type_list, list) { list_for_each_entry(tmp, &bus_type_list, list) {
if (tmp->bus == type) { if (tmp->bus == type) {
...@@ -269,28 +272,39 @@ static int acpi_platform_notify(struct device *dev) ...@@ -269,28 +272,39 @@ static int acpi_platform_notify(struct device *dev)
{ {
struct acpi_bus_type *type; struct acpi_bus_type *type;
acpi_handle handle; acpi_handle handle;
int ret = -EINVAL; int ret;
ret = acpi_bind_one(dev, NULL); ret = acpi_bind_one(dev, NULL);
if (!ret) if (ret && (!dev->bus || !dev->parent)) {
goto out;
if (!dev->bus || !dev->parent) {
/* bridge devices genernally haven't bus or parent */ /* bridge devices genernally haven't bus or parent */
ret = acpi_find_bridge_device(dev, &handle); 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); type = acpi_get_bus_type(dev->bus);
if (!type) { if (ret) {
DBG("No ACPI bus support for %s\n", dev_name(dev)); if (!type || !type->find_device) {
ret = -EINVAL; DBG("No ACPI bus support for %s\n", dev_name(dev));
goto end; 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)); if (type && type->setup)
end: type->setup(dev);
if (!ret)
acpi_bind_one(dev, handle);
out: out:
#if ACPI_GLUE_DEBUG #if ACPI_GLUE_DEBUG
...@@ -309,6 +323,12 @@ static int acpi_platform_notify(struct device *dev) ...@@ -309,6 +323,12 @@ static int acpi_platform_notify(struct device *dev)
static int acpi_platform_notify_remove(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); acpi_unbind_one(dev);
return 0; return 0;
} }
......
...@@ -67,6 +67,7 @@ struct acpi_ec { ...@@ -67,6 +67,7 @@ struct acpi_ec {
extern struct acpi_ec *first_ec; extern struct acpi_ec *first_ec;
int acpi_pci_root_init(void);
int acpi_ec_init(void); int acpi_ec_init(void);
int acpi_ec_ecdt_probe(void); int acpi_ec_ecdt_probe(void);
int acpi_boot_ec_enable(void); int acpi_boot_ec_enable(void);
......
/*
* 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;
}
...@@ -47,7 +47,6 @@ ACPI_MODULE_NAME("pci_root"); ...@@ -47,7 +47,6 @@ ACPI_MODULE_NAME("pci_root");
#define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge"
static int acpi_pci_root_add(struct acpi_device *device); 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_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 \ #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \
| OSC_ACTIVE_STATE_PWR_SUPPORT \ | OSC_ACTIVE_STATE_PWR_SUPPORT \
...@@ -67,7 +66,6 @@ static struct acpi_driver acpi_pci_root_driver = { ...@@ -67,7 +66,6 @@ static struct acpi_driver acpi_pci_root_driver = {
.ops = { .ops = {
.add = acpi_pci_root_add, .add = acpi_pci_root_add,
.remove = acpi_pci_root_remove, .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, ...@@ -188,21 +186,6 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
return AE_OK; 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 u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766";
static acpi_status acpi_pci_run_osc(acpi_handle handle, static acpi_status acpi_pci_run_osc(acpi_handle handle,
...@@ -452,7 +435,7 @@ static int acpi_pci_root_add(struct acpi_device *device) ...@@ -452,7 +435,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
int result; int result;
struct acpi_pci_root *root; struct acpi_pci_root *root;
acpi_handle handle; acpi_handle handle;
struct acpi_device *child; struct acpi_pci_driver *driver;
u32 flags, base_flags; u32 flags, base_flags;
bool is_osc_granted = false; bool is_osc_granted = false;
...@@ -603,21 +586,6 @@ static int acpi_pci_root_add(struct acpi_device *device) ...@@ -603,21 +586,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
goto out_del_root; 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 */ /* ASPM setting */
if (is_osc_granted) { if (is_osc_granted) {
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM)
...@@ -632,24 +600,6 @@ static int acpi_pci_root_add(struct acpi_device *device) ...@@ -632,24 +600,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
if (device->wakeup.flags.run_wake) if (device->wakeup.flags.run_wake)
device_set_run_wake(root->bus->bridge, true); 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) if (system_state != SYSTEM_BOOTING)
pci_assign_unassigned_bus_resources(root->bus); pci_assign_unassigned_bus_resources(root->bus);
...@@ -664,8 +614,17 @@ static int acpi_pci_root_start(struct acpi_device *device) ...@@ -664,8 +614,17 @@ static int acpi_pci_root_start(struct acpi_device *device)
pci_enable_bridges(root->bus); pci_enable_bridges(root->bus);
pci_bus_add_devices(root->bus); pci_bus_add_devices(root->bus);
return 0; 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) static int acpi_pci_root_remove(struct acpi_device *device, int type)
...@@ -699,7 +658,7 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) ...@@ -699,7 +658,7 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
return 0; return 0;
} }
static int __init acpi_pci_root_init(void) int __init acpi_pci_root_init(void)
{ {
acpi_hest_init(); acpi_hest_init();
...@@ -712,5 +671,3 @@ static int __init acpi_pci_root_init(void) ...@@ -712,5 +671,3 @@ static int __init acpi_pci_root_init(void)
return 0; return 0;
} }
subsys_initcall(acpi_pci_root_init);
...@@ -677,28 +677,6 @@ static int is_processor_present(acpi_handle handle) ...@@ -677,28 +677,6 @@ static int is_processor_present(acpi_handle handle)
return 0; 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, static void acpi_processor_hotplug_notify(acpi_handle handle,
u32 event, void *data) u32 event, void *data)
{ {
...@@ -721,12 +699,16 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, ...@@ -721,12 +699,16 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
if (!acpi_bus_get_device(handle, &device)) if (!acpi_bus_get_device(handle, &device))
break; break;
result = acpi_processor_device_add(handle, &device); result = acpi_bus_add(handle);
if (result) { if (result) {
acpi_handle_err(handle, "Unable to add the device\n"); acpi_handle_err(handle, "Unable to add the device\n");
break; 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; ost_code = ACPI_OST_SC_SUCCESS;
break; break;
...@@ -751,7 +733,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, ...@@ -751,7 +733,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
break; break;
} }
ej_event->handle = handle; ej_event->device = device;
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
acpi_os_hotplug_execute(acpi_bus_hot_remove_device, acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
(void *)ej_event); (void *)ej_event);
......
...@@ -116,24 +116,18 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); ...@@ -116,24 +116,18 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
void acpi_bus_hot_remove_device(void *context) void acpi_bus_hot_remove_device(void *context)
{ {
struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
struct acpi_device *device; struct acpi_device *device = ej_event->device;
acpi_handle handle = ej_event->handle; acpi_handle handle = device->handle;
acpi_handle temp; acpi_handle temp;
struct acpi_object_list arg_list; struct acpi_object_list arg_list;
union acpi_object arg; union acpi_object arg;
acpi_status status = AE_OK; acpi_status status = AE_OK;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
if (acpi_bus_get_device(handle, &device))
goto err_out;
if (!device)
goto err_out;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Hot-removing device %s...\n", dev_name(&device->dev))); "Hot-removing device %s...\n", dev_name(&device->dev)));
if (acpi_bus_trim(device, 1)) { if (acpi_bus_trim(device)) {
printk(KERN_ERR PREFIX printk(KERN_ERR PREFIX
"Removing device failed\n"); "Removing device failed\n");
goto err_out; goto err_out;
...@@ -215,7 +209,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, ...@@ -215,7 +209,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
goto err; goto err;
} }
ej_event->handle = acpi_device->handle; ej_event->device = acpi_device;
if (acpi_device->flags.eject_pending) { if (acpi_device->flags.eject_pending) {
/* event originated from ACPI eject notification */ /* event originated from ACPI eject notification */
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
...@@ -223,7 +217,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, ...@@ -223,7 +217,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
} else { } else {
/* event originated from user */ /* event originated from user */
ej_event->event = ACPI_OST_EC_OSPM_EJECT; ej_event->event = ACPI_OST_EC_OSPM_EJECT;
(void) acpi_evaluate_hotplug_ost(ej_event->handle, (void) acpi_evaluate_hotplug_ost(acpi_device->handle,
ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
} }
...@@ -494,7 +488,8 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv) ...@@ -494,7 +488,8 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_device *acpi_dev = to_acpi_device(dev);
struct acpi_driver *acpi_drv = to_acpi_driver(drv); 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) static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
...@@ -570,7 +565,6 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device) ...@@ -570,7 +565,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_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) static int acpi_device_probe(struct device * dev)
{ {
struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_device *acpi_dev = to_acpi_device(dev);
...@@ -579,9 +573,6 @@ static int acpi_device_probe(struct device * dev) ...@@ -579,9 +573,6 @@ static int acpi_device_probe(struct device * dev)
ret = acpi_bus_driver_init(acpi_dev, acpi_drv); ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
if (!ret) { if (!ret) {
if (acpi_dev->bus_ops.acpi_op_start)
acpi_start_single_object(acpi_dev);
if (acpi_drv->ops.notify) { if (acpi_drv->ops.notify) {
ret = acpi_device_install_notify_handler(acpi_dev); ret = acpi_device_install_notify_handler(acpi_dev);
if (ret) { if (ret) {
...@@ -704,7 +695,7 @@ static int acpi_device_register(struct acpi_device *device) ...@@ -704,7 +695,7 @@ static int acpi_device_register(struct acpi_device *device)
return result; return result;
} }
static void acpi_device_unregister(struct acpi_device *device, int type) static void acpi_device_unregister(struct acpi_device *device)
{ {
mutex_lock(&acpi_device_lock); mutex_lock(&acpi_device_lock);
if (device->parent) if (device->parent)
...@@ -760,24 +751,6 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) ...@@ -760,24 +751,6 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
return 0; 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 * acpi_bus_register_driver - register a driver with the ACPI bus
* @driver: driver being registered * @driver: driver being registered
...@@ -1395,33 +1368,9 @@ static int acpi_device_set_context(struct acpi_device *device) ...@@ -1395,33 +1368,9 @@ static int acpi_device_set_context(struct acpi_device *device)
return -ENODEV; return -ENODEV;
} }
static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
{
if (!dev)
return -EINVAL;
dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
device_release_driver(&dev->dev);
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;
}
static int acpi_add_single_object(struct acpi_device **child, static int acpi_add_single_object(struct acpi_device **child,
acpi_handle handle, int type, acpi_handle handle, int type,
unsigned long long sta, unsigned long long sta, bool match_driver)
struct acpi_bus_ops *ops)
{ {
int result; int result;
struct acpi_device *device; struct acpi_device *device;
...@@ -1437,7 +1386,6 @@ static int acpi_add_single_object(struct acpi_device **child, ...@@ -1437,7 +1386,6 @@ static int acpi_add_single_object(struct acpi_device **child,
device->device_type = type; device->device_type = type;
device->handle = handle; device->handle = handle;
device->parent = acpi_bus_get_parent(handle); device->parent = acpi_bus_get_parent(handle);
device->bus_ops = *ops; /* workround for not call .start */
STRUCT_TO_INT(device->status) = sta; STRUCT_TO_INT(device->status) = sta;
acpi_device_get_busid(device); acpi_device_get_busid(device);
...@@ -1488,16 +1436,9 @@ static int acpi_add_single_object(struct acpi_device **child, ...@@ -1488,16 +1436,9 @@ static int acpi_add_single_object(struct acpi_device **child,
if ((result = acpi_device_set_context(device))) if ((result = acpi_device_set_context(device)))
goto end; goto end;
device->flags.match_driver = match_driver;
result = acpi_device_register(device); 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: end:
if (!result) { if (!result) {
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
...@@ -1519,16 +1460,12 @@ static int acpi_add_single_object(struct acpi_device **child, ...@@ -1519,16 +1460,12 @@ static int acpi_add_single_object(struct acpi_device **child,
static void acpi_bus_add_power_resource(acpi_handle handle) 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; struct acpi_device *device = NULL;
acpi_bus_get_device(handle, &device); acpi_bus_get_device(handle, &device);
if (!device) if (!device)
acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER, 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, static int acpi_bus_type_and_status(acpi_handle handle, int *type,
...@@ -1570,16 +1507,19 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type, ...@@ -1570,16 +1507,19 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type,
return 0; return 0;
} }
static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
void *context, void **return_value) void *not_used, void **return_value)
{ {
struct acpi_bus_ops *ops = context; struct acpi_device *device = NULL;
int type; int type;
unsigned long long sta; unsigned long long sta;
struct acpi_device *device;
acpi_status status; acpi_status status;
int result; int result;
acpi_bus_get_device(handle, &device);
if (device)
goto out;
result = acpi_bus_type_and_status(handle, &type, &sta); result = acpi_bus_type_and_status(handle, &type, &sta);
if (result) if (result)
return AE_OK; return AE_OK;
...@@ -1596,150 +1536,130 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, ...@@ -1596,150 +1536,130 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
return AE_CTRL_DEPTH; return AE_CTRL_DEPTH;
} }
/* acpi_add_single_object(&device, handle, type, sta,
* We may already have an acpi_device from a previous enumeration. If type == ACPI_BUS_TYPE_POWER);
* 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);
}
if (!device) if (!device)
return AE_CTRL_DEPTH; return AE_CTRL_DEPTH;
if (ops->acpi_op_start && !(ops->acpi_op_add)) { device->flags.match_driver = true;
status = acpi_start_single_object(device);
if (ACPI_FAILURE(status))
return AE_CTRL_DEPTH;
}
out:
if (!*return_value) if (!*return_value)
*return_value = device; *return_value = device;
return AE_OK; return AE_OK;
} }
static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
struct acpi_device **child) void *not_used, void **ret_not_used)
{
acpi_status status = AE_OK;
struct acpi_device *device;
unsigned long long sta_not_used;
int type_not_used;
/*
* 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 (acpi_bus_get_device(handle, &device))
return AE_CTRL_DEPTH;
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) < 0) {
status = AE_CTRL_DEPTH;
}
return status;
}
static int acpi_bus_scan(acpi_handle handle)
{ {
acpi_status status;
void *device = NULL; void *device = NULL;
status = acpi_bus_check_add(handle, 0, ops, &device); if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device)))
if (ACPI_SUCCESS(status))
acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
acpi_bus_check_add, NULL, ops, &device); acpi_bus_check_add, NULL, NULL, &device);
if (child) if (!device)
*child = device;
if (device)
return 0;
else
return -ENODEV; return -ENODEV;
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);
return 0;
} }
/* /**
* acpi_bus_add and acpi_bus_start * 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 and (probably recently hot-plugged) * Scan a given ACPI tree (probably recently hot-plugged) and create and add
* create and add or starts found devices. * found devices.
* *
* If no devices were found -ENODEV is returned which does not * If no devices were found, -ENODEV is returned, but it does not mean that
* mean that this is a real error, there just have been no suitable * there has been a real error. There just have been no suitable ACPI objects
* ACPI objects in the table trunk from which the kernel could create * in the table trunk from which the kernel could create a device and add an
* a device and add/start an appropriate driver. * appropriate driver.
*/ */
int acpi_bus_add(acpi_handle handle)
int
acpi_bus_add(struct acpi_device **child,
struct acpi_device *parent, acpi_handle handle, int type)
{ {
struct acpi_bus_ops ops; int err;
memset(&ops, 0, sizeof(ops)); err = acpi_bus_scan(handle);
ops.acpi_op_add = 1; if (err)
return err;
return acpi_bus_scan(handle, &ops, child); acpi_update_all_gpes();
return 0;
} }
EXPORT_SYMBOL(acpi_bus_add); EXPORT_SYMBOL(acpi_bus_add);
int acpi_bus_start(struct acpi_device *device) static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used,
void *not_used, void **ret_not_used)
{ {
struct acpi_bus_ops ops; struct acpi_device *device = NULL;
int result;
if (!device)
return -EINVAL;
memset(&ops, 0, sizeof(ops));
ops.acpi_op_start = 1;
result = acpi_bus_scan(device->handle, &ops, NULL);
acpi_update_all_gpes();
return result; if (!acpi_bus_get_device(handle, &device)) {
device->removal_type = ACPI_BUS_REMOVAL_EJECT;
device_release_driver(&device->dev);
}
return AE_OK;
} }
EXPORT_SYMBOL(acpi_bus_start);
int acpi_bus_trim(struct acpi_device *start, int rmdevice) static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used,
void *not_used, void **ret_not_used)
{ {
acpi_status status; struct acpi_device *device = NULL;
struct acpi_device *parent, *child;
acpi_handle phandle, chandle;
acpi_object_type type;
u32 level = 1;
int err = 0;
parent = start;
phandle = start->handle;
child = chandle = NULL;
while ((level > 0) && parent && (!err)) {
status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
chandle, &chandle);
/* if (!acpi_bus_get_device(handle, &device))
* If this scope is exhausted then move our way back up. acpi_device_unregister(device);
*/
if (ACPI_FAILURE(status)) {
level--;
chandle = phandle;
acpi_get_parent(phandle, &phandle);
child = parent;
parent = parent->parent;
if (level == 0)
err = acpi_bus_remove(child, rmdevice);
else
err = acpi_bus_remove(child, 1);
continue; return AE_OK;
} }
status = acpi_get_type(chandle, &type); int acpi_bus_trim(struct acpi_device *start)
if (ACPI_FAILURE(status)) { {
continue; /*
} * Execute acpi_bus_device_detach() as a post-order callback to detach
/* * all ACPI drivers from the device nodes being removed.
* If there is a device corresponding to chandle then */
* parse it (depth-first). acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
*/ acpi_bus_device_detach, NULL, NULL);
if (acpi_bus_get_device(chandle, &child) == 0) { acpi_bus_device_detach(start->handle, 0, NULL, NULL);
level++; /*
phandle = chandle; * Execute acpi_bus_remove() as a post-order callback to remove device
chandle = NULL; * nodes in the given namespace scope.
parent = child; */
} acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
continue; acpi_bus_remove, NULL, NULL);
} acpi_bus_remove(start->handle, 0, NULL, NULL);
return err; return 0;
} }
EXPORT_SYMBOL_GPL(acpi_bus_trim); EXPORT_SYMBOL_GPL(acpi_bus_trim);
...@@ -1747,11 +1667,6 @@ static int acpi_bus_scan_fixed(void) ...@@ -1747,11 +1667,6 @@ static int acpi_bus_scan_fixed(void)
{ {
int result = 0; int result = 0;
struct acpi_device *device = NULL; 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. * Enumerate all fixed-feature devices.
...@@ -1759,16 +1674,14 @@ static int acpi_bus_scan_fixed(void) ...@@ -1759,16 +1674,14 @@ static int acpi_bus_scan_fixed(void)
if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
result = acpi_add_single_object(&device, NULL, result = acpi_add_single_object(&device, NULL,
ACPI_BUS_TYPE_POWER_BUTTON, ACPI_BUS_TYPE_POWER_BUTTON,
ACPI_STA_DEFAULT, ACPI_STA_DEFAULT, true);
&ops);
device_init_wakeup(&device->dev, true); device_init_wakeup(&device->dev, true);
} }
if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
result = acpi_add_single_object(&device, NULL, result = acpi_add_single_object(&device, NULL,
ACPI_BUS_TYPE_SLEEP_BUTTON, ACPI_BUS_TYPE_SLEEP_BUTTON,
ACPI_STA_DEFAULT, ACPI_STA_DEFAULT, true);
&ops);
} }
return result; return result;
...@@ -1777,11 +1690,6 @@ static int acpi_bus_scan_fixed(void) ...@@ -1777,11 +1690,6 @@ static int acpi_bus_scan_fixed(void)
int __init acpi_scan_init(void) int __init acpi_scan_init(void)
{ {
int result; 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); result = bus_register(&acpi_bus_type);
if (result) { if (result) {
...@@ -1790,17 +1698,21 @@ int __init acpi_scan_init(void) ...@@ -1790,17 +1698,21 @@ int __init acpi_scan_init(void)
} }
acpi_power_init(); acpi_power_init();
acpi_pci_root_init();
/* /*
* Enumerate devices in the ACPI namespace. * 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) if (!result)
result = acpi_bus_scan_fixed(); result = acpi_bus_scan_fixed();
if (result) if (result)
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); acpi_device_unregister(acpi_root);
else else
acpi_update_all_gpes(); acpi_update_all_gpes();
......
...@@ -734,34 +734,25 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus) ...@@ -734,34 +734,25 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
*/ */
static int acpiphp_bus_add(struct acpiphp_func *func) static int acpiphp_bus_add(struct acpiphp_func *func)
{ {
acpi_handle phandle; struct acpi_device *device;
struct acpi_device *device, *pdevice;
int ret_val; int ret_val;
acpi_get_parent(func->handle, &phandle);
if (acpi_bus_get_device(phandle, &pdevice)) {
dbg("no parent device, assuming NULL\n");
pdevice = NULL;
}
if (!acpi_bus_get_device(func->handle, &device)) { if (!acpi_bus_get_device(func->handle, &device)) {
dbg("bus exists... trim\n"); dbg("bus exists... trim\n");
/* this shouldn't be in here, so remove /* this shouldn't be in here, so remove
* the bus then re-add it... * the bus then re-add it...
*/ */
ret_val = acpi_bus_trim(device, 1); ret_val = acpi_bus_trim(device);
dbg("acpi_bus_trim return %x\n", ret_val); dbg("acpi_bus_trim return %x\n", ret_val);
} }
ret_val = acpi_bus_add(&device, pdevice, func->handle, ret_val = acpi_bus_add(func->handle);
ACPI_BUS_TYPE_DEVICE); if (!ret_val)
if (ret_val) { ret_val = acpi_bus_get_device(func->handle, &device);
dbg("error adding bus, %x\n",
-ret_val); if (ret_val)
goto acpiphp_bus_add_out; dbg("error adding bus, %x\n", -ret_val);
}
ret_val = acpi_bus_start(device);
acpiphp_bus_add_out:
return ret_val; return ret_val;
} }
...@@ -781,7 +772,7 @@ static int acpiphp_bus_trim(acpi_handle handle) ...@@ -781,7 +772,7 @@ static int acpiphp_bus_trim(acpi_handle handle)
return retval; return retval;
} }
retval = acpi_bus_trim(device, 1); retval = acpi_bus_trim(device);
if (retval) if (retval)
err("cannot remove from acpi list\n"); err("cannot remove from acpi list\n");
...@@ -1130,8 +1121,7 @@ static int acpiphp_configure_bridge (acpi_handle handle) ...@@ -1130,8 +1121,7 @@ static int acpiphp_configure_bridge (acpi_handle handle)
static void handle_bridge_insertion(acpi_handle handle, u32 type) static void handle_bridge_insertion(acpi_handle handle, u32 type)
{ {
struct acpi_device *device, *pdevice; struct acpi_device *device;
acpi_handle phandle;
if ((type != ACPI_NOTIFY_BUS_CHECK) && if ((type != ACPI_NOTIFY_BUS_CHECK) &&
(type != ACPI_NOTIFY_DEVICE_CHECK)) { (type != ACPI_NOTIFY_DEVICE_CHECK)) {
...@@ -1139,17 +1129,15 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type) ...@@ -1139,17 +1129,15 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type)
return; return;
} }
acpi_get_parent(handle, &phandle); if (acpi_bus_add(handle)) {
if (acpi_bus_get_device(phandle, &pdevice)) {
dbg("no parent device, assuming NULL\n");
pdevice = NULL;
}
if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
err("cannot add bridge to acpi list\n"); err("cannot add bridge to acpi list\n");
return; return;
} }
if (!acpiphp_configure_bridge(handle) && if (acpi_bus_get_device(handle, &device)) {
!acpi_bus_start(device)) err("ACPI device object missing\n");
return;
}
if (!acpiphp_configure_bridge(handle))
add_bridge(handle); add_bridge(handle);
else else
err("cannot configure and start bridge\n"); err("cannot configure and start bridge\n");
......
...@@ -412,7 +412,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -412,7 +412,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
if (SN_ACPI_BASE_SUPPORT() && ssdt) { if (SN_ACPI_BASE_SUPPORT() && ssdt) {
unsigned long long adr; unsigned long long adr;
struct acpi_device *pdevice; struct acpi_device *pdevice;
struct acpi_device *device;
acpi_handle phandle; acpi_handle phandle;
acpi_handle chandle = NULL; acpi_handle chandle = NULL;
acpi_handle rethandle; acpi_handle rethandle;
...@@ -448,8 +447,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -448,8 +447,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
if (ACPI_SUCCESS(ret) && if (ACPI_SUCCESS(ret) &&
(adr>>16) == (slot->device_num + 1)) { (adr>>16) == (slot->device_num + 1)) {
ret = acpi_bus_add(&device, pdevice, chandle, ret = acpi_bus_add(chandle);
ACPI_BUS_TYPE_DEVICE);
if (ACPI_FAILURE(ret)) { if (ACPI_FAILURE(ret)) {
printk(KERN_ERR "%s: acpi_bus_add " printk(KERN_ERR "%s: acpi_bus_add "
"failed (0x%x) for slot %d " "failed (0x%x) for slot %d "
...@@ -457,8 +455,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -457,8 +455,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
ret, (int)(adr>>16), ret, (int)(adr>>16),
(int)(adr&0xffff)); (int)(adr&0xffff));
/* try to continue on */ /* try to continue on */
} else {
acpi_bus_start(device);
} }
} }
} }
...@@ -539,7 +535,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -539,7 +535,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
ret = acpi_bus_get_device(chandle, ret = acpi_bus_get_device(chandle,
&device); &device);
if (ACPI_SUCCESS(ret)) if (ACPI_SUCCESS(ret))
acpi_bus_trim(device, 1); acpi_bus_trim(device);
} }
} }
......
...@@ -283,7 +283,6 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { ...@@ -283,7 +283,6 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = {
.is_manageable = acpi_pci_power_manageable, .is_manageable = acpi_pci_power_manageable,
.set_state = acpi_pci_set_power_state, .set_state = acpi_pci_set_power_state,
.choose_state = acpi_pci_choose_state, .choose_state = acpi_pci_choose_state,
.can_wakeup = acpi_pci_can_wakeup,
.sleep_wake = acpi_pci_sleep_wake, .sleep_wake = acpi_pci_sleep_wake,
.run_wake = acpi_pci_run_wake, .run_wake = acpi_pci_run_wake,
}; };
...@@ -321,10 +320,67 @@ static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) ...@@ -321,10 +320,67 @@ static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
return 0; return 0;
} }
static void pci_acpi_setup(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
acpi_handle handle = ACPI_HANDLE(dev);
struct acpi_device *adev;
acpi_status status;
acpi_handle dummy;
/*
* 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(handle, METHOD_NAME__PRT, &dummy);
if (ACPI_SUCCESS(status)) {
unsigned char bus;
bus = pci_dev->subordinate ?
pci_dev->subordinate->number : pci_dev->bus->number;
acpi_pci_irq_add_prt(handle, pci_domain_nr(pci_dev->bus), bus);
}
acpi_power_resource_register_device(dev, handle);
if (acpi_bus_get_device(handle, &adev) || !adev->wakeup.flags.valid)
return;
device_set_wakeup_capable(dev, true);
acpi_pci_sleep_wake(pci_dev, false);
pci_acpi_add_pm_notifier(adev, pci_dev);
if (adev->wakeup.flags.run_wake)
device_set_run_wake(dev, true);
}
static void pci_acpi_cleanup(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
acpi_handle handle = ACPI_HANDLE(dev);
struct acpi_device *adev;
if (!acpi_bus_get_device(handle, &adev) && adev->wakeup.flags.valid) {
device_set_wakeup_capable(dev, false);
device_set_run_wake(dev, false);
pci_acpi_remove_pm_notifier(adev);
}
acpi_power_resource_unregister_device(dev, handle);
if (pci_dev->subordinate)
acpi_pci_irq_del_prt(pci_domain_nr(pci_dev->bus),
pci_dev->subordinate->number);
}
static struct acpi_bus_type acpi_pci_bus = { static struct acpi_bus_type acpi_pci_bus = {
.bus = &pci_bus_type, .bus = &pci_bus_type,
.find_device = acpi_pci_find_device, .find_device = acpi_pci_find_device,
.find_bridge = acpi_pci_find_root_bridge, .find_bridge = acpi_pci_find_root_bridge,
.setup = pci_acpi_setup,
.cleanup = pci_acpi_cleanup,
}; };
static int __init acpi_pci_init(void) static int __init acpi_pci_init(void)
......
...@@ -450,7 +450,7 @@ static struct pci_platform_pm_ops *pci_platform_pm; ...@@ -450,7 +450,7 @@ static struct pci_platform_pm_ops *pci_platform_pm;
int pci_set_platform_pm(struct pci_platform_pm_ops *ops) int pci_set_platform_pm(struct pci_platform_pm_ops *ops)
{ {
if (!ops->is_manageable || !ops->set_state || !ops->choose_state if (!ops->is_manageable || !ops->set_state || !ops->choose_state
|| !ops->sleep_wake || !ops->can_wakeup) || !ops->sleep_wake)
return -EINVAL; return -EINVAL;
pci_platform_pm = ops; pci_platform_pm = ops;
return 0; return 0;
...@@ -473,11 +473,6 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) ...@@ -473,11 +473,6 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev)
pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR;
} }
static inline bool platform_pci_can_wakeup(struct pci_dev *dev)
{
return pci_platform_pm ? pci_platform_pm->can_wakeup(dev) : false;
}
static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
{ {
return pci_platform_pm ? return pci_platform_pm ?
...@@ -1985,25 +1980,6 @@ void pci_pm_init(struct pci_dev *dev) ...@@ -1985,25 +1980,6 @@ void pci_pm_init(struct pci_dev *dev)
} }
} }
/**
* platform_pci_wakeup_init - init platform wakeup if present
* @dev: PCI device
*
* Some devices don't have PCI PM caps but can still generate wakeup
* events through platform methods (like ACPI events). If @dev supports
* platform wakeup events, set the device flag to indicate as much. This
* may be redundant if the device also supports PCI PM caps, but double
* initialization should be safe in that case.
*/
void platform_pci_wakeup_init(struct pci_dev *dev)
{
if (!platform_pci_can_wakeup(dev))
return;
device_set_wakeup_capable(&dev->dev, true);
platform_pci_sleep_wake(dev, false);
}
static void pci_add_saved_cap(struct pci_dev *pci_dev, static void pci_add_saved_cap(struct pci_dev *pci_dev,
struct pci_cap_saved_state *new_cap) struct pci_cap_saved_state *new_cap)
{ {
......
...@@ -43,9 +43,6 @@ int pci_probe_reset_function(struct pci_dev *dev); ...@@ -43,9 +43,6 @@ int pci_probe_reset_function(struct pci_dev *dev);
* platform; to be used during system-wide transitions from a * platform; to be used during system-wide transitions from a
* sleeping state to the working state and vice versa * sleeping state to the working state and vice versa
* *
* @can_wakeup: returns 'true' if given device is capable of waking up the
* system from a sleeping state
*
* @sleep_wake: enables/disables the system wake up capability of given device * @sleep_wake: enables/disables the system wake up capability of given device
* *
* @run_wake: enables/disables the platform to generate run-time wake-up events * @run_wake: enables/disables the platform to generate run-time wake-up events
...@@ -59,7 +56,6 @@ struct pci_platform_pm_ops { ...@@ -59,7 +56,6 @@ struct pci_platform_pm_ops {
bool (*is_manageable)(struct pci_dev *dev); bool (*is_manageable)(struct pci_dev *dev);
int (*set_state)(struct pci_dev *dev, pci_power_t state); int (*set_state)(struct pci_dev *dev, pci_power_t state);
pci_power_t (*choose_state)(struct pci_dev *dev); pci_power_t (*choose_state)(struct pci_dev *dev);
bool (*can_wakeup)(struct pci_dev *dev);
int (*sleep_wake)(struct pci_dev *dev, bool enable); int (*sleep_wake)(struct pci_dev *dev, bool enable);
int (*run_wake)(struct pci_dev *dev, bool enable); int (*run_wake)(struct pci_dev *dev, bool enable);
}; };
...@@ -74,7 +70,6 @@ extern void pci_wakeup_bus(struct pci_bus *bus); ...@@ -74,7 +70,6 @@ extern void pci_wakeup_bus(struct pci_bus *bus);
extern void pci_config_pm_runtime_get(struct pci_dev *dev); extern void pci_config_pm_runtime_get(struct pci_dev *dev);
extern void pci_config_pm_runtime_put(struct pci_dev *dev); extern void pci_config_pm_runtime_put(struct pci_dev *dev);
extern void pci_pm_init(struct pci_dev *dev); extern void pci_pm_init(struct pci_dev *dev);
extern void platform_pci_wakeup_init(struct pci_dev *dev);
extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
void pci_free_cap_save_buffers(struct pci_dev *dev); void pci_free_cap_save_buffers(struct pci_dev *dev);
......
...@@ -1280,7 +1280,6 @@ static void pci_init_capabilities(struct pci_dev *dev) ...@@ -1280,7 +1280,6 @@ static void pci_init_capabilities(struct pci_dev *dev)
/* Power Management */ /* Power Management */
pci_pm_init(dev); pci_pm_init(dev);
platform_pci_wakeup_init(dev);
/* Vital Product Data */ /* Vital Product Data */
pci_vpd_pci22_init(dev); pci_vpd_pci22_init(dev);
......
...@@ -91,21 +91,12 @@ struct acpi_device; ...@@ -91,21 +91,12 @@ struct acpi_device;
typedef int (*acpi_op_add) (struct acpi_device * device); typedef int (*acpi_op_add) (struct acpi_device * device);
typedef int (*acpi_op_remove) (struct acpi_device * device, int type); typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
typedef int (*acpi_op_start) (struct acpi_device * device); typedef int (*acpi_op_start) (struct acpi_device * device);
typedef int (*acpi_op_bind) (struct acpi_device * device);
typedef int (*acpi_op_unbind) (struct acpi_device * device);
typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event); typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
struct acpi_bus_ops {
u32 acpi_op_add:1;
u32 acpi_op_start:1;
};
struct acpi_device_ops { struct acpi_device_ops {
acpi_op_add add; acpi_op_add add;
acpi_op_remove remove; acpi_op_remove remove;
acpi_op_start start; acpi_op_start start;
acpi_op_bind bind;
acpi_op_unbind unbind;
acpi_op_notify notify; acpi_op_notify notify;
}; };
...@@ -148,7 +139,8 @@ struct acpi_device_flags { ...@@ -148,7 +139,8 @@ struct acpi_device_flags {
u32 power_manageable:1; u32 power_manageable:1;
u32 performance_manageable:1; u32 performance_manageable:1;
u32 eject_pending:1; u32 eject_pending:1;
u32 reserved:24; u32 match_driver:1;
u32 reserved:23;
}; };
/* File System */ /* File System */
...@@ -279,11 +271,9 @@ struct acpi_device { ...@@ -279,11 +271,9 @@ struct acpi_device {
struct acpi_device_wakeup wakeup; struct acpi_device_wakeup wakeup;
struct acpi_device_perf performance; struct acpi_device_perf performance;
struct acpi_device_dir dir; struct acpi_device_dir dir;
struct acpi_device_ops ops;
struct acpi_driver *driver; struct acpi_driver *driver;
void *driver_data; void *driver_data;
struct device dev; struct device dev;
struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */
enum acpi_bus_removal_type removal_type; /* indicate for different removal type */ enum acpi_bus_removal_type removal_type; /* indicate for different removal type */
u8 physical_node_count; u8 physical_node_count;
struct list_head physical_node_list; struct list_head physical_node_list;
...@@ -316,7 +306,7 @@ struct acpi_bus_event { ...@@ -316,7 +306,7 @@ struct acpi_bus_event {
}; };
struct acpi_eject_event { struct acpi_eject_event {
acpi_handle handle; struct acpi_device *device;
u32 event; u32 event;
}; };
...@@ -356,11 +346,9 @@ static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 ty ...@@ -356,11 +346,9 @@ static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 ty
#endif #endif
int acpi_bus_register_driver(struct acpi_driver *driver); int acpi_bus_register_driver(struct acpi_driver *driver);
void acpi_bus_unregister_driver(struct acpi_driver *driver); void acpi_bus_unregister_driver(struct acpi_driver *driver);
int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent, int acpi_bus_add(acpi_handle handle);
acpi_handle handle, int type);
void acpi_bus_hot_remove_device(void *context); void acpi_bus_hot_remove_device(void *context);
int acpi_bus_trim(struct acpi_device *start, int rmdevice); int acpi_bus_trim(struct acpi_device *start);
int acpi_bus_start(struct acpi_device *device);
acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd); acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
int acpi_match_device_ids(struct acpi_device *device, int acpi_match_device_ids(struct acpi_device *device,
const struct acpi_device_id *ids); const struct acpi_device_id *ids);
...@@ -390,6 +378,8 @@ struct acpi_bus_type { ...@@ -390,6 +378,8 @@ struct acpi_bus_type {
int (*find_device) (struct device *, acpi_handle *); int (*find_device) (struct device *, acpi_handle *);
/* For bridges, such as PCI root bridge, IDE controller */ /* For bridges, such as PCI root bridge, IDE controller */
int (*find_bridge) (struct device *, acpi_handle *); int (*find_bridge) (struct device *, acpi_handle *);
void (*setup)(struct device *);
void (*cleanup)(struct device *);
}; };
int register_acpi_bus_type(struct acpi_bus_type *); int register_acpi_bus_type(struct acpi_bus_type *);
int unregister_acpi_bus_type(struct acpi_bus_type *); int unregister_acpi_bus_type(struct acpi_bus_type *);
...@@ -397,7 +387,6 @@ int unregister_acpi_bus_type(struct acpi_bus_type *); ...@@ -397,7 +387,6 @@ int unregister_acpi_bus_type(struct acpi_bus_type *);
struct acpi_pci_root { struct acpi_pci_root {
struct list_head node; struct list_head node;
struct acpi_device * device; struct acpi_device * device;
struct acpi_pci_id id;
struct pci_bus *bus; struct pci_bus *bus;
u16 segment; u16 segment;
struct resource secondary; /* downstream bus range */ struct resource secondary; /* downstream bus range */
......
...@@ -526,9 +526,14 @@ static inline int acpi_subsys_resume_early(struct device *dev) { return 0; } ...@@ -526,9 +526,14 @@ static inline int acpi_subsys_resume_early(struct device *dev) { return 0; }
#endif #endif
#if defined(CONFIG_ACPI) && defined(CONFIG_PM) #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
int acpi_dev_pm_attach(struct device *dev, bool power_on); int acpi_dev_pm_attach(struct device *dev, bool power_on);
void acpi_dev_pm_detach(struct device *dev, bool power_off); void acpi_dev_pm_detach(struct device *dev, bool power_off);
#else #else
static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
{
return NULL;
}
static inline int acpi_dev_pm_attach(struct device *dev, bool power_on) static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
{ {
return -ENODEV; return -ENODEV;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment