~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/dec/ioasic-irq.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  *      DEC I/O ASIC interrupts.
  4  *
  5  *      Copyright (c) 2002, 2003, 2013  Maciej W. Rozycki
  6  */
  7 
  8 #include <linux/init.h>
  9 #include <linux/irq.h>
 10 #include <linux/types.h>
 11 
 12 #include <asm/dec/ioasic.h>
 13 #include <asm/dec/ioasic_addrs.h>
 14 #include <asm/dec/ioasic_ints.h>
 15 
 16 static int ioasic_irq_base;
 17 
 18 static void unmask_ioasic_irq(struct irq_data *d)
 19 {
 20         u32 simr;
 21 
 22         simr = ioasic_read(IO_REG_SIMR);
 23         simr |= (1 << (d->irq - ioasic_irq_base));
 24         ioasic_write(IO_REG_SIMR, simr);
 25 }
 26 
 27 static void mask_ioasic_irq(struct irq_data *d)
 28 {
 29         u32 simr;
 30 
 31         simr = ioasic_read(IO_REG_SIMR);
 32         simr &= ~(1 << (d->irq - ioasic_irq_base));
 33         ioasic_write(IO_REG_SIMR, simr);
 34 }
 35 
 36 static void ack_ioasic_irq(struct irq_data *d)
 37 {
 38         mask_ioasic_irq(d);
 39         fast_iob();
 40 }
 41 
 42 static struct irq_chip ioasic_irq_type = {
 43         .name = "IO-ASIC",
 44         .irq_ack = ack_ioasic_irq,
 45         .irq_mask = mask_ioasic_irq,
 46         .irq_mask_ack = ack_ioasic_irq,
 47         .irq_unmask = unmask_ioasic_irq,
 48 };
 49 
 50 static void clear_ioasic_dma_irq(struct irq_data *d)
 51 {
 52         u32 sir;
 53 
 54         sir = ~(1 << (d->irq - ioasic_irq_base));
 55         ioasic_write(IO_REG_SIR, sir);
 56         fast_iob();
 57 }
 58 
 59 static struct irq_chip ioasic_dma_irq_type = {
 60         .name = "IO-ASIC-DMA",
 61         .irq_ack = clear_ioasic_dma_irq,
 62         .irq_mask = mask_ioasic_irq,
 63         .irq_unmask = unmask_ioasic_irq,
 64         .irq_eoi = clear_ioasic_dma_irq,
 65 };
 66 
 67 /*
 68  * I/O ASIC implements two kinds of DMA interrupts, informational and
 69  * error interrupts.
 70  *
 71  * The former do not stop DMA and should be cleared as soon as possible
 72  * so that if they retrigger before the handler has completed, usually as
 73  * a side effect of actions taken by the handler, then they are reissued.
 74  * These use the `handle_edge_irq' handler that clears the request right
 75  * away.
 76  *
 77  * The latter stop DMA and do not resume it until the interrupt has been
 78  * cleared.  This cannot be done until after a corrective action has been
 79  * taken and this also means they will not retrigger.  Therefore they use
 80  * the `handle_fasteoi_irq' handler that only clears the request on the
 81  * way out.  Because MIPS processor interrupt inputs, one of which the I/O
 82  * ASIC is cascaded to, are level-triggered it is recommended that error
 83  * DMA interrupt action handlers are registered with the IRQF_ONESHOT flag
 84  * set so that they are run with the interrupt line masked.
 85  *
 86  * This mask has `1' bits in the positions of informational interrupts.
 87  */
 88 #define IO_IRQ_DMA_INFO                                                 \
 89         (IO_IRQ_MASK(IO_INR_SCC0A_RXDMA) |                              \
 90          IO_IRQ_MASK(IO_INR_SCC1A_RXDMA) |                              \
 91          IO_IRQ_MASK(IO_INR_ISDN_TXDMA) |                               \
 92          IO_IRQ_MASK(IO_INR_ISDN_RXDMA) |                               \
 93          IO_IRQ_MASK(IO_INR_ASC_DMA))
 94 
 95 void __init init_ioasic_irqs(int base)
 96 {
 97         int i;
 98 
 99         /* Mask interrupts. */
100         ioasic_write(IO_REG_SIMR, 0);
101         fast_iob();
102 
103         for (i = base; i < base + IO_INR_DMA; i++)
104                 irq_set_chip_and_handler(i, &ioasic_irq_type,
105                                          handle_level_irq);
106         for (; i < base + IO_IRQ_LINES; i++)
107                 irq_set_chip_and_handler(i, &ioasic_dma_irq_type,
108                                          1 << (i - base) & IO_IRQ_DMA_INFO ?
109                                          handle_edge_irq : handle_fasteoi_irq);
110 
111         ioasic_irq_base = base;
112 }
113 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php