summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2024-03-22 15:24:24 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2024-03-25 10:59:13 +0100
commit9caee28f71300eb64ee256b9fef2247ca06be5cf (patch)
tree6c84a0b9fbd11c5cde8fbf035eb8118eb2a1820d
parent6c809314ab8837a83bc2575b5698ce763a6d280f (diff)
downloadbarebox-9caee28f71300eb64ee256b9fef2247ca06be5cf.tar.gz
barebox-9caee28f71300eb64ee256b9fef2247ca06be5cf.tar.xz
dma: correctly honour dma-noncoherent device tree property
Most barebox platforms are either completely cache-coherent with respect to DMA or completely non-coherent. To avoid having to walk the device tree for non-existent dma-coherent and dma-noncohrent properties, barebox thus only does this when CONFIG_OF_DMA_COHERENCY is selected. CONFIG_OF_DMA_COHERENCY is to be selected by platforms that have mixed coherency for DMA masters. Forgetting to select this option can be annoying to debug, which is why devinfo will inform the user of default DMA coherency assignments: DMA Coherent: false (default) In order to allow devinfo to differentiate implicit default and explicit device tree DMA coherency configuration, the struct device::dma_coherent member is not of boolean type, but Instead an enumeration that besides coherent and non-coherent also encodes a DEV_DMA_COHERENCE_DEFAULT state. In practice though, a boolean was saved in this dma_coherent member, leading to any dma-noncoherent property being ignored and the default coherency setting being taken for the node. By fixing the type confusion, we restore working Ethernet on the StarFive JH7100, which is the only SoC we currently support that requires /soc/dma-noncohrent to be set for proper operation of its DMA masters. Fixes: fbdea8fd54fe ("of: populate new device_d::dma_coherent attribute") Reported-by: Antony Pavlov <antonynpavlov@gmail.com> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20240322142424.981863-1-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/of/platform.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index ec1482b277..e2c252b1ff 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -90,6 +90,21 @@ static struct device_node *of_get_next_dma_parent(const struct device_node *np)
return args.np;
}
+static enum dev_dma_coherence of_dma_get_coherence(struct device_node *node)
+{
+ if (IS_ENABLED(CONFIG_OF_DMA_COHERENCY)) {
+ while (node) {
+ if (of_property_read_bool(node, "dma-coherent"))
+ return DEV_DMA_COHERENT;
+ if (of_property_read_bool(node, "dma-noncoherent"))
+ return DEV_DMA_NON_COHERENT;
+ node = of_get_next_dma_parent(node);
+ }
+ }
+
+ return DEV_DMA_COHERENCE_DEFAULT;
+}
+
/**
* of_dma_is_coherent - Check if device is coherent
* @np: device node
@@ -101,17 +116,14 @@ static struct device_node *of_get_next_dma_parent(const struct device_node *np)
*/
bool of_dma_is_coherent(struct device_node *node)
{
- if (IS_ENABLED(CONFIG_OF_DMA_COHERENCY)) {
- while (node) {
- if (of_property_read_bool(node, "dma-coherent"))
- return true;
- if (of_property_read_bool(node, "dma-noncoherent"))
- return false;
- node = of_get_next_dma_parent(node);
- }
+ switch (of_dma_get_coherence(node)) {
+ case DEV_DMA_COHERENT:
+ return true;
+ case DEV_DMA_NON_COHERENT:
+ return false;
+ case DEV_DMA_COHERENCE_DEFAULT:
+ return IS_ENABLED(CONFIG_ARCH_DMA_DEFAULT_COHERENT);
}
-
- return IS_ENABLED(CONFIG_ARCH_DMA_DEFAULT_COHERENT);
}
EXPORT_SYMBOL_GPL(of_dma_is_coherent);
@@ -129,7 +141,7 @@ static void of_dma_configure(struct device *dev, struct device_node *np)
}
dev->dma_offset = offset;
- dev->dma_coherent = of_dma_is_coherent(np);
+ dev->dma_coherent = of_dma_get_coherence(np);
}
/**