summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-atmel.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 1eb83c9..78c885d 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -269,6 +269,7 @@ struct atmel_spi_caps {
bool is_spi2;
bool has_wdrbt;
bool has_dma_support;
+ bool has_pdc_support;
};
/*
@@ -1426,7 +1427,28 @@ static void atmel_get_caps(struct atmel_spi *as)
as->caps.is_spi2 = version > 0x121;
as->caps.has_wdrbt = version >= 0x210;
+#ifdef CONFIG_SOC_SAM_V4_V5
+ /*
+ * Atmel SoCs based on ARM9 (SAM9x) cores should not use spi_map_buf()
+ * since this later function tries to map buffers with dma_map_sg()
+ * even if they have not been allocated inside DMA-safe areas.
+ * On SoCs based on Cortex A5 (SAMA5Dx), it works anyway because for
+ * those ARM cores, the data cache follows the PIPT model.
+ * Also the L2 cache controller of SAMA5D2 uses the PIPT model too.
+ * In case of PIPT caches, there cannot be cache aliases.
+ * However on ARM9 cores, the data cache follows the VIVT model, hence
+ * the cache aliases issue can occur when buffers are allocated from
+ * DMA-unsafe areas, by vmalloc() for instance, where cache coherency is
+ * not taken into account or at least not handled completely (cache
+ * lines of aliases are not invalidated).
+ * This is not a theorical issue: it was reproduced when trying to mount
+ * a UBI file-system on a at91sam9g35ek board.
+ */
+ as->caps.has_dma_support = false;
+#else
as->caps.has_dma_support = version >= 0x212;
+#endif
+ as->caps.has_pdc_support = version < 0x212;
}
/*-------------------------------------------------------------------------*/
@@ -1567,7 +1589,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
} else if (ret == -EPROBE_DEFER) {
return ret;
}
- } else {
+ } else if (as->caps.has_pdc_support) {
as->use_pdc = true;
}
OpenPOWER on IntegriCloud