Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19387b27 authored by Yasuaki Ishimatsu's avatar Yasuaki Ishimatsu Committed by Rafael J. Wysocki
Browse files

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: default avatarYasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Signed-off-by: default avatarWen Congyang <wency@cn.fujitsu.com>
Acked-by: default avatarDavid Rientjes <rientjes@google.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 54c4c7db
Loading
Loading
Loading
Loading
+24 −7
Original line number Diff line number Diff line
@@ -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;