// SPDX-License-Identifier: GPL-2.0
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/cpu.h>
#include <linux/of.h>
#include <linux/spinlock.h>
#include <linux/msi.h>

#include <asm/smp.h>
#include <asm/machdep.h>
#include <asm/irq.h>
#include <asm/errno.h>
#include <asm/xics.h>
#include <asm/rtas.h>

/* RTAS service tokens */
static int ibm_get_xive;
static int ibm_set_xive;
static int ibm_int_on;
static int ibm_int_off;

static void ics_rtas_unmask_irq(struct irq_data *d)
{
	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
	int call_status;
	int server;

	pr_devel("xics: unmask virq %d [hw 0x%x]\n", d->irq, hw_irq);

	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
		return;

	server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);

	call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
					  server, DEFAULT_PRIORITY);
	if (call_status != 0) {
		printk(KERN_ERR
			"%s: ibm_set_xive irq %u server %x returned %d\n",
			__func__, hw_irq, server, call_status);
		return;
	}

	/* Now unmask the interrupt (often a no-op) */
	call_status = rtas_call_reentrant(ibm_int_on, 1, 1, NULL, hw_irq);
	if (call_status != 0) {
		printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
			__func__, hw_irq, call_status);
		return;
	}
}

static unsigned int ics_rtas_startup(struct irq_data *d)
{
	/* unmask it */
	ics_rtas_unmask_irq(d);
	return 0;
}

static void ics_rtas_mask_real_irq(unsigned int hw_irq)
{
	int call_status;

	if (hw_irq == XICS_IPI)
		return;

	call_status = rtas_call_reentrant(ibm_int_off, 1, 1, NULL, hw_irq);
	if (call_status != 0) {
		printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
			__func__, hw_irq, call_status);
		return;
	}

	/* Have to set XIVE to 0xff to be able to remove a slot */
	call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
					  xics_default_server, 0xff);
	if (call_status != 0) {
		printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
			__func__, hw_irq, call_status);
		return;
	}
}

static void ics_rtas_mask_irq(struct irq_data *d)
{
	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);

	pr_devel("xics: mask virq %d [hw 0x%x]\n", d->irq, hw_irq);

	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
		return;
	ics_rtas_mask_real_irq(hw_irq);
}

static int ics_rtas_set_affinity(struct irq_data *d,
				 const struct cpumask *cpumask,
				 bool force)
{
	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
	int status;
	int xics_status[2];
	int irq_server;

	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
		return -1;

	status = rtas_call_reentrant(ibm_get_xive, 1, 3, xics_status, hw_irq);

	if (status) {
		printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
			__func__, hw_irq, status);
		return -1;
	}

	irq_server = xics_get_irq_server(d->irq, cpumask, 1);
	if (irq_server == -1) {
		pr_warn("%s: No online cpus in the mask %*pb for irq %d\n",
			__func__, cpumask_pr_args(cpumask), d->irq);
		return -1;
	}

	pr_debug("%s: irq %d [hw 0x%x] server: 0x%x\n", __func__, d->irq,
		 hw_irq, irq_server);

	status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL,
				     hw_irq, irq_server, xics_status[1]);

	if (status) {
		printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
			__func__, hw_irq, status);
		return -1;
	}

	return IRQ_SET_MASK_OK;
}

static struct irq_chip ics_rtas_irq_chip = {
	.name = "XICS",
	.irq_startup = ics_rtas_startup,
	.irq_mask = ics_rtas_mask_irq,
	.irq_unmask = ics_rtas_unmask_irq,
	.irq_eoi = NULL, /* Patched at init time */
	.irq_set_affinity = ics_rtas_set_affinity,
	.irq_set_type = xics_set_irq_type,
	.irq_retrigger = xics_retrigger,
};

static int ics_rtas_check(struct ics *ics, unsigned int hw_irq)
{
	int status[2];
	int rc;

	if (WARN_ON(hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS))
		return -EINVAL;

	/* Check if RTAS knows about this interrupt */
	rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, hw_irq);
	if (rc)
		return -ENXIO;

	return 0;
}

static void ics_rtas_mask_unknown(struct ics *ics, unsigned long vec)
{
	ics_rtas_mask_real_irq(vec);
}

static long ics_rtas_get_server(struct ics *ics, unsigned long vec)
{
	int rc, status[2];

	rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, vec);
	if (rc)
		return -1;
	return status[0];
}

static int ics_rtas_host_match(struct ics *ics, struct device_node *node)
{
	/* IBM machines have interrupt parents of various funky types for things
	 * like vdevices, events, etc... The trick we use here is to match
	 * everything here except the legacy 8259 which is compatible "chrp,iic"
	 */
	return !of_device_is_compatible(node, "chrp,iic");
}

/* Only one global & state struct ics */
static struct ics ics_rtas = {
	.check		= ics_rtas_check,
	.mask_unknown	= ics_rtas_mask_unknown,
	.get_server	= ics_rtas_get_server,
	.host_match	= ics_rtas_host_match,
	.chip = &ics_rtas_irq_chip,
};

__init int ics_rtas_init(void)
{
	ibm_get_xive = rtas_token("ibm,get-xive");
	ibm_set_xive = rtas_token("ibm,set-xive");
	ibm_int_on  = rtas_token("ibm,int-on");
	ibm_int_off = rtas_token("ibm,int-off");

	/* We enable the RTAS "ICS" if RTAS is present with the
	 * appropriate tokens
	 */
	if (ibm_get_xive == RTAS_UNKNOWN_SERVICE ||
	    ibm_set_xive == RTAS_UNKNOWN_SERVICE)
		return -ENODEV;

	/* We need to patch our irq chip's EOI to point to the
	 * right ICP
	 */
	ics_rtas_irq_chip.irq_eoi = icp_ops->eoi;

	/* Register ourselves */
	xics_register_ics(&ics_rtas);

	return 0;
}

