cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

irq.c (2298B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Interrupt handing routines for NEC VR4100 series.
      4 *
      5 *  Copyright (C) 2005-2007  Yoichi Yuasa <yuasa@linux-mips.org>
      6 */
      7#include <linux/export.h>
      8#include <linux/interrupt.h>
      9#include <linux/irq.h>
     10
     11#include <asm/irq_cpu.h>
     12#include <asm/vr41xx/irq.h>
     13
     14typedef struct irq_cascade {
     15	int (*get_irq)(unsigned int);
     16} irq_cascade_t;
     17
     18static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned;
     19
     20int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int))
     21{
     22	int retval = 0;
     23
     24	if (irq >= NR_IRQS)
     25		return -EINVAL;
     26
     27	if (irq_cascade[irq].get_irq != NULL)
     28		free_irq(irq, NULL);
     29
     30	irq_cascade[irq].get_irq = get_irq;
     31
     32	if (get_irq != NULL) {
     33		retval = request_irq(irq, no_action, IRQF_NO_THREAD,
     34				     "cascade", NULL);
     35		if (retval < 0)
     36			irq_cascade[irq].get_irq = NULL;
     37	}
     38
     39	return retval;
     40}
     41
     42EXPORT_SYMBOL_GPL(cascade_irq);
     43
     44static void irq_dispatch(unsigned int irq)
     45{
     46	irq_cascade_t *cascade;
     47
     48	if (irq >= NR_IRQS) {
     49		atomic_inc(&irq_err_count);
     50		return;
     51	}
     52
     53	cascade = irq_cascade + irq;
     54	if (cascade->get_irq != NULL) {
     55		struct irq_desc *desc = irq_to_desc(irq);
     56		struct irq_data *idata = irq_desc_get_irq_data(desc);
     57		struct irq_chip *chip = irq_desc_get_chip(desc);
     58		int ret;
     59
     60		if (chip->irq_mask_ack)
     61			chip->irq_mask_ack(idata);
     62		else {
     63			chip->irq_mask(idata);
     64			chip->irq_ack(idata);
     65		}
     66		ret = cascade->get_irq(irq);
     67		irq = ret;
     68		if (ret < 0)
     69			atomic_inc(&irq_err_count);
     70		else
     71			irq_dispatch(irq);
     72		if (!irqd_irq_disabled(idata) && chip->irq_unmask)
     73			chip->irq_unmask(idata);
     74	} else
     75		do_IRQ(irq);
     76}
     77
     78asmlinkage void plat_irq_dispatch(void)
     79{
     80	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
     81
     82	if (pending & CAUSEF_IP7)
     83		do_IRQ(TIMER_IRQ);
     84	else if (pending & 0x7800) {
     85		if (pending & CAUSEF_IP3)
     86			irq_dispatch(INT1_IRQ);
     87		else if (pending & CAUSEF_IP4)
     88			irq_dispatch(INT2_IRQ);
     89		else if (pending & CAUSEF_IP5)
     90			irq_dispatch(INT3_IRQ);
     91		else if (pending & CAUSEF_IP6)
     92			irq_dispatch(INT4_IRQ);
     93	} else if (pending & CAUSEF_IP2)
     94		irq_dispatch(INT0_IRQ);
     95	else if (pending & CAUSEF_IP0)
     96		do_IRQ(MIPS_SOFTINT0_IRQ);
     97	else if (pending & CAUSEF_IP1)
     98		do_IRQ(MIPS_SOFTINT1_IRQ);
     99	else
    100		spurious_interrupt();
    101}
    102
    103void __init arch_init_irq(void)
    104{
    105	mips_cpu_irq_init();
    106}