Commit e8f71df7 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'acpi-cleanup'

* acpi-cleanup: (21 commits)
  ACPI / hotplug: Fix concurrency issues and memory leaks
  ACPI: Remove the use of CONFIG_ACPI_CONTAINER_MODULE
  ACPI / scan: Full transition to D3cold in acpi_device_unregister()
  ACPI / scan: Make acpi_bus_hot_remove_device() acquire the scan lock
  ACPI: Drop the container.h header file
  ACPI / Documentation: refer to correct file for acpi_platform_device_ids[] table
  ACPI / scan: Make container driver use struct acpi_scan_handler
  ACPI / scan: Remove useless #ifndef from acpi_eject_store()
  ACPI: Unbind ACPI drv when probe failed
  ACPI: sysfs eject support for ACPI scan handlers
  ACPI / scan: Follow priorities of IDs when matching scan handlers
  ACPI / PCI: pci_slot: replace printk(KERN_xxx) with pr_xxx()
  ACPI / dock: Fix acpi_bus_get_device() check in drivers/acpi/dock.c
  ACPI / scan: Clean up acpi_bus_get_parent()
  ACPI / platform: Use struct acpi_scan_handler for creating devices
  ACPI / PCI: Make PCI IRQ link driver use struct acpi_scan_handler
  ACPI / PCI: Make PCI root driver use struct acpi_scan_handler
  ACPI / scan: Introduce struct acpi_scan_handler
  ACPI / scan: Make scanning of fixed devices follow the general scheme
  ACPI: Drop device start operation that is not used
  ...
parents b34bf8e3 3757b948
...@@ -63,8 +63,8 @@ from ACPI tables. ...@@ -63,8 +63,8 @@ from ACPI tables.
Currently the kernel is not able to automatically determine from which ACPI Currently the kernel is not able to automatically determine from which ACPI
device it should make the corresponding platform device so we need to add device it should make the corresponding platform device so we need to add
the ACPI device explicitly to acpi_platform_device_ids list defined in the ACPI device explicitly to acpi_platform_device_ids list defined in
drivers/acpi/scan.c. This limitation is only for the platform devices, SPI drivers/acpi/acpi_platform.c. This limitation is only for the platform
and I2C devices are created automatically as described below. devices, SPI and I2C devices are created automatically as described below.
SPI serial bus support SPI serial bus support
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
......
ACPI Scan Handlers
Copyright (C) 2012, Intel Corporation
Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
During system initialization and ACPI-based device hot-add, the ACPI namespace
is scanned in search of device objects that generally represent various pieces
of hardware. This causes a struct acpi_device object to be created and
registered with the driver core for every device object in the ACPI namespace
and the hierarchy of those struct acpi_device objects reflects the namespace
layout (i.e. parent device objects in the namespace are represented by parent
struct acpi_device objects and analogously for their children). Those struct
acpi_device objects are referred to as "device nodes" in what follows, but they
should not be confused with struct device_node objects used by the Device Trees
parsing code (although their role is analogous to the role of those objects).
During ACPI-based device hot-remove device nodes representing pieces of hardware
being removed are unregistered and deleted.
The core ACPI namespace scanning code in drivers/acpi/scan.c carries out basic
initialization of device nodes, such as retrieving common configuration
information from the device objects represented by them and populating them with
appropriate data, but some of them require additional handling after they have
been registered. For example, if the given device node represents a PCI host
bridge, its registration should cause the PCI bus under that bridge to be
enumerated and PCI devices on that bus to be registered with the driver core.
Similarly, if the device node represents a PCI interrupt link, it is necessary
to configure that link so that the kernel can use it.
Those additional configuration tasks usually depend on the type of the hardware
component represented by the given device node which can be determined on the
basis of the device node's hardware ID (HID). They are performed by objects
called ACPI scan handlers represented by the following structure:
struct acpi_scan_handler {
const struct acpi_device_id *ids;
struct list_head list_node;
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
void (*detach)(struct acpi_device *dev);
};
where ids is the list of IDs of device nodes the given handler is supposed to
take care of, list_node is the hook to the global list of ACPI scan handlers
maintained by the ACPI core and the .attach() and .detach() callbacks are
executed, respectively, after registration of new device nodes and before
unregistration of device nodes the handler attached to previously.
The namespace scanning function, acpi_bus_scan(), first registers all of the
device nodes in the given namespace scope with the driver core. Then, it tries
to match a scan handler against each of them using the ids arrays of the
available scan handlers. If a matching scan handler is found, its .attach()
callback is executed for the given device node. If that callback returns 1,
that means that the handler has claimed the device node and is now responsible
for carrying out any additional configuration tasks related to it. It also will
be responsible for preparing the device node for unregistration in that case.
The device node's handler field is then populated with the address of the scan
handler that has claimed it.
If the .attach() callback returns 0, it means that the device node is not
interesting to the given scan handler and may be matched against the next scan
handler in the list. If it returns a (negative) error code, that means that
the namespace scan should be terminated due to a serious error. The error code
returned should then reflect the type of the error.
The namespace trimming function, acpi_bus_trim(), first executes .detach()
callbacks from the scan handlers of all device nodes in the given namespace
scope (if they have scan handlers). Next, it unregisters all of the device
nodes in that scope.
ACPI scan handlers can be added to the list maintained by the ACPI core with the
help of the acpi_scan_add_handler() function taking a pointer to the new scan
handler as an argument. The order in which scan handlers are added to the list
is the order in which they are matched against device nodes during namespace
scans.
All scan handles must be added to the list before acpi_bus_scan() is run for the
first time and they cannot be removed from it.
...@@ -191,7 +191,7 @@ static int aml_nfw_add(struct acpi_device *device) ...@@ -191,7 +191,7 @@ static int aml_nfw_add(struct acpi_device *device)
return aml_nfw_add_global_handler(); return aml_nfw_add_global_handler();
} }
static int aml_nfw_remove(struct acpi_device *device, int type) static int aml_nfw_remove(struct acpi_device *device)
{ {
return aml_nfw_remove_global_handler(); return aml_nfw_remove_global_handler();
} }
......
...@@ -195,7 +195,7 @@ static int xo15_sci_add(struct acpi_device *device) ...@@ -195,7 +195,7 @@ static int xo15_sci_add(struct acpi_device *device)
return r; return r;
} }
static int xo15_sci_remove(struct acpi_device *device, int type) static int xo15_sci_remove(struct acpi_device *device)
{ {
acpi_disable_gpe(NULL, xo15_sci_gpe); acpi_disable_gpe(NULL, xo15_sci_gpe);
acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler); acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
......
...@@ -337,7 +337,7 @@ config X86_PM_TIMER ...@@ -337,7 +337,7 @@ config X86_PM_TIMER
systems require this timer. systems require this timer.
config ACPI_CONTAINER config ACPI_CONTAINER
tristate "Container and Module Devices (EXPERIMENTAL)" bool "Container and Module Devices (EXPERIMENTAL)"
depends on EXPERIMENTAL depends on EXPERIMENTAL
default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO) default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
help help
......
...@@ -60,7 +60,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file); ...@@ -60,7 +60,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file);
#endif #endif
static int acpi_ac_add(struct acpi_device *device); static int acpi_ac_add(struct acpi_device *device);
static int acpi_ac_remove(struct acpi_device *device, int type); static int acpi_ac_remove(struct acpi_device *device);
static void acpi_ac_notify(struct acpi_device *device, u32 event); static void acpi_ac_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id ac_device_ids[] = { static const struct acpi_device_id ac_device_ids[] = {
...@@ -337,7 +337,7 @@ static int acpi_ac_resume(struct device *dev) ...@@ -337,7 +337,7 @@ static int acpi_ac_resume(struct device *dev)
} }
#endif #endif
static int acpi_ac_remove(struct acpi_device *device, int type) static int acpi_ac_remove(struct acpi_device *device)
{ {
struct acpi_ac *ac = NULL; struct acpi_ac *ac = NULL;
......
...@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); ...@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL");
#define MEMORY_POWER_OFF_STATE 2 #define MEMORY_POWER_OFF_STATE 2
static int acpi_memory_device_add(struct acpi_device *device); static int acpi_memory_device_add(struct acpi_device *device);
static int acpi_memory_device_remove(struct acpi_device *device, int type); static int acpi_memory_device_remove(struct acpi_device *device);
static const struct acpi_device_id memory_device_ids[] = { static const struct acpi_device_id memory_device_ids[] = {
{ACPI_MEMORY_DEVICE_HID, 0}, {ACPI_MEMORY_DEVICE_HID, 0},
...@@ -153,14 +153,16 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) ...@@ -153,14 +153,16 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
return 0; return 0;
} }
static int 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)
{ {
struct acpi_device *device = NULL; struct acpi_device *device = NULL;
int result; int result = 0;
if (!acpi_bus_get_device(handle, &device) && device) acpi_scan_lock_acquire();
acpi_bus_get_device(handle, &device);
if (device)
goto end; goto end;
/* /*
...@@ -169,23 +171,28 @@ acpi_memory_get_device(acpi_handle handle, ...@@ -169,23 +171,28 @@ acpi_memory_get_device(acpi_handle handle,
*/ */
result = acpi_bus_scan(handle); result = acpi_bus_scan(handle);
if (result) { if (result) {
acpi_handle_warn(handle, "Cannot add acpi bus\n"); acpi_handle_warn(handle, "ACPI namespace scan failed\n");
return -EINVAL; result = -EINVAL;
goto out;
} }
result = acpi_bus_get_device(handle, &device); result = acpi_bus_get_device(handle, &device);
if (result) { if (result) {
acpi_handle_warn(handle, "Missing device object\n"); acpi_handle_warn(handle, "Missing device object\n");
return -EINVAL; result = -EINVAL;
goto out;
} }
end: end:
*mem_device = acpi_driver_data(device); *mem_device = acpi_driver_data(device);
if (!(*mem_device)) { if (!(*mem_device)) {
dev_err(&device->dev, "driver data not found\n"); dev_err(&device->dev, "driver data not found\n");
return -ENODEV; result = -ENODEV;
goto out;
} }
return 0; out:
acpi_scan_lock_release();
return result;
} }
static int acpi_memory_check_device(struct acpi_memory_device *mem_device) static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
...@@ -305,6 +312,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) ...@@ -305,6 +312,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
struct acpi_device *device; struct acpi_device *device;
struct acpi_eject_event *ej_event = NULL; struct acpi_eject_event *ej_event = NULL;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
acpi_status status;
switch (event) { switch (event) {
case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_BUS_CHECK:
...@@ -327,29 +335,40 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) ...@@ -327,29 +335,40 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"\nReceived EJECT REQUEST notification for device\n")); "\nReceived EJECT REQUEST notification for device\n"));
status = AE_ERROR;
acpi_scan_lock_acquire();
if (acpi_bus_get_device(handle, &device)) { if (acpi_bus_get_device(handle, &device)) {
acpi_handle_err(handle, "Device doesn't exist\n"); acpi_handle_err(handle, "Device doesn't exist\n");
break; goto unlock;
} }
mem_device = acpi_driver_data(device); mem_device = acpi_driver_data(device);
if (!mem_device) { if (!mem_device) {
acpi_handle_err(handle, "Driver Data is NULL\n"); acpi_handle_err(handle, "Driver Data is NULL\n");
break; goto unlock;
} }
ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
if (!ej_event) { if (!ej_event) {
pr_err(PREFIX "No memory, dropping EJECT\n"); pr_err(PREFIX "No memory, dropping EJECT\n");
break; goto unlock;
} }
get_device(&device->dev);
ej_event->device = device; 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, /* The eject is carried out asynchronously. */
(void *)ej_event); status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
ej_event);
if (ACPI_FAILURE(status)) {
put_device(&device->dev);
kfree(ej_event);
}
/* eject is performed asynchronously */ unlock:
return; acpi_scan_lock_release();
if (ACPI_SUCCESS(status))
return;
default: default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event)); "Unsupported event [0x%x]\n", event));
...@@ -360,7 +379,6 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) ...@@ -360,7 +379,6 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
/* Inform firmware that the hotplug operation has completed */ /* Inform firmware that the hotplug operation has completed */
(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
return;
} }
static void acpi_memory_device_free(struct acpi_memory_device *mem_device) static void acpi_memory_device_free(struct acpi_memory_device *mem_device)
...@@ -415,7 +433,7 @@ static int acpi_memory_device_add(struct acpi_device *device) ...@@ -415,7 +433,7 @@ static int acpi_memory_device_add(struct acpi_device *device)
return result; return result;
} }
static int acpi_memory_device_remove(struct acpi_device *device, int type) static int acpi_memory_device_remove(struct acpi_device *device)
{ {
struct acpi_memory_device *mem_device = NULL; struct acpi_memory_device *mem_device = NULL;
int result; int result;
......
...@@ -482,8 +482,7 @@ static int acpi_pad_add(struct acpi_device *device) ...@@ -482,8 +482,7 @@ static int acpi_pad_add(struct acpi_device *device)
return 0; return 0;
} }
static int acpi_pad_remove(struct acpi_device *device, static int acpi_pad_remove(struct acpi_device *device)
int type)
{ {
mutex_lock(&isolated_cpus_lock); mutex_lock(&isolated_cpus_lock);
acpi_pad_idle_cpus(0); acpi_pad_idle_cpus(0);
......
...@@ -22,6 +22,30 @@ ...@@ -22,6 +22,30 @@
ACPI_MODULE_NAME("platform"); ACPI_MODULE_NAME("platform");
/* Flags for acpi_create_platform_device */
#define ACPI_PLATFORM_CLK BIT(0)
/*
* The following ACPI IDs are known to be suitable for representing as
* platform devices.
*/
static const struct acpi_device_id acpi_platform_device_ids[] = {
{ "PNP0D40" },
/* Haswell LPSS devices */
{ "INT33C0", ACPI_PLATFORM_CLK },
{ "INT33C1", ACPI_PLATFORM_CLK },
{ "INT33C2", ACPI_PLATFORM_CLK },
{ "INT33C3", ACPI_PLATFORM_CLK },
{ "INT33C4", ACPI_PLATFORM_CLK },
{ "INT33C5", ACPI_PLATFORM_CLK },
{ "INT33C6", ACPI_PLATFORM_CLK },
{ "INT33C7", ACPI_PLATFORM_CLK },
{ }
};
static int acpi_create_platform_clks(struct acpi_device *adev) static int acpi_create_platform_clks(struct acpi_device *adev)
{ {
static struct platform_device *pdev; static struct platform_device *pdev;
...@@ -39,8 +63,7 @@ static int acpi_create_platform_clks(struct acpi_device *adev) ...@@ -39,8 +63,7 @@ static int acpi_create_platform_clks(struct acpi_device *adev)
/** /**
* acpi_create_platform_device - Create platform device for ACPI device node * acpi_create_platform_device - Create platform device for ACPI device node
* @adev: ACPI device node to create a platform device for. * @adev: ACPI device node to create a platform device for.
* @flags: ACPI_PLATFORM_* flags that affect the creation of the platform * @id: ACPI device ID used to match @adev.
* devices.
* *
* Check if the given @adev can be represented as a platform device and, if * Check if the given @adev can be represented as a platform device and, if
* that's the case, create and register a platform device, populate its common * that's the case, create and register a platform device, populate its common
...@@ -48,9 +71,10 @@ static int acpi_create_platform_clks(struct acpi_device *adev) ...@@ -48,9 +71,10 @@ static int acpi_create_platform_clks(struct acpi_device *adev)
* *
* Name of the platform device will be the same as @adev's. * Name of the platform device will be the same as @adev's.
*/ */
struct platform_device *acpi_create_platform_device(struct acpi_device *adev, static int acpi_create_platform_device(struct acpi_device *adev,
unsigned long flags) const struct acpi_device_id *id)
{ {
unsigned long flags = id->driver_data;
struct platform_device *pdev = NULL; struct platform_device *pdev = NULL;
struct acpi_device *acpi_parent; struct acpi_device *acpi_parent;
struct platform_device_info pdevinfo; struct platform_device_info pdevinfo;
...@@ -59,25 +83,28 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, ...@@ -59,25 +83,28 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
struct resource *resources; struct resource *resources;
int count; int count;
if ((flags & ACPI_PLATFORM_CLK) && acpi_create_platform_clks(adev)) { if (flags & ACPI_PLATFORM_CLK) {
dev_err(&adev->dev, "failed to create clocks\n"); int ret = acpi_create_platform_clks(adev);
return NULL; if (ret) {
dev_err(&adev->dev, "failed to create clocks\n");
return ret;
}
} }
/* If the ACPI node already has a physical device attached, skip it. */ /* If the ACPI node already has a physical device attached, skip it. */
if (adev->physical_node_count) if (adev->physical_node_count)
return NULL; return 0;
INIT_LIST_HEAD(&resource_list); INIT_LIST_HEAD(&resource_list);
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
if (count <= 0) if (count <= 0)
return NULL; return 0;
resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL);
if (!resources) { if (!resources) {
dev_err(&adev->dev, "No memory for resources\n"); dev_err(&adev->dev, "No memory for resources\n");
acpi_dev_free_resource_list(&resource_list); acpi_dev_free_resource_list(&resource_list);
return NULL; return -ENOMEM;
} }
count = 0; count = 0;
list_for_each_entry(rentry, &resource_list, node) list_for_each_entry(rentry, &resource_list, node)
...@@ -123,5 +150,15 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, ...@@ -123,5 +150,15 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
} }
kfree(resources); kfree(resources);
return pdev; return 1;
}
static struct acpi_scan_handler platform_handler = {
.ids = acpi_platform_device_ids,
.attach = acpi_create_platform_device,
};
void __init acpi_platform_init(void)
{
acpi_scan_add_handler(&platform_handler);
} }
...@@ -1111,7 +1111,7 @@ static int acpi_battery_add(struct acpi_device *device) ...@@ -1111,7 +1111,7 @@ static int acpi_battery_add(struct acpi_device *device)
return result; return result;
} }
static int acpi_battery_remove(struct acpi_device *device, int type) static int acpi_battery_remove(struct acpi_device *device)
{ {
struct acpi_battery *battery = NULL; struct acpi_battery *battery = NULL;
......
...@@ -75,7 +75,7 @@ static const struct acpi_device_id button_device_ids[] = { ...@@ -75,7 +75,7 @@ static const struct acpi_device_id button_device_ids[] = {
MODULE_DEVICE_TABLE(acpi, button_device_ids); MODULE_DEVICE_TABLE(acpi, button_device_ids);
static int acpi_button_add(struct acpi_device *device); static int acpi_button_add(struct acpi_device *device);
static int acpi_button_remove(struct acpi_device *device, int type); static int acpi_button_remove(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event); static void acpi_button_notify(struct acpi_device *device, u32 event);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
...@@ -433,7 +433,7 @@ static int acpi_button_add(struct acpi_device *device) ...@@ -433,7 +433,7 @@ static int acpi_button_add(struct acpi_device *device)
return error; return error;
} }
static int acpi_button_remove(struct acpi_device *device, int type) static int acpi_button_remove(struct acpi_device *device)
{ {
struct acpi_button *button = acpi_driver_data(device); struct acpi_button *button = acpi_driver_data(device);
......
...@@ -34,46 +34,34 @@ ...@@ -34,46 +34,34 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
#include <acpi/container.h>
#define PREFIX "ACPI: " #define PREFIX "ACPI: "
#define ACPI_CONTAINER_DEVICE_NAME "ACPI container device"
#define ACPI_CONTAINER_CLASS "container"
#define INSTALL_NOTIFY_HANDLER 1
#define UNINSTALL_NOTIFY_HANDLER 2
#define _COMPONENT ACPI_CONTAINER_COMPONENT #define _COMPONENT ACPI_CONTAINER_COMPONENT
ACPI_MODULE_NAME("container"); ACPI_MODULE_NAME("container");
MODULE_AUTHOR("Anil S Keshavamurthy");
MODULE_DESCRIPTION("ACPI container driver");
MODULE_LICENSE("GPL");
static int acpi_container_add(struct acpi_device *device);
static int acpi_container_remove(struct acpi_device *device, int type);
static const struct acpi_device_id container_device_ids[] = { static const struct acpi_device_id container_device_ids[] = {
{"ACPI0004", 0}, {"ACPI0004", 0},
{"PNP0A05", 0}, {"PNP0A05", 0},
{"PNP0A06", 0}, {"PNP0A06", 0},
{"", 0}, {"", 0},
}; };
MODULE_DEVICE_TABLE(acpi, container_device_ids);
static struct acpi_driver acpi_container_driver = { static int container_device_attach(struct acpi_device *device,
.name = "container", const struct acpi_device_id *not_used)
.class = ACPI_CONTAINER_CLASS, {
/*
* FIXME: This is necessary, so that acpi_eject_store() doesn't return
* -ENODEV for containers.
*/
return 1;
}
static struct acpi_scan_handler container_device_handler = {
.ids = container_device_ids, .ids = container_device_ids,
.ops = { .attach = container_device_attach,
.add = acpi_container_add,
.remove = acpi_container_remove,
},
}; };
/*******************************************************************/
static int is_device_present(acpi_handle handle) static int is_device_present(acpi_handle handle)
{ {
acpi_handle temp; acpi_handle temp;
...@@ -92,49 +80,6 @@ static int is_device_present(acpi_handle handle) ...@@ -92,49 +80,6 @@ static int is_device_present(acpi_handle handle)
return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT); return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT);
} }
static bool is_container_device(const char *hid)
{
const struct acpi_device_id *container_id;
for (container_id = container_device_ids;
container_id->id[0]; container_id++) {
if (!strcmp((char *)container_id->id, hid))
return true;
}
return false;
}
/*******************************************************************/
static int acpi_container_add(struct acpi_device *device)
{
struct acpi_container *container;
container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL);
if (!container)
return -ENOMEM;
container->handle = device->handle;
strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
device->driver_data = container;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",
acpi_device_name(device), acpi_device_bid(device)));
return 0;
}
static int acpi_container_remove(struct acpi_device *device, int type)
{
acpi_status status = AE_OK;
struct acpi_container *pc = NULL;
pc = acpi_driver_data(device);
kfree(pc);
return status;
}
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;
...@@ -143,6 +88,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) ...@@ -143,6 +88,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
acpi_status status; acpi_status status;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
acpi_scan_lock_acquire();
switch (type) { switch (type) {
case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_BUS_CHECK:
/* Fall through */ /* Fall through */
...@@ -158,7 +105,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) ...@@ -158,7 +105,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
/* device exist and this is a remove request */ /* device exist and this is a remove request */
device->flags.eject_pending = 1; device->flags.eject_pending = 1;
kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
return; goto out;
} }
break; break;
} }
...@@ -185,98 +132,59 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) ...@@ -185,98 +132,59 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
if (!acpi_bus_get_device(handle, &device) && device) { if (!acpi_bus_get_device(handle, &device) && device) {
device->flags.eject_pending = 1; device->flags.eject_pending = 1;
kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
return; goto out;
} }
break; break;
default: default:
/* non-hotplug event; possibly handled by other handler */ /* non-hotplug event; possibly handled by other handler */
return; goto out;
} }
/* Inform firmware that the hotplug operation has completed */ /* Inform firmware that the hotplug operation has completed */
(void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); (void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
return;
out:
acpi_scan_lock_release();
} }
static acpi_status static bool is_container(acpi_handle handle)
container_walk_namespace_cb(acpi_handle handle,
u32 lvl, void *context, void **rv)
{ {
char *hid = NULL;
struct acpi_device_info *info; struct acpi_device_info *info;
acpi_status status; bool ret = false;
int *action = context;
status = acpi_get_object_info(handle, &info); if (ACPI_FAILURE(acpi_get_object_info(handle, &info)))
if (ACPI_FAILURE(status)) { return false;
return AE_OK;
}
if (info->valid & ACPI_VALID_HID)
hid = info->hardware_id.string;
if (hid == NULL) {
goto end;
}
if (!is_container_device(hid)) if (info->valid & ACPI_VALID_HID) {
goto end; const struct acpi_device_id *id;
switch (*action) { for (id = container_device_ids; id->id[0]; id++) {
case INSTALL_NOTIFY_HANDLER: ret = !strcmp((char *)id->id, info->hardware_id.string);
acpi_install_notify_handler(handle, if (ret)
ACPI_SYSTEM_NOTIFY, break;
container_notify_cb, NULL); }
break;
case UNINSTALL_NOTIFY_HANDLER:
acpi_remove_notify_handler(handle,
ACPI_SYSTEM_NOTIFY,
container_notify_cb);
break;
default:
break;
} }
end:
kfree(info); kfree(info);
return ret;
return AE_OK;
} }
static int __init acpi_container_init(void) static acpi_status acpi_container_register_notify_handler(acpi_handle handle,
u32 lvl, void *ctxt,
void **retv)
{ {
int result = 0; if (is_container(handle))
int action = INSTALL_NOTIFY_HANDLER; acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
container_notify_cb, NULL);
result = acpi_bus_register_driver(&acpi_container_driver);
if (result < 0) {
return (result);
}
/* register notify handler to every container device */
acpi_walk_namespace(ACPI_TYPE_DEVICE,
ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX,
container_walk_namespace_cb, NULL, &action, NULL);
return (0); return AE_OK;
} }
static void __exit acpi_container_exit(void) void __init acpi_container_init(void)
{ {
int action = UNINSTALL_NOTIFY_HANDLER; acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
acpi_container_register_notify_handler, NULL,
NULL, NULL);
acpi_walk_namespace(ACPI_TYPE_DEVICE, acpi_scan_add_handler(&container_device_handler);
ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX,
container_walk_namespace_cb, NULL, &action, NULL);
acpi_bus_unregister_driver(&acpi_container_driver);
return;
} }
module_init(acpi_container_init);
module_exit(acpi_container_exit);
...@@ -744,7 +744,9 @@ static void acpi_dock_deferred_cb(void *context) ...@@ -744,7 +744,9 @@ static void acpi_dock_deferred_cb(void *context)
{ {
struct dock_data *data = context; struct dock_data *data = context;
acpi_scan_lock_acquire();
dock_notify(data->handle, data->event, data->ds); dock_notify(data->handle, data->event, data->ds);
acpi_scan_lock_release();
kfree(data); kfree(data);
} }
...@@ -757,20 +759,31 @@ static int acpi_dock_notifier_call(struct notifier_block *this, ...@@ -757,20 +759,31 @@ static int acpi_dock_notifier_call(struct notifier_block *this,
if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
&& event != ACPI_NOTIFY_EJECT_REQUEST) && event != ACPI_NOTIFY_EJECT_REQUEST)
return 0; return 0;
acpi_scan_lock_acquire();
list_for_each_entry(dock_station, &dock_stations, sibling) { list_for_each_entry(dock_station, &dock_stations, sibling) {
if (dock_station->handle == handle) { if (dock_station->handle == handle) {
struct dock_data *dd; struct dock_data *dd;
acpi_status status;
dd = kmalloc(sizeof(*dd), GFP_KERNEL); dd = kmalloc(sizeof(*dd), GFP_KERNEL);
if (!dd) if (!dd)
return 0; break;
dd->handle = handle; dd->handle = handle;
dd->event = event; dd->event = event;
dd->ds = dock_station; dd->ds = dock_station;
acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); status = acpi_os_hotplug_execute(acpi_dock_deferred_cb,
return 0 ; dd);
if (ACPI_FAILURE(status))
kfree(dd);
break;
} }
} }
acpi_scan_lock_release();
return 0; return 0;
} }
...@@ -825,7 +838,7 @@ static ssize_t show_docked(struct device *dev, ...@@ -825,7 +838,7 @@ static ssize_t show_docked(struct device *dev,
struct dock_station *dock_station = dev->platform_data; struct dock_station *dock_station = dev->platform_data;
if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp))) if (!acpi_bus_get_device(dock_station->handle, &tmp))
return snprintf(buf, PAGE_SIZE, "1\n"); return snprintf(buf, PAGE_SIZE, "1\n");
return snprintf(buf, PAGE_SIZE, "0\n"); return snprintf(buf, PAGE_SIZE, "0\n");
} }
......
...@@ -852,7 +852,7 @@ static int acpi_ec_add(struct acpi_device *device) ...@@ -852,7 +852,7 @@ static int acpi_ec_add(struct acpi_device *device)
return ret; return ret;
} }
static int acpi_ec_remove(struct acpi_device *device, int type) static int acpi_ec_remove(struct acpi_device *device)
{ {
struct acpi_ec *ec; struct acpi_ec *ec;
struct acpi_ec_query_handler *handler, *tmp; struct acpi_ec_query_handler *handler, *tmp;
......
...@@ -45,7 +45,7 @@ MODULE_DESCRIPTION("ACPI Fan Driver"); ...@@ -45,7 +45,7 @@ MODULE_DESCRIPTION("ACPI Fan Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static int acpi_fan_add(struct acpi_device *device); static int acpi_fan_add(struct acpi_device *device);
static int acpi_fan_remove(struct acpi_device *device, int type); static int acpi_fan_remove(struct acpi_device *device);
static const struct acpi_device_id fan_device_ids[] = { static const struct acpi_device_id fan_device_ids[] = {
{"PNP0C0B", 0}, {"PNP0C0B", 0},
...@@ -172,7 +172,7 @@ static int acpi_fan_add(struct acpi_device *device) ...@@ -172,7 +172,7 @@ static int acpi_fan_add(struct acpi_device *device)
return result; return result;
} }
static int acpi_fan_remove(struct acpi_device *device, int type) static int acpi_fan_remove(struct acpi_device *device)
{ {
struct thermal_cooling_device *cdev = acpi_driver_data(device); struct thermal_cooling_device *cdev = acpi_driver_data(device);
......
...@@ -70,7 +70,7 @@ static int acpi_hed_add(struct acpi_device *device) ...@@ -70,7 +70,7 @@ static int acpi_hed_add(struct acpi_device *device)
return 0; return 0;
} }
static int acpi_hed_remove(struct acpi_device *device, int type) static int acpi_hed_remove(struct acpi_device *device)
{ {
hed_handle = NULL; hed_handle = NULL;
return 0; return 0;
......
...@@ -25,8 +25,16 @@ ...@@ -25,8 +25,16 @@
int init_acpi_device_notify(void); int init_acpi_device_notify(void);
int acpi_scan_init(void); int acpi_scan_init(void);
void acpi_pci_root_init(void);
void acpi_pci_link_init(void);
void acpi_platform_init(void);
int acpi_sysfs_init(void); int acpi_sysfs_init(void);
void acpi_csrt_init(void); void acpi_csrt_init(void);
#ifdef CONFIG_ACPI_CONTAINER
void acpi_container_init(void);
#else
static inline void acpi_container_init(void) {}
#endif
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
extern struct dentry *acpi_debugfs_dir; extern struct dentry *acpi_debugfs_dir;
...@@ -86,7 +94,6 @@ struct acpi_ec { ...@@ -86,7 +94,6 @@ 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);
...@@ -118,10 +125,4 @@ static inline void suspend_nvs_restore(void) {} ...@@ -118,10 +125,4 @@ static inline void suspend_nvs_restore(void) {}
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
struct platform_device; struct platform_device;
/* Flags for acpi_create_platform_device */
#define ACPI_PLATFORM_CLK BIT(0)
struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
unsigned long flags);
#endif /* _ACPI_INTERNAL_H_ */ #endif /* _ACPI_INTERNAL_H_ */
...@@ -53,23 +53,19 @@ ACPI_MODULE_NAME("pci_link"); ...@@ -53,23 +53,19 @@ ACPI_MODULE_NAME("pci_link");
#define ACPI_PCI_LINK_FILE_STATUS "state" #define ACPI_PCI_LINK_FILE_STATUS "state"
#define ACPI_PCI_LINK_MAX_POSSIBLE 16 #define ACPI_PCI_LINK_MAX_POSSIBLE 16
static int acpi_pci_link_add(struct acpi_device *device); static int acpi_pci_link_add(struct acpi_device *device,
static int acpi_pci_link_remove(struct acpi_device *device, int type); const struct acpi_device_id *not_used);
static void acpi_pci_link_remove(struct acpi_device *device);
static const struct acpi_device_id link_device_ids[] = { static const struct acpi_device_id link_device_ids[] = {
{"PNP0C0F", 0}, {"PNP0C0F", 0},
{"", 0}, {"", 0},
}; };
MODULE_DEVICE_TABLE(acpi, link_device_ids);
static struct acpi_driver acpi_pci_link_driver = { static struct acpi_scan_handler pci_link_handler = {
.name = "pci_link",
.class = ACPI_PCI_LINK_CLASS,
.ids = link_device_ids, .ids = link_device_ids,
.ops = { .attach = acpi_pci_link_add,
.add = acpi_pci_link_add, .detach = acpi_pci_link_remove,
.remove = acpi_pci_link_remove,
},
}; };
/* /*
...@@ -692,7 +688,8 @@ int acpi_pci_link_free_irq(acpi_handle handle) ...@@ -692,7 +688,8 @@ int acpi_pci_link_free_irq(acpi_handle handle)
Driver Interface Driver Interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
static int acpi_pci_link_add(struct acpi_device *device) static int acpi_pci_link_add(struct acpi_device *device,
const struct acpi_device_id *not_used)
{ {
int result; int result;
struct acpi_pci_link *link; struct acpi_pci_link *link;
...@@ -746,7 +743,7 @@ static int acpi_pci_link_add(struct acpi_device *device) ...@@ -746,7 +743,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
if (result) if (result)
kfree(link); kfree(link);
return result; return result < 0 ? result : 1;
} }
static int acpi_pci_link_resume(struct acpi_pci_link *link) static int acpi_pci_link_resume(struct acpi_pci_link *link)
...@@ -766,7 +763,7 @@ static void irqrouter_resume(void) ...@@ -766,7 +763,7 @@ static void irqrouter_resume(void)
} }
} }
static int acpi_pci_link_remove(struct acpi_device *device, int type) static void acpi_pci_link_remove(struct acpi_device *device)
{ {
struct acpi_pci_link *link; struct acpi_pci_link *link;
...@@ -777,7 +774,6 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type) ...@@ -777,7 +774,6 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type)
mutex_unlock(&acpi_link_lock); mutex_unlock(&acpi_link_lock);
kfree(link); kfree(link);
return 0;
} }
/* /*
...@@ -874,20 +870,10 @@ static struct syscore_ops irqrouter_syscore_ops = { ...@@ -874,20 +870,10 @@ static struct syscore_ops irqrouter_syscore_ops = {
.resume = irqrouter_resume, .resume = irqrouter_resume,
}; };
static int __init irqrouter_init_ops(void) void __init acpi_pci_link_init(void)
{
if (!acpi_disabled && !acpi_noirq)
register_syscore_ops(&irqrouter_syscore_ops);
return 0;
}
device_initcall(irqrouter_init_ops);
static int __init acpi_pci_link_init(void)
{ {
if (acpi_noirq) if (acpi_noirq)
return 0; return;
if (acpi_irq_balance == -1) { if (acpi_irq_balance == -1) {
/* no command line switch: enable balancing in IOAPIC mode */ /* no command line switch: enable balancing in IOAPIC mode */
...@@ -896,11 +882,6 @@ static int __init acpi_pci_link_init(void) ...@@ -896,11 +882,6 @@ static int __init acpi_pci_link_init(void)
else else
acpi_irq_balance = 0; acpi_irq_balance = 0;
} }
register_syscore_ops(&irqrouter_syscore_ops);
if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0) acpi_scan_add_handler(&pci_link_handler);
return -ENODEV;
return 0;
} }
subsys_initcall(acpi_pci_link_init);
...@@ -45,8 +45,9 @@ ...@@ -45,8 +45,9 @@
ACPI_MODULE_NAME("pci_root"); ACPI_MODULE_NAME("pci_root");
#define ACPI_PCI_ROOT_CLASS "pci_bridge" #define ACPI_PCI_ROOT_CLASS "pci_bridge"
#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); const struct acpi_device_id *not_used);
static void acpi_pci_root_remove(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 \
...@@ -57,16 +58,11 @@ static const struct acpi_device_id root_device_ids[] = { ...@@ -57,16 +58,11 @@ static const struct acpi_device_id root_device_ids[] = {
{"PNP0A03", 0}, {"PNP0A03", 0},
{"", 0}, {"", 0},
}; };
MODULE_DEVICE_TABLE(acpi, root_device_ids);
static struct acpi_driver acpi_pci_root_driver = { static struct acpi_scan_handler pci_root_handler = {
.name = "pci_root",
.class = ACPI_PCI_ROOT_CLASS,
.ids = root_device_ids, .ids = root_device_ids,
.ops = { .attach = acpi_pci_root_add,
.add = acpi_pci_root_add, .detach = acpi_pci_root_remove,
.remove = acpi_pci_root_remove,
},
}; };
/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */ /* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */
...@@ -428,7 +424,8 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) ...@@ -428,7 +424,8 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
} }
EXPORT_SYMBOL(acpi_pci_osc_control_set); EXPORT_SYMBOL(acpi_pci_osc_control_set);
static int acpi_pci_root_add(struct acpi_device *device) static int acpi_pci_root_add(struct acpi_device *device,
const struct acpi_device_id *not_used)
{ {
unsigned long long segment, bus; unsigned long long segment, bus;
acpi_status status; acpi_status status;
...@@ -614,7 +611,7 @@ static int acpi_pci_root_add(struct acpi_device *device) ...@@ -614,7 +611,7 @@ static int acpi_pci_root_add(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 1;
out_del_root: out_del_root:
mutex_lock(&acpi_pci_root_lock); mutex_lock(&acpi_pci_root_lock);
...@@ -627,7 +624,7 @@ static int acpi_pci_root_add(struct acpi_device *device) ...@@ -627,7 +624,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
return result; return result;
} }
static int acpi_pci_root_remove(struct acpi_device *device, int type) static void acpi_pci_root_remove(struct acpi_device *device)
{ {
acpi_status status; acpi_status status;
acpi_handle handle; acpi_handle handle;
...@@ -655,19 +652,14 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) ...@@ -655,19 +652,14 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
list_del(&root->node); list_del(&root->node);
mutex_unlock(&acpi_pci_root_lock); mutex_unlock(&acpi_pci_root_lock);
kfree(root); kfree(root);
return 0;
} }
int __init acpi_pci_root_init(void) void __init acpi_pci_root_init(void)
{ {
acpi_hest_init(); acpi_hest_init();
if (acpi_pci_disabled) if (!acpi_pci_disabled) {
return 0; pci_acpi_crs_quirks();
acpi_scan_add_handler(&pci_root_handler);
pci_acpi_crs_quirks(); }
if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
return -ENODEV;
return 0;
} }
...@@ -50,13 +50,12 @@ module_param(debug, bool, 0644); ...@@ -50,13 +50,12 @@ module_param(debug, bool, 0644);
ACPI_MODULE_NAME("pci_slot"); ACPI_MODULE_NAME("pci_slot");
#define MY_NAME "pci_slot" #define MY_NAME "pci_slot"
#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg) #define err(format, arg...) pr_err("%s: " format , MY_NAME , ## arg)
#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg) #define info(format, arg...) pr_info("%s: " format , MY_NAME , ## arg)
#define dbg(format, arg...) \ #define dbg(format, arg...) \
do { \ do { \
if (debug) \ if (debug) \
printk(KERN_DEBUG "%s: " format, \ pr_debug("%s: " format, MY_NAME , ## arg); \
MY_NAME , ## arg); \
} while (0) } while (0)
#define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */
......
...@@ -81,7 +81,7 @@ MODULE_DESCRIPTION("ACPI Processor Driver"); ...@@ -81,7 +81,7 @@ MODULE_DESCRIPTION("ACPI Processor Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static int acpi_processor_add(struct acpi_device *device); static int acpi_processor_add(struct acpi_device *device);
static int acpi_processor_remove(struct acpi_device *device, int type); static int acpi_processor_remove(struct acpi_device *device);
static void acpi_processor_notify(struct acpi_device *device, u32 event); static void acpi_processor_notify(struct acpi_device *device, u32 event);
static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr); static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr);
static int acpi_processor_handle_eject(struct acpi_processor *pr); static int acpi_processor_handle_eject(struct acpi_processor *pr);
...@@ -610,7 +610,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) ...@@ -610,7 +610,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
return result; return result;
} }
static int acpi_processor_remove(struct acpi_device *device, int type) static int acpi_processor_remove(struct acpi_device *device)
{ {
struct acpi_processor *pr = NULL; struct acpi_processor *pr = NULL;
...@@ -623,7 +623,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type) ...@@ -623,7 +623,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
if (pr->id >= nr_cpu_ids) if (pr->id >= nr_cpu_ids)
goto free; goto free;
if (type == ACPI_BUS_REMOVAL_EJECT) { if (device->removal_type == ACPI_BUS_REMOVAL_EJECT) {
if (acpi_processor_handle_eject(pr)) if (acpi_processor_handle_eject(pr))
return -EINVAL; return -EINVAL;
} }
...@@ -683,8 +683,11 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, ...@@ -683,8 +683,11 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
struct acpi_device *device = NULL; struct acpi_device *device = NULL;
struct acpi_eject_event *ej_event = NULL; struct acpi_eject_event *ej_event = NULL;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
acpi_status status;
int result; int result;
acpi_scan_lock_acquire();
switch (event) { switch (event) {
case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK: case ACPI_NOTIFY_DEVICE_CHECK:
...@@ -733,25 +736,32 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, ...@@ -733,25 +736,32 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
break; break;
} }
get_device(&device->dev);
ej_event->device = device; 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, /* The eject is carried out asynchronously. */
(void *)ej_event); status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
ej_event);
/* eject is performed asynchronously */ if (ACPI_FAILURE(status)) {
return; put_device(&device->dev);
kfree(ej_event);
break;
}
goto out;
default: default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event)); "Unsupported event [0x%x]\n", event));
/* non-hotplug event; possibly handled by other handler */ /* non-hotplug event; possibly handled by other handler */
return; goto out;
} }
/* Inform firmware that the hotplug operation has completed */ /* Inform firmware that the hotplug operation has completed */
(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
return;
out:
acpi_scan_lock_release();
} }
static acpi_status is_processor_device(acpi_handle handle) static acpi_status is_processor_device(acpi_handle handle)
......
...@@ -130,7 +130,7 @@ struct acpi_sbs { ...@@ -130,7 +130,7 @@ struct acpi_sbs {
#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) #define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
static int acpi_sbs_remove(struct acpi_device *device, int type); static int acpi_sbs_remove(struct acpi_device *device);
static int acpi_battery_get_state(struct acpi_battery *battery); static int acpi_battery_get_state(struct acpi_battery *battery);
static inline int battery_scale(int log) static inline int battery_scale(int log)
...@@ -949,11 +949,11 @@ static int acpi_sbs_add(struct acpi_device *device) ...@@ -949,11 +949,11 @@ static int acpi_sbs_add(struct acpi_device *device)
acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs); acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
end: end:
if (result) if (result)
acpi_sbs_remove(device, 0); acpi_sbs_remove(device);
return result; return result;
} }
static int acpi_sbs_remove(struct acpi_device *device, int type) static int acpi_sbs_remove(struct acpi_device *device)
{ {
struct acpi_sbs *sbs; struct acpi_sbs *sbs;
int id; int id;
......
...@@ -33,7 +33,7 @@ struct acpi_smb_hc { ...@@ -33,7 +33,7 @@ struct acpi_smb_hc {
}; };
static int acpi_smbus_hc_add(struct acpi_device *device); static int acpi_smbus_hc_add(struct acpi_device *device);
static int acpi_smbus_hc_remove(struct acpi_device *device, int type); static int acpi_smbus_hc_remove(struct acpi_device *device);
static const struct acpi_device_id sbs_device_ids[] = { static const struct acpi_device_id sbs_device_ids[] = {
{"ACPI0001", 0}, {"ACPI0001", 0},
...@@ -296,7 +296,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device) ...@@ -296,7 +296,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
static int acpi_smbus_hc_remove(struct acpi_device *device, int type) static int acpi_smbus_hc_remove(struct acpi_device *device)
{ {
struct acpi_smb_hc *hc; struct acpi_smb_hc *hc;
......
This diff is collapsed.
...@@ -97,7 +97,7 @@ module_param(psv, int, 0644); ...@@ -97,7 +97,7 @@ module_param(psv, int, 0644);
MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type); static int acpi_thermal_remove(struct acpi_device *device);
static void acpi_thermal_notify(struct acpi_device *device, u32 event); static void acpi_thermal_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id thermal_device_ids[] = { static const struct acpi_device_id thermal_device_ids[] = {
...@@ -1111,7 +1111,7 @@ static int acpi_thermal_add(struct acpi_device *device) ...@@ -1111,7 +1111,7 @@ static int acpi_thermal_add(struct acpi_device *device)
return result; return result;
} }
static int acpi_thermal_remove(struct acpi_device *device, int type) static int acpi_thermal_remove(struct acpi_device *device)
{ {
struct acpi_thermal *tz = NULL; struct acpi_thermal *tz = NULL;
......
...@@ -88,7 +88,7 @@ module_param(use_bios_initial_backlight, bool, 0644); ...@@ -88,7 +88,7 @@ module_param(use_bios_initial_backlight, bool, 0644);
static int register_count = 0; static int register_count = 0;
static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device, int type); static int acpi_video_bus_remove(struct acpi_device *device);
static void acpi_video_bus_notify(struct acpi_device *device, u32 event); static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id video_device_ids[] = { static const struct acpi_device_id video_device_ids[] = {
...@@ -1740,7 +1740,7 @@ static int acpi_video_bus_add(struct acpi_device *device) ...@@ -1740,7 +1740,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
return error; return error;
} }
static int acpi_video_bus_remove(struct acpi_device *device, int type) static int acpi_video_bus_remove(struct acpi_device *device)
{ {
struct acpi_video_bus *video = NULL; struct acpi_video_bus *video = NULL;
......
...@@ -1041,7 +1041,7 @@ static int hpet_acpi_add(struct acpi_device *device) ...@@ -1041,7 +1041,7 @@ static int hpet_acpi_add(struct acpi_device *device)
return hpet_alloc(&data); return hpet_alloc(&data);
} }
static int hpet_acpi_remove(struct acpi_device *device, int type) static int hpet_acpi_remove(struct acpi_device *device)
{ {
/* XXX need to unregister clocksource, dealloc mem, etc */ /* XXX need to unregister clocksource, dealloc mem, etc */
return -EINVAL; return -EINVAL;
......
...@@ -1142,7 +1142,7 @@ static int sonypi_acpi_add(struct acpi_device *device) ...@@ -1142,7 +1142,7 @@ static int sonypi_acpi_add(struct acpi_device *device)
return 0; return 0;
} }
static int sonypi_acpi_remove(struct acpi_device *device, int type) static int sonypi_acpi_remove(struct acpi_device *device)
{ {
sonypi_acpi_device = NULL; sonypi_acpi_device = NULL;
return 0; return 0;
......
...@@ -911,7 +911,7 @@ static int acpi_power_meter_add(struct acpi_device *device) ...@@ -911,7 +911,7 @@ static int acpi_power_meter_add(struct acpi_device *device)
return res; return res;
} }
static int acpi_power_meter_remove(struct acpi_device *device, int type) static int acpi_power_meter_remove(struct acpi_device *device)
{ {
struct acpi_power_meter_resource *resource; struct acpi_power_meter_resource *resource;
......
...@@ -190,7 +190,7 @@ struct atk_acpi_input_buf { ...@@ -190,7 +190,7 @@ struct atk_acpi_input_buf {
}; };
static int atk_add(struct acpi_device *device); static int atk_add(struct acpi_device *device);
static int atk_remove(struct acpi_device *device, int type); static int atk_remove(struct acpi_device *device);
static void atk_print_sensor(struct atk_data *data, union acpi_object *obj); static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
static int atk_read_value(struct atk_sensor_data *sensor, u64 *value); static int atk_read_value(struct atk_sensor_data *sensor, u64 *value);
static void atk_free_sensors(struct atk_data *data); static void atk_free_sensors(struct atk_data *data);
...@@ -1416,7 +1416,7 @@ static int atk_add(struct acpi_device *device) ...@@ -1416,7 +1416,7 @@ static int atk_add(struct acpi_device *device)
return err; return err;
} }
static int atk_remove(struct acpi_device *device, int type) static int atk_remove(struct acpi_device *device)
{ {
struct atk_data *data = device->driver_data; struct atk_data *data = device->driver_data;
dev_dbg(&device->dev, "removing...\n"); dev_dbg(&device->dev, "removing...\n");
......
...@@ -406,7 +406,7 @@ static int acpi_smbus_cmi_add(struct acpi_device *device) ...@@ -406,7 +406,7 @@ static int acpi_smbus_cmi_add(struct acpi_device *device)
return -EIO; return -EIO;
} }
static int acpi_smbus_cmi_remove(struct acpi_device *device, int type) static int acpi_smbus_cmi_remove(struct acpi_device *device)
{ {
struct acpi_smbus_cmi *smbus_cmi = acpi_driver_data(device); struct acpi_smbus_cmi *smbus_cmi = acpi_driver_data(device);
......
...@@ -121,7 +121,7 @@ static int atlas_acpi_button_add(struct acpi_device *device) ...@@ -121,7 +121,7 @@ static int atlas_acpi_button_add(struct acpi_device *device)
return err; return err;
} }
static int atlas_acpi_button_remove(struct acpi_device *device, int type) static int atlas_acpi_button_remove(struct acpi_device *device)
{ {
acpi_status status; acpi_status status;
......
...@@ -1218,6 +1218,8 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) ...@@ -1218,6 +1218,8 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
handle = hp_work->handle; handle = hp_work->handle;
type = hp_work->type; type = hp_work->type;
acpi_scan_lock_acquire();
if (acpi_bus_get_device(handle, &device)) { if (acpi_bus_get_device(handle, &device)) {
/* This bridge must have just been physically inserted */ /* This bridge must have just been physically inserted */
handle_bridge_insertion(handle, type); handle_bridge_insertion(handle, type);
...@@ -1295,6 +1297,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) ...@@ -1295,6 +1297,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
} }
out: out:
acpi_scan_lock_release();
kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
} }
...@@ -1341,6 +1344,8 @@ static void _handle_hotplug_event_func(struct work_struct *work) ...@@ -1341,6 +1344,8 @@ static void _handle_hotplug_event_func(struct work_struct *work)
func = (struct acpiphp_func *)context; func = (struct acpiphp_func *)context;
acpi_scan_lock_acquire();
switch (type) { switch (type) {
case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_BUS_CHECK:
/* bus re-enumerate */ /* bus re-enumerate */
...@@ -1371,6 +1376,7 @@ static void _handle_hotplug_event_func(struct work_struct *work) ...@@ -1371,6 +1376,7 @@ static void _handle_hotplug_event_func(struct work_struct *work)
break; break;
} }
acpi_scan_lock_release();
kfree(hp_work); /* allocated in handle_hotplug_event_func */ kfree(hp_work); /* allocated in handle_hotplug_event_func */
} }
......
...@@ -425,6 +425,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -425,6 +425,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
pdevice = NULL; pdevice = NULL;
} }
acpi_scan_lock_acquire();
/* /*
* Walk the rootbus node's immediate children looking for * Walk the rootbus node's immediate children looking for
* the slot's device node(s). There can be more than * the slot's device node(s). There can be more than
...@@ -458,6 +459,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -458,6 +459,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
} }
} }
} }
acpi_scan_lock_release();
} }
/* Call the driver for the new device */ /* Call the driver for the new device */
...@@ -508,6 +510,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -508,6 +510,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
/* Get the rootbus node pointer */ /* Get the rootbus node pointer */
phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle;
acpi_scan_lock_acquire();
/* /*
* Walk the rootbus node's immediate children looking for * Walk the rootbus node's immediate children looking for
* the slot's device node(s). There can be more than * the slot's device node(s). There can be more than
...@@ -538,7 +541,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -538,7 +541,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
acpi_bus_trim(device); acpi_bus_trim(device);
} }
} }
acpi_scan_lock_release();
} }
/* Free the SN resources assigned to the Linux device.*/ /* Free the SN resources assigned to the Linux device.*/
......
...@@ -1910,7 +1910,7 @@ static int asus_acpi_add(struct acpi_device *device) ...@@ -1910,7 +1910,7 @@ static int asus_acpi_add(struct acpi_device *device)
return result; return result;
} }
static int asus_acpi_remove(struct acpi_device *device, int type) static int asus_acpi_remove(struct acpi_device *device)
{ {
struct asus_laptop *asus = acpi_driver_data(device); struct asus_laptop *asus = acpi_driver_data(device);
......
...@@ -432,7 +432,7 @@ static int cmpc_accel_add_v4(struct acpi_device *acpi) ...@@ -432,7 +432,7 @@ static int cmpc_accel_add_v4(struct acpi_device *acpi)
return error; return error;
} }
static int cmpc_accel_remove_v4(struct acpi_device *acpi, int type) static int cmpc_accel_remove_v4(struct acpi_device *acpi)
{ {
struct input_dev *inputdev; struct input_dev *inputdev;
struct cmpc_accel *accel; struct cmpc_accel *accel;
...@@ -668,7 +668,7 @@ static int cmpc_accel_add(struct acpi_device *acpi) ...@@ -668,7 +668,7 @@ static int cmpc_accel_add(struct acpi_device *acpi)
return error; return error;
} }
static int cmpc_accel_remove(struct acpi_device *acpi, int type) static int cmpc_accel_remove(struct acpi_device *acpi)
{ {
struct input_dev *inputdev; struct input_dev *inputdev;
struct cmpc_accel *accel; struct cmpc_accel *accel;
...@@ -753,7 +753,7 @@ static int cmpc_tablet_add(struct acpi_device *acpi) ...@@ -753,7 +753,7 @@ static int cmpc_tablet_add(struct acpi_device *acpi)
cmpc_tablet_idev_init); cmpc_tablet_idev_init);
} }
static int cmpc_tablet_remove(struct acpi_device *acpi, int type) static int cmpc_tablet_remove(struct acpi_device *acpi)
{ {
return cmpc_remove_acpi_notify_device(acpi); return cmpc_remove_acpi_notify_device(acpi);
} }
...@@ -1000,7 +1000,7 @@ static int cmpc_ipml_add(struct acpi_device *acpi) ...@@ -1000,7 +1000,7 @@ static int cmpc_ipml_add(struct acpi_device *acpi)
return retval; return retval;
} }
static int cmpc_ipml_remove(struct acpi_device *acpi, int type) static int cmpc_ipml_remove(struct acpi_device *acpi)
{ {
struct ipml200_dev *ipml; struct ipml200_dev *ipml;
...@@ -1079,7 +1079,7 @@ static int cmpc_keys_add(struct acpi_device *acpi) ...@@ -1079,7 +1079,7 @@ static int cmpc_keys_add(struct acpi_device *acpi)
cmpc_keys_idev_init); cmpc_keys_idev_init);
} }
static int cmpc_keys_remove(struct acpi_device *acpi, int type) static int cmpc_keys_remove(struct acpi_device *acpi)
{ {
return cmpc_remove_acpi_notify_device(acpi); return cmpc_remove_acpi_notify_device(acpi);
} }
......
...@@ -1501,7 +1501,7 @@ static int eeepc_acpi_add(struct acpi_device *device) ...@@ -1501,7 +1501,7 @@ static int eeepc_acpi_add(struct acpi_device *device)
return result; return result;
} }
static int eeepc_acpi_remove(struct acpi_device *device, int type) static int eeepc_acpi_remove(struct acpi_device *device)
{ {
struct eeepc_laptop *eeepc = acpi_driver_data(device); struct eeepc_laptop *eeepc = acpi_driver_data(device);
......
...@@ -733,7 +733,7 @@ static int acpi_fujitsu_add(struct acpi_device *device) ...@@ -733,7 +733,7 @@ static int acpi_fujitsu_add(struct acpi_device *device)
return result; return result;
} }
static int acpi_fujitsu_remove(struct acpi_device *device, int type) static int acpi_fujitsu_remove(struct acpi_device *device)
{ {
struct fujitsu_t *fujitsu = acpi_driver_data(device); struct fujitsu_t *fujitsu = acpi_driver_data(device);
struct input_dev *input = fujitsu->input; struct input_dev *input = fujitsu->input;
...@@ -938,7 +938,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) ...@@ -938,7 +938,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
return result; return result;
} }
static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) static int acpi_fujitsu_hotkey_remove(struct acpi_device *device)
{ {
struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device); struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device);
struct input_dev *input = fujitsu_hotkey->input; struct input_dev *input = fujitsu_hotkey->input;
......
...@@ -431,7 +431,7 @@ static int acpi_fujitsu_add(struct acpi_device *adev) ...@@ -431,7 +431,7 @@ static int acpi_fujitsu_add(struct acpi_device *adev)
return 0; return 0;
} }
static int acpi_fujitsu_remove(struct acpi_device *adev, int type) static int acpi_fujitsu_remove(struct acpi_device *adev)
{ {
free_irq(fujitsu.irq, fujitsu_interrupt); free_irq(fujitsu.irq, fujitsu_interrupt);
release_region(fujitsu.io_base, fujitsu.io_length); release_region(fujitsu.io_base, fujitsu.io_length);
......
...@@ -337,7 +337,7 @@ static int lis3lv02d_add(struct acpi_device *device) ...@@ -337,7 +337,7 @@ static int lis3lv02d_add(struct acpi_device *device)
return ret; return ret;
} }
static int lis3lv02d_remove(struct acpi_device *device, int type) static int lis3lv02d_remove(struct acpi_device *device)
{ {
if (!device) if (!device)
return -EINVAL; return -EINVAL;
......
...@@ -834,7 +834,7 @@ static int ideapad_acpi_add(struct acpi_device *adevice) ...@@ -834,7 +834,7 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
return ret; return ret;
} }
static int ideapad_acpi_remove(struct acpi_device *adevice, int type) static int ideapad_acpi_remove(struct acpi_device *adevice)
{ {
struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
int i; int i;
......
...@@ -200,7 +200,7 @@ static int intel_menlow_memory_add(struct acpi_device *device) ...@@ -200,7 +200,7 @@ static int intel_menlow_memory_add(struct acpi_device *device)
} }
static int intel_menlow_memory_remove(struct acpi_device *device, int type) static int intel_menlow_memory_remove(struct acpi_device *device)
{ {
struct thermal_cooling_device *cdev = acpi_driver_data(device); struct thermal_cooling_device *cdev = acpi_driver_data(device);
......
...@@ -176,7 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0, ...@@ -176,7 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0,
/* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */ /* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */
static int acpi_pcc_hotkey_add(struct acpi_device *device); static int acpi_pcc_hotkey_add(struct acpi_device *device);
static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type); static int acpi_pcc_hotkey_remove(struct acpi_device *device);
static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event); static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id pcc_device_ids[] = { static const struct acpi_device_id pcc_device_ids[] = {
...@@ -663,7 +663,7 @@ static int __init acpi_pcc_init(void) ...@@ -663,7 +663,7 @@ static int __init acpi_pcc_init(void)
return 0; return 0;
} }
static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) static int acpi_pcc_hotkey_remove(struct acpi_device *device)
{ {
struct pcc_acpi *pcc = acpi_driver_data(device); struct pcc_acpi *pcc = acpi_driver_data(device);
......
...@@ -2740,7 +2740,7 @@ static int sony_nc_add(struct acpi_device *device) ...@@ -2740,7 +2740,7 @@ static int sony_nc_add(struct acpi_device *device)
return result; return result;
} }
static int sony_nc_remove(struct acpi_device *device, int type) static int sony_nc_remove(struct acpi_device *device)
{ {
struct sony_nc_value *item; struct sony_nc_value *item;
...@@ -4111,7 +4111,7 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) ...@@ -4111,7 +4111,7 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
* ACPI driver * ACPI driver
* *
*****************/ *****************/
static int sony_pic_remove(struct acpi_device *device, int type) static int sony_pic_remove(struct acpi_device *device)
{ {
struct sony_pic_ioport *io, *tmp_io; struct sony_pic_ioport *io, *tmp_io;
struct sony_pic_irq *irq, *tmp_irq; struct sony_pic_irq *irq, *tmp_irq;
......
...@@ -157,7 +157,7 @@ static int acpi_topstar_add(struct acpi_device *device) ...@@ -157,7 +157,7 @@ static int acpi_topstar_add(struct acpi_device *device)
return -ENODEV; return -ENODEV;
} }
static int acpi_topstar_remove(struct acpi_device *device, int type) static int acpi_topstar_remove(struct acpi_device *device)
{ {
struct topstar_hkey *tps_hkey = acpi_driver_data(device); struct topstar_hkey *tps_hkey = acpi_driver_data(device);
......
...@@ -1118,7 +1118,7 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev) ...@@ -1118,7 +1118,7 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev)
return 0; return 0;
} }
static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type) static int toshiba_acpi_remove(struct acpi_device *acpi_dev)
{ {
struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
...@@ -1250,7 +1250,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) ...@@ -1250,7 +1250,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
return 0; return 0;
error: error:
toshiba_acpi_remove(acpi_dev, 0); toshiba_acpi_remove(acpi_dev);
return ret; return ret;
} }
......
...@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); ...@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL");
static int toshiba_bt_rfkill_add(struct acpi_device *device); static int toshiba_bt_rfkill_add(struct acpi_device *device);
static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type); static int toshiba_bt_rfkill_remove(struct acpi_device *device);
static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id bt_device_ids[] = { static const struct acpi_device_id bt_device_ids[] = {
...@@ -122,7 +122,7 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) ...@@ -122,7 +122,7 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device)
return result; return result;
} }
static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type) static int toshiba_bt_rfkill_remove(struct acpi_device *device)
{ {
/* clean up */ /* clean up */
return 0; return 0;
......
...@@ -92,7 +92,7 @@ module_param(debug_dump_wdg, bool, 0444); ...@@ -92,7 +92,7 @@ module_param(debug_dump_wdg, bool, 0444);
MODULE_PARM_DESC(debug_dump_wdg, MODULE_PARM_DESC(debug_dump_wdg,
"Dump available WMI interfaces [0/1]"); "Dump available WMI interfaces [0/1]");
static int acpi_wmi_remove(struct acpi_device *device, int type); static int acpi_wmi_remove(struct acpi_device *device);
static int acpi_wmi_add(struct acpi_device *device); static int acpi_wmi_add(struct acpi_device *device);
static void acpi_wmi_notify(struct acpi_device *device, u32 event); static void acpi_wmi_notify(struct acpi_device *device, u32 event);
...@@ -917,7 +917,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event) ...@@ -917,7 +917,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event)
} }
} }
static int acpi_wmi_remove(struct acpi_device *device, int type) static int acpi_wmi_remove(struct acpi_device *device)
{ {
acpi_remove_address_space_handler(device->handle, acpi_remove_address_space_handler(device->handle,
ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler); ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
......
...@@ -150,7 +150,7 @@ static int ebook_switch_add(struct acpi_device *device) ...@@ -150,7 +150,7 @@ static int ebook_switch_add(struct acpi_device *device)
return error; return error;
} }
static int ebook_switch_remove(struct acpi_device *device, int type) static int ebook_switch_remove(struct acpi_device *device)
{ {
struct ebook_switch *button = acpi_driver_data(device); struct ebook_switch *button = acpi_driver_data(device);
......
...@@ -296,7 +296,7 @@ static int quickstart_acpi_add(struct acpi_device *device) ...@@ -296,7 +296,7 @@ static int quickstart_acpi_add(struct acpi_device *device)
return ret; return ret;
} }
static int quickstart_acpi_remove(struct acpi_device *device, int type) static int quickstart_acpi_remove(struct acpi_device *device)
{ {
acpi_status status; acpi_status status;
struct quickstart_acpi *quickstart; struct quickstart_acpi *quickstart;
......
...@@ -196,7 +196,7 @@ static int apple_bl_add(struct acpi_device *dev) ...@@ -196,7 +196,7 @@ static int apple_bl_add(struct acpi_device *dev)
return 0; return 0;
} }
static int apple_bl_remove(struct acpi_device *dev, int type) static int apple_bl_remove(struct acpi_device *dev)
{ {
backlight_device_unregister(apple_backlight_device); backlight_device_unregister(apple_backlight_device);
......
...@@ -140,8 +140,7 @@ static int acpi_pad_add(struct acpi_device *device) ...@@ -140,8 +140,7 @@ static int acpi_pad_add(struct acpi_device *device)
return 0; return 0;
} }
static int acpi_pad_remove(struct acpi_device *device, static int acpi_pad_remove(struct acpi_device *device)
int type)
{ {
mutex_lock(&xen_cpu_lock); mutex_lock(&xen_cpu_lock);
xen_acpi_pad_idle_cpus(0); xen_acpi_pad_idle_cpus(0);
......
...@@ -83,20 +83,30 @@ enum acpi_bus_device_type { ...@@ -83,20 +83,30 @@ enum acpi_bus_device_type {
struct acpi_driver; struct acpi_driver;
struct acpi_device; struct acpi_device;
/*
* ACPI Scan Handler
* -----------------
*/
struct acpi_scan_handler {
const struct acpi_device_id *ids;
struct list_head list_node;
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
void (*detach)(struct acpi_device *dev);
};
/* /*
* ACPI Driver * ACPI Driver
* ----------- * -----------
*/ */
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);
typedef int (*acpi_op_start) (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_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_notify notify; acpi_op_notify notify;
}; };
...@@ -271,6 +281,7 @@ struct acpi_device { ...@@ -271,6 +281,7 @@ 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_scan_handler *handler;
struct acpi_driver *driver; struct acpi_driver *driver;
void *driver_data; void *driver_data;
struct device dev; struct device dev;
...@@ -384,6 +395,10 @@ int acpi_bus_receive_event(struct acpi_bus_event *event); ...@@ -384,6 +395,10 @@ int acpi_bus_receive_event(struct acpi_bus_event *event);
static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
{ return 0; } { return 0; }
#endif #endif
void acpi_scan_lock_acquire(void);
void acpi_scan_lock_release(void);
int acpi_scan_add_handler(struct acpi_scan_handler *handler);
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_scan(acpi_handle handle); int acpi_bus_scan(acpi_handle handle);
......
#ifndef __ACPI_CONTAINER_H
#define __ACPI_CONTAINER_H
#include <linux/kernel.h>
struct acpi_container {
acpi_handle handle;
unsigned long sun;
int state;
};
#endif /* __ACPI_CONTAINER_H */
...@@ -363,8 +363,7 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, ...@@ -363,8 +363,7 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
#if defined(CONFIG_ACPI_HOTPLUG_CPU) && \ #if defined(CONFIG_ACPI_HOTPLUG_CPU) && \
(defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \
defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) && \ defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) && \
(defined(CONFIG_ACPI_CONTAINER) || \ defined(CONFIG_ACPI_CONTAINER)
defined(CONFIG_ACPI_CONTAINER_MODULE))
#define ACPI_HOTPLUG_OST #define ACPI_HOTPLUG_OST
#endif #endif
......
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