diff options
author | Kyle Moffett <Kyle.D.Moffett@boeing.com> | 2011-12-22 05:19:09 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-02-22 18:49:58 -0500 |
commit | 3a7a7176e840f448aae929f7761ea80cf892c665 (patch) | |
tree | 8e4c90c6cb951801fa01db37ba278e4e1f4da17b /arch/powerpc/sysdev | |
parent | 27e74da9800289e69ba907777df1e2085231eff7 (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.c | 46 |
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 | } |