// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2009
 * Graeme Russ, <graeme.russ@gmail.com>
 *
 * (C) Copyright 2007
 * Daniel Hellstrom, Gaisler Research, <daniel@gaisler.com>
 *
 * (C) Copyright 2006
 * Detlev Zundel, DENX Software Engineering, <dzu@denx.de>
 *
 * (C) Copyright -2003
 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
 *
 * (C) Copyright 2002
 * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
 *
 * (C) Copyright 2001
 * Josh Huber, Mission Critical Linux, Inc, <huber@mclx.com>
 */

/*
 * This file contains the high-level API for the interrupt sub-system
 * of the x86 port of U-Boot. Most of the functionality has been
 * shamelessly stolen from the leon2 / leon3 ports of U-Boot.
 * Daniel Hellstrom, Detlev Zundel, Wolfgang Denk and Josh Huber are
 * credited for the corresponding work on those ports. The original
 * interrupt handling routines for the x86 port were written by
 * Daniel Engström
 */

#include <common.h>
#include <asm/interrupt.h>

#if !CONFIG_IS_ENABLED(X86_64)

struct irq_action {
	interrupt_handler_t *handler;
	void *arg;
	unsigned int count;
};

static struct irq_action irq_handlers[SYS_NUM_IRQS] = { {0} };
static int spurious_irq_cnt;
static int spurious_irq;

void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg)
{
	int status;

	if (irq < 0 || irq >= SYS_NUM_IRQS) {
		printf("irq_install_handler: bad irq number %d\n", irq);
		return;
	}

	if (irq_handlers[irq].handler != NULL)
		printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
				(ulong) handler,
				(ulong) irq_handlers[irq].handler);

	status = disable_interrupts();

	irq_handlers[irq].handler = handler;
	irq_handlers[irq].arg = arg;
	irq_handlers[irq].count = 0;

	if (CONFIG_IS_ENABLED(I8259_PIC))
		unmask_irq(irq);

	if (status)
		enable_interrupts();

	return;
}

void irq_free_handler(int irq)
{
	int status;

	if (irq < 0 || irq >= SYS_NUM_IRQS) {
		printf("irq_free_handler: bad irq number %d\n", irq);
		return;
	}

	status = disable_interrupts();

	if (CONFIG_IS_ENABLED(I8259_PIC))
		mask_irq(irq);

	irq_handlers[irq].handler = NULL;
	irq_handlers[irq].arg = NULL;

	if (status)
		enable_interrupts();

	return;
}

void do_irq(int hw_irq)
{
	int irq = hw_irq - 0x20;

	if (irq < 0 || irq >= SYS_NUM_IRQS) {
		printf("do_irq: bad irq number %d\n", irq);
		return;
	}

	if (irq_handlers[irq].handler) {
		if (CONFIG_IS_ENABLED(I8259_PIC))
			mask_irq(irq);

		irq_handlers[irq].handler(irq_handlers[irq].arg);
		irq_handlers[irq].count++;

		if (CONFIG_IS_ENABLED(I8259_PIC)) {
			unmask_irq(irq);
			specific_eoi(irq);
		}
	} else {
		if ((irq & 7) != 7) {
			spurious_irq_cnt++;
			spurious_irq = irq;
		}
	}
}
#endif

#if defined(CONFIG_CMD_IRQ)
int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#if !CONFIG_IS_ENABLED(X86_64)
	int irq;

	printf("Spurious IRQ: %u, last unknown IRQ: %d\n",
			spurious_irq_cnt, spurious_irq);

	printf("Interrupt-Information:\n");
	printf("Nr  Routine   Arg       Count\n");

	for (irq = 0; irq < SYS_NUM_IRQS; irq++) {
		if (irq_handlers[irq].handler != NULL) {
			printf("%02d  %08lx  %08lx  %d\n",
					irq,
					(ulong)irq_handlers[irq].handler,
					(ulong)irq_handlers[irq].arg,
					irq_handlers[irq].count);
		}
	}
#endif

	return 0;
}
#endif
