Onboard SD card doesn't work anymore after the 'mmc-v5.4-2' updates

Michael Ellerman mpe at ellerman.id.au
Wed Oct 23 16:42:34 AEDT 2019


Russell King - ARM Linux admin <linux at armlinux.org.uk> writes:
> On Tue, Oct 15, 2019 at 03:12:49PM +0200, Christian Zigotzky wrote:
>> Hello Russell,
>> 
>> You asked me about "dma-coherent" in the Cyrus device tree. Unfortunately I
>> don't find the property "dma-coherent" in the dtb source files.
>> 
>> Output of "fdtdump cyrus_p5020_eth_poweroff.dtb | grep dma":
>> 
>> dma0 = "/soc at ffe000000/dma at 100300";
>>         dma1 = "/soc at ffe000000/dma at 101300";
>>         dma at 100300 {
>>             compatible = "fsl,eloplus-dma";
>>             dma-channel at 0 {
>>                 compatible = "fsl,eloplus-dma-channel";
>>             dma-channel at 80 {
>>                 compatible = "fsl,eloplus-dma-channel";
>>             dma-channel at 100 {
>>                 compatible = "fsl,eloplus-dma-channel";
>>             dma-channel at 180 {
>>                 compatible = "fsl,eloplus-dma-channel";
>>         dma at 101300 {
>>             compatible = "fsl,eloplus-dma";
>>             dma-channel at 0 {
>>                 compatible = "fsl,eloplus-dma-channel";
>>             dma-channel at 80 {
>>                 compatible = "fsl,eloplus-dma-channel";
>>             dma-channel at 100 {
>>                 compatible = "fsl,eloplus-dma-channel";
>>             dma-channel at 180 {
>>                 compatible = "fsl,eloplus-dma-channel";
>
> Hmm, so it looks like PowerPC doesn't mark devices that are dma
> coherent with a property that describes them as such.
>
> I think this opens a wider question - what should of_dma_is_coherent()
> return for PowerPC?  It seems right now that it returns false for
> devices that are DMA coherent, which seems to me to be a recipe for
> future mistakes.

Right, it seems of_dma_is_coherent() has baked in the assumption that
devices are non-coherent unless explicitly marked as coherent.

Which is wrong on all or at least most existing powerpc systems
according to Ben.

> Any ideas from the PPC maintainers?

Fixing it at the source seems like the best option to prevent future
breakage.

So I guess that would mean making of_dma_is_coherent() return true/false
based on CONFIG_NOT_COHERENT_CACHE on powerpc.

We could do it like below, which would still allow the dma-coherent
property to work if it ever makes sense on a future powerpc platform.

I don't really know any of this embedded stuff well, so happy to take
other suggestions on how to handle this mess.

cheers


diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 25aaa3903000..b96c9010acb6 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -760,6 +760,22 @@ static int __init check_cache_coherency(void)
 late_initcall(check_cache_coherency);
 #endif /* CONFIG_CHECK_CACHE_COHERENCY */
 
+#ifndef CONFIG_NOT_COHERENT_CACHE
+/*
+ * For historical reasons powerpc kernels are built with hard wired knowledge of
+ * whether or not DMA accesses are cache coherent. Additionally device trees on
+ * powerpc do not typically support the dma-coherent property.
+ *
+ * So when we know that DMA is coherent, override arch_of_dma_is_coherent() to
+ * tell the drivers/of code that all devices are coherent regardless of whether
+ * they have a dma-coherent property.
+ */
+bool arch_of_dma_is_coherent(struct device_node *np)
+{
+	return true;
+}
+#endif
+
 #ifdef CONFIG_DEBUG_FS
 struct dentry *powerpc_debugfs_root;
 EXPORT_SYMBOL(powerpc_debugfs_root);
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 978427a9d5e6..3a4b2949a322 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -993,6 +993,14 @@ int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *siz
 }
 EXPORT_SYMBOL_GPL(of_dma_get_range);
 
+/*
+ * arch_of_dma_is_coherent - Arch hook to determine if device is coherent for DMA
+ */
+bool __weak arch_of_dma_is_coherent(struct device_node *np)
+{
+	return false;
+}
+
 /**
  * of_dma_is_coherent - Check if device is coherent
  * @np:	device node
@@ -1002,8 +1010,12 @@ EXPORT_SYMBOL_GPL(of_dma_get_range);
  */
 bool of_dma_is_coherent(struct device_node *np)
 {
-	struct device_node *node = of_node_get(np);
+	struct device_node *node;
+
+	if (arch_of_dma_is_coherent(np))
+		return true;
 
+	np = of_node_get(np);
 	while (node) {
 		if (of_property_read_bool(node, "dma-coherent")) {
 			of_node_put(node);


More information about the Linuxppc-dev mailing list