diff options
Diffstat (limited to 'arch/blackfin/mach-bf537/ints-priority.c')
-rw-r--r-- | arch/blackfin/mach-bf537/ints-priority.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c index f6500622b35..2137a209a22 100644 --- a/arch/blackfin/mach-bf537/ints-priority.c +++ b/arch/blackfin/mach-bf537/ints-priority.c | |||
@@ -10,6 +10,13 @@ | |||
10 | #include <linux/irq.h> | 10 | #include <linux/irq.h> |
11 | #include <asm/blackfin.h> | 11 | #include <asm/blackfin.h> |
12 | 12 | ||
13 | #include <asm/irq_handler.h> | ||
14 | #include <asm/bfin5xx_spi.h> | ||
15 | #include <asm/bfin_sport.h> | ||
16 | #include <asm/bfin_can.h> | ||
17 | #include <asm/bfin_dma.h> | ||
18 | #include <asm/dpmc.h> | ||
19 | |||
13 | void __init program_IAR(void) | 20 | void __init program_IAR(void) |
14 | { | 21 | { |
15 | /* Program the IAR0 Register with the configured priority */ | 22 | /* Program the IAR0 Register with the configured priority */ |
@@ -51,3 +58,159 @@ void __init program_IAR(void) | |||
51 | 58 | ||
52 | SSYNC(); | 59 | SSYNC(); |
53 | } | 60 | } |
61 | |||
62 | #define SPI_ERR_MASK (BIT_STAT_TXCOL | BIT_STAT_RBSY | BIT_STAT_MODF | BIT_STAT_TXE) /* SPI_STAT */ | ||
63 | #define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF) /* SPORT_STAT */ | ||
64 | #define PPI_ERR_MASK (0xFFFF & ~FLD) /* PPI_STATUS */ | ||
65 | #define EMAC_ERR_MASK (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE) /* EMAC_SYSTAT */ | ||
66 | #define UART_ERR_MASK (0x6) /* UART_IIR */ | ||
67 | #define CAN_ERR_MASK (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF) /* CAN_GIF */ | ||
68 | |||
69 | static int error_int_mask; | ||
70 | |||
71 | static void bf537_generic_error_mask_irq(struct irq_data *d) | ||
72 | { | ||
73 | error_int_mask &= ~(1L << (d->irq - IRQ_PPI_ERROR)); | ||
74 | if (!error_int_mask) | ||
75 | bfin_internal_mask_irq(IRQ_GENERIC_ERROR); | ||
76 | } | ||
77 | |||
78 | static void bf537_generic_error_unmask_irq(struct irq_data *d) | ||
79 | { | ||
80 | bfin_internal_unmask_irq(IRQ_GENERIC_ERROR); | ||
81 | error_int_mask |= 1L << (d->irq - IRQ_PPI_ERROR); | ||
82 | } | ||
83 | |||
84 | static struct irq_chip bf537_generic_error_irqchip = { | ||
85 | .name = "ERROR", | ||
86 | .irq_ack = bfin_ack_noop, | ||
87 | .irq_mask_ack = bf537_generic_error_mask_irq, | ||
88 | .irq_mask = bf537_generic_error_mask_irq, | ||
89 | .irq_unmask = bf537_generic_error_unmask_irq, | ||
90 | }; | ||
91 | |||
92 | static void bf537_demux_error_irq(unsigned int int_err_irq, | ||
93 | struct irq_desc *inta_desc) | ||
94 | { | ||
95 | int irq = 0; | ||
96 | |||
97 | #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) | ||
98 | if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK) | ||
99 | irq = IRQ_MAC_ERROR; | ||
100 | else | ||
101 | #endif | ||
102 | if (bfin_read_SPORT0_STAT() & SPORT_ERR_MASK) | ||
103 | irq = IRQ_SPORT0_ERROR; | ||
104 | else if (bfin_read_SPORT1_STAT() & SPORT_ERR_MASK) | ||
105 | irq = IRQ_SPORT1_ERROR; | ||
106 | else if (bfin_read_PPI_STATUS() & PPI_ERR_MASK) | ||
107 | irq = IRQ_PPI_ERROR; | ||
108 | else if (bfin_read_CAN_GIF() & CAN_ERR_MASK) | ||
109 | irq = IRQ_CAN_ERROR; | ||
110 | else if (bfin_read_SPI_STAT() & SPI_ERR_MASK) | ||
111 | irq = IRQ_SPI_ERROR; | ||
112 | else if ((bfin_read_UART0_IIR() & UART_ERR_MASK) == UART_ERR_MASK) | ||
113 | irq = IRQ_UART0_ERROR; | ||
114 | else if ((bfin_read_UART1_IIR() & UART_ERR_MASK) == UART_ERR_MASK) | ||
115 | irq = IRQ_UART1_ERROR; | ||
116 | |||
117 | if (irq) { | ||
118 | if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR))) | ||
119 | bfin_handle_irq(irq); | ||
120 | else { | ||
121 | |||
122 | switch (irq) { | ||
123 | case IRQ_PPI_ERROR: | ||
124 | bfin_write_PPI_STATUS(PPI_ERR_MASK); | ||
125 | break; | ||
126 | #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) | ||
127 | case IRQ_MAC_ERROR: | ||
128 | bfin_write_EMAC_SYSTAT(EMAC_ERR_MASK); | ||
129 | break; | ||
130 | #endif | ||
131 | case IRQ_SPORT0_ERROR: | ||
132 | bfin_write_SPORT0_STAT(SPORT_ERR_MASK); | ||
133 | break; | ||
134 | |||
135 | case IRQ_SPORT1_ERROR: | ||
136 | bfin_write_SPORT1_STAT(SPORT_ERR_MASK); | ||
137 | break; | ||
138 | |||
139 | case IRQ_CAN_ERROR: | ||
140 | bfin_write_CAN_GIS(CAN_ERR_MASK); | ||
141 | break; | ||
142 | |||
143 | case IRQ_SPI_ERROR: | ||
144 | bfin_write_SPI_STAT(SPI_ERR_MASK); | ||
145 | break; | ||
146 | |||
147 | default: | ||
148 | break; | ||
149 | } | ||
150 | |||
151 | pr_debug("IRQ %d:" | ||
152 | " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n", | ||
153 | irq); | ||
154 | } | ||
155 | } else | ||
156 | pr_err("%s: IRQ ?: PERIPHERAL ERROR INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", | ||
157 | __func__); | ||
158 | |||
159 | } | ||
160 | |||
161 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | ||
162 | static int mac_rx_int_mask; | ||
163 | |||
164 | static void bf537_mac_rx_mask_irq(struct irq_data *d) | ||
165 | { | ||
166 | mac_rx_int_mask &= ~(1L << (d->irq - IRQ_MAC_RX)); | ||
167 | if (!mac_rx_int_mask) | ||
168 | bfin_internal_mask_irq(IRQ_PH_INTA_MAC_RX); | ||
169 | } | ||
170 | |||
171 | static void bf537_mac_rx_unmask_irq(struct irq_data *d) | ||
172 | { | ||
173 | bfin_internal_unmask_irq(IRQ_PH_INTA_MAC_RX); | ||
174 | mac_rx_int_mask |= 1L << (d->irq - IRQ_MAC_RX); | ||
175 | } | ||
176 | |||
177 | static struct irq_chip bf537_mac_rx_irqchip = { | ||
178 | .name = "ERROR", | ||
179 | .irq_ack = bfin_ack_noop, | ||
180 | .irq_mask_ack = bf537_mac_rx_mask_irq, | ||
181 | .irq_mask = bf537_mac_rx_mask_irq, | ||
182 | .irq_unmask = bf537_mac_rx_unmask_irq, | ||
183 | }; | ||
184 | |||
185 | static void bf537_demux_mac_rx_irq(unsigned int int_irq, | ||
186 | struct irq_desc *desc) | ||
187 | { | ||
188 | if (bfin_read_DMA1_IRQ_STATUS() & (DMA_DONE | DMA_ERR)) | ||
189 | bfin_handle_irq(IRQ_MAC_RX); | ||
190 | else | ||
191 | bfin_demux_gpio_irq(int_irq, desc); | ||
192 | } | ||
193 | #endif | ||
194 | |||
195 | void __init init_mach_irq(void) | ||
196 | { | ||
197 | int irq; | ||
198 | |||
199 | #if defined(CONFIG_BF537) || defined(CONFIG_BF536) | ||
200 | /* Clear EMAC Interrupt Status bits so we can demux it later */ | ||
201 | bfin_write_EMAC_SYSTAT(-1); | ||
202 | #endif | ||
203 | |||
204 | irq_set_chained_handler(IRQ_GENERIC_ERROR, bf537_demux_error_irq); | ||
205 | for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) | ||
206 | irq_set_chip_and_handler(irq, &bf537_generic_error_irqchip, | ||
207 | handle_level_irq); | ||
208 | |||
209 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | ||
210 | irq_set_chained_handler(IRQ_PH_INTA_MAC_RX, bf537_demux_mac_rx_irq); | ||
211 | irq_set_chip_and_handler(IRQ_MAC_RX, &bf537_mac_rx_irqchip, handle_level_irq); | ||
212 | irq_set_chip_and_handler(IRQ_PORTH_INTA, &bf537_mac_rx_irqchip, handle_level_irq); | ||
213 | |||
214 | irq_set_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq); | ||
215 | #endif | ||
216 | } | ||