Skip to content

Commit 6ecba8e

Browse files
committed
arm64: Use bus notifiers to set per-device coherent DMA ops
Recently, the default DMA ops have been changed to non-coherent for alignment with 32-bit ARM platforms (and DT files). This patch adds bus notifiers to be able to set the coherent DMA ops (with no cache maintenance) for devices explicitly marked as coherent via the "dma-coherent" DT property. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent c7a4a76 commit 6ecba8e

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

arch/arm64/kernel/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ static int __init arm64_device_init(void)
396396
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
397397
return 0;
398398
}
399-
arch_initcall(arm64_device_init);
399+
arch_initcall_sync(arm64_device_init);
400400

401401
static DEFINE_PER_CPU(struct cpu, cpu_data);
402402

arch/arm64/mm/dma-mapping.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
#include <linux/slab.h>
2323
#include <linux/dma-mapping.h>
2424
#include <linux/dma-contiguous.h>
25+
#include <linux/of.h>
26+
#include <linux/platform_device.h>
2527
#include <linux/vmalloc.h>
2628
#include <linux/swiotlb.h>
29+
#include <linux/amba/bus.h>
2730

2831
#include <asm/cacheflush.h>
2932

@@ -305,17 +308,45 @@ struct dma_map_ops coherent_swiotlb_dma_ops = {
305308
};
306309
EXPORT_SYMBOL(coherent_swiotlb_dma_ops);
307310

311+
static int dma_bus_notifier(struct notifier_block *nb,
312+
unsigned long event, void *_dev)
313+
{
314+
struct device *dev = _dev;
315+
316+
if (event != BUS_NOTIFY_ADD_DEVICE)
317+
return NOTIFY_DONE;
318+
319+
if (of_property_read_bool(dev->of_node, "dma-coherent"))
320+
set_dma_ops(dev, &coherent_swiotlb_dma_ops);
321+
322+
return NOTIFY_OK;
323+
}
324+
325+
static struct notifier_block platform_bus_nb = {
326+
.notifier_call = dma_bus_notifier,
327+
};
328+
329+
static struct notifier_block amba_bus_nb = {
330+
.notifier_call = dma_bus_notifier,
331+
};
332+
308333
extern int swiotlb_late_init_with_default_size(size_t default_size);
309334

310335
static int __init swiotlb_late_init(void)
311336
{
312337
size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT);
313338

339+
/*
340+
* These must be registered before of_platform_populate().
341+
*/
342+
bus_register_notifier(&platform_bus_type, &platform_bus_nb);
343+
bus_register_notifier(&amba_bustype, &amba_bus_nb);
344+
314345
dma_ops = &noncoherent_swiotlb_dma_ops;
315346

316347
return swiotlb_late_init_with_default_size(swiotlb_size);
317348
}
318-
subsys_initcall(swiotlb_late_init);
349+
arch_initcall(swiotlb_late_init);
319350

320351
#define PREALLOC_DMA_DEBUG_ENTRIES 4096
321352

0 commit comments

Comments
 (0)