aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/cavium-octeon/octeon-irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/cavium-octeon/octeon-irq.c')
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c89
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
64static 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
64static int octeon_coreid_for_cpu(int cpu) 70static 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,
996static int octeon_irq_gpio_map(struct irq_domain *d, 990static 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);