diff options
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/address.c | 4 | ||||
-rw-r--r-- | drivers/of/device.c | 6 | ||||
-rw-r--r-- | drivers/of/of_reserved_mem.c | 13 |
3 files changed, 17 insertions, 6 deletions
diff --git a/drivers/of/address.c b/drivers/of/address.c index eb9ab4f1e80b..1c3257a2d4e3 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -1034,11 +1034,13 @@ out: */ bool of_dma_is_coherent(struct device_node *np) { - struct device_node *node = of_node_get(np); + struct device_node *node; if (IS_ENABLED(CONFIG_OF_DMA_DEFAULT_COHERENT)) return true; + node = of_node_get(np); + while (node) { if (of_property_read_bool(node, "dma-coherent")) { of_node_put(node); diff --git a/drivers/of/device.c b/drivers/of/device.c index 655dee422563..aedfaaafd3e7 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -93,7 +93,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, { const struct iommu_ops *iommu; const struct bus_dma_region *map = NULL; - dma_addr_t dma_start = 0; + u64 dma_start = 0; u64 mask, end, size = 0; bool coherent; int ret; @@ -109,10 +109,10 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, return ret == -ENODEV ? 0 : ret; } else { const struct bus_dma_region *r = map; - dma_addr_t dma_end = 0; + u64 dma_end = 0; /* Determine the overall bounds of all DMA regions */ - for (dma_start = ~(dma_addr_t)0; r->size; r++) { + for (dma_start = ~0; r->size; r++) { /* Take lower and upper limits */ if (r->dma_start < dma_start) dma_start = r->dma_start; diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index bcd154485972..a7fbc5e37e19 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -200,6 +200,16 @@ static int __init __rmem_cmp(const void *a, const void *b) if (ra->base > rb->base) return 1; + /* + * Put the dynamic allocations (address == 0, size == 0) before static + * allocations at address 0x0 so that overlap detection works + * correctly. + */ + if (ra->size < rb->size) + return -1; + if (ra->size > rb->size) + return 1; + return 0; } @@ -217,8 +227,7 @@ static void __init __rmem_check_for_overlap(void) this = &reserved_mem[i]; next = &reserved_mem[i + 1]; - if (!(this->base && next->base)) - continue; + if (this->base + this->size > next->base) { phys_addr_t this_end, next_end; |