// SPDX-License-Identifier: GPL-2.0-only
/*
 * IOAPIC/IOxAPIC/IOSAPIC driver
 *
 * Copyright (C) 2009 Fujitsu Limited.
 * (c) Copyright 2009 Hewlett-Packard Development Company, L.P.
 *
 * Copyright (C) 2014 Intel Corporation
 *
 * Based on original drivers/pci/ioapic.c
 *	Yinghai Lu <yinghai@kernel.org>
 *	Jiang Liu <jiang.liu@intel.com>
 */

/*
 * This driver manages I/O APICs added by hotplug after boot.
 * We try to claim all I/O APIC devices, but those present at boot were
 * registered when we parsed the ACPI MADT.
 */

#define pr_fmt(fmt) "ACPI: IOAPIC: " fmt

#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/pci.h>
#include <acpi/acpi.h>

struct acpi_pci_ioapic {
	acpi_handle	root_handle;
	acpi_handle	handle;
	u32		gsi_base;
	struct resource	res;
	struct pci_dev	*pdev;
	struct list_head list;
};

static LIST_HEAD(ioapic_list);
static DEFINE_MUTEX(ioapic_list_lock);

static acpi_status setup_res(struct acpi_resource *acpi_res, void *data)
{
	struct resource *res = data;
	struct resource_win win;

	/*
	 * We might assign this to 'res' later, make sure all pointers are
	 * cleared before the resource is added to the global list
	 */
	memset(&win, 0, sizeof(win));

	res->flags = 0;
	if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
		return AE_OK;

	if (!acpi_dev_resource_memory(acpi_res, res)) {
		if (acpi_dev_resource_address_space(acpi_res, &win) ||
		    acpi_dev_resource_ext_address_space(acpi_res, &win))
			*res = win.res;
	}
	if ((res->flags & IORESOURCE_PREFETCH) ||
	    (res->flags & IORESOURCE_DISABLED))
		res->flags = 0;

	return AE_CTRL_TERMINATE;
}

static bool acpi_is_ioapic(acpi_handle handle, char **type)
{
	acpi_status status;
	struct acpi_device_info *info;
	char *hid = NULL;
	bool match = false;

	if (!acpi_has_method(handle, "_GSB"))
		return false;

	status = acpi_get_object_info(handle, &info);
	if (ACPI_SUCCESS(status)) {
		if (info->valid & ACPI_VALID_HID)
			hid = info->hardware_id.string;
		if (hid) {
			if (strcmp(hid, "ACPI0009") == 0) {
				*type = "IOxAPIC";
				match = true;
			} else if (strcmp(hid, "ACPI000A") == 0) {
				*type = "IOAPIC";
				match = true;
			}
		}
		kfree(info);
	}

	return match;
}

static acpi_status handle_ioapic_add(acpi_handle handle, u32 lvl,
				     void *context, void **rv)
{
	acpi_status status;
	unsigned long long gsi_base;
	struct acpi_pci_ioapic *ioapic;
	struct pci_dev *dev = NULL;
	struct resource *res = NULL, *pci_res = NULL, *crs_res;
	char *type = NULL;

	if (!acpi_is_ioapic(handle, &type))
		return AE_OK;

	mutex_lock(&ioapic_list_lock);
	list_for_each_entry(ioapic, &ioapic_list, list)
		if (ioapic->handle == handle) {
			mutex_unlock(&ioapic_list_lock);
			return AE_OK;
		}

	status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsi_base);
	if (ACPI_FAILURE(status)) {
		acpi_handle_warn(handle, "failed to evaluate _GSB method\n");
		goto exit;
	}

	ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL);
	if (!ioapic) {
		pr_err("cannot allocate memory for new IOAPIC\n");
		goto exit;
	} else {
		ioapic->root_handle = (acpi_handle)context;
		ioapic->handle = handle;
		ioapic->gsi_base = (u32)gsi_base;
		INIT_LIST_HEAD(&ioapic->list);
	}

	if (acpi_ioapic_registered(handle, (u32)gsi_base))
		goto done;

	dev = acpi_get_pci_dev(handle);
	if (dev && pci_resource_len(dev, 0)) {
		if (pci_enable_device(dev) < 0)
			goto exit_put;
		pci_set_master(dev);
		if (pci_request_region(dev, 0, type))
			goto exit_disable;
		pci_res = &dev->resource[0];
		ioapic->pdev = dev;
	} else {
		pci_dev_put(dev);
		dev = NULL;
	}

	crs_res = &ioapic->res;
	acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
	crs_res->name = type;
	crs_res->flags |= IORESOURCE_BUSY;
	if (crs_res->flags == 0) {
		acpi_handle_warn(handle, "failed to get resource\n");
		goto exit_release;
	} else if (insert_resource(&iomem_resource, crs_res)) {
		acpi_handle_warn(handle, "failed to insert resource\n");
		goto exit_release;
	}

	/* try pci resource first, then "_CRS" resource */
	res = pci_res;
	if (!res || !res->flags)
		res = crs_res;

	if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
		acpi_handle_warn(handle, "failed to register IOAPIC\n");
		goto exit_release;
	}
done:
	list_add(&ioapic->list, &ioapic_list);
	mutex_unlock(&ioapic_list_lock);

	if (dev)
		dev_info(&dev->dev, "%s at %pR, GSI %u\n",
			 type, res, (u32)gsi_base);
	else
		acpi_handle_info(handle, "%s at %pR, GSI %u\n",
				 type, res, (u32)gsi_base);

	return AE_OK;

exit_release:
	if (dev)
		pci_release_region(dev, 0);
	if (ioapic->res.flags && ioapic->res.parent)
		release_resource(&ioapic->res);
exit_disable:
	if (dev)
		pci_disable_device(dev);
exit_put:
	pci_dev_put(dev);
	kfree(ioapic);
exit:
	mutex_unlock(&ioapic_list_lock);
	*(acpi_status *)rv = AE_ERROR;
	return AE_OK;
}

int acpi_ioapic_add(acpi_handle root_handle)
{
	acpi_status status, retval = AE_OK;

	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
				     UINT_MAX, handle_ioapic_add, NULL,
				     root_handle, (void **)&retval);

	return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
}

void pci_ioapic_remove(struct acpi_pci_root *root)
{
	struct acpi_pci_ioapic *ioapic, *tmp;

	mutex_lock(&ioapic_list_lock);
	list_for_each_entry_safe(ioapic, tmp, &ioapic_list, list) {
		if (root->device->handle != ioapic->root_handle)
			continue;
		if (ioapic->pdev) {
			pci_release_region(ioapic->pdev, 0);
			pci_disable_device(ioapic->pdev);
			pci_dev_put(ioapic->pdev);
		}
	}
	mutex_unlock(&ioapic_list_lock);
}

int acpi_ioapic_remove(struct acpi_pci_root *root)
{
	int retval = 0;
	struct acpi_pci_ioapic *ioapic, *tmp;

	mutex_lock(&ioapic_list_lock);
	list_for_each_entry_safe(ioapic, tmp, &ioapic_list, list) {
		if (root->device->handle != ioapic->root_handle)
			continue;
		if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
			retval = -EBUSY;
		if (ioapic->res.flags && ioapic->res.parent)
			release_resource(&ioapic->res);
		list_del(&ioapic->list);
		kfree(ioapic);
	}
	mutex_unlock(&ioapic_list_lock);

	return retval;
}
