aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorKyle Moffett <Kyle.D.Moffett@boeing.com>2011-12-22 05:19:09 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-02-22 18:49:58 -0500
commit3a7a7176e840f448aae929f7761ea80cf892c665 (patch)
tree8e4c90c6cb951801fa01db37ba278e4e1f4da17b /arch/powerpc/sysdev
parent27e74da9800289e69ba907777df1e2085231eff7 (diff)
powerpc/mpic: Fix use of "flags" variable in mpic_alloc()
The mpic_alloc() function takes a "flags" parameter and assigns it into the mpic->flags variable fairly early on, but several later pieces of code detect various device-tree properties and save them into the "mpic->flags" variable (EG: "big-endian" => MPIC_BIG_ENDIAN). Unfortunately, a number of codepaths (including several which test the flag MPIC_BIG_ENDIAN!) test "flags" instead of "mpic->flags", and get wrong answers as a result. Consolidate the device-tree flag tests early in mpic_alloc() and change all of the checks after "mpic->flags" is init'ed to use "mpic->flags". [BenH: Fixed up use of mpic->node before it's initialized] Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/mpic.c46
1 files changed, 22 insertions, 24 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 4e9ccb1015de..9deec44ede83 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1182,6 +1182,14 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1182 } 1182 }
1183 } 1183 }
1184 1184
1185 /* Read extra device-tree properties into the flags variable */
1186 if (of_get_property(node, "big-endian", NULL))
1187 flags |= MPIC_BIG_ENDIAN;
1188 if (of_get_property(node, "pic-no-reset", NULL))
1189 flags |= MPIC_NO_RESET;
1190 if (of_device_is_compatible(node, "fsl,mpic"))
1191 flags |= MPIC_FSL;
1192
1185 mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL); 1193 mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
1186 if (mpic == NULL) 1194 if (mpic == NULL)
1187 goto err_of_node_put; 1195 goto err_of_node_put;
@@ -1189,15 +1197,16 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1189 mpic->name = name; 1197 mpic->name = name;
1190 mpic->node = node; 1198 mpic->node = node;
1191 mpic->paddr = phys_addr; 1199 mpic->paddr = phys_addr;
1200 mpic->flags = flags;
1192 1201
1193 mpic->hc_irq = mpic_irq_chip; 1202 mpic->hc_irq = mpic_irq_chip;
1194 mpic->hc_irq.name = name; 1203 mpic->hc_irq.name = name;
1195 if (!(flags & MPIC_SECONDARY)) 1204 if (!(mpic->flags & MPIC_SECONDARY))
1196 mpic->hc_irq.irq_set_affinity = mpic_set_affinity; 1205 mpic->hc_irq.irq_set_affinity = mpic_set_affinity;
1197#ifdef CONFIG_MPIC_U3_HT_IRQS 1206#ifdef CONFIG_MPIC_U3_HT_IRQS
1198 mpic->hc_ht_irq = mpic_irq_ht_chip; 1207 mpic->hc_ht_irq = mpic_irq_ht_chip;
1199 mpic->hc_ht_irq.name = name; 1208 mpic->hc_ht_irq.name = name;
1200 if (!(flags & MPIC_SECONDARY)) 1209 if (!(mpic->flags & MPIC_SECONDARY))
1201 mpic->hc_ht_irq.irq_set_affinity = mpic_set_affinity; 1210 mpic->hc_ht_irq.irq_set_affinity = mpic_set_affinity;
1202#endif /* CONFIG_MPIC_U3_HT_IRQS */ 1211#endif /* CONFIG_MPIC_U3_HT_IRQS */
1203 1212
@@ -1209,12 +1218,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1209 mpic->hc_tm = mpic_tm_chip; 1218 mpic->hc_tm = mpic_tm_chip;
1210 mpic->hc_tm.name = name; 1219 mpic->hc_tm.name = name;
1211 1220
1212 mpic->flags = flags;
1213 mpic->isu_size = isu_size; 1221 mpic->isu_size = isu_size;
1214 mpic->irq_count = irq_count; 1222 mpic->irq_count = irq_count;
1215 mpic->num_sources = 0; /* so far */ 1223 mpic->num_sources = 0; /* so far */
1216 1224
1217 if (flags & MPIC_LARGE_VECTORS) 1225 if (mpic->flags & MPIC_LARGE_VECTORS)
1218 intvec_top = 2047; 1226 intvec_top = 2047;
1219 else 1227 else
1220 intvec_top = 255; 1228 intvec_top = 255;
@@ -1233,12 +1241,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1233 mpic->ipi_vecs[3] = intvec_top - 1; 1241 mpic->ipi_vecs[3] = intvec_top - 1;
1234 mpic->spurious_vec = intvec_top; 1242 mpic->spurious_vec = intvec_top;
1235 1243
1236 /* Check for "big-endian" in device-tree */
1237 if (of_get_property(mpic->node, "big-endian", NULL) != NULL)
1238 mpic->flags |= MPIC_BIG_ENDIAN;
1239 if (of_device_is_compatible(mpic->node, "fsl,mpic"))
1240 mpic->flags |= MPIC_FSL;
1241
1242 /* Look for protected sources */ 1244 /* Look for protected sources */
1243 psrc = of_get_property(mpic->node, "protected-sources", &psize); 1245 psrc = of_get_property(mpic->node, "protected-sources", &psize);
1244 if (psrc) { 1246 if (psrc) {
@@ -1254,11 +1256,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1254 } 1256 }
1255 1257
1256#ifdef CONFIG_MPIC_WEIRD 1258#ifdef CONFIG_MPIC_WEIRD
1257 mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; 1259 mpic->hw_set = mpic_infos[MPIC_GET_REGSET(mpic->flags)];
1258#endif 1260#endif
1259 1261
1260 /* default register type */ 1262 /* default register type */
1261 if (flags & MPIC_BIG_ENDIAN) 1263 if (mpic->flags & MPIC_BIG_ENDIAN)
1262 mpic->reg_type = mpic_access_mmio_be; 1264 mpic->reg_type = mpic_access_mmio_be;
1263 else 1265 else
1264 mpic->reg_type = mpic_access_mmio_le; 1266 mpic->reg_type = mpic_access_mmio_le;
@@ -1268,10 +1270,10 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1268 * only if the kernel includes DCR support. 1270 * only if the kernel includes DCR support.
1269 */ 1271 */
1270#ifdef CONFIG_PPC_DCR 1272#ifdef CONFIG_PPC_DCR
1271 if (flags & MPIC_USES_DCR) 1273 if (mpic->flags & MPIC_USES_DCR)
1272 mpic->reg_type = mpic_access_dcr; 1274 mpic->reg_type = mpic_access_dcr;
1273#else 1275#else
1274 BUG_ON(flags & MPIC_USES_DCR); 1276 BUG_ON(mpic->flags & MPIC_USES_DCR);
1275#endif 1277#endif
1276 1278
1277 /* Map the global registers */ 1279 /* Map the global registers */
@@ -1283,10 +1285,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1283 /* When using a device-node, reset requests are only honored if the MPIC 1285 /* When using a device-node, reset requests are only honored if the MPIC
1284 * is allowed to reset. 1286 * is allowed to reset.
1285 */ 1287 */
1286 if (of_get_property(mpic->node, "pic-no-reset", NULL)) 1288 if ((mpic->flags & MPIC_WANTS_RESET) && !(mpic->flags & MPIC_NO_RESET)) {
1287 mpic->flags |= MPIC_NO_RESET;
1288
1289 if ((flags & MPIC_WANTS_RESET) && !(mpic->flags & MPIC_NO_RESET)) {
1290 printk(KERN_DEBUG "mpic: Resetting\n"); 1289 printk(KERN_DEBUG "mpic: Resetting\n");
1291 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), 1290 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
1292 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) 1291 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
@@ -1297,12 +1296,12 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1297 } 1296 }
1298 1297
1299 /* CoreInt */ 1298 /* CoreInt */
1300 if (flags & MPIC_ENABLE_COREINT) 1299 if (mpic->flags & MPIC_ENABLE_COREINT)
1301 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), 1300 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
1302 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) 1301 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1303 | MPIC_GREG_GCONF_COREINT); 1302 | MPIC_GREG_GCONF_COREINT);
1304 1303
1305 if (flags & MPIC_ENABLE_MCK) 1304 if (mpic->flags & MPIC_ENABLE_MCK)
1306 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), 1305 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
1307 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) 1306 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1308 | MPIC_GREG_GCONF_MCK); 1307 | MPIC_GREG_GCONF_MCK);
@@ -1313,7 +1312,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1313 */ 1312 */
1314 greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); 1313 greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
1315 if (isu_size == 0) { 1314 if (isu_size == 0) {
1316 if (flags & MPIC_BROKEN_FRR_NIRQS) 1315 if (mpic->flags & MPIC_BROKEN_FRR_NIRQS)
1317 mpic->num_sources = mpic->irq_count; 1316 mpic->num_sources = mpic->irq_count;
1318 else 1317 else
1319 mpic->num_sources = 1318 mpic->num_sources =
@@ -1347,8 +1346,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1347 1346
1348 mpic->irqhost = irq_alloc_host(mpic->node, IRQ_HOST_MAP_LINEAR, 1347 mpic->irqhost = irq_alloc_host(mpic->node, IRQ_HOST_MAP_LINEAR,
1349 isu_size ? isu_size : mpic->num_sources, 1348 isu_size ? isu_size : mpic->num_sources,
1350 &mpic_host_ops, 1349 &mpic_host_ops, intvec_top + 1);
1351 flags & MPIC_LARGE_VECTORS ? 2048 : 256);
1352 1350
1353 /* 1351 /*
1354 * FIXME: The code leaks the MPIC object and mappings here; this 1352 * FIXME: The code leaks the MPIC object and mappings here; this
@@ -1383,7 +1381,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1383 mpic->next = mpics; 1381 mpic->next = mpics;
1384 mpics = mpic; 1382 mpics = mpic;
1385 1383
1386 if (!(flags & MPIC_SECONDARY)) { 1384 if (!(mpic->flags & MPIC_SECONDARY)) {
1387 mpic_primary = mpic; 1385 mpic_primary = mpic;
1388 irq_set_default_host(mpic->irqhost); 1386 irq_set_default_host(mpic->irqhost);
1389 } 1387 }