diff options
Diffstat (limited to 'arch/mips/cavium-octeon/octeon-irq.c')
-rw-r--r-- | arch/mips/cavium-octeon/octeon-irq.c | 89 |
1 files changed, 43 insertions, 46 deletions
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 7fb1f222b8a5..274cd4fad30c 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c | |||
@@ -61,6 +61,12 @@ static void octeon_irq_set_ciu_mapping(int irq, int line, int bit, | |||
61 | octeon_irq_ciu_to_irq[line][bit] = irq; | 61 | octeon_irq_ciu_to_irq[line][bit] = irq; |
62 | } | 62 | } |
63 | 63 | ||
64 | static void octeon_irq_force_ciu_mapping(struct irq_domain *domain, | ||
65 | int irq, int line, int bit) | ||
66 | { | ||
67 | irq_domain_associate(domain, irq, line << 6 | bit); | ||
68 | } | ||
69 | |||
64 | static int octeon_coreid_for_cpu(int cpu) | 70 | static int octeon_coreid_for_cpu(int cpu) |
65 | { | 71 | { |
66 | #ifdef CONFIG_SMP | 72 | #ifdef CONFIG_SMP |
@@ -183,19 +189,9 @@ static void __init octeon_irq_init_core(void) | |||
183 | mutex_init(&cd->core_irq_mutex); | 189 | mutex_init(&cd->core_irq_mutex); |
184 | 190 | ||
185 | irq = OCTEON_IRQ_SW0 + i; | 191 | irq = OCTEON_IRQ_SW0 + i; |
186 | switch (irq) { | 192 | irq_set_chip_data(irq, cd); |
187 | case OCTEON_IRQ_TIMER: | 193 | irq_set_chip_and_handler(irq, &octeon_irq_chip_core, |
188 | case OCTEON_IRQ_SW0: | 194 | handle_percpu_irq); |
189 | case OCTEON_IRQ_SW1: | ||
190 | case OCTEON_IRQ_5: | ||
191 | case OCTEON_IRQ_PERF: | ||
192 | irq_set_chip_data(irq, cd); | ||
193 | irq_set_chip_and_handler(irq, &octeon_irq_chip_core, | ||
194 | handle_percpu_irq); | ||
195 | break; | ||
196 | default: | ||
197 | break; | ||
198 | } | ||
199 | } | 195 | } |
200 | } | 196 | } |
201 | 197 | ||
@@ -890,7 +886,6 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d, | |||
890 | unsigned int type; | 886 | unsigned int type; |
891 | unsigned int pin; | 887 | unsigned int pin; |
892 | unsigned int trigger; | 888 | unsigned int trigger; |
893 | struct octeon_irq_gpio_domain_data *gpiod; | ||
894 | 889 | ||
895 | if (d->of_node != node) | 890 | if (d->of_node != node) |
896 | return -EINVAL; | 891 | return -EINVAL; |
@@ -925,8 +920,7 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d, | |||
925 | break; | 920 | break; |
926 | } | 921 | } |
927 | *out_type = type; | 922 | *out_type = type; |
928 | gpiod = d->host_data; | 923 | *out_hwirq = pin; |
929 | *out_hwirq = gpiod->base_hwirq + pin; | ||
930 | 924 | ||
931 | return 0; | 925 | return 0; |
932 | } | 926 | } |
@@ -996,19 +990,21 @@ static int octeon_irq_ciu_map(struct irq_domain *d, | |||
996 | static int octeon_irq_gpio_map(struct irq_domain *d, | 990 | static int octeon_irq_gpio_map(struct irq_domain *d, |
997 | unsigned int virq, irq_hw_number_t hw) | 991 | unsigned int virq, irq_hw_number_t hw) |
998 | { | 992 | { |
999 | unsigned int line = hw >> 6; | 993 | struct octeon_irq_gpio_domain_data *gpiod = d->host_data; |
1000 | unsigned int bit = hw & 63; | 994 | unsigned int line, bit; |
1001 | 995 | ||
1002 | if (!octeon_irq_virq_in_range(virq)) | 996 | if (!octeon_irq_virq_in_range(virq)) |
1003 | return -EINVAL; | 997 | return -EINVAL; |
1004 | 998 | ||
999 | hw += gpiod->base_hwirq; | ||
1000 | line = hw >> 6; | ||
1001 | bit = hw & 63; | ||
1005 | if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0) | 1002 | if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0) |
1006 | return -EINVAL; | 1003 | return -EINVAL; |
1007 | 1004 | ||
1008 | octeon_irq_set_ciu_mapping(virq, line, bit, | 1005 | octeon_irq_set_ciu_mapping(virq, line, bit, |
1009 | octeon_irq_gpio_chip, | 1006 | octeon_irq_gpio_chip, |
1010 | octeon_irq_handle_gpio); | 1007 | octeon_irq_handle_gpio); |
1011 | |||
1012 | return 0; | 1008 | return 0; |
1013 | } | 1009 | } |
1014 | 1010 | ||
@@ -1149,6 +1145,7 @@ static void __init octeon_irq_init_ciu(void) | |||
1149 | struct irq_chip *chip_wd; | 1145 | struct irq_chip *chip_wd; |
1150 | struct device_node *gpio_node; | 1146 | struct device_node *gpio_node; |
1151 | struct device_node *ciu_node; | 1147 | struct device_node *ciu_node; |
1148 | struct irq_domain *ciu_domain = NULL; | ||
1152 | 1149 | ||
1153 | octeon_irq_init_ciu_percpu(); | 1150 | octeon_irq_init_ciu_percpu(); |
1154 | octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; | 1151 | octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; |
@@ -1177,31 +1174,6 @@ static void __init octeon_irq_init_ciu(void) | |||
1177 | /* Mips internal */ | 1174 | /* Mips internal */ |
1178 | octeon_irq_init_core(); | 1175 | octeon_irq_init_core(); |
1179 | 1176 | ||
1180 | /* CIU_0 */ | ||
1181 | for (i = 0; i < 16; i++) | ||
1182 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); | ||
1183 | |||
1184 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); | ||
1185 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); | ||
1186 | |||
1187 | for (i = 0; i < 4; i++) | ||
1188 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); | ||
1189 | for (i = 0; i < 4; i++) | ||
1190 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); | ||
1191 | |||
1192 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); | ||
1193 | for (i = 0; i < 4; i++) | ||
1194 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip, handle_edge_irq); | ||
1195 | |||
1196 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); | ||
1197 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); | ||
1198 | |||
1199 | /* CIU_1 */ | ||
1200 | for (i = 0; i < 16; i++) | ||
1201 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); | ||
1202 | |||
1203 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); | ||
1204 | |||
1205 | gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio"); | 1177 | gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio"); |
1206 | if (gpio_node) { | 1178 | if (gpio_node) { |
1207 | struct octeon_irq_gpio_domain_data *gpiod; | 1179 | struct octeon_irq_gpio_domain_data *gpiod; |
@@ -1219,10 +1191,35 @@ static void __init octeon_irq_init_ciu(void) | |||
1219 | 1191 | ||
1220 | ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu"); | 1192 | ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu"); |
1221 | if (ciu_node) { | 1193 | if (ciu_node) { |
1222 | irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL); | 1194 | ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL); |
1223 | of_node_put(ciu_node); | 1195 | of_node_put(ciu_node); |
1224 | } else | 1196 | } else |
1225 | pr_warn("Cannot find device node for cavium,octeon-3860-ciu.\n"); | 1197 | panic("Cannot find device node for cavium,octeon-3860-ciu."); |
1198 | |||
1199 | /* CIU_0 */ | ||
1200 | for (i = 0; i < 16; i++) | ||
1201 | octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i + 0); | ||
1202 | |||
1203 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); | ||
1204 | octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); | ||
1205 | |||
1206 | for (i = 0; i < 4; i++) | ||
1207 | octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 0, i + 36); | ||
1208 | for (i = 0; i < 4; i++) | ||
1209 | octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 0, i + 40); | ||
1210 | |||
1211 | octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_RML, 0, 46); | ||
1212 | for (i = 0; i < 4; i++) | ||
1213 | octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52); | ||
1214 | |||
1215 | octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56); | ||
1216 | octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_BOOTDMA, 0, 63); | ||
1217 | |||
1218 | /* CIU_1 */ | ||
1219 | for (i = 0; i < 16; i++) | ||
1220 | octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); | ||
1221 | |||
1222 | octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB1, 1, 17); | ||
1226 | 1223 | ||
1227 | /* Enable the CIU lines */ | 1224 | /* Enable the CIU lines */ |
1228 | set_c0_status(STATUSF_IP3 | STATUSF_IP2); | 1225 | set_c0_status(STATUSF_IP3 | STATUSF_IP2); |