diff options
| author | Anton Blanchard <anton@samba.org> | 2013-08-06 12:01:40 -0400 |
|---|---|---|
| committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-08-14 01:33:29 -0400 |
| commit | 7560d32757392f91a1b5714c309add266b336c5a (patch) | |
| tree | 3b92e89cbd31131698fe18096690d60aaf9d323d /arch/powerpc/kernel | |
| parent | 1502b480e2296359728e4b4e112faf5a5599ca32 (diff) | |
powerpc: Make device tree accesses in VIO subsystem endian safe
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
| -rw-r--r-- | arch/powerpc/kernel/vio.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 31875a6002b7..78a350670de3 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
| @@ -1312,8 +1312,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) | |||
| 1312 | { | 1312 | { |
| 1313 | struct vio_dev *viodev; | 1313 | struct vio_dev *viodev; |
| 1314 | struct device_node *parent_node; | 1314 | struct device_node *parent_node; |
| 1315 | const unsigned int *unit_address; | 1315 | const __be32 *prop; |
| 1316 | const unsigned int *pfo_resid = NULL; | ||
| 1317 | enum vio_dev_family family; | 1316 | enum vio_dev_family family; |
| 1318 | const char *of_node_name = of_node->name ? of_node->name : "<unknown>"; | 1317 | const char *of_node_name = of_node->name ? of_node->name : "<unknown>"; |
| 1319 | 1318 | ||
| @@ -1360,6 +1359,8 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) | |||
| 1360 | /* we need the 'device_type' property, in order to match with drivers */ | 1359 | /* we need the 'device_type' property, in order to match with drivers */ |
| 1361 | viodev->family = family; | 1360 | viodev->family = family; |
| 1362 | if (viodev->family == VDEVICE) { | 1361 | if (viodev->family == VDEVICE) { |
| 1362 | unsigned int unit_address; | ||
| 1363 | |||
| 1363 | if (of_node->type != NULL) | 1364 | if (of_node->type != NULL) |
| 1364 | viodev->type = of_node->type; | 1365 | viodev->type = of_node->type; |
| 1365 | else { | 1366 | else { |
| @@ -1368,24 +1369,24 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) | |||
| 1368 | goto out; | 1369 | goto out; |
| 1369 | } | 1370 | } |
| 1370 | 1371 | ||
| 1371 | unit_address = of_get_property(of_node, "reg", NULL); | 1372 | prop = of_get_property(of_node, "reg", NULL); |
| 1372 | if (unit_address == NULL) { | 1373 | if (prop == NULL) { |
| 1373 | pr_warn("%s: node %s missing 'reg'\n", | 1374 | pr_warn("%s: node %s missing 'reg'\n", |
| 1374 | __func__, of_node_name); | 1375 | __func__, of_node_name); |
| 1375 | goto out; | 1376 | goto out; |
| 1376 | } | 1377 | } |
| 1377 | dev_set_name(&viodev->dev, "%x", *unit_address); | 1378 | unit_address = of_read_number(prop, 1); |
| 1379 | dev_set_name(&viodev->dev, "%x", unit_address); | ||
| 1378 | viodev->irq = irq_of_parse_and_map(of_node, 0); | 1380 | viodev->irq = irq_of_parse_and_map(of_node, 0); |
| 1379 | viodev->unit_address = *unit_address; | 1381 | viodev->unit_address = unit_address; |
| 1380 | } else { | 1382 | } else { |
| 1381 | /* PFO devices need their resource_id for submitting COP_OPs | 1383 | /* PFO devices need their resource_id for submitting COP_OPs |
| 1382 | * This is an optional field for devices, but is required when | 1384 | * This is an optional field for devices, but is required when |
| 1383 | * performing synchronous ops */ | 1385 | * performing synchronous ops */ |
| 1384 | pfo_resid = of_get_property(of_node, "ibm,resource-id", NULL); | 1386 | prop = of_get_property(of_node, "ibm,resource-id", NULL); |
| 1385 | if (pfo_resid != NULL) | 1387 | if (prop != NULL) |
| 1386 | viodev->resource_id = *pfo_resid; | 1388 | viodev->resource_id = of_read_number(prop, 1); |
| 1387 | 1389 | ||
| 1388 | unit_address = NULL; | ||
| 1389 | dev_set_name(&viodev->dev, "%s", of_node_name); | 1390 | dev_set_name(&viodev->dev, "%s", of_node_name); |
| 1390 | viodev->type = of_node_name; | 1391 | viodev->type = of_node_name; |
| 1391 | viodev->irq = 0; | 1392 | viodev->irq = 0; |
| @@ -1622,7 +1623,6 @@ static struct vio_dev *vio_find_name(const char *name) | |||
| 1622 | */ | 1623 | */ |
| 1623 | struct vio_dev *vio_find_node(struct device_node *vnode) | 1624 | struct vio_dev *vio_find_node(struct device_node *vnode) |
| 1624 | { | 1625 | { |
| 1625 | const uint32_t *unit_address; | ||
| 1626 | char kobj_name[20]; | 1626 | char kobj_name[20]; |
| 1627 | struct device_node *vnode_parent; | 1627 | struct device_node *vnode_parent; |
| 1628 | const char *dev_type; | 1628 | const char *dev_type; |
| @@ -1638,10 +1638,13 @@ struct vio_dev *vio_find_node(struct device_node *vnode) | |||
| 1638 | 1638 | ||
| 1639 | /* construct the kobject name from the device node */ | 1639 | /* construct the kobject name from the device node */ |
| 1640 | if (!strcmp(dev_type, "vdevice")) { | 1640 | if (!strcmp(dev_type, "vdevice")) { |
| 1641 | unit_address = of_get_property(vnode, "reg", NULL); | 1641 | const __be32 *prop; |
| 1642 | if (!unit_address) | 1642 | |
| 1643 | prop = of_get_property(vnode, "reg", NULL); | ||
| 1644 | if (!prop) | ||
| 1643 | return NULL; | 1645 | return NULL; |
| 1644 | snprintf(kobj_name, sizeof(kobj_name), "%x", *unit_address); | 1646 | snprintf(kobj_name, sizeof(kobj_name), "%x", |
| 1647 | (uint32_t)of_read_number(prop, 1)); | ||
| 1645 | } else if (!strcmp(dev_type, "ibm,platform-facilities")) | 1648 | } else if (!strcmp(dev_type, "ibm,platform-facilities")) |
| 1646 | snprintf(kobj_name, sizeof(kobj_name), "%s", vnode->name); | 1649 | snprintf(kobj_name, sizeof(kobj_name), "%s", vnode->name); |
| 1647 | else | 1650 | else |
