/*
 * Copyright 2001 MontaVista Software Inc.
 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
 *
 * Copyright (C) 2001 Ralf Baechle
 * Copyright (C) 2005  MIPS Technologies, Inc.	All rights reserved.
 *	Author: Maciej W. Rozycki <macro@mips.com>
 *
 * This file define the irq handler for MIPS CPU interrupts.
 *
 * This program is free software; you can redistribute	it and/or modify it
 * under  the terms of	the GNU General	 Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

/*
 * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
 * level triggered (i.e., cannot be cleared from CPU; must be cleared from
 * device).
 *
 * The first two are software interrupts (i.e. not exposed as pins) which
 * may be used for IPIs in multi-threaded single-core systems.
 *
 * The last one is usually the CPU timer interrupt if the counter register
 * is present, or for old CPUs with an external FPU by convention it's the
 * FPU exception interrupt.
 */
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>

#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
#include <asm/setup.h>

static struct irq_domain *irq_domain;
static struct irq_domain *ipi_domain;

static inline void unmask_mips_irq(struct irq_data *d)
{
	set_c0_status(IE_SW0 << d->hwirq);
	irq_enable_hazard();
}

static inline void mask_mips_irq(struct irq_data *d)
{
	clear_c0_status(IE_SW0 << d->hwirq);
	irq_disable_hazard();
}

static struct irq_chip mips_cpu_irq_controller = {
	.name		= "MIPS",
	.irq_ack	= mask_mips_irq,
	.irq_mask	= mask_mips_irq,
	.irq_mask_ack	= mask_mips_irq,
	.irq_unmask	= unmask_mips_irq,
	.irq_eoi	= unmask_mips_irq,
	.irq_disable	= mask_mips_irq,
	.irq_enable	= unmask_mips_irq,
};

/*
 * Basically the same as above but taking care of all the MT stuff
 */

static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d)
{
	unsigned int vpflags = dvpe();

	clear_c0_cause(C_SW0 << d->hwirq);
	evpe(vpflags);
	unmask_mips_irq(d);
	return 0;
}

/*
 * While we ack the interrupt interrupts are disabled and thus we don't need
 * to deal with concurrency issues.  Same for mips_cpu_irq_end.
 */
static void mips_mt_cpu_irq_ack(struct irq_data *d)
{
	unsigned int vpflags = dvpe();
	clear_c0_cause(C_SW0 << d->hwirq);
	evpe(vpflags);
	mask_mips_irq(d);
}

#ifdef CONFIG_GENERIC_IRQ_IPI

static void mips_mt_send_ipi(struct irq_data *d, unsigned int cpu)
{
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	unsigned long flags;
	int vpflags;

	local_irq_save(flags);

	/* We can only send IPIs to VPEs within the local core */
	WARN_ON(cpu_data[cpu].core != current_cpu_data.core);

	vpflags = dvpe();
	settc(cpu_vpe_id(&cpu_data[cpu]));
	write_vpe_c0_cause(read_vpe_c0_cause() | (C_SW0 << hwirq));
	evpe(vpflags);

	local_irq_restore(flags);
}

#endif /* CONFIG_GENERIC_IRQ_IPI */

static struct irq_chip mips_mt_cpu_irq_controller = {
	.name		= "MIPS",
	.irq_startup	= mips_mt_cpu_irq_startup,
	.irq_ack	= mips_mt_cpu_irq_ack,
	.irq_mask	= mask_mips_irq,
	.irq_mask_ack	= mips_mt_cpu_irq_ack,
	.irq_unmask	= unmask_mips_irq,
	.irq_eoi	= unmask_mips_irq,
	.irq_disable	= mask_mips_irq,
	.irq_enable	= unmask_mips_irq,
#ifdef CONFIG_GENERIC_IRQ_IPI
	.ipi_send_single = mips_mt_send_ipi,
#endif
};

asmlinkage void __weak plat_irq_dispatch(void)
{
	unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM;
	unsigned int virq;
	int irq;

	if (!pending) {
		spurious_interrupt();
		return;
	}

	pending >>= CAUSEB_IP;
	while (pending) {
		irq = fls(pending) - 1;
		if (IS_ENABLED(CONFIG_GENERIC_IRQ_IPI) && irq < 2)
			virq = irq_linear_revmap(ipi_domain, irq);
		else
			virq = irq_linear_revmap(irq_domain, irq);
		do_IRQ(virq);
		pending &= ~BIT(irq);
	}
}

static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
			     irq_hw_number_t hw)
{
	struct irq_chip *chip;

	if (hw < 2 && cpu_has_mipsmt) {
		/* Software interrupts are used for MT/CMT IPI */
		chip = &mips_mt_cpu_irq_controller;
	} else {
		chip = &mips_cpu_irq_controller;
	}

	if (cpu_has_vint)
		set_vi_handler(hw, plat_irq_dispatch);

	irq_set_chip_and_handler(irq, chip, handle_percpu_irq);

	return 0;
}

static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = {
	.map = mips_cpu_intc_map,
	.xlate = irq_domain_xlate_onecell,
};

#ifdef CONFIG_GENERIC_IRQ_IPI

struct cpu_ipi_domain_state {
	DECLARE_BITMAP(allocated, 2);
};

static int mips_cpu_ipi_alloc(struct irq_domain *domain, unsigned int virq,
			      unsigned int nr_irqs, void *arg)
{
	struct cpu_ipi_domain_state *state = domain->host_data;
	unsigned int i, hwirq;
	int ret;

	for (i = 0; i < nr_irqs; i++) {
		hwirq = find_first_zero_bit(state->allocated, 2);
		if (hwirq == 2)
			return -EBUSY;
		bitmap_set(state->allocated, hwirq, 1);

		ret = irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq,
						    &mips_mt_cpu_irq_controller,
						    NULL);
		if (ret)
			return ret;

		ret = irq_set_irq_type(virq + i, IRQ_TYPE_LEVEL_HIGH);
		if (ret)
			return ret;
	}

	return 0;
}

static int mips_cpu_ipi_match(struct irq_domain *d, struct device_node *node,
			      enum irq_domain_bus_token bus_token)
{
	bool is_ipi;

	switch (bus_token) {
	case DOMAIN_BUS_IPI:
		is_ipi = d->bus_token == bus_token;
		return (!node || (to_of_node(d->fwnode) == node)) && is_ipi;
	default:
		return 0;
	}
}

static const struct irq_domain_ops mips_cpu_ipi_chip_ops = {
	.alloc	= mips_cpu_ipi_alloc,
	.match	= mips_cpu_ipi_match,
};

static void mips_cpu_register_ipi_domain(struct device_node *of_node)
{
	struct cpu_ipi_domain_state *ipi_domain_state;

	ipi_domain_state = kzalloc(sizeof(*ipi_domain_state), GFP_KERNEL);
	ipi_domain = irq_domain_add_hierarchy(irq_domain,
					      IRQ_DOMAIN_FLAG_IPI_SINGLE,
					      2, of_node,
					      &mips_cpu_ipi_chip_ops,
					      ipi_domain_state);
	if (!ipi_domain)
		panic("Failed to add MIPS CPU IPI domain");
	irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI);
}

#else /* !CONFIG_GENERIC_IRQ_IPI */

static inline void mips_cpu_register_ipi_domain(struct device_node *of_node) {}

#endif /* !CONFIG_GENERIC_IRQ_IPI */

static void __init __mips_cpu_irq_init(struct device_node *of_node)
{
	/* Mask interrupts. */
	clear_c0_status(ST0_IM);
	clear_c0_cause(CAUSEF_IP);

	irq_domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0,
					   &mips_cpu_intc_irq_domain_ops,
					   NULL);
	if (!irq_domain)
		panic("Failed to add irqdomain for MIPS CPU");

	/*
	 * Only proceed to register the software interrupt IPI implementation
	 * for CPUs which implement the MIPS MT (multi-threading) ASE.
	 */
	if (cpu_has_mipsmt)
		mips_cpu_register_ipi_domain(of_node);
}

void __init mips_cpu_irq_init(void)
{
	__mips_cpu_irq_init(NULL);
}

int __init mips_cpu_irq_of_init(struct device_node *of_node,
				struct device_node *parent)
{
	__mips_cpu_irq_init(of_node);
	return 0;
}
IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
