You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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 ...
This commit is contained in:
@@ -63,8 +63,8 @@ from ACPI tables.
|
||||
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
|
||||
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
|
||||
and I2C devices are created automatically as described below.
|
||||
drivers/acpi/acpi_platform.c. This limitation is only for the platform
|
||||
devices, SPI and I2C devices are created automatically as described below.
|
||||
|
||||
SPI serial bus support
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
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)
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ err_sysfs:
|
||||
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_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
|
||||
|
||||
@@ -337,7 +337,7 @@ config X86_PM_TIMER
|
||||
systems require this timer.
|
||||
|
||||
config ACPI_CONTAINER
|
||||
tristate "Container and Module Devices (EXPERIMENTAL)"
|
||||
bool "Container and Module Devices (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
|
||||
help
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file);
|
||||
#endif
|
||||
|
||||
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 const struct acpi_device_id ac_device_ids[] = {
|
||||
@@ -337,7 +337,7 @@ static int acpi_ac_resume(struct device *dev)
|
||||
}
|
||||
#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;
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL");
|
||||
#define MEMORY_POWER_OFF_STATE 2
|
||||
|
||||
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[] = {
|
||||
{ACPI_MEMORY_DEVICE_HID, 0},
|
||||
@@ -153,14 +153,16 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_memory_get_device(acpi_handle handle,
|
||||
struct acpi_memory_device **mem_device)
|
||||
static int acpi_memory_get_device(acpi_handle handle,
|
||||
struct acpi_memory_device **mem_device)
|
||||
{
|
||||
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;
|
||||
|
||||
/*
|
||||
@@ -169,23 +171,28 @@ acpi_memory_get_device(acpi_handle handle,
|
||||
*/
|
||||
result = acpi_bus_scan(handle);
|
||||
if (result) {
|
||||
acpi_handle_warn(handle, "Cannot add acpi bus\n");
|
||||
return -EINVAL;
|
||||
acpi_handle_warn(handle, "ACPI namespace scan failed\n");
|
||||
result = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
result = acpi_bus_get_device(handle, &device);
|
||||
if (result) {
|
||||
acpi_handle_warn(handle, "Missing device object\n");
|
||||
return -EINVAL;
|
||||
result = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
end:
|
||||
end:
|
||||
*mem_device = acpi_driver_data(device);
|
||||
if (!(*mem_device)) {
|
||||
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)
|
||||
@@ -305,6 +312,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
|
||||
struct acpi_device *device;
|
||||
struct acpi_eject_event *ej_event = NULL;
|
||||
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
|
||||
acpi_status status;
|
||||
|
||||
switch (event) {
|
||||
case ACPI_NOTIFY_BUS_CHECK:
|
||||
@@ -327,29 +335,40 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"\nReceived EJECT REQUEST notification for device\n"));
|
||||
|
||||
status = AE_ERROR;
|
||||
acpi_scan_lock_acquire();
|
||||
|
||||
if (acpi_bus_get_device(handle, &device)) {
|
||||
acpi_handle_err(handle, "Device doesn't exist\n");
|
||||
break;
|
||||
goto unlock;
|
||||
}
|
||||
mem_device = acpi_driver_data(device);
|
||||
if (!mem_device) {
|
||||
acpi_handle_err(handle, "Driver Data is NULL\n");
|
||||
break;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
|
||||
if (!ej_event) {
|
||||
pr_err(PREFIX "No memory, dropping EJECT\n");
|
||||
break;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
get_device(&device->dev);
|
||||
ej_event->device = device;
|
||||
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
|
||||
acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
|
||||
(void *)ej_event);
|
||||
/* The eject is carried out asynchronously. */
|
||||
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 */
|
||||
return;
|
||||
unlock:
|
||||
acpi_scan_lock_release();
|
||||
if (ACPI_SUCCESS(status))
|
||||
return;
|
||||
default:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Unsupported event [0x%x]\n", event));
|
||||
@@ -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 */
|
||||
(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
int result;
|
||||
|
||||
@@ -482,8 +482,7 @@ static int acpi_pad_add(struct acpi_device *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_pad_remove(struct acpi_device *device,
|
||||
int type)
|
||||
static int acpi_pad_remove(struct acpi_device *device)
|
||||
{
|
||||
mutex_lock(&isolated_cpus_lock);
|
||||
acpi_pad_idle_cpus(0);
|
||||
|
||||
@@ -22,6 +22,30 @@
|
||||
|
||||
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 struct platform_device *pdev;
|
||||
@@ -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
|
||||
* @adev: ACPI device node to create a platform device for.
|
||||
* @flags: ACPI_PLATFORM_* flags that affect the creation of the platform
|
||||
* devices.
|
||||
* @id: ACPI device ID used to match @adev.
|
||||
*
|
||||
* 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
|
||||
@@ -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.
|
||||
*/
|
||||
struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
|
||||
unsigned long flags)
|
||||
static int acpi_create_platform_device(struct acpi_device *adev,
|
||||
const struct acpi_device_id *id)
|
||||
{
|
||||
unsigned long flags = id->driver_data;
|
||||
struct platform_device *pdev = NULL;
|
||||
struct acpi_device *acpi_parent;
|
||||
struct platform_device_info pdevinfo;
|
||||
@@ -59,25 +83,28 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
|
||||
struct resource *resources;
|
||||
int count;
|
||||
|
||||
if ((flags & ACPI_PLATFORM_CLK) && acpi_create_platform_clks(adev)) {
|
||||
dev_err(&adev->dev, "failed to create clocks\n");
|
||||
return NULL;
|
||||
if (flags & ACPI_PLATFORM_CLK) {
|
||||
int ret = acpi_create_platform_clks(adev);
|
||||
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 (adev->physical_node_count)
|
||||
return NULL;
|
||||
return 0;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
|
||||
if (count <= 0)
|
||||
return NULL;
|
||||
return 0;
|
||||
|
||||
resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL);
|
||||
if (!resources) {
|
||||
dev_err(&adev->dev, "No memory for resources\n");
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
return NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
count = 0;
|
||||
list_for_each_entry(rentry, &resource_list, node)
|
||||
@@ -123,5 +150,15 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
|
||||
}
|
||||
|
||||
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 @@ fail:
|
||||
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;
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ static const struct acpi_device_id button_device_ids[] = {
|
||||
MODULE_DEVICE_TABLE(acpi, button_device_ids);
|
||||
|
||||
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);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -433,7 +433,7 @@ static int acpi_button_add(struct acpi_device *device)
|
||||
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);
|
||||
|
||||
|
||||
+48
-140
@@ -34,46 +34,34 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
#include <acpi/container.h>
|
||||
|
||||
#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
|
||||
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[] = {
|
||||
{"ACPI0004", 0},
|
||||
{"PNP0A05", 0},
|
||||
{"PNP0A06", 0},
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, container_device_ids);
|
||||
|
||||
static struct acpi_driver acpi_container_driver = {
|
||||
.name = "container",
|
||||
.class = ACPI_CONTAINER_CLASS,
|
||||
static int container_device_attach(struct acpi_device *device,
|
||||
const struct acpi_device_id *not_used)
|
||||
{
|
||||
/*
|
||||
* 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,
|
||||
.ops = {
|
||||
.add = acpi_container_add,
|
||||
.remove = acpi_container_remove,
|
||||
},
|
||||
.attach = container_device_attach,
|
||||
};
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
static int is_device_present(acpi_handle handle)
|
||||
{
|
||||
acpi_handle temp;
|
||||
@@ -92,49 +80,6 @@ static int is_device_present(acpi_handle handle)
|
||||
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)
|
||||
{
|
||||
struct acpi_device *device = NULL;
|
||||
@@ -143,6 +88,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
|
||||
acpi_status status;
|
||||
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
|
||||
|
||||
acpi_scan_lock_acquire();
|
||||
|
||||
switch (type) {
|
||||
case ACPI_NOTIFY_BUS_CHECK:
|
||||
/* Fall through */
|
||||
@@ -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->flags.eject_pending = 1;
|
||||
kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -185,98 +132,59 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
|
||||
if (!acpi_bus_get_device(handle, &device) && device) {
|
||||
device->flags.eject_pending = 1;
|
||||
kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* non-hotplug event; possibly handled by other handler */
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Inform firmware that the hotplug operation has completed */
|
||||
(void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
|
||||
return;
|
||||
|
||||
out:
|
||||
acpi_scan_lock_release();
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
container_walk_namespace_cb(acpi_handle handle,
|
||||
u32 lvl, void *context, void **rv)
|
||||
static bool is_container(acpi_handle handle)
|
||||
{
|
||||
char *hid = NULL;
|
||||
struct acpi_device_info *info;
|
||||
acpi_status status;
|
||||
int *action = context;
|
||||
bool ret = false;
|
||||
|
||||
status = acpi_get_object_info(handle, &info);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return AE_OK;
|
||||
if (ACPI_FAILURE(acpi_get_object_info(handle, &info)))
|
||||
return false;
|
||||
|
||||
if (info->valid & ACPI_VALID_HID) {
|
||||
const struct acpi_device_id *id;
|
||||
|
||||
for (id = container_device_ids; id->id[0]; id++) {
|
||||
ret = !strcmp((char *)id->id, info->hardware_id.string);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->valid & ACPI_VALID_HID)
|
||||
hid = info->hardware_id.string;
|
||||
|
||||
if (hid == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!is_container_device(hid))
|
||||
goto end;
|
||||
|
||||
switch (*action) {
|
||||
case INSTALL_NOTIFY_HANDLER:
|
||||
acpi_install_notify_handler(handle,
|
||||
ACPI_SYSTEM_NOTIFY,
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static acpi_status acpi_container_register_notify_handler(acpi_handle handle,
|
||||
u32 lvl, void *ctxt,
|
||||
void **retv)
|
||||
{
|
||||
if (is_container(handle))
|
||||
acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
|
||||
container_notify_cb, NULL);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int __init acpi_container_init(void)
|
||||
void __init acpi_container_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
int action = INSTALL_NOTIFY_HANDLER;
|
||||
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
|
||||
acpi_container_register_notify_handler, NULL,
|
||||
NULL, 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);
|
||||
acpi_scan_add_handler(&container_device_handler);
|
||||
}
|
||||
|
||||
static void __exit acpi_container_exit(void)
|
||||
{
|
||||
int action = UNINSTALL_NOTIFY_HANDLER;
|
||||
|
||||
|
||||
acpi_walk_namespace(ACPI_TYPE_DEVICE,
|
||||
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);
|
||||
|
||||
+17
-4
@@ -744,7 +744,9 @@ static void acpi_dock_deferred_cb(void *context)
|
||||
{
|
||||
struct dock_data *data = context;
|
||||
|
||||
acpi_scan_lock_acquire();
|
||||
dock_notify(data->handle, data->event, data->ds);
|
||||
acpi_scan_lock_release();
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
&& event != ACPI_NOTIFY_EJECT_REQUEST)
|
||||
return 0;
|
||||
|
||||
acpi_scan_lock_acquire();
|
||||
|
||||
list_for_each_entry(dock_station, &dock_stations, sibling) {
|
||||
if (dock_station->handle == handle) {
|
||||
struct dock_data *dd;
|
||||
acpi_status status;
|
||||
|
||||
dd = kmalloc(sizeof(*dd), GFP_KERNEL);
|
||||
if (!dd)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
dd->handle = handle;
|
||||
dd->event = event;
|
||||
dd->ds = dock_station;
|
||||
acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd);
|
||||
return 0 ;
|
||||
status = acpi_os_hotplug_execute(acpi_dock_deferred_cb,
|
||||
dd);
|
||||
if (ACPI_FAILURE(status))
|
||||
kfree(dd);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
acpi_scan_lock_release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -825,7 +838,7 @@ static ssize_t show_docked(struct device *dev,
|
||||
|
||||
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, "0\n");
|
||||
}
|
||||
|
||||
+1
-1
@@ -852,7 +852,7 @@ static int acpi_ec_add(struct acpi_device *device)
|
||||
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_query_handler *handler, *tmp;
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ MODULE_DESCRIPTION("ACPI Fan Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
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[] = {
|
||||
{"PNP0C0B", 0},
|
||||
@@ -172,7 +172,7 @@ static int acpi_fan_add(struct acpi_device *device)
|
||||
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);
|
||||
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ static int acpi_hed_add(struct acpi_device *device)
|
||||
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;
|
||||
return 0;
|
||||
|
||||
@@ -25,8 +25,16 @@
|
||||
|
||||
int init_acpi_device_notify(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);
|
||||
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
|
||||
extern struct dentry *acpi_debugfs_dir;
|
||||
@@ -86,7 +94,6 @@ struct acpi_ec {
|
||||
|
||||
extern struct acpi_ec *first_ec;
|
||||
|
||||
int acpi_pci_root_init(void);
|
||||
int acpi_ec_init(void);
|
||||
int acpi_ec_ecdt_probe(void);
|
||||
int acpi_boot_ec_enable(void);
|
||||
@@ -118,10 +125,4 @@ static inline void suspend_nvs_restore(void) {}
|
||||
-------------------------------------------------------------------------- */
|
||||
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_ */
|
||||
|
||||
+14
-33
@@ -53,23 +53,19 @@ ACPI_MODULE_NAME("pci_link");
|
||||
#define ACPI_PCI_LINK_FILE_STATUS "state"
|
||||
#define ACPI_PCI_LINK_MAX_POSSIBLE 16
|
||||
|
||||
static int acpi_pci_link_add(struct acpi_device *device);
|
||||
static int acpi_pci_link_remove(struct acpi_device *device, int type);
|
||||
static int acpi_pci_link_add(struct acpi_device *device,
|
||||
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[] = {
|
||||
{"PNP0C0F", 0},
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, link_device_ids);
|
||||
|
||||
static struct acpi_driver acpi_pci_link_driver = {
|
||||
.name = "pci_link",
|
||||
.class = ACPI_PCI_LINK_CLASS,
|
||||
static struct acpi_scan_handler pci_link_handler = {
|
||||
.ids = link_device_ids,
|
||||
.ops = {
|
||||
.add = acpi_pci_link_add,
|
||||
.remove = acpi_pci_link_remove,
|
||||
},
|
||||
.attach = acpi_pci_link_add,
|
||||
.detach = acpi_pci_link_remove,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -692,7 +688,8 @@ int acpi_pci_link_free_irq(acpi_handle handle)
|
||||
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;
|
||||
struct acpi_pci_link *link;
|
||||
@@ -746,7 +743,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
|
||||
if (result)
|
||||
kfree(link);
|
||||
|
||||
return result;
|
||||
return result < 0 ? result : 1;
|
||||
}
|
||||
|
||||
static int acpi_pci_link_resume(struct acpi_pci_link *link)
|
||||
@@ -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;
|
||||
|
||||
@@ -777,7 +774,6 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type)
|
||||
mutex_unlock(&acpi_link_lock);
|
||||
|
||||
kfree(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -874,20 +870,10 @@ static struct syscore_ops irqrouter_syscore_ops = {
|
||||
.resume = irqrouter_resume,
|
||||
};
|
||||
|
||||
static int __init irqrouter_init_ops(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)
|
||||
void __init acpi_pci_link_init(void)
|
||||
{
|
||||
if (acpi_noirq)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (acpi_irq_balance == -1) {
|
||||
/* no command line switch: enable balancing in IOAPIC mode */
|
||||
@@ -896,11 +882,6 @@ static int __init acpi_pci_link_init(void)
|
||||
else
|
||||
acpi_irq_balance = 0;
|
||||
}
|
||||
|
||||
if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
register_syscore_ops(&irqrouter_syscore_ops);
|
||||
acpi_scan_add_handler(&pci_link_handler);
|
||||
}
|
||||
|
||||
subsys_initcall(acpi_pci_link_init);
|
||||
|
||||
+15
-23
@@ -45,8 +45,9 @@
|
||||
ACPI_MODULE_NAME("pci_root");
|
||||
#define ACPI_PCI_ROOT_CLASS "pci_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_remove(struct acpi_device *device, int type);
|
||||
static int acpi_pci_root_add(struct acpi_device *device,
|
||||
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 \
|
||||
| OSC_ACTIVE_STATE_PWR_SUPPORT \
|
||||
@@ -57,16 +58,11 @@ static const struct acpi_device_id root_device_ids[] = {
|
||||
{"PNP0A03", 0},
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, root_device_ids);
|
||||
|
||||
static struct acpi_driver acpi_pci_root_driver = {
|
||||
.name = "pci_root",
|
||||
.class = ACPI_PCI_ROOT_CLASS,
|
||||
static struct acpi_scan_handler pci_root_handler = {
|
||||
.ids = root_device_ids,
|
||||
.ops = {
|
||||
.add = acpi_pci_root_add,
|
||||
.remove = acpi_pci_root_remove,
|
||||
},
|
||||
.attach = acpi_pci_root_add,
|
||||
.detach = acpi_pci_root_remove,
|
||||
};
|
||||
|
||||
/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */
|
||||
@@ -428,7 +424,8 @@ out:
|
||||
}
|
||||
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;
|
||||
acpi_status status;
|
||||
@@ -614,7 +611,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
|
||||
pci_enable_bridges(root->bus);
|
||||
|
||||
pci_bus_add_devices(root->bus);
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
out_del_root:
|
||||
mutex_lock(&acpi_pci_root_lock);
|
||||
@@ -627,7 +624,7 @@ end:
|
||||
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_handle handle;
|
||||
@@ -655,19 +652,14 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
|
||||
list_del(&root->node);
|
||||
mutex_unlock(&acpi_pci_root_lock);
|
||||
kfree(root);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init acpi_pci_root_init(void)
|
||||
void __init acpi_pci_root_init(void)
|
||||
{
|
||||
acpi_hest_init();
|
||||
|
||||
if (acpi_pci_disabled)
|
||||
return 0;
|
||||
|
||||
pci_acpi_crs_quirks();
|
||||
if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
if (!acpi_pci_disabled) {
|
||||
pci_acpi_crs_quirks();
|
||||
acpi_scan_add_handler(&pci_root_handler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,13 +50,12 @@ module_param(debug, bool, 0644);
|
||||
ACPI_MODULE_NAME("pci_slot");
|
||||
|
||||
#define MY_NAME "pci_slot"
|
||||
#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
|
||||
#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
|
||||
#define err(format, arg...) pr_err("%s: " format , MY_NAME , ## arg)
|
||||
#define info(format, arg...) pr_info("%s: " format , MY_NAME , ## arg)
|
||||
#define dbg(format, arg...) \
|
||||
do { \
|
||||
if (debug) \
|
||||
printk(KERN_DEBUG "%s: " format, \
|
||||
MY_NAME , ## arg); \
|
||||
pr_debug("%s: " format, MY_NAME , ## arg); \
|
||||
} while (0)
|
||||
|
||||
#define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user