[PATCH] ACPI: ARM64: IORT: rework iort_node_get_id() for NC->SMMU->ITS case part #2

From: Sinan Kaya
Date: Mon Jan 02 2017 - 17:16:45 EST


Code won't collect the output ID as it traverses NC->SMMU->ITS path.
Adding support for this use case.

A named node can have an output ID of 0x20 and SMMU can have an output
parameter of 0x80000. The device ID needs to be 0x80000+0x20 for this
use case.

Signed-off-by: Sinan Kaya <okaya@xxxxxxxxxxxxxx>
---
drivers/acpi/arm64/iort.c | 58 ++++++++++++++++++++++++++---------------------
1 file changed, 32 insertions(+), 26 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 882e624..19cb97a 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -296,18 +296,16 @@ static int iort_id_single_map(struct acpi_iort_id_mapping *map, u8 type,
u32 *rid_out)
{
/* Single mapping does not care for input id */
- if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
- if (type == ACPI_IORT_NODE_NAMED_COMPONENT ||
- type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
- if (rid_out)
- *rid_out = map->output_base;
- return 0;
- }
-
- pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n",
- map, type);
+ if (type == ACPI_IORT_NODE_NAMED_COMPONENT ||
+ type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
+ if (rid_out)
+ *rid_out = map->output_base;
+ return 0;
}

+ pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n",
+ map, type);
+
return -ENXIO;
}

@@ -327,13 +325,20 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
u32 *id_out, u8 type_mask,
int index)
{
- struct acpi_iort_node *parent;
- struct acpi_iort_id_mapping *map;
+ u32 id = 0;

while (node) {
- if (!node->mapping_offset || !node->mapping_count ||
- index >= node->mapping_count)
- return NULL;
+ struct acpi_iort_id_mapping *map;
+
+ if (IORT_TYPE_MASK(node->type) & type_mask) {
+ if (id_out)
+ *id_out = id;
+
+ return node;
+ }
+
+ if (!node->mapping_offset || !node->mapping_count)
+ goto fail_map;

map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
node->mapping_offset);
@@ -342,24 +347,25 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
if (!map->output_reference) {
pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
node, node->type);
- return NULL;
+ goto fail_map;
}

- parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
- map->output_reference);
-
- /* go upstream to find its parent */
- if (!(IORT_TYPE_MASK(parent->type) & type_mask)) {
- node = parent;
- continue;
+ if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
+ if (iort_id_single_map(&map[index], node->type, &id))
+ goto fail_map;
+ } else {
+ if (iort_id_map(map, id, &id))
+ goto fail_map;
}

- if (iort_id_single_map(&map[index], node->type, id_out))
- break;
+ if (index == node->mapping_count)
+ goto fail_map;

- return parent;
+ node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+ map->output_reference);
}

+fail_map:
return NULL;
}

--
1.9.1


--------------34DCB64D893974D565DDD218--