// SPDX-License-Identifier: GPL-2.0-only
/*
 * ACPI support for platform bus type.
 *
 * Copyright (C) 2012, Intel Corporation
 * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
 *          Mathias Nyman <mathias.nyman@linux.intel.com>
 *          Rafael J. Wysocki <rafael.j.wysocki@intel.com>
 */

#include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/platform_device.h>

#include "internal.h"

/* Exclude devices that have no _CRS resources provided */
#define ACPI_ALLOW_WO_RESOURCES		BIT(0)

static const struct acpi_device_id forbidden_id_list[] = {
	{"ACPI0009", 0},	/* IOxAPIC */
	{"ACPI000A", 0},	/* IOAPIC */
	{"PNP0000",  0},	/* PIC */
	{"PNP0100",  0},	/* Timer */
	{"PNP0200",  0},	/* AT DMA Controller */
	{ACPI_SMBUS_MS_HID,  ACPI_ALLOW_WO_RESOURCES},	/* ACPI SMBUS virtual device */
	{ }
};

static struct platform_device *acpi_platform_device_find_by_companion(struct acpi_device *adev)
{
	struct device *dev;

	dev = bus_find_device_by_acpi_dev(&platform_bus_type, adev);
	return dev ? to_platform_device(dev) : NULL;
}

static int acpi_platform_device_remove_notify(struct notifier_block *nb,
					      unsigned long value, void *arg)
{
	struct acpi_device *adev = arg;
	struct platform_device *pdev;

	switch (value) {
	case ACPI_RECONFIG_DEVICE_ADD:
		/* Nothing to do here */
		break;
	case ACPI_RECONFIG_DEVICE_REMOVE:
		if (!acpi_device_enumerated(adev))
			break;

		pdev = acpi_platform_device_find_by_companion(adev);
		if (!pdev)
			break;

		platform_device_unregister(pdev);
		put_device(&pdev->dev);
		break;
	}

	return NOTIFY_OK;
}

static struct notifier_block acpi_platform_notifier = {
	.notifier_call = acpi_platform_device_remove_notify,
};

static unsigned int acpi_platform_adjust_resources(struct acpi_device *adev,
						   struct resource *new_res,
						   struct resource *resources,
						   unsigned int count)
{
	unsigned int i;

	if (!(new_res->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
		return count;

	for (i = 0; i < count; ) {
		struct resource *res = &resources[i];

		/*
		 * Look for overlaps of resources of the same type that would
		 * cause resource insertion to fail down the road.
		 */
		if (__resource_contains_unbound(res, new_res) ||
		    __resource_contains_unbound(new_res, res) ||
		    resource_type(new_res) != resource_type(res) ||
		    !resource_union(new_res, res, new_res)) {
			i++;
			continue;
		}

		dev_info(&adev->dev, "%pR expanded due to overlap\n", new_res);
		/*
		 * Eliminate the previously processed resource that overlapped
		 * with the new one because it is not necessary any more.
		 */
		memmove(res, res + 1, (--count - i) * sizeof(*res));
	}

	return count;
}

static void acpi_platform_fill_resource(struct device *parent,
					const struct resource *src,
					struct resource *dest)
{
	*dest = *src;
	/*
	 * If the device has parent we need to take its resources into
	 * account as well because this device might consume part of those.
	 */
	if (parent && dev_is_pci(parent))
		dest->parent = pci_find_resource(to_pci_dev(parent), dest);
}

static unsigned int acpi_platform_resource_count(struct acpi_resource *ares, void *data)
{
	bool *has_resources = data;

	*has_resources = true;

	return AE_CTRL_TERMINATE;
}

/**
 * acpi_create_platform_device - Create platform device for ACPI device node
 * @adev: ACPI device node to create a platform device for.
 * @properties: Optional collection of build-in properties.
 *
 * Check if the given @adev can be represented as a platform device and, if
 * that's the case, create and register a platform device, populate its common
 * resources and returns a pointer to it.  Otherwise, return %NULL.
 *
 * Name of the platform device will be the same as @adev's.
 */
struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
						    const struct property_entry *properties)
{
	struct acpi_device *p = acpi_dev_parent(adev);
	struct device *parent __free(put_device) = acpi_bus_get_primary_device(p);
	struct platform_device *pdev = NULL;
	struct platform_device_info pdevinfo;
	const struct acpi_device_id *match;
	struct resource *resources = NULL;
	int count = 0;

	/* If the ACPI node already has a physical device attached, skip it. */
	if (adev->physical_node_count && !adev->pnp.type.backlight)
		return NULL;

	match = acpi_match_acpi_device(forbidden_id_list, adev);
	if (match) {
		if (match->driver_data & ACPI_ALLOW_WO_RESOURCES) {
			bool has_resources = false;

			acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
					    acpi_platform_resource_count, &has_resources);
			if (has_resources)
				return ERR_PTR(-EINVAL);
		} else {
			return ERR_PTR(-EINVAL);
		}
	}

	if (adev->device_type == ACPI_BUS_TYPE_DEVICE) {
		LIST_HEAD(resource_list);

		count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
		if (count < 0)
			return ERR_PTR(-ENODATA);

		if (count > 0) {
			struct resource_entry *rentry;

			resources = kzalloc_objs(*resources, count);
			if (!resources) {
				acpi_dev_free_resource_list(&resource_list);
				return ERR_PTR(-ENOMEM);
			}
			count = 0;
			list_for_each_entry(rentry, &resource_list, node) {
				count = acpi_platform_adjust_resources(adev,
								       rentry->res,
								       resources,
								       count);
				acpi_platform_fill_resource(parent, rentry->res,
							    &resources[count++]);
			}
			acpi_dev_free_resource_list(&resource_list);
		}
	}

	memset(&pdevinfo, 0, sizeof(pdevinfo));
	/*
	 * If the ACPI node has a parent and that parent has a physical device
	 * attached to it, that physical device should be the parent of the
	 * platform device we are about to create.
	 */
	pdevinfo.parent = parent;
	pdevinfo.name = dev_name(&adev->dev);
	pdevinfo.id = PLATFORM_DEVID_NONE;
	pdevinfo.res = resources;
	pdevinfo.num_res = count;
	pdevinfo.fwnode = acpi_fwnode_handle(adev);
	pdevinfo.properties = properties;

	if (acpi_dma_supported(adev))
		pdevinfo.dma_mask = DMA_BIT_MASK(32);
	else
		pdevinfo.dma_mask = 0;

	pdev = platform_device_register_full(&pdevinfo);
	if (IS_ERR(pdev))
		dev_err(&adev->dev, "platform device creation failed: %ld\n",
			PTR_ERR(pdev));
	else {
		set_dev_node(&pdev->dev, acpi_get_node(adev->handle));
		dev_dbg(&adev->dev, "created platform device %s\n",
			dev_name(&pdev->dev));
	}

	kfree(resources);

	return pdev;
}
EXPORT_SYMBOL_GPL(acpi_create_platform_device);

void __init acpi_platform_init(void)
{
	acpi_reconfig_notifier_register(&acpi_platform_notifier);
}
