|
@@ -31,6 +31,7 @@ static LIST_HEAD(bus_type_list);
|
|
|
static DECLARE_RWSEM(bus_type_sem);
|
|
|
|
|
|
#define PHYSICAL_NODE_STRING "physical_node"
|
|
|
+#define PHYSICAL_NODE_NAME_SIZE (sizeof(PHYSICAL_NODE_STRING) + 10)
|
|
|
|
|
|
int register_acpi_bus_type(struct acpi_bus_type *type)
|
|
|
{
|
|
@@ -112,7 +113,9 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
|
|
|
struct acpi_device *acpi_dev;
|
|
|
acpi_status status;
|
|
|
struct acpi_device_physical_node *physical_node, *pn;
|
|
|
- char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
|
|
|
+ char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
|
|
|
+ struct list_head *physnode_list;
|
|
|
+ unsigned int node_id;
|
|
|
int retval = -EINVAL;
|
|
|
|
|
|
if (ACPI_HANDLE(dev)) {
|
|
@@ -139,25 +142,27 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
|
|
|
|
|
|
mutex_lock(&acpi_dev->physical_node_lock);
|
|
|
|
|
|
- /* Sanity check. */
|
|
|
- list_for_each_entry(pn, &acpi_dev->physical_node_list, node)
|
|
|
+ /*
|
|
|
+ * Keep the list sorted by node_id so that the IDs of removed nodes can
|
|
|
+ * be recycled easily.
|
|
|
+ */
|
|
|
+ physnode_list = &acpi_dev->physical_node_list;
|
|
|
+ node_id = 0;
|
|
|
+ list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
|
|
|
+ /* Sanity check. */
|
|
|
if (pn->dev == dev) {
|
|
|
dev_warn(dev, "Already associated with ACPI node\n");
|
|
|
goto err_free;
|
|
|
}
|
|
|
-
|
|
|
- /* allocate physical node id according to physical_node_id_bitmap */
|
|
|
- physical_node->node_id =
|
|
|
- find_first_zero_bit(acpi_dev->physical_node_id_bitmap,
|
|
|
- ACPI_MAX_PHYSICAL_NODE);
|
|
|
- if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
|
|
|
- retval = -ENOSPC;
|
|
|
- goto err_free;
|
|
|
+ if (pn->node_id == node_id) {
|
|
|
+ physnode_list = &pn->node;
|
|
|
+ node_id++;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap);
|
|
|
+ physical_node->node_id = node_id;
|
|
|
physical_node->dev = dev;
|
|
|
- list_add_tail(&physical_node->node, &acpi_dev->physical_node_list);
|
|
|
+ list_add(&physical_node->node, physnode_list);
|
|
|
acpi_dev->physical_node_count++;
|
|
|
|
|
|
mutex_unlock(&acpi_dev->physical_node_lock);
|
|
@@ -208,7 +213,7 @@ int acpi_unbind_one(struct device *dev)
|
|
|
|
|
|
mutex_lock(&acpi_dev->physical_node_lock);
|
|
|
list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
|
|
|
- char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
|
|
|
+ char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
|
|
|
|
|
|
entry = list_entry(node, struct acpi_device_physical_node,
|
|
|
node);
|
|
@@ -216,7 +221,6 @@ int acpi_unbind_one(struct device *dev)
|
|
|
continue;
|
|
|
|
|
|
list_del(node);
|
|
|
- clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap);
|
|
|
|
|
|
acpi_dev->physical_node_count--;
|
|
|
|