// SPDX-License-Identifier: GPL-2.0-only

/*
 * ACPI support for platform bus type.
 *
 * Copyright (C) 2015, Linaro Ltd
 * Author: Graeme Gregory <graeme.gregory@linaro.org>
 */

#include <linux/acpi.h>
#include <linux/amba/bus.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include "internal.h"

static const struct acpi_device_id amba_id_list[] = {
	{"ARMH0061", 0}, /* PL061 GPIO Device */
	{"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */
	{"ARMHC500", 0}, /* ARM CoreSight ETM4x */
	{"ARMHC501", 0}, /* ARM CoreSight ETR */
	{"ARMHC502", 0}, /* ARM CoreSight STM */
	{"ARMHC503", 0}, /* ARM CoreSight Debug */
	{"ARMHC979", 0}, /* ARM CoreSight TPIU */
	{"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
	{"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
	{"ARMHC9CA", 0}, /* ARM CoreSight CATU */
	{"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */
	{"", 0},
};

static void amba_register_dummy_clk(void)
{
	static struct clk *amba_dummy_clk;

	/* If clock already registered */
	if (amba_dummy_clk)
		return;

	amba_dummy_clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0);
	clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
}

static int amba_handler_attach(struct acpi_device *adev,
				const struct acpi_device_id *id)
{
	struct acpi_device *parent = acpi_dev_parent(adev);
	struct amba_device *dev;
	struct resource_entry *rentry;
	struct list_head resource_list;
	bool address_found = false;
	int irq_no = 0;
	int ret;

	/* If the ACPI node already has a physical device attached, skip it. */
	if (adev->physical_node_count)
		return 0;

	dev = amba_device_alloc(dev_name(&adev->dev), 0, 0);
	if (!dev) {
		dev_err(&adev->dev, "%s(): amba_device_alloc() failed\n",
			__func__);
		return -ENOMEM;
	}

	INIT_LIST_HEAD(&resource_list);
	ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
	if (ret < 0)
		goto err_free;

	list_for_each_entry(rentry, &resource_list, node) {
		switch (resource_type(rentry->res)) {
		case IORESOURCE_MEM:
			if (!address_found) {
				dev->res = *rentry->res;
				dev->res.name = dev_name(&dev->dev);
				address_found = true;
			}
			break;
		case IORESOURCE_IRQ:
			if (irq_no < AMBA_NR_IRQS)
				dev->irq[irq_no++] = rentry->res->start;
			break;
		default:
			dev_warn(&adev->dev, "Invalid resource\n");
			break;
		}
	}

	acpi_dev_free_resource_list(&resource_list);

	/*
	 * 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 amba device we are about to create.
	 */
	if (parent)
		dev->dev.parent = acpi_get_first_physical_node(parent);

	ACPI_COMPANION_SET(&dev->dev, adev);

	ret = amba_device_add(dev, &iomem_resource);
	if (ret) {
		dev_err(&adev->dev, "%s(): amba_device_add() failed (%d)\n",
		       __func__, ret);
		goto err_free;
	}

	return 1;

err_free:
	amba_device_put(dev);
	return ret;
}

static struct acpi_scan_handler amba_handler = {
	.ids = amba_id_list,
	.attach = amba_handler_attach,
};

void __init acpi_amba_init(void)
{
	amba_register_dummy_clk();
	acpi_scan_add_handler(&amba_handler);
}
