|
@@ -50,16 +50,20 @@ static inline struct page *dma_addr_to_page(struct device *dev,
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
|
|
+ * The affected CPUs below in 'cpu_needs_post_dma_flush()' can
|
|
|
|
+ * speculatively fill random cachelines with stale data at any time,
|
|
|
|
+ * requiring an extra flush post-DMA.
|
|
|
|
+ *
|
|
* Warning on the terminology - Linux calls an uncached area coherent;
|
|
* Warning on the terminology - Linux calls an uncached area coherent;
|
|
* MIPS terminology calls memory areas with hardware maintained coherency
|
|
* MIPS terminology calls memory areas with hardware maintained coherency
|
|
* coherent.
|
|
* coherent.
|
|
*/
|
|
*/
|
|
-
|
|
|
|
-static inline int cpu_is_noncoherent_r10000(struct device *dev)
|
|
|
|
|
|
+static inline int cpu_needs_post_dma_flush(struct device *dev)
|
|
{
|
|
{
|
|
return !plat_device_is_coherent(dev) &&
|
|
return !plat_device_is_coherent(dev) &&
|
|
(current_cpu_type() == CPU_R10000 ||
|
|
(current_cpu_type() == CPU_R10000 ||
|
|
- current_cpu_type() == CPU_R12000);
|
|
|
|
|
|
+ current_cpu_type() == CPU_R12000 ||
|
|
|
|
+ current_cpu_type() == CPU_BMIPS5000);
|
|
}
|
|
}
|
|
|
|
|
|
static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
|
|
static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
|
|
@@ -230,7 +234,7 @@ static inline void __dma_sync(struct page *page,
|
|
static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
|
|
static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
|
|
size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
|
|
size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
|
|
{
|
|
{
|
|
- if (cpu_is_noncoherent_r10000(dev))
|
|
|
|
|
|
+ if (cpu_needs_post_dma_flush(dev))
|
|
__dma_sync(dma_addr_to_page(dev, dma_addr),
|
|
__dma_sync(dma_addr_to_page(dev, dma_addr),
|
|
dma_addr & ~PAGE_MASK, size, direction);
|
|
dma_addr & ~PAGE_MASK, size, direction);
|
|
|
|
|
|
@@ -284,7 +288,7 @@ static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
|
|
static void mips_dma_sync_single_for_cpu(struct device *dev,
|
|
static void mips_dma_sync_single_for_cpu(struct device *dev,
|
|
dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
|
|
dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
|
|
{
|
|
{
|
|
- if (cpu_is_noncoherent_r10000(dev))
|
|
|
|
|
|
+ if (cpu_needs_post_dma_flush(dev))
|
|
__dma_sync(dma_addr_to_page(dev, dma_handle),
|
|
__dma_sync(dma_addr_to_page(dev, dma_handle),
|
|
dma_handle & ~PAGE_MASK, size, direction);
|
|
dma_handle & ~PAGE_MASK, size, direction);
|
|
}
|
|
}
|
|
@@ -305,7 +309,7 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev,
|
|
|
|
|
|
/* Make sure that gcc doesn't leave the empty loop body. */
|
|
/* Make sure that gcc doesn't leave the empty loop body. */
|
|
for (i = 0; i < nelems; i++, sg++) {
|
|
for (i = 0; i < nelems; i++, sg++) {
|
|
- if (cpu_is_noncoherent_r10000(dev))
|
|
|
|
|
|
+ if (cpu_needs_post_dma_flush(dev))
|
|
__dma_sync(sg_page(sg), sg->offset, sg->length,
|
|
__dma_sync(sg_page(sg), sg->offset, sg->length,
|
|
direction);
|
|
direction);
|
|
}
|
|
}
|