diff options
Diffstat (limited to 'arch/sh/kernel/cpu/irq/intc2.c')
-rw-r--r-- | arch/sh/kernel/cpu/irq/intc2.c | 182 |
1 files changed, 36 insertions, 146 deletions
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index d4b2bb7e08c7..74defe76a058 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c | |||
@@ -11,27 +11,33 @@ | |||
11 | * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. | 11 | * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. |
12 | */ | 12 | */ |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/irq.h> | 15 | #include <linux/io.h> |
16 | #include <asm/system.h> | 16 | |
17 | #include <asm/io.h> | 17 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) |
18 | #define INTC2_BASE 0xfe080000 | ||
19 | #define INTC2_INTMSK (INTC2_BASE + 0x40) | ||
20 | #define INTC2_INTMSKCLR (INTC2_BASE + 0x60) | ||
21 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | ||
22 | #define INTC2_BASE 0xffd40000 | ||
23 | #define INTC2_INTMSK (INTC2_BASE + 0x38) | ||
24 | #define INTC2_INTMSKCLR (INTC2_BASE + 0x3c) | ||
25 | #endif | ||
18 | 26 | ||
19 | static void disable_intc2_irq(unsigned int irq) | 27 | static void disable_intc2_irq(unsigned int irq) |
20 | { | 28 | { |
21 | struct intc2_data *p = get_irq_chip_data(irq); | 29 | struct intc2_data *p = get_irq_chip_data(irq); |
22 | ctrl_outl(1 << p->msk_shift, | 30 | ctrl_outl(1 << p->msk_shift, INTC2_INTMSK + p->msk_offset); |
23 | INTC2_BASE + INTC2_INTMSK_OFFSET + p->msk_offset); | ||
24 | } | 31 | } |
25 | 32 | ||
26 | static void enable_intc2_irq(unsigned int irq) | 33 | static void enable_intc2_irq(unsigned int irq) |
27 | { | 34 | { |
28 | struct intc2_data *p = get_irq_chip_data(irq); | 35 | struct intc2_data *p = get_irq_chip_data(irq); |
29 | ctrl_outl(1 << p->msk_shift, | 36 | ctrl_outl(1 << p->msk_shift, INTC2_INTMSKCLR + p->msk_offset); |
30 | INTC2_BASE + INTC2_INTMSKCLR_OFFSET + p->msk_offset); | ||
31 | } | 37 | } |
32 | 38 | ||
33 | static struct irq_chip intc2_irq_chip = { | 39 | static struct irq_chip intc2_irq_chip = { |
34 | .typename = "intc2", | 40 | .name = "INTC2", |
35 | .mask = disable_intc2_irq, | 41 | .mask = disable_intc2_irq, |
36 | .unmask = enable_intc2_irq, | 42 | .unmask = enable_intc2_irq, |
37 | .mask_ack = disable_intc2_irq, | 43 | .mask_ack = disable_intc2_irq, |
@@ -45,150 +51,34 @@ static struct irq_chip intc2_irq_chip = { | |||
45 | * PIO1 which is INTPRI00[19,16] and INTMSK00[13] | 51 | * PIO1 which is INTPRI00[19,16] and INTMSK00[13] |
46 | * would be: ^ ^ ^ ^ | 52 | * would be: ^ ^ ^ ^ |
47 | * | | | | | 53 | * | | | | |
48 | * make_intc2_irq(84, 0, 16, 0, 13); | 54 | * { 84, 0, 16, 0, 13 }, |
55 | * | ||
56 | * in the intc2_data table. | ||
49 | */ | 57 | */ |
50 | void make_intc2_irq(struct intc2_data *p) | 58 | void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs) |
51 | { | 59 | { |
52 | unsigned int flags; | 60 | int i; |
53 | unsigned long ipr; | ||
54 | |||
55 | disable_irq_nosync(p->irq); | ||
56 | |||
57 | /* Set the priority level */ | ||
58 | local_irq_save(flags); | ||
59 | |||
60 | ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset); | ||
61 | ipr &= ~(0xf << p->ipr_shift); | ||
62 | ipr |= p->priority << p->ipr_shift; | ||
63 | ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset); | ||
64 | |||
65 | local_irq_restore(flags); | ||
66 | 61 | ||
67 | set_irq_chip_and_handler(p->irq, &intc2_irq_chip, handle_level_irq); | 62 | for (i = 0; i < nr_irqs; i++) { |
68 | set_irq_chip_data(p->irq, p); | 63 | unsigned long ipr, flags; |
64 | struct intc2_data *p = table + i; | ||
69 | 65 | ||
70 | enable_intc2_irq(p->irq); | 66 | disable_irq_nosync(p->irq); |
71 | } | ||
72 | 67 | ||
73 | static struct intc2_data intc2_irq_table[] = { | 68 | /* Set the priority level */ |
74 | #if defined(CONFIG_CPU_SUBTYPE_ST40) | 69 | local_irq_save(flags); |
75 | {64, 0, 0, 0, 0, 13}, /* PCI serr */ | ||
76 | {65, 0, 4, 0, 1, 13}, /* PCI err */ | ||
77 | {66, 0, 4, 0, 2, 13}, /* PCI ad */ | ||
78 | {67, 0, 4, 0, 3, 13}, /* PCI pwd down */ | ||
79 | {72, 0, 8, 0, 5, 13}, /* DMAC INT0 */ | ||
80 | {73, 0, 8, 0, 6, 13}, /* DMAC INT1 */ | ||
81 | {74, 0, 8, 0, 7, 13}, /* DMAC INT2 */ | ||
82 | {75, 0, 8, 0, 8, 13}, /* DMAC INT3 */ | ||
83 | {76, 0, 8, 0, 9, 13}, /* DMAC INT4 */ | ||
84 | {78, 0, 8, 0, 11, 13}, /* DMAC ERR */ | ||
85 | {80, 0, 12, 0, 12, 13}, /* PIO0 */ | ||
86 | {84, 0, 16, 0, 13, 13}, /* PIO1 */ | ||
87 | {88, 0, 20, 0, 14, 13}, /* PIO2 */ | ||
88 | {112, 4, 0, 4, 0, 13}, /* Mailbox */ | ||
89 | #ifdef CONFIG_CPU_SUBTYPE_ST40GX1 | ||
90 | {116, 4, 4, 4, 4, 13}, /* SSC0 */ | ||
91 | {120, 4, 8, 4, 8, 13}, /* IR Blaster */ | ||
92 | {124, 4, 12, 4, 12, 13}, /* USB host */ | ||
93 | {128, 4, 16, 4, 16, 13}, /* Video processor BLITTER */ | ||
94 | {132, 4, 20, 4, 20, 13}, /* UART0 */ | ||
95 | {134, 4, 20, 4, 22, 13}, /* UART2 */ | ||
96 | {136, 4, 24, 4, 24, 13}, /* IO_PIO0 */ | ||
97 | {140, 4, 28, 4, 28, 13}, /* EMPI */ | ||
98 | {144, 8, 0, 8, 0, 13}, /* MAFE */ | ||
99 | {148, 8, 4, 8, 4, 13}, /* PWM */ | ||
100 | {152, 8, 8, 8, 8, 13}, /* SSC1 */ | ||
101 | {156, 8, 12, 8, 12, 13}, /* IO_PIO1 */ | ||
102 | {160, 8, 16, 8, 16, 13}, /* USB target */ | ||
103 | {164, 8, 20, 8, 20, 13}, /* UART1 */ | ||
104 | {168, 8, 24, 8, 24, 13}, /* Teletext */ | ||
105 | {172, 8, 28, 8, 28, 13}, /* VideoSync VTG */ | ||
106 | {173, 8, 28, 8, 29, 13}, /* VideoSync DVP0 */ | ||
107 | {174, 8, 28, 8, 30, 13}, /* VideoSync DVP1 */ | ||
108 | #endif | ||
109 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
110 | /* | ||
111 | * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0 | ||
112 | */ | ||
113 | /* INTPRIO0 | INTMSK0 */ | ||
114 | {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ | ||
115 | {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ | ||
116 | {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ | ||
117 | {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ | ||
118 | /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */ | ||
119 | /* INTPRIO4 | INTMSK0 */ | ||
120 | {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ | ||
121 | {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ | ||
122 | {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ | ||
123 | {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */ | ||
124 | {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */ | ||
125 | {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ | ||
126 | {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ | ||
127 | {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ | ||
128 | /* INTPRIO8 | INTMSK0 */ | ||
129 | {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ | ||
130 | {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ | ||
131 | {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ | ||
132 | {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ | ||
133 | {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ | ||
134 | {65, 8, 24, 0, 16, 3}, /* LCDC */ | ||
135 | /* 66, 67 unused */ | ||
136 | {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ | ||
137 | {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ | ||
138 | {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ | ||
139 | /* 71 unused */ | ||
140 | {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ | ||
141 | {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ | ||
142 | {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ | ||
143 | {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */ | ||
144 | {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */ | ||
145 | {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ | ||
146 | {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ | ||
147 | {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ | ||
148 | /* | INTMSK4 */ | ||
149 | {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ | ||
150 | {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ | ||
151 | {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ | ||
152 | {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ | ||
153 | {84, 8, 0, 4, 19, 3}, /* HSPII */ | ||
154 | /* INTPRIOC | INTMSK4 */ | ||
155 | /* 85-87 unused/reserved */ | ||
156 | {88, 12, 20, 4, 18, 3}, /* MMCI0 */ | ||
157 | {89, 12, 20, 4, 17, 3}, /* MMCI1 */ | ||
158 | {90, 12, 20, 4, 16, 3}, /* MMCI2 */ | ||
159 | {91, 12, 20, 4, 15, 3}, /* MMCI3 */ | ||
160 | {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/ | ||
161 | /* 93-107 reserved/undocumented */ | ||
162 | {108,12, 4, 4, 1, 3}, /* ADC */ | ||
163 | {109,12, 0, 4, 0, 3}, /* CMTI */ | ||
164 | /* 110-111 reserved/unused */ | ||
165 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | ||
166 | { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2}, | ||
167 | { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, | ||
168 | { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, | ||
169 | { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, | ||
170 | { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
171 | { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
172 | { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
173 | { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
174 | 70 | ||
175 | { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | 71 | ipr = ctrl_inl(INTC2_BASE + p->ipr_offset); |
176 | { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | 72 | ipr &= ~(0xf << p->ipr_shift); |
177 | { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | 73 | ipr |= p->priority << p->ipr_shift; |
178 | { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | 74 | ctrl_outl(ipr, INTC2_BASE + p->ipr_offset); |
179 | 75 | ||
180 | { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY }, | 76 | local_irq_restore(flags); |
181 | { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY }, | ||
182 | { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY }, | ||
183 | { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY }, | ||
184 | { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY }, | ||
185 | #endif | ||
186 | }; | ||
187 | 77 | ||
188 | void __init init_IRQ_intc2(void) | 78 | set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip, |
189 | { | 79 | handle_level_irq, "level"); |
190 | int i; | 80 | set_irq_chip_data(p->irq, p); |
191 | 81 | ||
192 | for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++) | 82 | enable_intc2_irq(p->irq); |
193 | make_intc2_irq(intc2_irq_table + i); | 83 | } |
194 | } | 84 | } |