File: /usr/src/linux/include/asm-cris/irq.h

1     /*
2      * Interrupt handling assembler and defines for Linux/CRIS
3      *
4      * Copyright (c) 2000, 2001 Axis Communications AB
5      *
6      * Authors:   Bjorn Wesen (bjornw@axis.com)
7      *
8      * $Id: irq.h,v 1.13 2001/07/06 18:52:08 hp Exp $
9      */
10     
11     #ifndef _ASM_IRQ_H
12     #define _ASM_IRQ_H
13     
14     /*
15      *	linux/include/asm-cris/irq.h
16      */
17     
18     #include <linux/linkage.h>
19     #include <asm/segment.h>
20     
21     #include <asm/sv_addr_ag.h>
22     
23     #define NR_IRQS 32
24     #define SOME_IRQ_NBR        IO_BITNR(R_VECT_MASK_RD, some)   /* 0 ? */
25     #define NMI_IRQ_NBR         IO_BITNR(R_VECT_MASK_RD, nmi)    /* 1 */
26     #define TIMER0_IRQ_NBR      IO_BITNR(R_VECT_MASK_RD, timer0) /* 2 */
27     #define TIMER1_IRQ_NBR      IO_BITNR(R_VECT_MASK_RD, timer1) /* 3 */
28     /* mio, ata, par0, scsi0 on 4 */
29     /* par1, scsi1 on 5 */
30     #define NETWORK_STATUS_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, network) /* 6 */
31     
32     #define SERIAL_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, serial) /* 8 */
33     #define PA_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, pa) /* 11 */
34     /* extdma0 and extdma1 is at irq 12 and 13 and/or same as dma5 and dma6 ? */
35     #define EXTDMA0_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma0)
36     #define EXTDMA1_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma1)
37     
38     /* dma0-9 is irq 16..25 */
39     /* 16,17: network */
40     #define DMA0_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma0)
41     #define DMA1_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma1)
42     #define NETWORK_DMA_TX_IRQ_NBR DMA0_TX_IRQ_NBR
43     #define NETWORK_DMA_RX_IRQ_NBR DMA1_RX_IRQ_NBR
44     
45     /* 18,19: dma2 and dma3 shared by par0, scsi0, ser2 and ata */
46     #define DMA2_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma2)
47     #define DMA3_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma3)
48     #define SER2_DMA_TX_IRQ_NBR DMA2_TX_IRQ_NBR
49     #define SER2_DMA_RX_IRQ_NBR DMA3_RX_IRQ_NBR
50     
51     /* 20,21: dma4 and dma5 shared by par1, scsi1, ser3 and extdma0 */
52     #define DMA4_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma4)
53     #define DMA5_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma5)
54     #define SER3_DMA_TX_IRQ_NBR DMA4_TX_IRQ_NBR
55     #define SER3_DMA_RX_IRQ_NBR DMA5_RX_IRQ_NBR
56     
57     /* 22,23: dma6 and dma7 shared by ser0, extdma1 and mem2mem */
58     #define DMA6_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma6)
59     #define DMA7_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma7)
60     #define SER0_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR
61     #define SER0_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR
62     #define MEM2MEM_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR
63     #define MEM2MEM_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR
64     
65     /* 24,25: dma8 and dma9 shared by ser1 and usb */
66     #define DMA8_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma8)
67     #define DMA9_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma9)
68     #define SER1_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR
69     #define SER1_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR
70     #define USB_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR
71     #define USB_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR
72     
73     /* usb: controller at irq 31 + uses DMA8 and DMA9 */
74     #define USB_HC_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, usb)
75     
76     
77     
78     
79     
80     extern void disable_irq(unsigned int);
81     extern void enable_irq(unsigned int);
82     
83     #define disable_irq_nosync      disable_irq
84     #define enable_irq_nosync       enable_irq
85     
86     /* our fine, global, etrax irq vector! the pointer lives in the head.S file. */
87     
88     typedef void (*irqvectptr)(void);
89     
90     struct etrax_interrupt_vector {
91     	irqvectptr v[256];
92     };
93     
94     extern struct etrax_interrupt_vector *etrax_irv;
95     void set_int_vector(int n, irqvectptr addr, irqvectptr saddr);
96     void set_break_vector(int n, irqvectptr addr);
97     
98     #define __STR(x) #x
99     #define STR(x) __STR(x)
100      
101     /* SAVE_ALL saves registers so they match pt_regs */
102     
103     #define SAVE_ALL \
104       "move irp,[sp=sp-16]\n\t" /* push instruction pointer and fake SBFS struct */ \
105       "push srp\n\t"       /* push subroutine return pointer */ \
106       "push dccr\n\t"      /* push condition codes */ \
107       "push mof\n\t"       /* push multiply overflow reg */ \
108       "di\n\t"             /* need to disable irq's at this point */\
109       "subq 14*4,sp\n\t"   /* make room for r0-r13 */ \
110       "movem r13,[sp]\n\t" /* push the r0-r13 registers */ \
111       "push r10\n\t"       /* push orig_r10 */ \
112       "clear.d [sp=sp-4]\n\t"  /* frametype - this is a normal stackframe */
113     
114       /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq in irq.c */
115     
116     #define BLOCK_IRQ(mask,nr) \
117       "move.d " #mask ",r0\n\t" \
118       "move.d r0,[0xb00000d8]\n\t" 
119       
120     #define UNBLOCK_IRQ(mask) \
121       "move.d " #mask ",r0\n\t" \
122       "move.d r0,[0xb00000dc]\n\t" 
123     
124     #define IRQ_NAME2(nr) nr##_interrupt(void)
125     #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
126     #define sIRQ_NAME(nr) IRQ_NAME2(sIRQ##nr)
127     #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
128     
129       /* the asm IRQ handler makes sure the causing IRQ is blocked, then it calls
130        * do_IRQ (with irq disabled still). after that it unblocks and jumps to
131        * ret_from_intr (entry.S)
132        */
133     
134     #define BUILD_IRQ(nr,mask) \
135     void IRQ_NAME(nr); \
136     void sIRQ_NAME(nr); \
137     void BAD_IRQ_NAME(nr); \
138     __asm__ ( \
139               ".text\n\t" \
140               "_IRQ" #nr "_interrupt:\n\t" \
141     	  SAVE_ALL \
142     	  "_sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \
143     	  BLOCK_IRQ(mask,nr) /* this must be done to prevent irq loops when we ei later */ \
144     	  "moveq "#nr",r10\n\t" \
145     	  "move.d sp,r11\n\t" \
146     	  "jsr _do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \
147     	  UNBLOCK_IRQ(mask) \
148     	  "moveq 0,r9\n\t" /* make ret_from_intr realise we came from an irq */ \
149     	  "jump _ret_from_intr\n\t" \
150               "_bad_IRQ" #nr "_interrupt:\n\t" \
151     	  "push r0\n\t" \
152     	  BLOCK_IRQ(mask,nr) \
153     	  "pop r0\n\t" \
154               "reti\n\t" \
155               "nop\n");
156     
157     
158     #endif  /* _ASM_IRQ_H */
159     
160     
161