diff options
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
| -rw-r--r-- | arch/powerpc/sysdev/mpic.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 6ffdda244bb1..8619f2a3f1f6 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
| @@ -175,13 +175,16 @@ static inline void _mpic_write(enum mpic_reg_type type, | |||
| 175 | switch(type) { | 175 | switch(type) { |
| 176 | #ifdef CONFIG_PPC_DCR | 176 | #ifdef CONFIG_PPC_DCR |
| 177 | case mpic_access_dcr: | 177 | case mpic_access_dcr: |
| 178 | return dcr_write(rb->dhost, reg, value); | 178 | dcr_write(rb->dhost, reg, value); |
| 179 | break; | ||
| 179 | #endif | 180 | #endif |
| 180 | case mpic_access_mmio_be: | 181 | case mpic_access_mmio_be: |
| 181 | return out_be32(rb->base + (reg >> 2), value); | 182 | out_be32(rb->base + (reg >> 2), value); |
| 183 | break; | ||
| 182 | case mpic_access_mmio_le: | 184 | case mpic_access_mmio_le: |
| 183 | default: | 185 | default: |
| 184 | return out_le32(rb->base + (reg >> 2), value); | 186 | out_le32(rb->base + (reg >> 2), value); |
| 187 | break; | ||
| 185 | } | 188 | } |
| 186 | } | 189 | } |
| 187 | 190 | ||
| @@ -1000,7 +1003,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
| 1000 | const char *name) | 1003 | const char *name) |
| 1001 | { | 1004 | { |
| 1002 | struct mpic *mpic; | 1005 | struct mpic *mpic; |
| 1003 | u32 reg; | 1006 | u32 greg_feature; |
| 1004 | const char *vers; | 1007 | const char *vers; |
| 1005 | int i; | 1008 | int i; |
| 1006 | int intvec_top; | 1009 | int intvec_top; |
| @@ -1064,7 +1067,8 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
| 1064 | 1067 | ||
| 1065 | /* Look for protected sources */ | 1068 | /* Look for protected sources */ |
| 1066 | if (node) { | 1069 | if (node) { |
| 1067 | unsigned int psize, bits, mapsize; | 1070 | int psize; |
| 1071 | unsigned int bits, mapsize; | ||
| 1068 | const u32 *psrc = | 1072 | const u32 *psrc = |
| 1069 | of_get_property(node, "protected-sources", &psize); | 1073 | of_get_property(node, "protected-sources", &psize); |
| 1070 | if (psrc) { | 1074 | if (psrc) { |
| @@ -1107,8 +1111,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
| 1107 | * in, try to obtain one | 1111 | * in, try to obtain one |
| 1108 | */ | 1112 | */ |
| 1109 | if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) { | 1113 | if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) { |
| 1110 | const u32 *reg; | 1114 | const u32 *reg = of_get_property(node, "reg", NULL); |
| 1111 | reg = of_get_property(node, "reg", NULL); | ||
| 1112 | BUG_ON(reg == NULL); | 1115 | BUG_ON(reg == NULL); |
| 1113 | paddr = of_translate_address(node, reg); | 1116 | paddr = of_translate_address(node, reg); |
| 1114 | BUG_ON(paddr == OF_BAD_ADDR); | 1117 | BUG_ON(paddr == OF_BAD_ADDR); |
| @@ -1137,12 +1140,13 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
| 1137 | * MPICs, num sources as well. On ISU MPICs, sources are counted | 1140 | * MPICs, num sources as well. On ISU MPICs, sources are counted |
| 1138 | * as ISUs are added | 1141 | * as ISUs are added |
| 1139 | */ | 1142 | */ |
| 1140 | reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); | 1143 | greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); |
| 1141 | mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK) | 1144 | mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK) |
| 1142 | >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; | 1145 | >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; |
| 1143 | if (isu_size == 0) | 1146 | if (isu_size == 0) |
| 1144 | mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK) | 1147 | mpic->num_sources = |
| 1145 | >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; | 1148 | ((greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK) |
| 1149 | >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; | ||
| 1146 | 1150 | ||
| 1147 | /* Map the per-CPU registers */ | 1151 | /* Map the per-CPU registers */ |
| 1148 | for (i = 0; i < mpic->num_cpus; i++) { | 1152 | for (i = 0; i < mpic->num_cpus; i++) { |
| @@ -1161,7 +1165,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
| 1161 | mpic->isu_mask = (1 << mpic->isu_shift) - 1; | 1165 | mpic->isu_mask = (1 << mpic->isu_shift) - 1; |
| 1162 | 1166 | ||
| 1163 | /* Display version */ | 1167 | /* Display version */ |
| 1164 | switch (reg & MPIC_GREG_FEATURE_VERSION_MASK) { | 1168 | switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) { |
| 1165 | case 1: | 1169 | case 1: |
| 1166 | vers = "1.0"; | 1170 | vers = "1.0"; |
| 1167 | break; | 1171 | break; |
| @@ -1321,7 +1325,7 @@ void __init mpic_set_serial_int(struct mpic *mpic, int enable) | |||
| 1321 | 1325 | ||
| 1322 | void mpic_irq_set_priority(unsigned int irq, unsigned int pri) | 1326 | void mpic_irq_set_priority(unsigned int irq, unsigned int pri) |
| 1323 | { | 1327 | { |
| 1324 | int is_ipi; | 1328 | unsigned int is_ipi; |
| 1325 | struct mpic *mpic = mpic_find(irq, &is_ipi); | 1329 | struct mpic *mpic = mpic_find(irq, &is_ipi); |
| 1326 | unsigned int src = mpic_irq_to_hw(irq); | 1330 | unsigned int src = mpic_irq_to_hw(irq); |
| 1327 | unsigned long flags; | 1331 | unsigned long flags; |
| @@ -1344,7 +1348,7 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) | |||
| 1344 | 1348 | ||
| 1345 | unsigned int mpic_irq_get_priority(unsigned int irq) | 1349 | unsigned int mpic_irq_get_priority(unsigned int irq) |
| 1346 | { | 1350 | { |
| 1347 | int is_ipi; | 1351 | unsigned int is_ipi; |
| 1348 | struct mpic *mpic = mpic_find(irq, &is_ipi); | 1352 | struct mpic *mpic = mpic_find(irq, &is_ipi); |
| 1349 | unsigned int src = mpic_irq_to_hw(irq); | 1353 | unsigned int src = mpic_irq_to_hw(irq); |
| 1350 | unsigned long flags; | 1354 | unsigned long flags; |
| @@ -1406,11 +1410,6 @@ void mpic_cpu_set_priority(int prio) | |||
| 1406 | mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio); | 1410 | mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio); |
| 1407 | } | 1411 | } |
| 1408 | 1412 | ||
| 1409 | /* | ||
| 1410 | * XXX: someone who knows mpic should check this. | ||
| 1411 | * do we need to eoi the ipi including for kexec cpu here (see xics comments)? | ||
| 1412 | * or can we reset the mpic in the new kernel? | ||
| 1413 | */ | ||
| 1414 | void mpic_teardown_this_cpu(int secondary) | 1413 | void mpic_teardown_this_cpu(int secondary) |
| 1415 | { | 1414 | { |
| 1416 | struct mpic *mpic = mpic_primary; | 1415 | struct mpic *mpic = mpic_primary; |
| @@ -1430,6 +1429,10 @@ void mpic_teardown_this_cpu(int secondary) | |||
| 1430 | 1429 | ||
| 1431 | /* Set current processor priority to max */ | 1430 | /* Set current processor priority to max */ |
| 1432 | mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); | 1431 | mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); |
| 1432 | /* We need to EOI the IPI since not all platforms reset the MPIC | ||
| 1433 | * on boot and new interrupts wouldn't get delivered otherwise. | ||
| 1434 | */ | ||
| 1435 | mpic_eoi(mpic); | ||
| 1433 | 1436 | ||
| 1434 | spin_unlock_irqrestore(&mpic_lock, flags); | 1437 | spin_unlock_irqrestore(&mpic_lock, flags); |
| 1435 | } | 1438 | } |
