// SPDX-License-Identifier: GPL-2.0-only
/*
 * Author: Sudeep Holla <sudeep.holla@arm.com>
 * Copyright 2021 Arm Limited
 *
 * The PCC Address Space also referred as PCC Operation Region pertains to the
 * region of PCC subspace that succeeds the PCC signature. The PCC Operation
 * Region works in conjunction with the PCC Table(Platform Communications
 * Channel Table). PCC subspaces that are marked for use as PCC Operation
 * Regions must not be used as PCC subspaces for the standard ACPI features
 * such as CPPC, RASF, PDTT and MPST. These standard features must always use
 * the PCC Table instead.
 *
 * This driver sets up the PCC Address Space and installs an handler to enable
 * handling of PCC OpRegion in the firmware.
 *
 */
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/completion.h>
#include <linux/idr.h>
#include <linux/io.h>

#include <acpi/pcc.h>

/*
 * Arbitrary retries in case the remote processor is slow to respond
 * to PCC commands
 */
#define PCC_CMD_WAIT_RETRIES_NUM	500ULL

struct pcc_data {
	struct pcc_mbox_chan *pcc_chan;
	struct completion done;
	struct mbox_client cl;
	struct acpi_pcc_info ctx;
};

static struct acpi_pcc_info pcc_ctx;

static void pcc_rx_callback(struct mbox_client *cl, void *m)
{
	struct pcc_data *data = container_of(cl, struct pcc_data, cl);

	complete(&data->done);
}

static acpi_status
acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
			     void *handler_context,  void **region_context)
{
	struct pcc_data *data;
	struct acpi_pcc_info *ctx = handler_context;
	struct pcc_mbox_chan *pcc_chan;
	acpi_status ret;

	data = kzalloc_obj(*data);
	if (!data)
		return AE_NO_MEMORY;

	data->cl.rx_callback = pcc_rx_callback;
	data->cl.knows_txdone = true;
	data->ctx.length = ctx->length;
	data->ctx.subspace_id = ctx->subspace_id;
	data->ctx.internal_buffer = ctx->internal_buffer;

	init_completion(&data->done);
	data->pcc_chan = pcc_mbox_request_channel(&data->cl, ctx->subspace_id);
	if (IS_ERR(data->pcc_chan)) {
		pr_err("Failed to find PCC channel for subspace %d\n",
		       ctx->subspace_id);
		ret = AE_NOT_FOUND;
		goto err_free_data;
	}

	pcc_chan = data->pcc_chan;
	if (!pcc_chan->mchan->mbox->txdone_irq) {
		pr_err("This channel-%d does not support interrupt.\n",
		       ctx->subspace_id);
		ret = AE_SUPPORT;
		goto err_free_channel;
	}

	*region_context = data;
	return AE_OK;

err_free_channel:
	pcc_mbox_free_channel(data->pcc_chan);
err_free_data:
	kfree(data);

	return ret;
}

static acpi_status
acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
			       u32 bits, acpi_integer *value,
			       void *handler_context, void *region_context)
{
	int ret;
	struct pcc_data *data = region_context;
	u64 usecs_lat;

	reinit_completion(&data->done);

	/* Write to Shared Memory */
	memcpy_toio(data->pcc_chan->shmem, (void *)value, data->ctx.length);

	ret = mbox_send_message(data->pcc_chan->mchan, NULL);
	if (ret < 0)
		return AE_ERROR;

	/*
	 * pcc_chan->latency is just a Nominal value. In reality the remote
	 * processor could be much slower to reply. So add an arbitrary
	 * amount of wait on top of Nominal.
	 */
	usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
	ret = wait_for_completion_timeout(&data->done,
						usecs_to_jiffies(usecs_lat));
	if (ret == 0) {
		pr_err("PCC command executed timeout!\n");
		return AE_TIME;
	}

	mbox_chan_txdone(data->pcc_chan->mchan, ret);

	memcpy_fromio(value, data->pcc_chan->shmem, data->ctx.length);

	return AE_OK;
}

void __init acpi_init_pcc(void)
{
	acpi_status status;

	status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
						    ACPI_ADR_SPACE_PLATFORM_COMM,
						    &acpi_pcc_address_space_handler,
						    &acpi_pcc_address_space_setup,
						    &pcc_ctx);
	if (ACPI_FAILURE(status))
		pr_alert("OperationRegion handler could not be installed\n");
}
