aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-06 08:32:54 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-06 08:32:54 -0400
commit007ccfcf89401e764c33965b739310d86a94626d (patch)
tree4d7270405a42bee29537f51e29f1c07b613f9269
parent623cf33cb055b1e81fa47e4fc16789b2c129e31e (diff)
ACPI: Drop physical_node_id_bitmap from struct acpi_device
The physical_node_id_bitmap in struct acpi_device is only used for looking up the first currently unused dependent phyiscal node ID by acpi_bind_one(). It is not really necessary, however, because acpi_bind_one() walks the entire physical_node_list of the given device object for sanity checking anyway and if that list is always sorted by node_id, it is straightforward to find the first gap between the currently used node IDs and use that number as the ID of the new list node. This also removes the artificial limit of the maximum number of dependent physical devices per ACPI device object, which now depends only on the capacity of unsigend int. As a result, it fixes a regression introduced by commit e2ff394 (ACPI / memhotplug: Bind removable memory blocks to ACPI device nodes) that caused acpi_memory_enable_device() to fail when the number of 128 MB blocks within one removable memory module was greater than 32. Reported-and-tested-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Reviewed-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
-rw-r--r--drivers/acpi/glue.c34
-rw-r--r--include/acpi/acpi_bus.h8
2 files changed, 21 insertions, 21 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index f68095756fb7..17e15d11bd39 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -31,6 +31,7 @@ static LIST_HEAD(bus_type_list);
31static DECLARE_RWSEM(bus_type_sem); 31static DECLARE_RWSEM(bus_type_sem);
32 32
33#define PHYSICAL_NODE_STRING "physical_node" 33#define PHYSICAL_NODE_STRING "physical_node"
34#define PHYSICAL_NODE_NAME_SIZE (sizeof(PHYSICAL_NODE_STRING) + 10)
34 35
35int register_acpi_bus_type(struct acpi_bus_type *type) 36int register_acpi_bus_type(struct acpi_bus_type *type)
36{ 37{
@@ -112,7 +113,9 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
112 struct acpi_device *acpi_dev; 113 struct acpi_device *acpi_dev;
113 acpi_status status; 114 acpi_status status;
114 struct acpi_device_physical_node *physical_node, *pn; 115 struct acpi_device_physical_node *physical_node, *pn;
115 char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2]; 116 char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
117 struct list_head *physnode_list;
118 unsigned int node_id;
116 int retval = -EINVAL; 119 int retval = -EINVAL;
117 120
118 if (ACPI_HANDLE(dev)) { 121 if (ACPI_HANDLE(dev)) {
@@ -139,25 +142,27 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
139 142
140 mutex_lock(&acpi_dev->physical_node_lock); 143 mutex_lock(&acpi_dev->physical_node_lock);
141 144
142 /* Sanity check. */ 145 /*
143 list_for_each_entry(pn, &acpi_dev->physical_node_list, node) 146 * Keep the list sorted by node_id so that the IDs of removed nodes can
147 * be recycled easily.
148 */
149 physnode_list = &acpi_dev->physical_node_list;
150 node_id = 0;
151 list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
152 /* Sanity check. */
144 if (pn->dev == dev) { 153 if (pn->dev == dev) {
145 dev_warn(dev, "Already associated with ACPI node\n"); 154 dev_warn(dev, "Already associated with ACPI node\n");
146 goto err_free; 155 goto err_free;
147 } 156 }
148 157 if (pn->node_id == node_id) {
149 /* allocate physical node id according to physical_node_id_bitmap */ 158 physnode_list = &pn->node;
150 physical_node->node_id = 159 node_id++;
151 find_first_zero_bit(acpi_dev->physical_node_id_bitmap, 160 }
152 ACPI_MAX_PHYSICAL_NODE);
153 if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
154 retval = -ENOSPC;
155 goto err_free;
156 } 161 }
157 162
158 set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap); 163 physical_node->node_id = node_id;
159 physical_node->dev = dev; 164 physical_node->dev = dev;
160 list_add_tail(&physical_node->node, &acpi_dev->physical_node_list); 165 list_add(&physical_node->node, physnode_list);
161 acpi_dev->physical_node_count++; 166 acpi_dev->physical_node_count++;
162 167
163 mutex_unlock(&acpi_dev->physical_node_lock); 168 mutex_unlock(&acpi_dev->physical_node_lock);
@@ -208,7 +213,7 @@ int acpi_unbind_one(struct device *dev)
208 213
209 mutex_lock(&acpi_dev->physical_node_lock); 214 mutex_lock(&acpi_dev->physical_node_lock);
210 list_for_each_safe(node, next, &acpi_dev->physical_node_list) { 215 list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
211 char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2]; 216 char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
212 217
213 entry = list_entry(node, struct acpi_device_physical_node, 218 entry = list_entry(node, struct acpi_device_physical_node,
214 node); 219 node);
@@ -216,7 +221,6 @@ int acpi_unbind_one(struct device *dev)
216 continue; 221 continue;
217 222
218 list_del(node); 223 list_del(node);
219 clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap);
220 224
221 acpi_dev->physical_node_count--; 225 acpi_dev->physical_node_count--;
222 226
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 56e6b68c8d2f..5026aaa35133 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -274,15 +274,12 @@ struct acpi_device_wakeup {
274}; 274};
275 275
276struct acpi_device_physical_node { 276struct acpi_device_physical_node {
277 u8 node_id; 277 unsigned int node_id;
278 struct list_head node; 278 struct list_head node;
279 struct device *dev; 279 struct device *dev;
280 bool put_online:1; 280 bool put_online:1;
281}; 281};
282 282
283/* set maximum of physical nodes to 32 for expansibility */
284#define ACPI_MAX_PHYSICAL_NODE 32
285
286/* Device */ 283/* Device */
287struct acpi_device { 284struct acpi_device {
288 int device_type; 285 int device_type;
@@ -302,10 +299,9 @@ struct acpi_device {
302 struct acpi_driver *driver; 299 struct acpi_driver *driver;
303 void *driver_data; 300 void *driver_data;
304 struct device dev; 301 struct device dev;
305 u8 physical_node_count; 302 unsigned int physical_node_count;
306 struct list_head physical_node_list; 303 struct list_head physical_node_list;
307 struct mutex physical_node_lock; 304 struct mutex physical_node_lock;
308 DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE);
309 struct list_head power_dependent; 305 struct list_head power_dependent;
310 void (*remove)(struct acpi_device *); 306 void (*remove)(struct acpi_device *);
311}; 307};