/*
 * Linux/Meta general interrupt handling code
 *
 */

#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irqchip/metag-ext.h>
#include <linux/irqchip/metag.h>
#include <linux/irqdomain.h>
#include <linux/ratelimit.h>

#include <asm/core_reg.h>
#include <asm/mach/arch.h>
#include <asm/uaccess.h>

#ifdef CONFIG_4KSTACKS
union irq_ctx {
	struct thread_info      tinfo;
	u32                     stack[THREAD_SIZE/sizeof(u32)];
};

static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
#endif

static struct irq_domain *root_domain;

static unsigned int startup_meta_irq(struct irq_data *data)
{
	tbi_startup_interrupt(data->hwirq);
	return 0;
}

static void shutdown_meta_irq(struct irq_data *data)
{
	tbi_shutdown_interrupt(data->hwirq);
}

void do_IRQ(int irq, struct pt_regs *regs)
{
	struct pt_regs *old_regs = set_irq_regs(regs);
#ifdef CONFIG_4KSTACKS
	struct irq_desc *desc;
	union irq_ctx *curctx, *irqctx;
	u32 *isp;
#endif

	irq_enter();

	irq = irq_linear_revmap(root_domain, irq);

#ifdef CONFIG_DEBUG_STACKOVERFLOW
	/* Debugging check for stack overflow: is there less than 1KB free? */
	{
		unsigned long sp;

		sp = __core_reg_get(A0StP);
		sp &= THREAD_SIZE - 1;

		if (unlikely(sp > (THREAD_SIZE - 1024)))
			pr_err("Stack overflow in do_IRQ: %ld\n", sp);
	}
#endif


#ifdef CONFIG_4KSTACKS
	curctx = (union irq_ctx *) current_thread_info();
	irqctx = hardirq_ctx[smp_processor_id()];

	/*
	 * this is where we switch to the IRQ stack. However, if we are
	 * already using the IRQ stack (because we interrupted a hardirq
	 * handler) we can't do that and just have to keep using the
	 * current stack (which is the irq stack already after all)
	 */
	if (curctx != irqctx) {
		/* build the stack frame on the IRQ stack */
		isp = (u32 *) ((char *)irqctx + sizeof(struct thread_info));
		irqctx->tinfo.task = curctx->tinfo.task;

		/*
		 * Copy the softirq bits in preempt_count so that the
		 * softirq checks work in the hardirq context.
		 */
		irqctx->tinfo.preempt_count =
			(irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) |
			(curctx->tinfo.preempt_count & SOFTIRQ_MASK);

		desc = irq_to_desc(irq);

		asm volatile (
			"MOV   D0.5,%0\n"
			"MOV   D1Ar1,%1\n"
			"MOV   D1RtP,%2\n"
			"MOV   D0Ar2,%3\n"
			"SWAP  A0StP,D0.5\n"
			"SWAP  PC,D1RtP\n"
			"MOV   A0StP,D0.5\n"
			:
			: "r" (isp), "r" (irq), "r" (desc->handle_irq),
			  "r" (desc)
			: "memory", "cc", "D1Ar1", "D0Ar2", "D1Ar3", "D0Ar4",
			  "D1Ar5", "D0Ar6", "D0Re0", "D1Re0", "D0.4", "D1RtP",
			  "D0.5"
			);
	} else
#endif
		generic_handle_irq(irq);

	irq_exit();

	set_irq_regs(old_regs);
}

#ifdef CONFIG_4KSTACKS

static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;

static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;

/*
 * allocate per-cpu stacks for hardirq and for softirq processing
 */
void irq_ctx_init(int cpu)
{
	union irq_ctx *irqctx;

	if (hardirq_ctx[cpu])
		return;

	irqctx = (union irq_ctx *) &hardirq_stack[cpu * THREAD_SIZE];
	irqctx->tinfo.task              = NULL;
	irqctx->tinfo.cpu               = cpu;
	irqctx->tinfo.preempt_count     = HARDIRQ_OFFSET;
	irqctx->tinfo.addr_limit        = MAKE_MM_SEG(0);

	hardirq_ctx[cpu] = irqctx;

	irqctx = (union irq_ctx *) &softirq_stack[cpu * THREAD_SIZE];
	irqctx->tinfo.task              = NULL;
	irqctx->tinfo.cpu               = cpu;
	irqctx->tinfo.preempt_count     = 0;
	irqctx->tinfo.addr_limit        = MAKE_MM_SEG(0);

	softirq_ctx[cpu] = irqctx;

	pr_info("CPU %u irqstacks, hard=%p soft=%p\n",
		cpu, hardirq_ctx[cpu], softirq_ctx[cpu]);
}

void irq_ctx_exit(int cpu)
{
	hardirq_ctx[smp_processor_id()] = NULL;
}

extern asmlinkage void __do_softirq(void);

void do_softirq_own_stack(void)
{
	struct thread_info *curctx;
	union irq_ctx *irqctx;
	u32 *isp;

	curctx = current_thread_info();
	irqctx = softirq_ctx[smp_processor_id()];
	irqctx->tinfo.task = curctx->task;

	/* build the stack frame on the softirq stack */
	isp = (u32 *) ((char *)irqctx + sizeof(struct thread_info));

	asm volatile (
		"MOV   D0.5,%0\n"
		"SWAP  A0StP,D0.5\n"
		"CALLR D1RtP,___do_softirq\n"
		"MOV   A0StP,D0.5\n"
		:
		: "r" (isp)
		: "memory", "cc", "D1Ar1", "D0Ar2", "D1Ar3", "D0Ar4",
		  "D1Ar5", "D0Ar6", "D0Re0", "D1Re0", "D0.4", "D1RtP",
		  "D0.5"
		);
}
#endif

static struct irq_chip meta_irq_type = {
	.name = "META-IRQ",
	.irq_startup = startup_meta_irq,
	.irq_shutdown = shutdown_meta_irq,
};

/**
 * tbisig_map() - Map a TBI signal number to a virtual IRQ number.
 * @hw:		Number of the TBI signal. Must be in range.
 *
 * Returns:	The virtual IRQ number of the TBI signal number IRQ specified by
 *		@hw.
 */
int tbisig_map(unsigned int hw)
{
	return irq_create_mapping(root_domain, hw);
}

/**
 * metag_tbisig_map() - map a tbi signal to a Linux virtual IRQ number
 * @d:		root irq domain
 * @irq:	virtual irq number
 * @hw:		hardware irq number (TBI signal number)
 *
 * This sets up a virtual irq for a specified TBI signal number.
 */
static int metag_tbisig_map(struct irq_domain *d, unsigned int irq,
			    irq_hw_number_t hw)
{
#ifdef CONFIG_SMP
	irq_set_chip_and_handler(irq, &meta_irq_type, handle_percpu_irq);
#else
	irq_set_chip_and_handler(irq, &meta_irq_type, handle_simple_irq);
#endif
	return 0;
}

static const struct irq_domain_ops metag_tbisig_domain_ops = {
	.map = metag_tbisig_map,
};

/*
 * void init_IRQ(void)
 *
 * Parameters:	None
 *
 * Returns:	Nothing
 *
 * This function should be called during kernel startup to initialize
 * the IRQ handling routines.
 */
void __init init_IRQ(void)
{
	root_domain = irq_domain_add_linear(NULL, 32,
					    &metag_tbisig_domain_ops, NULL);
	if (unlikely(!root_domain))
		panic("init_IRQ: cannot add root IRQ domain");

	irq_ctx_init(smp_processor_id());

	init_internal_IRQ();
	init_external_IRQ();

	if (machine_desc->init_irq)
		machine_desc->init_irq();
}

int __init arch_probe_nr_irqs(void)
{
	if (machine_desc->nr_irqs)
		nr_irqs = machine_desc->nr_irqs;
	return 0;
}

#ifdef CONFIG_HOTPLUG_CPU
/*
 * The CPU has been marked offline.  Migrate IRQs off this CPU.  If
 * the affinity settings do not allow other CPUs, force them onto any
 * available CPU.
 */
void migrate_irqs(void)
{
	unsigned int i, cpu = smp_processor_id();

	for_each_active_irq(i) {
		struct irq_data *data = irq_get_irq_data(i);
		unsigned int newcpu;

		if (irqd_is_per_cpu(data))
			continue;

		if (!cpumask_test_cpu(cpu, data->affinity))
			continue;

		newcpu = cpumask_any_and(data->affinity, cpu_online_mask);

		if (newcpu >= nr_cpu_ids) {
			pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n",
					    i, cpu);

			cpumask_setall(data->affinity);
		}
		irq_set_affinity(i, data->affinity);
	}
}
#endif /* CONFIG_HOTPLUG_CPU */
