|
@@ -306,25 +306,37 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
|
|
|
+static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
|
|
|
{
|
|
|
int result;
|
|
|
struct acpi_memory_info *info, *n;
|
|
|
|
|
|
-
|
|
|
- /*
|
|
|
- * Ask the VM to offline this memory range.
|
|
|
- * Note: Assume that this function returns zero on success
|
|
|
- */
|
|
|
list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
|
|
|
if (info->enabled) {
|
|
|
result = remove_memory(info->start_addr, info->length);
|
|
|
if (result)
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ list_del(&info->list);
|
|
|
kfree(info);
|
|
|
}
|
|
|
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
|
|
|
+{
|
|
|
+ int result;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Ask the VM to offline this memory range.
|
|
|
+ * Note: Assume that this function returns zero on success
|
|
|
+ */
|
|
|
+ result = acpi_memory_remove_memory(mem_device);
|
|
|
+ if (result)
|
|
|
+ return result;
|
|
|
+
|
|
|
/* Power-off and eject the device */
|
|
|
result = acpi_memory_powerdown_device(mem_device);
|
|
|
if (result) {
|
|
@@ -474,12 +486,17 @@ static int acpi_memory_device_add(struct acpi_device *device)
|
|
|
static int acpi_memory_device_remove(struct acpi_device *device, int type)
|
|
|
{
|
|
|
struct acpi_memory_device *mem_device = NULL;
|
|
|
-
|
|
|
+ int result;
|
|
|
|
|
|
if (!device || !acpi_driver_data(device))
|
|
|
return -EINVAL;
|
|
|
|
|
|
mem_device = acpi_driver_data(device);
|
|
|
+
|
|
|
+ result = acpi_memory_remove_memory(mem_device);
|
|
|
+ if (result)
|
|
|
+ return result;
|
|
|
+
|
|
|
kfree(mem_device);
|
|
|
|
|
|
return 0;
|