diff options
author | Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> | 2012-11-15 01:59:31 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2012-11-15 19:56:01 -0500 |
commit | 19387b27e42d5e20a8188cfa15dc902114d98c43 (patch) | |
tree | de8cf045932189609013e435f281dd760952d80b /drivers/acpi/acpi_memhotplug.c | |
parent | 54c4c7db6cb94d7d1217df6d7fca6847c61744ab (diff) |
ACPI / memory-hotplug: add memory offline code to acpi_memory_device_remove()
The memory device can be removed by 2 ways:
1. send eject request by SCI
2. echo 1 >/sys/bus/pci/devices/PNP0C80:XX/eject
In the 1st case, acpi_memory_disable_device() will be called.
In the 2nd case, acpi_memory_device_remove() will be called.
acpi_memory_device_remove() will also be called when we unbind the
memory device from the driver acpi_memhotplug or a driver initialization
fails.
acpi_memory_disable_device() has already implemented a code which
offlines memory and releases acpi_memory_info struct. But
acpi_memory_device_remove() has not implemented it yet.
So the patch move offlining memory and releasing acpi_memory_info struct
codes to a new function acpi_memory_remove_memory(). And it is used by both
acpi_memory_device_remove() and acpi_memory_disable_device().
Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Acked-by: David Rientjes <rientjes@google.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpi_memhotplug.c')
-rw-r--r-- | drivers/acpi/acpi_memhotplug.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 1e90e8f01007..736ec047e0fc 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -306,25 +306,37 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) | |||
306 | return 0; | 306 | return 0; |
307 | } | 307 | } |
308 | 308 | ||
309 | static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) | 309 | static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) |
310 | { | 310 | { |
311 | int result; | 311 | int result; |
312 | struct acpi_memory_info *info, *n; | 312 | struct acpi_memory_info *info, *n; |
313 | 313 | ||
314 | |||
315 | /* | ||
316 | * Ask the VM to offline this memory range. | ||
317 | * Note: Assume that this function returns zero on success | ||
318 | */ | ||
319 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) { | 314 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) { |
320 | if (info->enabled) { | 315 | if (info->enabled) { |
321 | result = remove_memory(info->start_addr, info->length); | 316 | result = remove_memory(info->start_addr, info->length); |
322 | if (result) | 317 | if (result) |
323 | return result; | 318 | return result; |
324 | } | 319 | } |
320 | |||
321 | list_del(&info->list); | ||
325 | kfree(info); | 322 | kfree(info); |
326 | } | 323 | } |
327 | 324 | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) | ||
329 | { | ||
330 | int result; | ||
331 | |||
332 | /* | ||
333 | * Ask the VM to offline this memory range. | ||
334 | * Note: Assume that this function returns zero on success | ||
335 | */ | ||
336 | result = acpi_memory_remove_memory(mem_device); | ||
337 | if (result) | ||
338 | return result; | ||
339 | |||
328 | /* Power-off and eject the device */ | 340 | /* Power-off and eject the device */ |
329 | result = acpi_memory_powerdown_device(mem_device); | 341 | result = acpi_memory_powerdown_device(mem_device); |
330 | if (result) { | 342 | if (result) { |
@@ -474,12 +486,17 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
474 | static int acpi_memory_device_remove(struct acpi_device *device, int type) | 486 | static int acpi_memory_device_remove(struct acpi_device *device, int type) |
475 | { | 487 | { |
476 | struct acpi_memory_device *mem_device = NULL; | 488 | struct acpi_memory_device *mem_device = NULL; |
477 | 489 | int result; | |
478 | 490 | ||
479 | if (!device || !acpi_driver_data(device)) | 491 | if (!device || !acpi_driver_data(device)) |
480 | return -EINVAL; | 492 | return -EINVAL; |
481 | 493 | ||
482 | mem_device = acpi_driver_data(device); | 494 | mem_device = acpi_driver_data(device); |
495 | |||
496 | result = acpi_memory_remove_memory(mem_device); | ||
497 | if (result) | ||
498 | return result; | ||
499 | |||
483 | kfree(mem_device); | 500 | kfree(mem_device); |
484 | 501 | ||
485 | return 0; | 502 | return 0; |