Commit 90d2bbc1 authored by Hongchen Zhang's avatar Hongchen Zhang
Browse files

LoongArch: use arch specific phys_to_dma

LoongArch inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8H2OZ



--------------------------------

To be compatible with OLD firmware which has no _DMA method,
we should use arch specific phys_to_dma.

Signed-off-by: default avatarHongchen Zhang <zhanghongchen@loongson.cn>
parent 6d1a9a5b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ config LOONGARCH
	select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
	select HAVE_SETUP_PER_CPU_AREA if NUMA
	select HAVE_STACKPROTECTOR
	select ARCH_HAS_PHYS_TO_DMA
	select HAVE_SYSCALL_TRACEPOINTS
	select HAVE_TIF_NOHZ
	select HAVE_VIRT_CPU_ACCOUNTING_GEN if !SMP
+27 −0
Original line number Diff line number Diff line
@@ -4,6 +4,28 @@
 */
#include <linux/acpi.h>
#include <linux/dma-direct.h>
#include <asm/loongson.h>

/*
 * We extract 4bit node id (bit 44~47) from Loongson-3's
 * 48bit physical address space and embed it into 40bit.
 */

static int node_id_offset;

dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
{
	long nid = (paddr >> 44) & 0xf;

	return ((nid << 44) ^ paddr) | (nid << node_id_offset);
}

phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
{
	long nid = (daddr >> node_id_offset) & 0xf;

	return ((nid << node_id_offset) ^ daddr) | (nid << 44);
}

void acpi_arch_dma_setup(struct device *dev)
{
@@ -11,6 +33,11 @@ void acpi_arch_dma_setup(struct device *dev)
	u64 mask, end = 0;
	const struct bus_dma_region *map = NULL;

	if (node_id_offset == 0) {
		node_id_offset = ((readl(LS7A_DMA_CFG) & LS7A_DMA_NODE_MASK) >> LS7A_DMA_NODE_SHF);
		node_id_offset += 36;
	}

	ret = acpi_dma_get_range(dev, &map);
	if (!ret && map) {
		const struct bus_dma_region *r = map;