/*
 * 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.exec_domain       = 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.exec_domain       = 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 */
