// SPDX-License-Identifier: GPL-2.0
/*
 * ARM APMT table support.
 * Design document number: ARM DEN0117.
 *
 * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
 *
 */

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

#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include "init.h"

#define DEV_NAME "arm-cs-arch-pmu"

/* There can be up to 3 resources: page 0 and 1 address, and interrupt. */
#define DEV_MAX_RESOURCE_COUNT 3

/* Root pointer to the mapped APMT table */
static struct acpi_table_header *apmt_table;

static int __init apmt_init_resources(struct resource *res,
				      struct acpi_apmt_node *node)
{
	int irq, trigger;
	int num_res = 0;

	res[num_res].start = node->base_address0;
	res[num_res].end = node->base_address0 + SZ_4K - 1;
	res[num_res].flags = IORESOURCE_MEM;

	num_res++;

	if (node->flags & ACPI_APMT_FLAGS_DUAL_PAGE) {
		res[num_res].start = node->base_address1;
		res[num_res].end = node->base_address1 + SZ_4K - 1;
		res[num_res].flags = IORESOURCE_MEM;

		num_res++;
	}

	if (node->ovflw_irq != 0) {
		trigger = (node->ovflw_irq_flags & ACPI_APMT_OVFLW_IRQ_FLAGS_MODE);
		trigger = (trigger == ACPI_APMT_OVFLW_IRQ_FLAGS_MODE_LEVEL) ?
			ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
		irq = acpi_register_gsi(NULL, node->ovflw_irq, trigger,
						ACPI_ACTIVE_HIGH);

		if (irq <= 0) {
			pr_warn("APMT could not register gsi hwirq %d\n", irq);
			return num_res;
		}

		res[num_res].start = irq;
		res[num_res].end = irq;
		res[num_res].flags = IORESOURCE_IRQ;

		num_res++;
	}

	return num_res;
}

/**
 * apmt_add_platform_device() - Allocate a platform device for APMT node
 * @node: Pointer to device ACPI APMT node
 * @fwnode: fwnode associated with the APMT node
 *
 * Returns: 0 on success, <0 failure
 */
static int __init apmt_add_platform_device(struct acpi_apmt_node *node,
					   struct fwnode_handle *fwnode)
{
	struct platform_device *pdev;
	int ret, count;
	struct resource res[DEV_MAX_RESOURCE_COUNT];

	pdev = platform_device_alloc(DEV_NAME, PLATFORM_DEVID_AUTO);
	if (!pdev)
		return -ENOMEM;

	memset(res, 0, sizeof(res));

	count = apmt_init_resources(res, node);

	ret = platform_device_add_resources(pdev, res, count);
	if (ret)
		goto dev_put;

	/*
	 * Add a copy of APMT node pointer to platform_data to be used to
	 * retrieve APMT data information.
	 */
	ret = platform_device_add_data(pdev, &node, sizeof(node));
	if (ret)
		goto dev_put;

	pdev->dev.fwnode = fwnode;

	ret = platform_device_add(pdev);

	if (ret)
		goto dev_put;

	return 0;

dev_put:
	platform_device_put(pdev);

	return ret;
}

static int __init apmt_init_platform_devices(void)
{
	struct acpi_apmt_node *apmt_node;
	struct acpi_table_apmt *apmt;
	struct fwnode_handle *fwnode;
	u64 offset, end;
	int ret;

	/*
	 * apmt_table and apmt both point to the start of APMT table, but
	 * have different struct types
	 */
	apmt = (struct acpi_table_apmt *)apmt_table;
	offset = sizeof(*apmt);
	end = apmt->header.length;

	while (offset < end) {
		apmt_node = ACPI_ADD_PTR(struct acpi_apmt_node, apmt,
				 offset);

		fwnode = acpi_alloc_fwnode_static();
		if (!fwnode)
			return -ENOMEM;

		ret = apmt_add_platform_device(apmt_node, fwnode);
		if (ret) {
			acpi_free_fwnode_static(fwnode);
			return ret;
		}

		offset += apmt_node->length;
	}

	return 0;
}

void __init acpi_apmt_init(void)
{
	acpi_status status;
	int ret;

	/**
	 * APMT table nodes will be used at runtime after the apmt init,
	 * so we don't need to call acpi_put_table() to release
	 * the APMT table mapping.
	 */
	status = acpi_get_table(ACPI_SIG_APMT, 0, &apmt_table);

	if (ACPI_FAILURE(status)) {
		if (status != AE_NOT_FOUND) {
			const char *msg = acpi_format_exception(status);

			pr_err("Failed to get APMT table, %s\n", msg);
		}

		return;
	}

	ret = apmt_init_platform_devices();
	if (ret) {
		pr_err("Failed to initialize APMT platform devices, ret: %d\n", ret);
		acpi_put_table(apmt_table);
	}
}
