/*
 * Copyright (C) 2012 Intel Corporation
 *    Author: Liu Jinsong <jinsong.liu@intel.com>
 *    Author: Jiang Yunhong <yunhong.jiang@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/acpi.h>
#include <xen/acpi.h>
#include <xen/interface/platform.h>
#include <asm/xen/hypercall.h>

#define PREFIX "ACPI:xen_memory_hotplug:"

struct acpi_memory_info {
	struct list_head list;
	u64 start_addr;		/* Memory Range start physical addr */
	u64 length;		/* Memory Range length */
	unsigned short caching;	/* memory cache attribute */
	unsigned short write_protect;	/* memory read/write attribute */
				/* copied from buffer getting from _CRS */
	unsigned int enabled:1;
};

struct acpi_memory_device {
	struct acpi_device *device;
	struct list_head res_list;
};

static bool acpi_hotmem_initialized __read_mostly;

static int xen_hotadd_memory(int pxm, struct acpi_memory_info *info)
{
	int rc;
	struct xen_platform_op op;

	op.cmd = XENPF_mem_hotadd;
	op.u.mem_add.spfn = info->start_addr >> PAGE_SHIFT;
	op.u.mem_add.epfn = (info->start_addr + info->length) >> PAGE_SHIFT;
	op.u.mem_add.pxm = pxm;

	rc = HYPERVISOR_dom0_op(&op);
	if (rc)
		pr_err(PREFIX "Xen Hotplug Memory Add failed on "
			"0x%lx -> 0x%lx, _PXM: %d, error: %d\n",
			(unsigned long)info->start_addr,
			(unsigned long)(info->start_addr + info->length),
			pxm, rc);

	return rc;
}

static int xen_acpi_memory_enable_device(struct acpi_memory_device *mem_device)
{
	int pxm, result;
	int num_enabled = 0;
	struct acpi_memory_info *info;

	if (!mem_device)
		return -EINVAL;

	pxm = xen_acpi_get_pxm(mem_device->device->handle);
	if (pxm < 0)
		return pxm;

	list_for_each_entry(info, &mem_device->res_list, list) {
		if (info->enabled) { /* just sanity check...*/
			num_enabled++;
			continue;
		}

		if (!info->length)
			continue;

		result = xen_hotadd_memory(pxm, info);
		if (result)
			continue;
		info->enabled = 1;
		num_enabled++;
	}

	if (!num_enabled)
		return -ENODEV;

	return 0;
}

static acpi_status
acpi_memory_get_resource(struct acpi_resource *resource, void *context)
{
	struct acpi_memory_device *mem_device = context;
	struct acpi_resource_address64 address64;
	struct acpi_memory_info *info, *new;
	acpi_status status;

	status = acpi_resource_to_address64(resource, &address64);
	if (ACPI_FAILURE(status) ||
	    (address64.resource_type != ACPI_MEMORY_RANGE))
		return AE_OK;

	list_for_each_entry(info, &mem_device->res_list, list) {
		if ((info->caching == address64.info.mem.caching) &&
		    (info->write_protect == address64.info.mem.write_protect) &&
		    (info->start_addr + info->length == address64.minimum)) {
			info->length += address64.address_length;
			return AE_OK;
		}
	}

	new = kzalloc(sizeof(struct acpi_memory_info), GFP_KERNEL);
	if (!new)
		return AE_ERROR;

	INIT_LIST_HEAD(&new->list);
	new->caching = address64.info.mem.caching;
	new->write_protect = address64.info.mem.write_protect;
	new->start_addr = address64.minimum;
	new->length = address64.address_length;
	list_add_tail(&new->list, &mem_device->res_list);

	return AE_OK;
}

static int
acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
{
	acpi_status status;
	struct acpi_memory_info *info, *n;

	if (!list_empty(&mem_device->res_list))
		return 0;

	status = acpi_walk_resources(mem_device->device->handle,
		METHOD_NAME__CRS, acpi_memory_get_resource, mem_device);

	if (ACPI_FAILURE(status)) {
		list_for_each_entry_safe(info, n, &mem_device->res_list, list)
			kfree(info);
		INIT_LIST_HEAD(&mem_device->res_list);
		return -EINVAL;
	}

	return 0;
}

static int acpi_memory_get_device(acpi_handle handle,
				  struct acpi_memory_device **mem_device)
{
	struct acpi_device *device = NULL;
	int result = 0;

	acpi_scan_lock_acquire();

	acpi_bus_get_device(handle, &device);
	if (acpi_device_enumerated(device))
		goto end;

	/*
	 * Now add the notified device.  This creates the acpi_device
	 * and invokes .add function
	 */
	result = acpi_bus_scan(handle);
	if (result) {
		pr_warn(PREFIX "ACPI namespace scan failed\n");
		result = -EINVAL;
		goto out;
	}
	device = NULL;
	acpi_bus_get_device(handle, &device);
	if (!acpi_device_enumerated(device)) {
		pr_warn(PREFIX "Missing device object\n");
		result = -EINVAL;
		goto out;
	}

end:
	*mem_device = acpi_driver_data(device);
	if (!(*mem_device)) {
		pr_err(PREFIX "driver data not found\n");
		result = -ENODEV;
		goto out;
	}

out:
	acpi_scan_lock_release();
	return result;
}

static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
{
	unsigned long long current_status;

	/* Get device present/absent information from the _STA */
	if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle,
				"_STA", NULL, &current_status)))
		return -ENODEV;
	/*
	 * Check for device status. Device should be
	 * present/enabled/functioning.
	 */
	if (!((current_status & ACPI_STA_DEVICE_PRESENT)
	      && (current_status & ACPI_STA_DEVICE_ENABLED)
	      && (current_status & ACPI_STA_DEVICE_FUNCTIONING)))
		return -ENODEV;

	return 0;
}

static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
{
	pr_debug(PREFIX "Xen does not support memory hotremove\n");

	return -ENOSYS;
}

static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
{
	struct acpi_memory_device *mem_device;
	struct acpi_device *device;
	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */

	switch (event) {
	case ACPI_NOTIFY_BUS_CHECK:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			"\nReceived BUS CHECK notification for device\n"));
		/* Fall Through */
	case ACPI_NOTIFY_DEVICE_CHECK:
		if (event == ACPI_NOTIFY_DEVICE_CHECK)
			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			"\nReceived DEVICE CHECK notification for device\n"));

		if (acpi_memory_get_device(handle, &mem_device)) {
			pr_err(PREFIX "Cannot find driver data\n");
			break;
		}

		ost_code = ACPI_OST_SC_SUCCESS;
		break;

	case ACPI_NOTIFY_EJECT_REQUEST:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			"\nReceived EJECT REQUEST notification for device\n"));

		acpi_scan_lock_acquire();
		if (acpi_bus_get_device(handle, &device)) {
			acpi_scan_lock_release();
			pr_err(PREFIX "Device doesn't exist\n");
			break;
		}
		mem_device = acpi_driver_data(device);
		if (!mem_device) {
			acpi_scan_lock_release();
			pr_err(PREFIX "Driver Data is NULL\n");
			break;
		}

		/*
		 * TBD: implement acpi_memory_disable_device and invoke
		 * acpi_bus_remove if Xen support hotremove in the future
		 */
		acpi_memory_disable_device(mem_device);
		acpi_scan_lock_release();
		break;

	default:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Unsupported event [0x%x]\n", event));
		/* non-hotplug event; possibly handled by other handler */
		return;
	}

	(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
	return;
}

static int xen_acpi_memory_device_add(struct acpi_device *device)
{
	int result;
	struct acpi_memory_device *mem_device = NULL;


	if (!device)
		return -EINVAL;

	mem_device = kzalloc(sizeof(struct acpi_memory_device), GFP_KERNEL);
	if (!mem_device)
		return -ENOMEM;

	INIT_LIST_HEAD(&mem_device->res_list);
	mem_device->device = device;
	sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME);
	sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS);
	device->driver_data = mem_device;

	/* Get the range from the _CRS */
	result = acpi_memory_get_device_resources(mem_device);
	if (result) {
		kfree(mem_device);
		return result;
	}

	/*
	 * For booting existed memory devices, early boot code has recognized
	 * memory area by EFI/E820. If DSDT shows these memory devices on boot,
	 * hotplug is not necessary for them.
	 * For hot-added memory devices during runtime, it need hypercall to
	 * Xen hypervisor to add memory.
	 */
	if (!acpi_hotmem_initialized)
		return 0;

	if (!acpi_memory_check_device(mem_device))
		result = xen_acpi_memory_enable_device(mem_device);

	return result;
}

static int xen_acpi_memory_device_remove(struct acpi_device *device)
{
	struct acpi_memory_device *mem_device = NULL;

	if (!device || !acpi_driver_data(device))
		return -EINVAL;

	mem_device = acpi_driver_data(device);
	kfree(mem_device);

	return 0;
}

/*
 * Helper function to check for memory device
 */
static acpi_status is_memory_device(acpi_handle handle)
{
	char *hardware_id;
	acpi_status status;
	struct acpi_device_info *info;

	status = acpi_get_object_info(handle, &info);
	if (ACPI_FAILURE(status))
		return status;

	if (!(info->valid & ACPI_VALID_HID)) {
		kfree(info);
		return AE_ERROR;
	}

	hardware_id = info->hardware_id.string;
	if ((hardware_id == NULL) ||
	    (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID)))
		status = AE_ERROR;

	kfree(info);
	return status;
}

static acpi_status
acpi_memory_register_notify_handler(acpi_handle handle,
				    u32 level, void *ctxt, void **retv)
{
	acpi_status status;

	status = is_memory_device(handle);
	if (ACPI_FAILURE(status))
		return AE_OK;	/* continue */

	status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
					     acpi_memory_device_notify, NULL);
	/* continue */
	return AE_OK;
}

static acpi_status
acpi_memory_deregister_notify_handler(acpi_handle handle,
				      u32 level, void *ctxt, void **retv)
{
	acpi_status status;

	status = is_memory_device(handle);
	if (ACPI_FAILURE(status))
		return AE_OK;	/* continue */

	status = acpi_remove_notify_handler(handle,
					    ACPI_SYSTEM_NOTIFY,
					    acpi_memory_device_notify);

	return AE_OK;	/* continue */
}

static const struct acpi_device_id memory_device_ids[] = {
	{ACPI_MEMORY_DEVICE_HID, 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, memory_device_ids);

static struct acpi_driver xen_acpi_memory_device_driver = {
	.name = "acpi_memhotplug",
	.class = ACPI_MEMORY_DEVICE_CLASS,
	.ids = memory_device_ids,
	.ops = {
		.add = xen_acpi_memory_device_add,
		.remove = xen_acpi_memory_device_remove,
		},
};

static int __init xen_acpi_memory_device_init(void)
{
	int result;
	acpi_status status;

	if (!xen_initial_domain())
		return -ENODEV;

	/* unregister the stub which only used to reserve driver space */
	xen_stub_memory_device_exit();

	result = acpi_bus_register_driver(&xen_acpi_memory_device_driver);
	if (result < 0) {
		xen_stub_memory_device_init();
		return -ENODEV;
	}

	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
				     ACPI_UINT32_MAX,
				     acpi_memory_register_notify_handler,
				     NULL, NULL, NULL);

	if (ACPI_FAILURE(status)) {
		pr_warn(PREFIX "walk_namespace failed\n");
		acpi_bus_unregister_driver(&xen_acpi_memory_device_driver);
		xen_stub_memory_device_init();
		return -ENODEV;
	}

	acpi_hotmem_initialized = true;
	return 0;
}

static void __exit xen_acpi_memory_device_exit(void)
{
	acpi_status status;

	if (!xen_initial_domain())
		return;

	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
				     ACPI_UINT32_MAX,
				     acpi_memory_deregister_notify_handler,
				     NULL, NULL, NULL);
	if (ACPI_FAILURE(status))
		pr_warn(PREFIX "walk_namespace failed\n");

	acpi_bus_unregister_driver(&xen_acpi_memory_device_driver);

	/*
	 * stub reserve space again to prevent any chance of native
	 * driver loading.
	 */
	xen_stub_memory_device_init();
	return;
}

module_init(xen_acpi_memory_device_init);
module_exit(xen_acpi_memory_device_exit);
ACPI_MODULE_NAME("xen-acpi-memhotplug");
MODULE_AUTHOR("Liu Jinsong <jinsong.liu@intel.com>");
MODULE_DESCRIPTION("Xen Hotplug Mem Driver");
MODULE_LICENSE("GPL");
