sparc32: use DMA_DIRECT_REMAP

From: Christoph Hellwig
Date: Mon Sep 13 2021 - 12:44:55 EST


Use the generic dma remapping allocator instead of open coding it.
This also avoids setting up page tables from irq context which is
generally dangerous and uses the atomic pool instead.

The only interesting part is the architecture specific pgprot_dmacoherent
definition that sets the SRMMU_PRIV bit as done by the old implementation.
(I have no idea what it is useful for, though).

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
arch/sparc/Kconfig | 3 +-
arch/sparc/include/asm/pgtable_32.h | 8 +++++
arch/sparc/kernel/ioport.c | 54 -----------------------------
3 files changed, 10 insertions(+), 55 deletions(-)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index f0c0f955e1695..8089258d6cc97 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -54,8 +54,9 @@ config SPARC32
def_bool !64BIT
select ARCH_32BIT_OFF_T
select ARCH_HAS_SYNC_DMA_FOR_CPU
- select GENERIC_ATOMIC64
select CLZ_TAB
+ select DMA_DIRECT_REMAP
+ select GENERIC_ATOMIC64
select HAVE_UID16
select OLD_SIGACTION
select ZONE_DMA
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index ffccfe3b22ed3..1e7984ff7b320 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -313,6 +313,14 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
return prot;
}

+#define pgprot_dmacoherent pgprot_dmacoherent
+static inline pgprot_t pgprot_dmacoherent(pgprot_t prot)
+{
+ pgprot_val(prot) &= ~pgprot_val(__pgprot(SRMMU_CACHE));
+ pgprot_val(prot) |= pgprot_val(__pgprot(SRMMU_PRIV));
+ return prot;
+}
+
static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 3eb748e862220..57a72c46eddb0 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -300,60 +300,6 @@ arch_initcall(sparc_register_ioport);

#endif /* CONFIG_SBUS */

-
-/* Allocate and map kernel buffer using consistent mode DMA for a device.
- * hwdev should be valid struct pci_dev pointer for PCI devices.
- */
-void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t gfp, unsigned long attrs)
-{
- unsigned long addr;
- void *va;
-
- if (!size || size > 256 * 1024) /* __get_free_pages() limit */
- return NULL;
-
- size = PAGE_ALIGN(size);
- va = (void *) __get_free_pages(gfp | __GFP_ZERO, get_order(size));
- if (!va) {
- printk("%s: no %zd pages\n", __func__, size >> PAGE_SHIFT);
- return NULL;
- }
-
- addr = sparc_dma_alloc_resource(dev, size);
- if (!addr)
- goto err_nomem;
-
- srmmu_mapiorange(0, virt_to_phys(va), addr, size);
-
- *dma_handle = virt_to_phys(va);
- return (void *)addr;
-
-err_nomem:
- free_pages((unsigned long)va, get_order(size));
- return NULL;
-}
-
-/* Free and unmap a consistent DMA buffer.
- * cpu_addr is what was returned arch_dma_alloc, size must be the same as what
- * was passed into arch_dma_alloc, and likewise dma_addr must be the same as
- * what *dma_ndler was set to.
- *
- * References to the memory and mappings associated with cpu_addr/dma_addr
- * past this call are illegal.
- */
-void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_addr, unsigned long attrs)
-{
- size = PAGE_ALIGN(size);
-
- if (!sparc_dma_free_resource(cpu_addr, size))
- return;
-
- srmmu_unmapiorange((unsigned long)cpu_addr, size);
- free_pages((unsigned long)phys_to_virt(dma_addr), get_order(size));
-}
-
/*
* IIep is write-through, not flushing on cpu to device transfer.
*
--
2.30.2


--huq684BweRXVnRxX--