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-hotplug'
* acpi-hotplug: ACPI / scan: ACPI device object sysfs attribute for _STA evaluation ACPI / hotplug / driver core: Handle containers in a special way ACPI / hotplug: Add demand_offline hotplug profile flag ACPI / bind: Move acpi_get_child() to drivers/ide/ide-acpi.c ACPI / bind: Pass struct acpi_device pointer to acpi_bind_one() ACPI / bind: Rework struct acpi_bus_type ACPI / bind: Redefine acpi_preset_companion() ACPI / bind: Redefine acpi_get_child() PCI / ACPI: Use acpi_find_child_device() for child devices lookup ACPI / bind: Simplify child device lookups ACPI / scan: Use direct recurrence for device hierarchy walks ACPI: Introduce acpi_set_device_status() ACPI / hotplug: Drop unfinished global notification handling routines ACPI / hotplug: Rework generic code to handle suprise removals ACPI / hotplug: Move container-specific code out of the core ACPI / hotplug: Make ACPI PCI root hotplug use common hotplug code ACPI / hotplug: Introduce common hotplug function acpi_device_hotplug() ACPI / hotplug: Do not fail bus and device checks for disabled hotplug ACPI / scan: Add acpi_device objects for all device nodes in the namespace ACPI / scan: Define non-empty device removal handler
This commit is contained in:
@@ -235,10 +235,6 @@ Wysocki <rafael.j.wysocki@intel.com>.
|
||||
named object's type in the second column). In that case the object's
|
||||
directory in sysfs will contain the 'path' attribute whose value is
|
||||
the full path to the node from the namespace root.
|
||||
struct acpi_device objects are created for the ACPI namespace nodes
|
||||
whose _STA control methods return PRESENT or FUNCTIONING. The power
|
||||
resource nodes or nodes without _STA are assumed to be both PRESENT
|
||||
and FUNCTIONING.
|
||||
F:
|
||||
The struct acpi_device object is created for a fixed hardware
|
||||
feature (as indicated by the fixed feature flag's name in the second
|
||||
@@ -340,7 +336,7 @@ Wysocki <rafael.j.wysocki@intel.com>.
|
||||
| +-------------+-------+----------------+
|
||||
| |
|
||||
| | +- - - - - - - +- - - - - - +- - - - - - - -+
|
||||
| +-| * PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: |
|
||||
| +-| PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: |
|
||||
| | +- - - - - - - +- - - - - - +- - - - - - - -+
|
||||
| |
|
||||
| | +------------+------------+-----------------------+
|
||||
@@ -390,6 +386,3 @@ Wysocki <rafael.j.wysocki@intel.com>.
|
||||
attribute (as described earlier in this document).
|
||||
NOTE: N/A indicates the device object does not have the 'path' or the
|
||||
'modalias' attribute.
|
||||
NOTE: The PNP0C0D device listed above is highlighted (marked by "*")
|
||||
to indicate it will be created only when its _STA methods return
|
||||
PRESENT or FUNCTIONING.
|
||||
|
||||
@@ -180,14 +180,14 @@ static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info)
|
||||
|
||||
static int acpi_bind_memblk(struct memory_block *mem, void *arg)
|
||||
{
|
||||
return acpi_bind_one(&mem->dev, (acpi_handle)arg);
|
||||
return acpi_bind_one(&mem->dev, arg);
|
||||
}
|
||||
|
||||
static int acpi_bind_memory_blocks(struct acpi_memory_info *info,
|
||||
acpi_handle handle)
|
||||
struct acpi_device *adev)
|
||||
{
|
||||
return walk_memory_range(acpi_meminfo_start_pfn(info),
|
||||
acpi_meminfo_end_pfn(info), (void *)handle,
|
||||
acpi_meminfo_end_pfn(info), adev,
|
||||
acpi_bind_memblk);
|
||||
}
|
||||
|
||||
@@ -197,8 +197,7 @@ static int acpi_unbind_memblk(struct memory_block *mem, void *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_unbind_memory_blocks(struct acpi_memory_info *info,
|
||||
acpi_handle handle)
|
||||
static void acpi_unbind_memory_blocks(struct acpi_memory_info *info)
|
||||
{
|
||||
walk_memory_range(acpi_meminfo_start_pfn(info),
|
||||
acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk);
|
||||
@@ -242,9 +241,9 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
|
||||
if (result && result != -EEXIST)
|
||||
continue;
|
||||
|
||||
result = acpi_bind_memory_blocks(info, handle);
|
||||
result = acpi_bind_memory_blocks(info, mem_device->device);
|
||||
if (result) {
|
||||
acpi_unbind_memory_blocks(info, handle);
|
||||
acpi_unbind_memory_blocks(info);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -285,7 +284,7 @@ static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
|
||||
if (nid == NUMA_NO_NODE)
|
||||
nid = memory_add_physaddr_to_nid(info->start_addr);
|
||||
|
||||
acpi_unbind_memory_blocks(info, handle);
|
||||
acpi_unbind_memory_blocks(info);
|
||||
remove_memory(nid, info->start_addr, info->length);
|
||||
list_del(&info->list);
|
||||
kfree(info);
|
||||
|
||||
@@ -395,7 +395,7 @@ static int acpi_processor_add(struct acpi_device *device,
|
||||
goto err;
|
||||
}
|
||||
|
||||
result = acpi_bind_one(dev, pr->handle);
|
||||
result = acpi_bind_one(dev, device);
|
||||
if (result)
|
||||
goto err;
|
||||
|
||||
|
||||
+5
-70
@@ -50,9 +50,6 @@ struct acpi_device *acpi_root;
|
||||
struct proc_dir_entry *acpi_root_dir;
|
||||
EXPORT_SYMBOL(acpi_root_dir);
|
||||
|
||||
#define STRUCT_TO_INT(s) (*((int*)&s))
|
||||
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
static int set_copy_dsdt(const struct dmi_system_id *id)
|
||||
{
|
||||
@@ -113,18 +110,16 @@ int acpi_bus_get_status(struct acpi_device *device)
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
STRUCT_TO_INT(device->status) = (int) sta;
|
||||
acpi_set_device_status(device, sta);
|
||||
|
||||
if (device->status.functional && !device->status.present) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
|
||||
"functional but not present;\n",
|
||||
device->pnp.bus_id,
|
||||
(u32) STRUCT_TO_INT(device->status)));
|
||||
device->pnp.bus_id, (u32)sta));
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
|
||||
device->pnp.bus_id,
|
||||
(u32) STRUCT_TO_INT(device->status)));
|
||||
device->pnp.bus_id, (u32)sta));
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_bus_get_status);
|
||||
@@ -337,58 +332,6 @@ static void acpi_bus_osc_support(void)
|
||||
Notification Handling
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
static void acpi_bus_check_device(acpi_handle handle)
|
||||
{
|
||||
struct acpi_device *device;
|
||||
acpi_status status;
|
||||
struct acpi_device_status old_status;
|
||||
|
||||
if (acpi_bus_get_device(handle, &device))
|
||||
return;
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
old_status = device->status;
|
||||
|
||||
/*
|
||||
* Make sure this device's parent is present before we go about
|
||||
* messing with the device.
|
||||
*/
|
||||
if (device->parent && !device->parent->status.present) {
|
||||
device->status = device->parent->status;
|
||||
return;
|
||||
}
|
||||
|
||||
status = acpi_bus_get_status(device);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Device Insertion/Removal
|
||||
*/
|
||||
if ((device->status.present) && !(old_status.present)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
|
||||
/* TBD: Handle device insertion */
|
||||
} else if (!(device->status.present) && (old_status.present)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
|
||||
/* TBD: Handle device removal */
|
||||
}
|
||||
}
|
||||
|
||||
static void acpi_bus_check_scope(acpi_handle handle)
|
||||
{
|
||||
/* Status Change? */
|
||||
acpi_bus_check_device(handle);
|
||||
|
||||
/*
|
||||
* TBD: Enumerate child devices within this device's scope and
|
||||
* run acpi_bus_check_device()'s on them.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_bus_notify
|
||||
* ---------------
|
||||
@@ -405,19 +348,11 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
|
||||
switch (type) {
|
||||
|
||||
case ACPI_NOTIFY_BUS_CHECK:
|
||||
acpi_bus_check_scope(handle);
|
||||
/*
|
||||
* TBD: We'll need to outsource certain events to non-ACPI
|
||||
* drivers via the device manager (device.c).
|
||||
*/
|
||||
/* TBD */
|
||||
break;
|
||||
|
||||
case ACPI_NOTIFY_DEVICE_CHECK:
|
||||
acpi_bus_check_device(handle);
|
||||
/*
|
||||
* TBD: We'll need to outsource certain events to non-ACPI
|
||||
* drivers via the device manager (device.c).
|
||||
*/
|
||||
/* TBD */
|
||||
break;
|
||||
|
||||
case ACPI_NOTIFY_DEVICE_WAKE:
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include <linux/container.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -44,19 +43,65 @@ static const struct acpi_device_id container_device_ids[] = {
|
||||
{"", 0},
|
||||
};
|
||||
|
||||
static int container_device_attach(struct acpi_device *device,
|
||||
static int acpi_container_offline(struct container_dev *cdev)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(&cdev->dev);
|
||||
struct acpi_device *child;
|
||||
|
||||
/* Check all of the dependent devices' physical companions. */
|
||||
list_for_each_entry(child, &adev->children, node)
|
||||
if (!acpi_scan_is_offline(child, false))
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_container_release(struct device *dev)
|
||||
{
|
||||
kfree(to_container_dev(dev));
|
||||
}
|
||||
|
||||
static int container_device_attach(struct acpi_device *adev,
|
||||
const struct acpi_device_id *not_used)
|
||||
{
|
||||
/* This is necessary for container hotplug to work. */
|
||||
struct container_dev *cdev;
|
||||
struct device *dev;
|
||||
int ret;
|
||||
|
||||
cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
|
||||
if (!cdev)
|
||||
return -ENOMEM;
|
||||
|
||||
cdev->offline = acpi_container_offline;
|
||||
dev = &cdev->dev;
|
||||
dev->bus = &container_subsys;
|
||||
dev_set_name(dev, "%s", dev_name(&adev->dev));
|
||||
ACPI_COMPANION_SET(dev, adev);
|
||||
dev->release = acpi_container_release;
|
||||
ret = device_register(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
adev->driver_data = dev;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void container_device_detach(struct acpi_device *adev)
|
||||
{
|
||||
struct device *dev = acpi_driver_data(adev);
|
||||
|
||||
adev->driver_data = NULL;
|
||||
if (dev)
|
||||
device_unregister(dev);
|
||||
}
|
||||
|
||||
static struct acpi_scan_handler container_handler = {
|
||||
.ids = container_device_ids,
|
||||
.attach = container_device_attach,
|
||||
.detach = container_device_detach,
|
||||
.hotplug = {
|
||||
.enabled = true,
|
||||
.mode = AHM_CONTAINER,
|
||||
.demand_offline = true,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -256,6 +256,8 @@ int acpi_bus_init_power(struct acpi_device *device)
|
||||
return -EINVAL;
|
||||
|
||||
device->power.state = ACPI_STATE_UNKNOWN;
|
||||
if (!acpi_device_is_present(device))
|
||||
return 0;
|
||||
|
||||
result = acpi_device_get_power(device, &state);
|
||||
if (result)
|
||||
@@ -302,15 +304,18 @@ int acpi_device_fix_up_power(struct acpi_device *device)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int acpi_bus_update_power(acpi_handle handle, int *state_p)
|
||||
int acpi_device_update_power(struct acpi_device *device, int *state_p)
|
||||
{
|
||||
struct acpi_device *device;
|
||||
int state;
|
||||
int result;
|
||||
|
||||
result = acpi_bus_get_device(handle, &device);
|
||||
if (result)
|
||||
if (device->power.state == ACPI_STATE_UNKNOWN) {
|
||||
result = acpi_bus_init_power(device);
|
||||
if (!result && state_p)
|
||||
*state_p = device->power.state;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
result = acpi_device_get_power(device, &state);
|
||||
if (result)
|
||||
@@ -338,6 +343,15 @@ int acpi_bus_update_power(acpi_handle handle, int *state_p)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_bus_update_power(acpi_handle handle, int *state_p)
|
||||
{
|
||||
struct acpi_device *device;
|
||||
int result;
|
||||
|
||||
result = acpi_bus_get_device(handle, &device);
|
||||
return result ? result : acpi_device_update_power(device, state_p);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_bus_update_power);
|
||||
|
||||
bool acpi_bus_power_manageable(acpi_handle handle)
|
||||
|
||||
+3
-6
@@ -323,14 +323,11 @@ static int dock_present(struct dock_station *ds)
|
||||
*/
|
||||
static void dock_create_acpi_device(acpi_handle handle)
|
||||
{
|
||||
struct acpi_device *device;
|
||||
struct acpi_device *device = NULL;
|
||||
int ret;
|
||||
|
||||
if (acpi_bus_get_device(handle, &device)) {
|
||||
/*
|
||||
* no device created for this object,
|
||||
* so we should create one.
|
||||
*/
|
||||
acpi_bus_get_device(handle, &device);
|
||||
if (!acpi_device_enumerated(device)) {
|
||||
ret = acpi_bus_scan(handle);
|
||||
if (ret)
|
||||
pr_debug("error adding bus, %x\n", -ret);
|
||||
|
||||
+58
-103
@@ -37,7 +37,7 @@ int register_acpi_bus_type(struct acpi_bus_type *type)
|
||||
{
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
if (type && type->match && type->find_device) {
|
||||
if (type && type->match && type->find_companion) {
|
||||
down_write(&bus_type_sem);
|
||||
list_add_tail(&type->list, &bus_type_list);
|
||||
up_write(&bus_type_sem);
|
||||
@@ -82,109 +82,74 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
|
||||
#define FIND_CHILD_MIN_SCORE 1
|
||||
#define FIND_CHILD_MAX_SCORE 2
|
||||
|
||||
static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used,
|
||||
void *not_used, void **ret_p)
|
||||
{
|
||||
struct acpi_device *adev = NULL;
|
||||
|
||||
acpi_bus_get_device(handle, &adev);
|
||||
if (adev) {
|
||||
*ret_p = handle;
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int do_find_child_checks(acpi_handle handle, bool is_bridge)
|
||||
static int find_child_checks(struct acpi_device *adev, bool check_children)
|
||||
{
|
||||
bool sta_present = true;
|
||||
unsigned long long sta;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
|
||||
status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
|
||||
if (status == AE_NOT_FOUND)
|
||||
sta_present = false;
|
||||
else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED))
|
||||
return -ENODEV;
|
||||
|
||||
if (is_bridge) {
|
||||
void *test = NULL;
|
||||
if (check_children && list_empty(&adev->children))
|
||||
return -ENODEV;
|
||||
|
||||
/* Check if this object has at least one child device. */
|
||||
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
|
||||
acpi_dev_present, NULL, NULL, &test);
|
||||
if (!test)
|
||||
return -ENODEV;
|
||||
}
|
||||
return sta_present ? FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE;
|
||||
}
|
||||
|
||||
struct find_child_context {
|
||||
u64 addr;
|
||||
bool is_bridge;
|
||||
acpi_handle ret;
|
||||
int ret_score;
|
||||
};
|
||||
|
||||
static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
|
||||
void *data, void **not_used)
|
||||
struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
|
||||
u64 address, bool check_children)
|
||||
{
|
||||
struct find_child_context *context = data;
|
||||
unsigned long long addr;
|
||||
acpi_status status;
|
||||
int score;
|
||||
struct acpi_device *adev, *ret = NULL;
|
||||
int ret_score = 0;
|
||||
|
||||
status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
|
||||
if (ACPI_FAILURE(status) || addr != context->addr)
|
||||
return AE_OK;
|
||||
if (!parent)
|
||||
return NULL;
|
||||
|
||||
if (!context->ret) {
|
||||
/* This is the first matching object. Save its handle. */
|
||||
context->ret = handle;
|
||||
return AE_OK;
|
||||
list_for_each_entry(adev, &parent->children, node) {
|
||||
unsigned long long addr;
|
||||
acpi_status status;
|
||||
int score;
|
||||
|
||||
status = acpi_evaluate_integer(adev->handle, METHOD_NAME__ADR,
|
||||
NULL, &addr);
|
||||
if (ACPI_FAILURE(status) || addr != address)
|
||||
continue;
|
||||
|
||||
if (!ret) {
|
||||
/* This is the first matching object. Save it. */
|
||||
ret = adev;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* There is more than one matching device object with the same
|
||||
* _ADR value. That really is unexpected, so we are kind of
|
||||
* beyond the scope of the spec here. We have to choose which
|
||||
* one to return, though.
|
||||
*
|
||||
* First, check if the previously found object is good enough
|
||||
* and return it if so. Second, do the same for the object that
|
||||
* we've just found.
|
||||
*/
|
||||
if (!ret_score) {
|
||||
ret_score = find_child_checks(ret, check_children);
|
||||
if (ret_score == FIND_CHILD_MAX_SCORE)
|
||||
return ret;
|
||||
}
|
||||
score = find_child_checks(adev, check_children);
|
||||
if (score == FIND_CHILD_MAX_SCORE) {
|
||||
return adev;
|
||||
} else if (score > ret_score) {
|
||||
ret = adev;
|
||||
ret_score = score;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* There is more than one matching object with the same _ADR value.
|
||||
* That really is unexpected, so we are kind of beyond the scope of the
|
||||
* spec here. We have to choose which one to return, though.
|
||||
*
|
||||
* First, check if the previously found object is good enough and return
|
||||
* its handle if so. Second, check the same for the object that we've
|
||||
* just found.
|
||||
*/
|
||||
if (!context->ret_score) {
|
||||
score = do_find_child_checks(context->ret, context->is_bridge);
|
||||
if (score == FIND_CHILD_MAX_SCORE)
|
||||
return AE_CTRL_TERMINATE;
|
||||
else
|
||||
context->ret_score = score;
|
||||
}
|
||||
score = do_find_child_checks(handle, context->is_bridge);
|
||||
if (score == FIND_CHILD_MAX_SCORE) {
|
||||
context->ret = handle;
|
||||
return AE_CTRL_TERMINATE;
|
||||
} else if (score > context->ret_score) {
|
||||
context->ret = handle;
|
||||
context->ret_score = score;
|
||||
}
|
||||
return AE_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge)
|
||||
{
|
||||
if (parent) {
|
||||
struct find_child_context context = {
|
||||
.addr = addr,
|
||||
.is_bridge = is_bridge,
|
||||
};
|
||||
|
||||
acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, do_find_child,
|
||||
NULL, &context, NULL);
|
||||
return context.ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_find_child);
|
||||
EXPORT_SYMBOL_GPL(acpi_find_child_device);
|
||||
|
||||
static void acpi_physnode_link_name(char *buf, unsigned int node_id)
|
||||
{
|
||||
@@ -195,9 +160,8 @@ static void acpi_physnode_link_name(char *buf, unsigned int node_id)
|
||||
strcpy(buf, PHYSICAL_NODE_STRING);
|
||||
}
|
||||
|
||||
int acpi_bind_one(struct device *dev, acpi_handle handle)
|
||||
int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
||||
{
|
||||
struct acpi_device *acpi_dev = NULL;
|
||||
struct acpi_device_physical_node *physical_node, *pn;
|
||||
char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
|
||||
struct list_head *physnode_list;
|
||||
@@ -205,14 +169,12 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
|
||||
int retval = -EINVAL;
|
||||
|
||||
if (ACPI_COMPANION(dev)) {
|
||||
if (handle) {
|
||||
if (acpi_dev) {
|
||||
dev_warn(dev, "ACPI companion already set\n");
|
||||
return -EINVAL;
|
||||
} else {
|
||||
acpi_dev = ACPI_COMPANION(dev);
|
||||
}
|
||||
} else {
|
||||
acpi_bus_get_device(handle, &acpi_dev);
|
||||
}
|
||||
if (!acpi_dev)
|
||||
return -EINVAL;
|
||||
@@ -322,29 +284,22 @@ int acpi_unbind_one(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_unbind_one);
|
||||
|
||||
void acpi_preset_companion(struct device *dev, acpi_handle parent, u64 addr)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
|
||||
if (!acpi_bus_get_device(acpi_get_child(parent, addr), &adev))
|
||||
ACPI_COMPANION_SET(dev, adev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_preset_companion);
|
||||
|
||||
static int acpi_platform_notify(struct device *dev)
|
||||
{
|
||||
struct acpi_bus_type *type = acpi_get_bus_type(dev);
|
||||
acpi_handle handle;
|
||||
int ret;
|
||||
|
||||
ret = acpi_bind_one(dev, NULL);
|
||||
if (ret && type) {
|
||||
ret = type->find_device(dev, &handle);
|
||||
if (ret) {
|
||||
struct acpi_device *adev;
|
||||
|
||||
adev = type->find_companion(dev);
|
||||
if (!adev) {
|
||||
DBG("Unable to get handle for %s\n", dev_name(dev));
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
ret = acpi_bind_one(dev, handle);
|
||||
ret = acpi_bind_one(dev, adev);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ 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_pci_root_hp_init(void);
|
||||
void acpi_processor_init(void);
|
||||
void acpi_platform_init(void);
|
||||
int acpi_sysfs_init(void);
|
||||
@@ -73,6 +72,9 @@ void acpi_lpss_init(void);
|
||||
static inline void acpi_lpss_init(void) {}
|
||||
#endif
|
||||
|
||||
bool acpi_queue_hotplug_work(struct work_struct *work);
|
||||
bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent);
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Device Node Initialization / Removal
|
||||
-------------------------------------------------------------------------- */
|
||||
@@ -85,9 +87,9 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
|
||||
int type, unsigned long long sta);
|
||||
void acpi_device_add_finalize(struct acpi_device *device);
|
||||
void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
|
||||
int acpi_bind_one(struct device *dev, acpi_handle handle);
|
||||
int acpi_bind_one(struct device *dev, struct acpi_device *adev);
|
||||
int acpi_unbind_one(struct device *dev);
|
||||
void acpi_bus_device_eject(void *data, u32 ost_src);
|
||||
bool acpi_device_is_present(struct acpi_device *adev);
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Power Resource
|
||||
@@ -105,6 +107,8 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
|
||||
int acpi_power_on_resources(struct acpi_device *device, int state);
|
||||
int acpi_power_transition(struct acpi_device *device, int state);
|
||||
|
||||
int acpi_device_update_power(struct acpi_device *device, int *state_p);
|
||||
|
||||
int acpi_wakeup_device_init(void);
|
||||
void acpi_early_processor_set_pdc(void);
|
||||
|
||||
|
||||
+5
-1
@@ -1211,6 +1211,10 @@ acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src)
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
bool acpi_queue_hotplug_work(struct work_struct *work)
|
||||
{
|
||||
return queue_work(kacpi_hotplug_wq, work);
|
||||
}
|
||||
|
||||
acpi_status
|
||||
acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
|
||||
@@ -1790,7 +1794,7 @@ acpi_status __init acpi_os_initialize1(void)
|
||||
{
|
||||
kacpid_wq = alloc_workqueue("kacpid", 0, 1);
|
||||
kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
|
||||
kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1);
|
||||
kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
|
||||
BUG_ON(!kacpid_wq);
|
||||
BUG_ON(!kacpi_notify_wq);
|
||||
BUG_ON(!kacpi_hotplug_wq);
|
||||
|
||||
+11
-111
@@ -49,6 +49,12 @@ 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);
|
||||
|
||||
static int acpi_pci_root_scan_dependent(struct acpi_device *adev)
|
||||
{
|
||||
acpiphp_check_host_bridge(adev->handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \
|
||||
| OSC_PCI_ASPM_SUPPORT \
|
||||
| OSC_PCI_CLOCK_PM_SUPPORT \
|
||||
@@ -64,7 +70,8 @@ static struct acpi_scan_handler pci_root_handler = {
|
||||
.attach = acpi_pci_root_add,
|
||||
.detach = acpi_pci_root_remove,
|
||||
.hotplug = {
|
||||
.ignore = true,
|
||||
.enabled = true,
|
||||
.scan_dependent = acpi_pci_root_scan_dependent,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -622,116 +629,9 @@ static void acpi_pci_root_remove(struct acpi_device *device)
|
||||
void __init acpi_pci_root_init(void)
|
||||
{
|
||||
acpi_hest_init();
|
||||
|
||||
if (!acpi_pci_disabled) {
|
||||
pci_acpi_crs_quirks();
|
||||
acpi_scan_add_handler(&pci_root_handler);
|
||||
}
|
||||
}
|
||||
/* Support root bridge hotplug */
|
||||
|
||||
static void handle_root_bridge_insertion(acpi_handle handle)
|
||||
{
|
||||
struct acpi_device *device;
|
||||
|
||||
if (!acpi_bus_get_device(handle, &device)) {
|
||||
dev_printk(KERN_DEBUG, &device->dev,
|
||||
"acpi device already exists; ignoring notify\n");
|
||||
if (acpi_pci_disabled)
|
||||
return;
|
||||
}
|
||||
|
||||
if (acpi_bus_scan(handle))
|
||||
acpi_handle_err(handle, "cannot add bridge to acpi list\n");
|
||||
}
|
||||
|
||||
static void hotplug_event_root(void *data, u32 type)
|
||||
{
|
||||
acpi_handle handle = data;
|
||||
struct acpi_pci_root *root;
|
||||
|
||||
acpi_scan_lock_acquire();
|
||||
|
||||
root = acpi_pci_find_root(handle);
|
||||
|
||||
switch (type) {
|
||||
case ACPI_NOTIFY_BUS_CHECK:
|
||||
/* bus enumerate */
|
||||
acpi_handle_printk(KERN_DEBUG, handle,
|
||||
"Bus check notify on %s\n", __func__);
|
||||
if (root)
|
||||
acpiphp_check_host_bridge(handle);
|
||||
else
|
||||
handle_root_bridge_insertion(handle);
|
||||
|
||||
break;
|
||||
|
||||
case ACPI_NOTIFY_DEVICE_CHECK:
|
||||
/* device check */
|
||||
acpi_handle_printk(KERN_DEBUG, handle,
|
||||
"Device check notify on %s\n", __func__);
|
||||
if (!root)
|
||||
handle_root_bridge_insertion(handle);
|
||||
break;
|
||||
|
||||
case ACPI_NOTIFY_EJECT_REQUEST:
|
||||
/* request device eject */
|
||||
acpi_handle_printk(KERN_DEBUG, handle,
|
||||
"Device eject notify on %s\n", __func__);
|
||||
if (!root)
|
||||
break;
|
||||
|
||||
get_device(&root->device->dev);
|
||||
|
||||
acpi_scan_lock_release();
|
||||
|
||||
acpi_bus_device_eject(root->device, ACPI_NOTIFY_EJECT_REQUEST);
|
||||
return;
|
||||
default:
|
||||
acpi_handle_warn(handle,
|
||||
"notify_handler: unknown event type 0x%x\n",
|
||||
type);
|
||||
break;
|
||||
}
|
||||
|
||||
acpi_scan_lock_release();
|
||||
}
|
||||
|
||||
static void handle_hotplug_event_root(acpi_handle handle, u32 type,
|
||||
void *context)
|
||||
{
|
||||
acpi_hotplug_execute(hotplug_event_root, handle, type);
|
||||
}
|
||||
|
||||
static acpi_status __init
|
||||
find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||
{
|
||||
acpi_status status;
|
||||
int *count = (int *)context;
|
||||
|
||||
if (!acpi_is_root_bridge(handle))
|
||||
return AE_OK;
|
||||
|
||||
(*count)++;
|
||||
|
||||
status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
|
||||
handle_hotplug_event_root, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
acpi_handle_printk(KERN_DEBUG, handle,
|
||||
"notify handler is not installed, exit status: %u\n",
|
||||
(unsigned int)status);
|
||||
else
|
||||
acpi_handle_printk(KERN_DEBUG, handle,
|
||||
"notify handler is installed\n");
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
void __init acpi_pci_root_hp_init(void)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
|
||||
|
||||
printk(KERN_DEBUG "Found %d acpi root devices\n", num);
|
||||
pci_acpi_crs_quirks();
|
||||
acpi_scan_add_handler_with_hotplug(&pci_root_handler, "pci_root");
|
||||
}
|
||||
|
||||
+324
-233
File diff suppressed because it is too large
Load Diff
+13
-13
@@ -178,12 +178,12 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
|
||||
/* bind acpi handle to pata port */
|
||||
void ata_acpi_bind_port(struct ata_port *ap)
|
||||
{
|
||||
acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
|
||||
struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
|
||||
|
||||
if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_handle)
|
||||
if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_companion)
|
||||
return;
|
||||
|
||||
acpi_preset_companion(&ap->tdev, host_handle, ap->port_no);
|
||||
acpi_preset_companion(&ap->tdev, host_companion, ap->port_no);
|
||||
|
||||
if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
|
||||
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
|
||||
@@ -196,17 +196,17 @@ void ata_acpi_bind_port(struct ata_port *ap)
|
||||
void ata_acpi_bind_dev(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
acpi_handle port_handle = ACPI_HANDLE(&ap->tdev);
|
||||
acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
|
||||
acpi_handle parent_handle;
|
||||
struct acpi_device *port_companion = ACPI_COMPANION(&ap->tdev);
|
||||
struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
|
||||
struct acpi_device *parent;
|
||||
u64 adr;
|
||||
|
||||
/*
|
||||
* For both sata/pata devices, host handle is required.
|
||||
* For pata device, port handle is also required.
|
||||
* For both sata/pata devices, host companion device is required.
|
||||
* For pata device, port companion device is also required.
|
||||
*/
|
||||
if (libata_noacpi || !host_handle ||
|
||||
(!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_handle))
|
||||
if (libata_noacpi || !host_companion ||
|
||||
(!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_companion))
|
||||
return;
|
||||
|
||||
if (ap->flags & ATA_FLAG_ACPI_SATA) {
|
||||
@@ -214,13 +214,13 @@ void ata_acpi_bind_dev(struct ata_device *dev)
|
||||
adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
|
||||
else
|
||||
adr = SATA_ADR(ap->port_no, dev->link->pmp);
|
||||
parent_handle = host_handle;
|
||||
parent = host_companion;
|
||||
} else {
|
||||
adr = dev->devno;
|
||||
parent_handle = port_handle;
|
||||
parent = port_companion;
|
||||
}
|
||||
|
||||
acpi_preset_companion(&dev->tdev, parent_handle, adr);
|
||||
acpi_preset_companion(&dev->tdev, parent, adr);
|
||||
|
||||
register_hotplug_dock_device(ata_dev_acpi_handle(dev),
|
||||
&ata_acpi_dev_dock_ops, dev, NULL, NULL);
|
||||
|
||||
@@ -4,7 +4,7 @@ obj-y := core.o bus.o dd.o syscore.o \
|
||||
driver.o class.o platform.o \
|
||||
cpu.o firmware.o init.o map.o devres.o \
|
||||
attribute_container.o transport_class.o \
|
||||
topology.o
|
||||
topology.o container.o
|
||||
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
|
||||
obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
|
||||
obj-y += power/
|
||||
|
||||
@@ -100,6 +100,7 @@ static inline int hypervisor_init(void) { return 0; }
|
||||
#endif
|
||||
extern int platform_bus_init(void);
|
||||
extern void cpu_dev_init(void);
|
||||
extern void container_dev_init(void);
|
||||
|
||||
struct kobject *virtual_device_parent(struct device *dev);
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* System bus type for containers.
|
||||
*
|
||||
* Copyright (C) 2013, Intel Corporation
|
||||
* Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/container.h>
|
||||
|
||||
#include "base.h"
|
||||
|
||||
#define CONTAINER_BUS_NAME "container"
|
||||
|
||||
static int trivial_online(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int container_offline(struct device *dev)
|
||||
{
|
||||
struct container_dev *cdev = to_container_dev(dev);
|
||||
|
||||
return cdev->offline ? cdev->offline(cdev) : 0;
|
||||
}
|
||||
|
||||
struct bus_type container_subsys = {
|
||||
.name = CONTAINER_BUS_NAME,
|
||||
.dev_name = CONTAINER_BUS_NAME,
|
||||
.online = trivial_online,
|
||||
.offline = container_offline,
|
||||
};
|
||||
|
||||
void __init container_dev_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = subsys_system_register(&container_subsys, NULL);
|
||||
if (ret)
|
||||
pr_err("%s() failed: %d\n", __func__, ret);
|
||||
}
|
||||
@@ -33,4 +33,5 @@ void __init driver_init(void)
|
||||
platform_bus_init();
|
||||
cpu_dev_init();
|
||||
memory_dev_init();
|
||||
container_dev_init();
|
||||
}
|
||||
|
||||
@@ -97,6 +97,17 @@ bool ide_port_acpi(ide_hwif_t *hwif)
|
||||
return ide_noacpi == 0 && hwif->acpidata;
|
||||
}
|
||||
|
||||
static acpi_handle acpi_get_child(acpi_handle handle, u64 addr)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
|
||||
if (!handle || acpi_bus_get_device(handle, &adev))
|
||||
return NULL;
|
||||
|
||||
adev = acpi_find_child_device(adev, addr, false);
|
||||
return adev ? adev->handle : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ide_get_dev_handle - finds acpi_handle and PCI device.function
|
||||
* @dev: device to locate
|
||||
|
||||
@@ -308,7 +308,7 @@ static void sdio_acpi_set_handle(struct sdio_func *func)
|
||||
struct mmc_host *host = func->card->host;
|
||||
u64 addr = (host->slotno << 16) | func->num;
|
||||
|
||||
acpi_preset_companion(&func->dev, ACPI_HANDLE(host->parent), addr);
|
||||
acpi_preset_companion(&func->dev, ACPI_COMPANION(host->parent), addr);
|
||||
}
|
||||
#else
|
||||
static inline void sdio_acpi_set_handle(struct sdio_func *func) {}
|
||||
|
||||
@@ -491,7 +491,7 @@ static void acpiphp_bus_add(acpi_handle handle)
|
||||
|
||||
acpi_bus_scan(handle);
|
||||
acpi_bus_get_device(handle, &adev);
|
||||
if (adev)
|
||||
if (acpi_device_enumerated(adev))
|
||||
acpi_device_set_power(adev, ACPI_STATE_D0);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user