// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright 2011 IBM Corporation.
 */
#include <linux/types.h>
#include <linux/threads.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/debugfs.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/cpu.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/delay.h>

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

/* Globals common to all ICP/ICS implementations */
const struct icp_ops	*icp_ops;

unsigned int xics_default_server		= 0xff;
unsigned int xics_default_distrib_server	= 0;
unsigned int xics_interrupt_server_size		= 8;

DEFINE_PER_CPU(struct xics_cppr, xics_cppr);

struct irq_domain *xics_host;

static struct ics *xics_ics;

void xics_update_irq_servers(void)
{
	int i, j;
	struct device_node *np;
	u32 ilen;
	const __be32 *ireg;
	u32 hcpuid;

	/* Find the server numbers for the boot cpu. */
	np = of_get_cpu_node(boot_cpuid, NULL);
	BUG_ON(!np);

	hcpuid = get_hard_smp_processor_id(boot_cpuid);
	xics_default_server = xics_default_distrib_server = hcpuid;

	pr_devel("xics: xics_default_server = 0x%x\n", xics_default_server);

	ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
	if (!ireg) {
		of_node_put(np);
		return;
	}

	i = ilen / sizeof(int);

	/* Global interrupt distribution server is specified in the last
	 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
	 * entry fom this property for current boot cpu id and use it as
	 * default distribution server
	 */
	for (j = 0; j < i; j += 2) {
		if (be32_to_cpu(ireg[j]) == hcpuid) {
			xics_default_distrib_server = be32_to_cpu(ireg[j+1]);
			break;
		}
	}
	pr_devel("xics: xics_default_distrib_server = 0x%x\n",
		 xics_default_distrib_server);
	of_node_put(np);
}

/* GIQ stuff, currently only supported on RTAS setups, will have
 * to be sorted properly for bare metal
 */
void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
{
#ifdef CONFIG_PPC_RTAS
	int index;
	int status;

	if (!rtas_indicator_present(GLOBAL_INTERRUPT_QUEUE, NULL))
		return;

	index = (1UL << xics_interrupt_server_size) - 1 - gserver;

	status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, index, join);

	WARN(status < 0, "set-indicator(%d, %d, %u) returned %d\n",
	     GLOBAL_INTERRUPT_QUEUE, index, join, status);
#endif
}

void xics_setup_cpu(void)
{
	icp_ops->set_priority(LOWEST_PRIORITY);

	xics_set_cpu_giq(xics_default_distrib_server, 1);
}

void xics_mask_unknown_vec(unsigned int vec)
{
	pr_err("Interrupt 0x%x (real) is invalid, disabling it.\n", vec);

	if (WARN_ON(!xics_ics))
		return;
	xics_ics->mask_unknown(xics_ics, vec);
}


#ifdef CONFIG_SMP

static void __init xics_request_ipi(void)
{
	unsigned int ipi;

	ipi = irq_create_mapping(xics_host, XICS_IPI);
	BUG_ON(!ipi);

	/*
	 * IPIs are marked IRQF_PERCPU. The handler was set in map.
	 */
	BUG_ON(request_irq(ipi, icp_ops->ipi_action,
			   IRQF_NO_DEBUG | IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL));
}

void __init xics_smp_probe(void)
{
	/* Register all the IPIs */
	xics_request_ipi();

	/* Setup cause_ipi callback based on which ICP is used */
	smp_ops->cause_ipi = icp_ops->cause_ipi;
}

#endif /* CONFIG_SMP */

noinstr void xics_teardown_cpu(void)
{
	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);

	/*
	 * we have to reset the cppr index to 0 because we're
	 * not going to return from the IPI
	 */
	os_cppr->index = 0;
	icp_ops->set_priority(0);
	icp_ops->teardown_cpu();
}

noinstr void xics_kexec_teardown_cpu(int secondary)
{
	xics_teardown_cpu();

	icp_ops->flush_ipi();

	/*
	 * Some machines need to have at least one cpu in the GIQ,
	 * so leave the master cpu in the group.
	 */
	if (secondary)
		xics_set_cpu_giq(xics_default_distrib_server, 0);
}


#ifdef CONFIG_HOTPLUG_CPU

/* Interrupts are disabled. */
void xics_migrate_irqs_away(void)
{
	int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
	unsigned int irq, virq;
	struct irq_desc *desc;

	pr_debug("%s: CPU %u\n", __func__, cpu);

	/* If we used to be the default server, move to the new "boot_cpuid" */
	if (hw_cpu == xics_default_server)
		xics_update_irq_servers();

	/* Reject any interrupt that was queued to us... */
	icp_ops->set_priority(0);

	/* Remove ourselves from the global interrupt queue */
	xics_set_cpu_giq(xics_default_distrib_server, 0);

	for_each_irq_desc(virq, desc) {
		struct irq_chip *chip;
		long server;
		unsigned long flags;
		struct irq_data *irqd;

		/* We can't set affinity on ISA interrupts */
		if (virq < NR_IRQS_LEGACY)
			continue;
		/* We only need to migrate enabled IRQS */
		if (!desc->action)
			continue;
		/* We need a mapping in the XICS IRQ domain */
		irqd = irq_domain_get_irq_data(xics_host, virq);
		if (!irqd)
			continue;
		irq = irqd_to_hwirq(irqd);
		/* We need to get IPIs still. */
		if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
			continue;
		chip = irq_desc_get_chip(desc);
		if (!chip || !chip->irq_set_affinity)
			continue;

		raw_spin_lock_irqsave(&desc->lock, flags);

		/* Locate interrupt server */
		server = xics_ics->get_server(xics_ics, irq);
		if (server < 0) {
			pr_err("%s: Can't find server for irq %d/%x\n",
			       __func__, virq, irq);
			goto unlock;
		}

		/* We only support delivery to all cpus or to one cpu.
		 * The irq has to be migrated only in the single cpu
		 * case.
		 */
		if (server != hw_cpu)
			goto unlock;

		/* This is expected during cpu offline. */
		if (cpu_online(cpu))
			pr_warn("IRQ %u affinity broken off cpu %u\n",
				virq, cpu);

		/* Reset affinity to all cpus */
		raw_spin_unlock_irqrestore(&desc->lock, flags);
		irq_set_affinity(virq, cpu_all_mask);
		continue;
unlock:
		raw_spin_unlock_irqrestore(&desc->lock, flags);
	}

	/* Allow "sufficient" time to drop any inflight IRQ's */
	mdelay(5);

	/*
	 * Allow IPIs again. This is done at the very end, after migrating all
	 * interrupts, the expectation is that we'll only get woken up by an IPI
	 * interrupt beyond this point, but leave externals masked just to be
	 * safe. If we're using icp-opal this may actually allow all
	 * interrupts anyway, but that should be OK.
	 */
	icp_ops->set_priority(DEFAULT_PRIORITY);

}
#endif /* CONFIG_HOTPLUG_CPU */

#ifdef CONFIG_SMP
/*
 * For the moment we only implement delivery to all cpus or one cpu.
 *
 * If the requested affinity is cpu_all_mask, we set global affinity.
 * If not we set it to the first cpu in the mask, even if multiple cpus
 * are set. This is so things like irqbalance (which set core and package
 * wide affinities) do the right thing.
 *
 * We need to fix this to implement support for the links
 */
int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
			unsigned int strict_check)
{

	if (!distribute_irqs)
		return xics_default_server;

	if (!cpumask_subset(cpu_possible_mask, cpumask)) {
		int server = cpumask_first_and(cpu_online_mask, cpumask);

		if (server < nr_cpu_ids)
			return get_hard_smp_processor_id(server);

		if (strict_check)
			return -1;
	}

	/*
	 * Workaround issue with some versions of JS20 firmware that
	 * deliver interrupts to cpus which haven't been started. This
	 * happens when using the maxcpus= boot option.
	 */
	if (cpumask_equal(cpu_online_mask, cpu_present_mask))
		return xics_default_distrib_server;

	return xics_default_server;
}
#endif /* CONFIG_SMP */

static int xics_host_match(struct irq_domain *h, struct device_node *node,
			   enum irq_domain_bus_token bus_token)
{
	if (WARN_ON(!xics_ics))
		return 0;
	return xics_ics->host_match(xics_ics, node) ? 1 : 0;
}

/* Dummies */
static void xics_ipi_unmask(struct irq_data *d) { }
static void xics_ipi_mask(struct irq_data *d) { }

static struct irq_chip xics_ipi_chip = {
	.name = "XICS",
	.irq_eoi = NULL, /* Patched at init time */
	.irq_mask = xics_ipi_mask,
	.irq_unmask = xics_ipi_unmask,
};

static int xics_host_map(struct irq_domain *domain, unsigned int virq,
			 irq_hw_number_t hwirq)
{
	pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hwirq);

	/*
	 * Mark interrupts as edge sensitive by default so that resend
	 * actually works. The device-tree parsing will turn the LSIs
	 * back to level.
	 */
	irq_clear_status_flags(virq, IRQ_LEVEL);

	/* Don't call into ICS for IPIs */
	if (hwirq == XICS_IPI) {
		irq_set_chip_and_handler(virq, &xics_ipi_chip,
					 handle_percpu_irq);
		return 0;
	}

	if (WARN_ON(!xics_ics))
		return -EINVAL;

	if (xics_ics->check(xics_ics, hwirq))
		return -EINVAL;

	/* Let the ICS be the chip data for the XICS domain. For ICS native */
	irq_domain_set_info(domain, virq, hwirq, xics_ics->chip,
			    xics_ics, handle_fasteoi_irq, NULL, NULL);

	return 0;
}

static int xics_host_xlate(struct irq_domain *h, struct device_node *ct,
			   const u32 *intspec, unsigned int intsize,
			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)

{
	*out_hwirq = intspec[0];

	/*
	 * If intsize is at least 2, we look for the type in the second cell,
	 * we assume the LSB indicates a level interrupt.
	 */
	if (intsize > 1) {
		if (intspec[1] & 1)
			*out_flags = IRQ_TYPE_LEVEL_LOW;
		else
			*out_flags = IRQ_TYPE_EDGE_RISING;
	} else
		*out_flags = IRQ_TYPE_LEVEL_LOW;

	return 0;
}

int xics_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
	/*
	 * We only support these. This has really no effect other than setting
	 * the corresponding descriptor bits mind you but those will in turn
	 * affect the resend function when re-enabling an edge interrupt.
	 *
	 * Set set the default to edge as explained in map().
	 */
	if (flow_type == IRQ_TYPE_DEFAULT || flow_type == IRQ_TYPE_NONE)
		flow_type = IRQ_TYPE_EDGE_RISING;

	if (flow_type != IRQ_TYPE_EDGE_RISING &&
	    flow_type != IRQ_TYPE_LEVEL_LOW)
		return -EINVAL;

	irqd_set_trigger_type(d, flow_type);

	return IRQ_SET_MASK_OK_NOCOPY;
}

int xics_retrigger(struct irq_data *data)
{
	/*
	 * We need to push a dummy CPPR when retriggering, since the subsequent
	 * EOI will try to pop it. Passing 0 works, as the function hard codes
	 * the priority value anyway.
	 */
	xics_push_cppr(0);

	/* Tell the core to do a soft retrigger */
	return 0;
}

#ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
static int xics_host_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
				      unsigned long *hwirq, unsigned int *type)
{
	return xics_host_xlate(d, to_of_node(fwspec->fwnode), fwspec->param,
			       fwspec->param_count, hwirq, type);
}

static int xics_host_domain_alloc(struct irq_domain *domain, unsigned int virq,
				  unsigned int nr_irqs, void *arg)
{
	struct irq_fwspec *fwspec = arg;
	irq_hw_number_t hwirq;
	unsigned int type = IRQ_TYPE_NONE;
	int i, rc;

	rc = xics_host_domain_translate(domain, fwspec, &hwirq, &type);
	if (rc)
		return rc;

	pr_debug("%s %d/%lx #%d\n", __func__, virq, hwirq, nr_irqs);

	for (i = 0; i < nr_irqs; i++)
		irq_domain_set_info(domain, virq + i, hwirq + i, xics_ics->chip,
				    xics_ics, handle_fasteoi_irq, NULL, NULL);

	return 0;
}

static void xics_host_domain_free(struct irq_domain *domain,
				  unsigned int virq, unsigned int nr_irqs)
{
	pr_debug("%s %d #%d\n", __func__, virq, nr_irqs);
}
#endif

static const struct irq_domain_ops xics_host_ops = {
#ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
	.alloc	= xics_host_domain_alloc,
	.free	= xics_host_domain_free,
	.translate = xics_host_domain_translate,
#endif
	.match = xics_host_match,
	.map = xics_host_map,
	.xlate = xics_host_xlate,
};

static int __init xics_allocate_domain(void)
{
	struct fwnode_handle *fn;

	fn = irq_domain_alloc_named_fwnode("XICS");
	if (!fn)
		return -ENOMEM;

	xics_host = irq_domain_create_tree(fn, &xics_host_ops, NULL);
	if (!xics_host) {
		irq_domain_free_fwnode(fn);
		return -ENOMEM;
	}

	irq_set_default_host(xics_host);
	return 0;
}

void __init xics_register_ics(struct ics *ics)
{
	if (WARN_ONCE(xics_ics, "XICS: Source Controller is already defined !"))
		return;
	xics_ics = ics;
}

static void __init xics_get_server_size(void)
{
	struct device_node *np;
	const __be32 *isize;

	/* We fetch the interrupt server size from the first ICS node
	 * we find if any
	 */
	np = of_find_compatible_node(NULL, NULL, "ibm,ppc-xics");
	if (!np)
		return;

	isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
	if (isize)
		xics_interrupt_server_size = be32_to_cpu(*isize);

	of_node_put(np);
}

void __init xics_init(void)
{
	int rc = -1;

	/* Fist locate ICP */
	if (firmware_has_feature(FW_FEATURE_LPAR))
		rc = icp_hv_init();
	if (rc < 0) {
		rc = icp_native_init();
		if (rc == -ENODEV)
		    rc = icp_opal_init();
	}
	if (rc < 0) {
		pr_warn("XICS: Cannot find a Presentation Controller !\n");
		return;
	}

	/* Copy get_irq callback over to ppc_md */
	ppc_md.get_irq = icp_ops->get_irq;

	/* Patch up IPI chip EOI */
	xics_ipi_chip.irq_eoi = icp_ops->eoi;

	/* Now locate ICS */
	rc = ics_rtas_init();
	if (rc < 0)
		rc = ics_opal_init();
	if (rc < 0)
		rc = ics_native_init();
	if (rc < 0)
		pr_warn("XICS: Cannot find a Source Controller !\n");

	/* Initialize common bits */
	xics_get_server_size();
	xics_update_irq_servers();
	rc = xics_allocate_domain();
	if (rc < 0)
		pr_err("XICS: Failed to create IRQ domain");
	xics_setup_cpu();
}
