Skip to content

Commit

Permalink
parisc: mm: Convert to GENERIC_IOREMAP
Browse files Browse the repository at this point in the history
By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
iounmap() are visible and available to arch. Arch only needs to
provide implementation of arch_ioremap() or arch_iounmap() if there's
arch specific handling needed in its ioremap() or iounmap(). This
change will simplify implementation by removing duplicated codes with
generic ioremap() and iounmap(), and has the equivalent functioality
as before.

For parisc, add hook arch_ioremap() for parisc's special operation when
ioremap(), then ioremap_[wc|uc]() are converted to use ioremap_prot()
from GENERIC_IOREMAP.

Meanwhile, add macro ARCH_HAS_IOREMAP_WC since the added ioremap_wc()
will conflict with the one in include/asm-generic/iomap.h, then an
compiling error is seen:

./include/asm-generic/iomap.h:97: warning: "ioremap_wc" redefined
   97 | #define ioremap_wc ioremap

And benefit from the commit 437b6b3 ("parisc: Use the generic
IO helpers"), those macros don't need be added any more.

Signed-off-by: Baoquan He <bhe@redhat.com>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
  • Loading branch information
Baoquan He authored and intel-lab-lkp committed Oct 9, 2022
1 parent 98da032 commit c462137
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 64 deletions.
1 change: 1 addition & 0 deletions arch/parisc/Kconfig
Expand Up @@ -36,6 +36,7 @@ config PARISC
select GENERIC_ATOMIC64 if !64BIT
select GENERIC_IRQ_PROBE
select GENERIC_PCI_IOMAP
select GENERIC_IOREMAP
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_SMP_IDLE_THREAD
select GENERIC_ARCH_TOPOLOGY if SMP
Expand Down
19 changes: 14 additions & 5 deletions arch/parisc/include/asm/io.h
Expand Up @@ -2,6 +2,8 @@
#ifndef _ASM_IO_H
#define _ASM_IO_H

#define ARCH_HAS_IOREMAP_WC

#include <linux/types.h>
#include <linux/pgtable.h>

Expand Down Expand Up @@ -125,12 +127,19 @@ static inline void gsc_writeq(unsigned long long val, unsigned long addr)
/*
* The standard PCI ioremap interfaces
*/
void __iomem *ioremap(unsigned long offset, unsigned long size);
#define ioremap_wc ioremap
#define ioremap_uc ioremap
#define pci_iounmap pci_iounmap
void __iomem *
arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val);
#define arch_ioremap arch_ioremap

#define _PAGE_IOREMAP (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \
_PAGE_ACCESSED | _PAGE_NO_CACHE)

extern void iounmap(const volatile void __iomem *addr);
#define ioremap_wc(addr, size) \
ioremap_prot((addr), (size), _PAGE_IOREMAP)
#define ioremap_uc(addr, size) \
ioremap_prot((addr), (size), _PAGE_IOREMAP)

#define pci_iounmap pci_iounmap

void memset_io(volatile void __iomem *addr, unsigned char val, int count);
void memcpy_fromio(void *dst, const volatile void __iomem *src, int count);
Expand Down
65 changes: 6 additions & 59 deletions arch/parisc/mm/ioremap.c
Expand Up @@ -13,38 +13,19 @@
#include <linux/io.h>
#include <linux/mm.h>

/*
* Generic mapping function (not visible outside):
*/

/*
* Remap an arbitrary physical address space into the kernel virtual
* address space.
*
* NOTE! We need to allow non-page-aligned mappings too: we will obviously
* have to convert them into an offset in a page-aligned mapping, but the
* caller shouldn't need to know that small detail.
*/
void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
void __iomem *
arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val)
{
void __iomem *addr;
struct vm_struct *area;
unsigned long offset, last_addr;
pgprot_t pgprot;
phys_addr_t phys_addr = *paddr;

#ifdef CONFIG_EISA
unsigned long end = phys_addr + size - 1;
/* Support EISA addresses */
if ((phys_addr >= 0x00080000 && end < 0x000fffff) ||
(phys_addr >= 0x00500000 && end < 0x03bfffff))
phys_addr |= F_EXTEND(0xfc000000);
*paddr = phys_addr |= F_EXTEND(0xfc000000);
#endif

/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
if (!size || last_addr < phys_addr)
return NULL;

/*
* Don't allow anybody to remap normal RAM that we're using..
*/
Expand All @@ -58,43 +39,9 @@ void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
for (page = virt_to_page(t_addr);
page <= virt_to_page(t_end); page++) {
if(!PageReserved(page))
return NULL;
return IOMEM_ERR_PTR(-EINVAL);
}
}

pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY |
_PAGE_ACCESSED | _PAGE_NO_CACHE);

/*
* Mappings have to be page-aligned
*/
offset = phys_addr & ~PAGE_MASK;
phys_addr &= PAGE_MASK;
size = PAGE_ALIGN(last_addr + 1) - phys_addr;

/*
* Ok, go for it..
*/
area = get_vm_area(size, VM_IOREMAP);
if (!area)
return NULL;

addr = (void __iomem *) area->addr;
if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
phys_addr, pgprot)) {
vunmap(addr);
return NULL;
}

return (void __iomem *) (offset + (char __iomem *)addr);
}
EXPORT_SYMBOL(ioremap);

void iounmap(const volatile void __iomem *io_addr)
{
unsigned long addr = (unsigned long)io_addr & PAGE_MASK;

if (is_vmalloc_addr((void *)addr))
vunmap((void *)addr);
return NULL;
}
EXPORT_SYMBOL(iounmap);

0 comments on commit c462137

Please sign in to comment.