>From c5ab7172a400bfd5b460374e70394fe78c260603 Mon Sep 17 00:00:00 2001 From: Sinan Kaya Date: Mon, 2 Jan 2017 17:16:45 -0500 Subject: [PATCH] ACPI: ARM64: IORT: rework iort_node_get_id() for NC->SMMU->ITS case part #2 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 --- 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