Beispiel #1
0
/*
 * Install handler for Neponset IRQ.  Note that we have to loop here
 * since the ETHERNET and USAR IRQs are level based, and we need to
 * ensure that the IRQ signal is deasserted before returning.  This
 * is rather unfortunate.
 */
static void
neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
{
	unsigned int irr;

	while (1) {
		struct irqdesc *d;

		/*
		 * Acknowledge the parent IRQ.
		 */
		desc->chip->ack(irq);

		/*
		 * Read the interrupt reason register.  Let's have all
		 * active IRQ bits high.  Note: there is a typo in the
		 * Neponset user's guide for the SA1111 IRR level.
		 */
		irr = IRR ^ (IRR_ETHERNET | IRR_USAR);

		if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
			break;

		/*
		 * Since there is no individual mask, we have to
		 * mask the parent IRQ.  This is safe, since we'll
		 * recheck the register for any pending IRQs.
		 */
		if (irr & (IRR_ETHERNET | IRR_USAR)) {
			desc->chip->mask(irq);

			if (irr & IRR_ETHERNET) {
				d = irq_desc + IRQ_NEPONSET_SMC9196;
				desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs);
			}

			if (irr & IRR_USAR) {
				d = irq_desc + IRQ_NEPONSET_USAR;
				desc_handle_irq(IRQ_NEPONSET_USAR, d, regs);
			}

			desc->chip->unmask(irq);
		}

		if (irr & IRR_SA1111) {
			d = irq_desc + IRQ_NEPONSET_SA1111;
			desc_handle_irq(IRQ_NEPONSET_SA1111, d, regs);
		}
	}
}
Beispiel #2
0
static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
{
	unsigned int subsrc, submsk;

	subsrc = __raw_readl(S3C2410_SUBSRCPND);
	submsk = __raw_readl(S3C2410_INTSUBMSK);

	subsrc  &= ~submsk;

	if (subsrc & INTBIT(IRQ_S3C2412_SDI))
		desc_handle_irq(IRQ_S3C2412_SDI, irq_desc + IRQ_S3C2412_SDI);

	if (subsrc & INTBIT(IRQ_S3C2412_CF))
		desc_handle_irq(IRQ_S3C2412_CF, irq_desc + IRQ_S3C2412_CF);
}
Beispiel #3
0
static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	u32 ex_interrupt;
	int i;

	desc->chip->mask(irq);

	ex_interrupt = *IXDP2X01_INT_STAT_REG & valid_irq_mask;

	if (!ex_interrupt) {
		printk(KERN_ERR "Spurious IXDP2X01 CPLD interrupt!\n");
		return;
	}

	for (i = 0; i < IXP2000_BOARD_IRQS; i++) {
		if (ex_interrupt & (1 << i)) {
			struct irq_desc *cpld_desc;
			int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
			cpld_desc = irq_desc + cpld_irq;
			desc_handle_irq(cpld_irq, cpld_desc);
		}
	}

	desc->chip->unmask(irq);
}
Beispiel #4
0
Datei: irq.c Projekt: 274914765/C
static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
{
    unsigned int subsrc, submsk;
    unsigned int end;
    struct irq_desc *mydesc;

    /* read the current pending interrupts, and the mask
     * for what it is available */

    subsrc = __raw_readl(S3C2410_SUBSRCPND);
    submsk = __raw_readl(S3C2410_INTSUBMSK);

    subsrc  &= ~submsk;
    subsrc >>= (irq - S3C2410_IRQSUB(0));
    subsrc  &= (1 << len)-1;

    end = len + irq;
    mydesc = irq_desc + irq;

    for (; irq < end && subsrc; irq++) {
        if (subsrc & 1)
            desc_handle_irq(irq, mydesc);

        mydesc++;
        subsrc >>= 1;
    }
}
Beispiel #5
0
/* Although we have two interrupt lines for the timers, we only have one
 * status register which clears all pending timer interrupts on reading. So
 * we have to handle all timer interrupts in one place.
 */
static void
h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
			struct pt_regs *regs)
{
	unsigned int mask, irq;

	mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);

	if ( mask & TSTAT_T0INT ) {
		write_seqlock(&xtime_lock);
		timer_tick(regs);
		write_sequnlock(&xtime_lock);
		if( mask == TSTAT_T0INT )
			return;
	}

	mask >>= 1;
	irq = IRQ_TIMER1;
	desc = irq_desc + irq;
	while (mask) {
		if (mask & 1)
			desc_handle_irq(irq, desc, regs);
		irq++;
		desc++;
		mask >>= 1;
	}
}
Beispiel #6
0
void orion_gpio_irq_handler(int pinoff)
{
	u32 cause;
	int pin;

	cause = readl(GPIO_DATA_IN(pinoff)) & readl(GPIO_LEVEL_MASK(pinoff));
	cause |= readl(GPIO_EDGE_CAUSE(pinoff)) & readl(GPIO_EDGE_MASK(pinoff));

	for (pin = pinoff; pin < pinoff + 8; pin++) {
		int irq = gpio_to_irq(pin);
		struct irq_desc *desc = irq_desc + irq;

		if (!(cause & (1 << (pin & 31))))
			continue;

		if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
			/* Swap polarity (race with GPIO line) */
			u32 polarity;

			polarity = readl(GPIO_IN_POL(pin));
			polarity ^= 1 << (pin & 31);
			writel(polarity, GPIO_IN_POL(pin));
		}
		desc_handle_irq(irq, desc);
	}
}
Beispiel #7
0
/*
 * IRQ11 (GPIO11 through 27) handler.  We enter here with the
 * irq_controller_lock held, and IRQs disabled.  Decode the IRQ
 * and call the handler.
 */
static void
sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc,
			 struct pt_regs *regs)
{
	unsigned int mask;

	mask = GEDR & 0xfffff800;
	do {
		/*
		 * clear down all currently active IRQ sources.
		 * We will be processing them all.
		 */
		GEDR = mask;

		irq = IRQ_GPIO11;
		desc = irq_desc + irq;
		mask >>= 11;
		do {
			if (mask & 1)
				desc_handle_irq(irq, desc, regs);
			mask >>= 1;
			irq++;
			desc++;
		} while (mask);

		mask = GEDR & 0xfffff800;
	} while (mask);
}
Beispiel #8
0
static void kev7a400_cpld_handler (unsigned int irq, struct irq_desc *desc)
{
    u32 mask = CPLD_LATCHED_INTS;
    irq = IRQ_KEV7A400_CPLD;
    for (; mask; mask >>= 1, ++irq)
        if (mask & 1)
            desc_handle_irq(irq, desc);
}
Beispiel #9
0
/*************************************************************************
 * IRQ handling IXP2000
 *************************************************************************/
static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irq_desc *desc)
{                               
	int i;
	unsigned long status = *IXP2000_GPIO_INST;
		   
	for (i = 0; i <= 7; i++) {
		if (status & (1<<i)) {
			desc = irq_desc + i + IRQ_IXP2000_GPIO0;
			desc_handle_irq(i + IRQ_IXP2000_GPIO0, desc);
		}
	}
}
Beispiel #10
0
/*
 * Error interrupts. These are used extensively by the microengine drivers
 */
static void ixp2000_err_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	int i;
	unsigned long status = *IXP2000_IRQ_ERR_STATUS;

	for(i = 31; i >= 0; i--) {
		if(status & (1 << i)) {
			desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i;
			desc_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc);
		}
	}
}
Beispiel #11
0
static void
isa_irq_handler(unsigned int irq, struct irq_desc *desc)
{
    unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE;

    if (isa_irq < _ISA_IRQ(0) || isa_irq >= _ISA_IRQ(16)) {
        do_bad_IRQ(isa_irq, desc);
        return;
    }

    desc = irq_desc + isa_irq;
    desc_handle_irq(isa_irq, desc);
}
Beispiel #12
0
static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled;
	do {
		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
		if (likely(pending)) {
			irq = MAINSTONE_IRQ(0) + __ffs(pending);
			desc = irq_desc + irq;
			desc_handle_irq(irq, desc);
		}
		pending = MST_INTSETCLR & mainstone_irq_enabled;
	} while (pending);
}
Beispiel #13
0
static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
	do {
		GEDR(0) = GPIO_bit(0);	/* clear our parent irq */
		if (likely(pending)) {
			irq = LUBBOCK_IRQ(0) + __ffs(pending);
			desc = irq_desc + irq;
			desc_handle_irq(irq, desc);
		}
		pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
	} while (pending);
}
Beispiel #14
0
static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
	unsigned	pin;
	struct irq_desc	*gpio;
	struct at91_gpio_bank *bank;
	void __iomem	*pio;
	u32		isr;

	bank = get_irq_chip_data(irq);
	pio = bank->regbase;

	/* temporarily mask (level sensitive) parent IRQ */
	desc->chip->ack(irq);
	for (;;) {
		/* Reading ISR acks pending (edge triggered) GPIO interrupts.
		 * When there none are pending, we're finished unless we need
		 * to process multiple banks (like ID_PIOCDE on sam9263).
		 */
		isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR);
		if (!isr) {
			if (!bank->next)
				break;
			bank = bank->next;
			pio = bank->regbase;
			continue;
		}

		pin = bank->chipbase;
		gpio = &irq_desc[pin];

		while (isr) {
			if (isr & 1) {
				if (unlikely(gpio->depth)) {
					/*
					 * The core ARM interrupt handler lazily disables IRQs so
					 * another IRQ must be generated before it actually gets
					 * here to be disabled on the GPIO controller.
					 */
					gpio_irq_mask(pin);
				}
				else
					desc_handle_irq(pin, gpio);
			}
			pin++;
			gpio++;
			isr >>= 1;
		}
	}
	desc->chip->unmask(irq);
	/* now it may re-trigger */
}
Beispiel #15
0
static void
imx_gpio_handler(unsigned int mask, unsigned int irq,
                 struct irqdesc *desc, struct pt_regs *regs)
{
	desc = irq_desc + irq;
	while (mask) {
		if (mask & 1) {
			DEBUG_IRQ("handling irq %d\n", irq);
			desc_handle_irq(irq, desc, regs);
		}
		irq++;
		desc++;
		mask >>= 1;
	}
}
Beispiel #16
0
static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
{
    unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;

    do {
        GEDR(PCM990_CTRL_INT_IRQ_GPIO) =
                    GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO);
        if (likely(pending)) {
            irq = PCM027_IRQ(0) + __ffs(pending);
            desc = irq_desc + irq;
            desc_handle_irq(irq, desc);
        }
        pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
    } while (pending);
}
Beispiel #17
0
static void a9m9750dev_fpga_demux_handler(unsigned int irq,
		struct irq_desc *desc)
{
	int stat = FPGA_ISR;

	while (stat != 0) {
		int irqno = fls(stat) - 1;

		stat &= ~(1 << irqno);

		desc = irq_desc + FPGA_IRQ(irqno);

		desc_handle_irq(irqno, desc);
	}
}
Beispiel #18
0
static void
h720x_gpio_handler(unsigned int mask, unsigned int irq,
                 struct irq_desc *desc)
{
	IRQDBG("%s irq: %d\n", __func__, irq);
	desc = irq_desc + irq;
	while (mask) {
		if (mask & 1) {
			IRQDBG("handling irq %d\n", irq);
			desc_handle_irq(irq, desc);
		}
		irq++;
		desc++;
		mask >>= 1;
	}
}
Beispiel #19
0
static void
imx_fpga_handler(unsigned int mask, unsigned int irq,
                 struct irq_desc *desc)
{
	pr_debug("%s: mask:0x%04x\n", __FUNCTION__, mask);
	desc = irq_desc + irq;
	while (mask) {
		if (mask & 1) {
			pr_debug("handling irq %d\n", irq);
			desc_handle_irq(irq, desc);
		}
		irq++;
		desc++;
		mask >>= 1;
	}
}
Beispiel #20
0
static void lpd270_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	unsigned long pending;

	pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled;
	do {
		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
		if (likely(pending)) {
			irq = LPD270_IRQ(0) + __ffs(pending);
			desc = irq_desc + irq;
			desc_handle_irq(irq, desc);

			pending = __raw_readw(LPD270_INT_STATUS) &
						lpd270_irq_enabled;
		}
	} while (pending);
}
Beispiel #21
0
static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	unsigned long cause = readl(PMU_INTERRUPT_CAUSE);

	cause &= readl(PMU_INTERRUPT_MASK);
	if (cause == 0) {
		do_bad_IRQ(irq, desc);
		return;
	}

	for (irq = 0; irq < NR_PMU_IRQS; irq++) {
		if (!(cause & (1 << irq)))
			continue;
		irq = pmu_to_irq(irq);
		desc = irq_desc + irq;
		desc_handle_irq(irq, desc);
	}
}
static void
egpio_handler(unsigned int irq, struct irq_desc *desc)
{
	int i;
	// Read current pins.
	u16 readval = egpio[0];
	// Process all set pins.
	for (i=0; i<LAST_EGPIO; i++) {
		int irqpin = i+8;
		if (!(readval & (1<<irqpin)))
			continue;
		// Ack/unmask current pin.
		egpio[0] = ~(1<<irqpin);
		// Handle irq
		irq = IRQ_EGPIO(i);
		desc = &irq_desc[irq];
		desc_handle_irq(irq, desc);
	}
}
Beispiel #23
0
static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc)
{
	u16 ex_interrupt =
		*IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID;
	int i;

	desc->chip->ack(irq);

	for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) {
		if (ex_interrupt & (1 << i)) {
			struct irq_desc *cpld_desc;
			int cpld_irq =
				IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i);
			cpld_desc = irq_desc + cpld_irq;
			desc_handle_irq(cpld_irq, cpld_desc);
		}
	}

	desc->chip->unmask(irq);
}
Beispiel #24
0
static void
sic_handle_irq(unsigned int irq, struct irq_desc *desc)
{
	unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS);

	if (status == 0) {
		do_bad_IRQ(irq, desc);
		return;
	}

	do {
		irq = ffs(status) - 1;
		status &= ~(1 << irq);

		irq += IRQ_SIC_START;

		desc = irq_desc + irq;
		desc_handle_irq(irq, desc);
	} while (status);
}
Beispiel #25
0
void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc)
{
	struct irq_desc *d;
	u32 stat;
	int fpga_irq;

	stat = get_fpga_unmasked_irqs();

	if (!stat)
		return;

	for (fpga_irq = OMAP1510_IH_FPGA_BASE;
	     (fpga_irq < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS)) && stat;
	     fpga_irq++, stat >>= 1) {
		if (stat & 1) {
			d = irq_desc + fpga_irq;
			desc_handle_irq(fpga_irq, d);
		}
	}
}
Beispiel #26
0
static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
	unsigned	pin;
	struct irq_desc	*gpio;
	void __iomem	*pio;
	u32		isr;

	pio = get_irq_chip_data(irq);

	/* temporarily mask (level sensitive) parent IRQ */
	desc->chip->ack(irq);
	for (;;) {
		/* reading ISR acks the pending (edge triggered) GPIO interrupt */
		isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR);
		if (!isr)
			break;

		pin = (unsigned) get_irq_data(irq);
		gpio = &irq_desc[pin];

		while (isr) {
			if (isr & 1) {
				if (unlikely(gpio->depth)) {
					/*
					 * The core ARM interrupt handler lazily disables IRQs so
					 * another IRQ must be generated before it actually gets
					 * here to be disabled on the GPIO controller.
					 */
					gpio_irq_mask(pin);
				}
				else
					desc_handle_irq(pin, gpio);
			}
			pin++;
			gpio++;
			isr >>= 1;
		}
	}
	desc->chip->unmask(irq);
	/* now it may re-trigger */
}
Beispiel #27
0
static void iop13xx_msi_handler(unsigned int irq, struct irq_desc *desc)
{
	int i, j;
	unsigned long status;

	/* read IMIPR registers and find any active interrupts,
	 * then call ISR for each active interrupt
	 */
	for (i = 0; i < ARRAY_SIZE(read_imipr); i++) {
		status = (read_imipr[i])();
		if (!status)
			continue;

		do {
			j = find_first_bit(&status, 32);
			(write_imipr[i])(1 << j); /* write back to clear bit */
			desc = irq_desc + IRQ_IOP13XX_MSI_0 + j + (32*i);
			desc_handle_irq(IRQ_IOP13XX_MSI_0 + j + (32*i),	desc);
			status = (read_imipr[i])();
		} while (status);
	}
}
/*
 * PNX EXTINT : only EXTINT 3 is managed by Linux
 * We need to unmask the GPIO bank interrupt as soon as possible to
 * avoid missing GPIO interrupts for other lines in the bank.
 * Then we need to mask-read-clear-unmask the triggered GPIO lines
 * in the bank to avoid missing nested interrupts for a GPIO line.
 * If we wait to unmask individual GPIO lines in the bank after the
 * line's interrupt handler has been run, we may miss some nested
 * interrupts.
 */
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	unsigned long isr;
	unsigned long flags;
	unsigned int gpio_irq;

	/* LPA TBD */
	desc->chip->ack(irq);

	/* read status */
	hw_raw_local_irq_save ( flags );
	isr = __raw_readl(EXTINT_STATUS_REG) & __raw_readl(EXTINT_ENABLE3_REG);
	/* clear IRQ source(s)*/
	__raw_writel(~isr, EXTINT_STATUS_REG);
	hw_raw_local_irq_restore ( flags );

	gpio_irq = IRQ_COUNT;
	for (; isr != 0; isr >>= 1, gpio_irq++) {
		struct irq_desc *d;
		if (!(isr & 1))
			continue;
		d = irq_desc + gpio_irq;
#ifdef CONFIG_DEBUG_EXTINT
		printk(KERN_ERR "got something from EXTINT#%i line\n",
		       gpio_irq - IRQ_COUNT);
#endif
		desc_handle_irq(gpio_irq, d);
	}

#ifdef CONFIG_NKERNEL
	/*
	 * interrupt forwarding routine of osware masks INTC_IID_EXT2
	 * so we have to unmask it after irq handling
	 */
	hw_raw_local_irq_save ( flags );
	__raw_writel((1<<26 | 1<<16), INTC_REQUESTx(IRQ_EXTINT3));
	hw_raw_local_irq_restore ( flags );
#endif
}
Beispiel #29
0
/* Although we have two interrupt lines for the timers, we only have one
 * status register which clears all pending timer interrupts on reading. So
 * we have to handle all timer interrupts in one place.
 */
static void
h7202_timerx_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
{
	unsigned int mask, irq;

	mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);

	if ( mask & TSTAT_T0INT ) {
		timer_tick();
		if( mask == TSTAT_T0INT )
			return;
	}

	mask >>= 1;
	irq = IRQ_TIMER1;
	desc = irq_desc + irq;
	while (mask) {
		if (mask & 1)
			desc_handle_irq(irq, desc);
		irq++;
		desc++;
		mask >>= 1;
	}
}
Beispiel #30
0
/*
 * TODO: Should this just be done at ASM level?
 */
static void pci_handler(unsigned int irq, struct irq_desc *desc)
{
    u32 pci_interrupt;
    unsigned int irqno;
    struct irq_desc *int_desc;

    pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS;

    desc->chip->ack(irq);

    /* See which PCI_INTA, or PCI_INTB interrupted */
    if (pci_interrupt & (1 << 26)) {
        irqno = IRQ_IXP23XX_INTB;
    } else if (pci_interrupt & (1 << 27)) {
        irqno = IRQ_IXP23XX_INTA;
    } else {
        BUG();
    }

    int_desc = irq_desc + irqno;
    desc_handle_irq(irqno, int_desc);

    desc->chip->unmask(irq);
}