// 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 */
	{"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 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 (adev->parent)
		dev->dev.parent = acpi_get_first_physical_node(adev->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);
}
