[PATCH v2 09/11] dma: align barebox DMA coherency setting with kernel's

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



ARM platforms that have cache-coherent peripherals should select
OF_DMA_COHERENCY. These same platforms may run into issues if kernel DT
is changed to assume cache coherency, while barebox DT wasn't.

Therefore add a fixup that fixes up barebox dma-coherent setting into
the kernel's. That way we only have to make sure that Linux and barebox
are in-sync regarding CONFIG_ARCH_DMA_DEFAULT_COHERENT.

Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx>
---
v1 -> v2:
  - split from Layerscape support and make it generic to all users of
    CONFIG_OF_DMA_COHERENCY
  - fixup both dma-coherent or dma-noncoherent if needed
  - don't fix up new property of coherency setting is the default
---
 drivers/dma/Kconfig     |  5 ++++-
 drivers/dma/Makefile    |  1 +
 drivers/dma/of_fixups.c | 40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 1 deletion(-)
 create mode 100644 drivers/dma/of_fixups.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 635b11c7af7d..e7516466d9d3 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -15,6 +15,9 @@ config OF_DMA_COHERENCY
 	  For most platforms supported, either all DMA is coherent or it isn't.
 	  Platforms that have DMA masters of mixed coherency or that differ
 	  from the architecture default will select this option to parse
-	  DMA coherency out of the DT.
+	  DMA coherency out of the DT. This allows barebox to choose the
+	  correct cache maintenance operation during runtime and will cause
+	  barebox to fix up its own DMA coherency setting into the kernel
+	  DT if it differs.
 
 endmenu
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index b55c16e768d5..77bd8abba52c 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -2,3 +2,4 @@
 obj-$(CONFIG_HAS_DMA)		+= map.o
 obj-$(CONFIG_DMA_API_DEBUG)	+= debug.o
 obj-$(CONFIG_MXS_APBH_DMA)	+= apbh_dma.o
+obj-$(CONFIG_OF_DMA_COHERENCY)	+= of_fixups.o
diff --git a/drivers/dma/of_fixups.c b/drivers/dma/of_fixups.c
new file mode 100644
index 000000000000..668313bbfb57
--- /dev/null
+++ b/drivers/dma/of_fixups.c
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <of.h>
+#include <of_address.h>
+#include <driver.h>
+
+static int of_dma_coherent_fixup(struct device_node *root, void *data)
+{
+	struct device_node *soc;
+	enum dev_dma_coherence coherency = (enum dev_dma_coherence)(uintptr_t)data;
+
+	soc = of_find_node_by_path_from(root, "/soc");
+	if (!soc)
+		return -ENOENT;
+
+	of_property_write_bool(soc, "dma-noncoherent", coherency == DEV_DMA_NON_COHERENT);
+	of_property_write_bool(soc, "dma-coherent", coherency == DEV_DMA_COHERENT);
+
+	return 0;
+}
+
+static int of_dma_coherent_fixup_register(void)
+{
+	struct device_node *soc;
+	enum dev_dma_coherence soc_dma_coherency;
+
+	soc = of_find_node_by_path("/soc");
+	if (!soc)
+		return -ENOENT;
+
+	if (of_property_read_bool(soc, "dma-coherent"))
+		soc_dma_coherency = DEV_DMA_COHERENT;
+	else if (of_property_read_bool(soc, "dma-noncoherent"))
+		soc_dma_coherency = DEV_DMA_NON_COHERENT;
+	else
+		soc_dma_coherency = DEV_DMA_COHERENCE_DEFAULT;
+
+	return of_register_fixup(of_dma_coherent_fixup, (void *)(uintptr_t)soc_dma_coherency);
+}
+coredevice_initcall(of_dma_coherent_fixup_register);
-- 
2.39.2





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux