History

irqchip/gicv3: Handle resource request failure consistently

Due to a silly oversight on my part, making the simple switch to of_io_request_and_map() in the DT path inadvertently introduced divergent behaviour, whereby failng to request an iomem region now becomes fatal for DT, vs. being silently ignored for ACPI. Refactor a bit harder, so that request errors are non-fatal in both paths as intended, but also consistently reported as well.

Robin Murphy committed 4 years ago

Commit 4deb96e1 parent 6fac8241 file · +31 −10Browse files

Unified · Split

drivers/irqchip/irq-gic-v3.c+31−10
@@ -2042,15 +2042,40 @@ static void __init gic_of_setup_kvm_info(struct device_node *node) · 2041 unmodified lines
2042 vgic_set_kvm_info(&gic_v3_kvm_info);2042 vgic_set_kvm_info(&gic_v3_kvm_info);
2043}2043}
2044 2044
2045static void gic_request_region(resource_size_t base, resource_size_t size,
2046 const char *name)
2047{
2048 if (!request_mem_region(base, size, name))
2049 pr_warn_once(FW_BUG "%s region %pa has overlapping address\n",
2050 name, &base);
2051}
2052
2053static void __iomem *gic_of_iomap(struct device_node *node, int idx,
2054 const char *name, struct resource *res)
2055{
2056 void __iomem *base;
2057 int ret;
2058
2059 ret = of_address_to_resource(node, idx, res);
2060 if (ret)
2061 return IOMEM_ERR_PTR(ret);
2062
2063 gic_request_region(res->start, resource_size(res), name);
2064 base = of_iomap(node, idx);
2065
2066 return base ?: IOMEM_ERR_PTR(-ENOMEM);
2067}
2068
2045static int __init gic_of_init(struct device_node *node, struct device_node *parent)2069static int __init gic_of_init(struct device_node *node, struct device_node *parent)
2046{2070{
2047 void __iomem *dist_base;2071 void __iomem *dist_base;
2048 struct redist_region *rdist_regs;2072 struct redist_region *rdist_regs;
2073 struct resource res;
2049 u64 redist_stride;2074 u64 redist_stride;
2050 u32 nr_redist_regions;2075 u32 nr_redist_regions;
2051 int err, i;2076 int err, i;
2052 2077
2053 dist_base = of_io_request_and_map(node, 0, "GICD");2078 dist_base = gic_of_iomap(node, 0, "GICD", &res);
2054 if (IS_ERR(dist_base)) {2079 if (IS_ERR(dist_base)) {
2055 pr_err("%pOF: unable to map gic dist registers\n", node);2080 pr_err("%pOF: unable to map gic dist registers\n", node);
2056 return PTR_ERR(dist_base);2081 return PTR_ERR(dist_base);
@@ -2073,12 +2098,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare · 16 unmodified lines
2073 }2098 }
2074 2099
2075 for (i = 0; i < nr_redist_regions; i++) {2100 for (i = 0; i < nr_redist_regions; i++) {
2076 struct resource res;2101 rdist_regs[i].redist_base = gic_of_iomap(node, 1 + i, "GICR", &res);
2077 int ret;2102 if (IS_ERR(rdist_regs[i].redist_base)) {
2078
2079 ret = of_address_to_resource(node, 1 + i, &res);
2080 rdist_regs[i].redist_base = of_io_request_and_map(node, 1 + i, "GICR");
2081 if (ret || IS_ERR(rdist_regs[i].redist_base)) {
2082 pr_err("%pOF: couldn't map region %d\n", node, i);2103 pr_err("%pOF: couldn't map region %d\n", node, i);
2083 err = -ENODEV;2104 err = -ENODEV;
2084 goto out_unmap_rdist;2105 goto out_unmap_rdist;
@@ -2151,7 +2172,7 @@ gic_acpi_parse_madt_redist(union acpi_subtable_headers *header, · 66 unmodified lines
2151 pr_err("Couldn't map GICR region @%llx\n", redist->base_address);2172 pr_err("Couldn't map GICR region @%llx\n", redist->base_address);
2152 return -ENOMEM;2173 return -ENOMEM;
2153 }2174 }
2154 request_mem_region(redist->base_address, redist->length, "GICR");2175 gic_request_region(redist->base_address, redist->length, "GICR");
2155 2176
2156 gic_acpi_register_redist(redist->base_address, redist_base);2177 gic_acpi_register_redist(redist->base_address, redist_base);
2157 return 0;2178 return 0;
@@ -2174,7 +2195,7 @@ gic_acpi_parse_madt_gicc(union acpi_subtable_headers *header, · 16 unmodified lines
2174 redist_base = ioremap(gicc->gicr_base_address, size);2195 redist_base = ioremap(gicc->gicr_base_address, size);
2175 if (!redist_base)2196 if (!redist_base)
2176 return -ENOMEM;2197 return -ENOMEM;
2177 request_mem_region(gicc->gicr_base_address, size, "GICR");2198 gic_request_region(gicc->gicr_base_address, size, "GICR");
2178 2199
2179 gic_acpi_register_redist(gicc->gicr_base_address, redist_base);2200 gic_acpi_register_redist(gicc->gicr_base_address, redist_base);
2180 return 0;2201 return 0;
@@ -2376,7 +2397,7 @@ gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end) · 195 unmodified lines
2376 pr_err("Unable to map GICD registers\n");2397 pr_err("Unable to map GICD registers\n");
2377 return -ENOMEM;2398 return -ENOMEM;
2378 }2399 }
2379 request_mem_region(dist->base_address, ACPI_GICV3_DIST_MEM_SIZE, "GICD");2400 gic_request_region(dist->base_address, ACPI_GICV3_DIST_MEM_SIZE, "GICD");
2380 2401
2381 err = gic_validate_dist_version(acpi_data.dist_base);2402 err = gic_validate_dist_version(acpi_data.dist_base);
2382 if (err) {2403 if (err) {