The ioremap/iounmap is implemented in arch/s390/pci/pci.c. While CONFIG_PCI is disabled,the compilation error is reported: s390x-linux-gnu-ld: drivers/pcmcia/cistpl.o: in function `set_cis_map': cistpl.c:(.text+0x32a): undefined reference to `ioremap' s390x-linux-gnu-ld: cistpl.c:(.text+0x360): undefined reference to `iounmap' s390x-linux-gnu-ld: cistpl.c:(.text+0x384): undefined reference to `iounmap' s390x-linux-gnu-ld: cistpl.c:(.text+0x396): undefined reference to `ioremap' s390x-linux-gnu-ld: drivers/pcmcia/cistpl.o: in function `release_cis_mem': cistpl.c:(.text+0xcb8): undefined reference to `iounmap' Add arch/s390/mm/ioremap.c file and move ioremap/ioremap_wc/ioremap_rt/iounmap to it to fix the error. Reported-by: kernel test robot <lkp@xxxxxxxxx> Signed-off-by: Bixuan Cui <cuibixuan@xxxxxxxxxx> --- arch/s390/include/asm/io.h | 8 ++--- arch/s390/mm/Makefile | 2 +- arch/s390/mm/ioremap.c | 64 +++++++++++++++++++++++++++++++++ arch/s390/pci/pci.c | 73 ++++++-------------------------------- 4 files changed, 80 insertions(+), 67 deletions(-) create mode 100644 arch/s390/mm/ioremap.c diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index e3882b012bfa..48a55644c34f 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h @@ -22,6 +22,10 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); #define IO_SPACE_LIMIT 0 +#define ioremap ioremap +#define ioremap_wt ioremap_wt +#define ioremap_wc ioremap_wc + void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot); void __iomem *ioremap(phys_addr_t addr, size_t size); void __iomem *ioremap_wc(phys_addr_t addr, size_t size); @@ -51,10 +55,6 @@ static inline void ioport_unmap(void __iomem *p) #define pci_iomap_wc pci_iomap_wc #define pci_iomap_wc_range pci_iomap_wc_range -#define ioremap ioremap -#define ioremap_wt ioremap_wt -#define ioremap_wc ioremap_wc - #define memcpy_fromio(dst, src, count) zpci_memcpy_fromio(dst, src, count) #define memcpy_toio(dst, src, count) zpci_memcpy_toio(dst, src, count) #define memset_io(dst, val, count) zpci_memset_io(dst, val, count) diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index cd67e94c16aa..74c22dfb131b 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile @@ -4,7 +4,7 @@ # obj-y := init.o fault.o extmem.o mmap.o vmem.o maccess.o -obj-y += page-states.o pageattr.o pgtable.o pgalloc.o +obj-y += page-states.o pageattr.o pgtable.o pgalloc.o ioremap.o obj-$(CONFIG_CMM) += cmm.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/arch/s390/mm/ioremap.c b/arch/s390/mm/ioremap.c new file mode 100644 index 000000000000..132e6ddff36f --- /dev/null +++ b/arch/s390/mm/ioremap.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021 Huawei Ltd. + * Author: Bixuan Cui <cuibixuan@xxxxxxxxxx> + */ +#include <linux/vmalloc.h> +#include <linux/io.h> +#include <linux/mm.h> +#include <linux/jump_label.h> + +static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot) +{ + unsigned long offset, vaddr; + struct vm_struct *area; + phys_addr_t last_addr; + + last_addr = addr + size - 1; + if (!size || last_addr < addr) + return NULL; + + offset = addr & ~PAGE_MASK; + addr &= PAGE_MASK; + size = PAGE_ALIGN(size + offset); + area = get_vm_area(size, VM_IOREMAP); + if (!area) + return NULL; + + vaddr = (unsigned long) area->addr; + if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) { + free_vm_area(area); + return NULL; + } + return (void __iomem *) ((unsigned long) area->addr + offset); +} + +void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot) +{ + return __ioremap(addr, size, __pgprot(prot)); +} +EXPORT_SYMBOL(ioremap_prot); + +void __iomem *ioremap(phys_addr_t addr, size_t size) +{ + return __ioremap(addr, size, PAGE_KERNEL); +} +EXPORT_SYMBOL(ioremap); + +void __iomem *ioremap_wc(phys_addr_t addr, size_t size) +{ + return __ioremap(addr, size, pgprot_writecombine(PAGE_KERNEL)); +} +EXPORT_SYMBOL(ioremap_wc); + +void __iomem *ioremap_wt(phys_addr_t addr, size_t size) +{ + return __ioremap(addr, size, pgprot_writethrough(PAGE_KERNEL)); +} +EXPORT_SYMBOL(ioremap_wt); + +void iounmap(volatile void __iomem *addr) +{ + vunmap((__force void *) ((unsigned long) addr & PAGE_MASK)); +} +EXPORT_SYMBOL(iounmap); diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index dd14641b2d20..be300850df9c 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -227,65 +227,6 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count) zpci_memcpy_toio(to, from, count); } -static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot) -{ - unsigned long offset, vaddr; - struct vm_struct *area; - phys_addr_t last_addr; - - last_addr = addr + size - 1; - if (!size || last_addr < addr) - return NULL; - - if (!static_branch_unlikely(&have_mio)) - return (void __iomem *) addr; - - offset = addr & ~PAGE_MASK; - addr &= PAGE_MASK; - size = PAGE_ALIGN(size + offset); - area = get_vm_area(size, VM_IOREMAP); - if (!area) - return NULL; - - vaddr = (unsigned long) area->addr; - if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) { - free_vm_area(area); - return NULL; - } - return (void __iomem *) ((unsigned long) area->addr + offset); -} - -void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot) -{ - return __ioremap(addr, size, __pgprot(prot)); -} -EXPORT_SYMBOL(ioremap_prot); - -void __iomem *ioremap(phys_addr_t addr, size_t size) -{ - return __ioremap(addr, size, PAGE_KERNEL); -} -EXPORT_SYMBOL(ioremap); - -void __iomem *ioremap_wc(phys_addr_t addr, size_t size) -{ - return __ioremap(addr, size, pgprot_writecombine(PAGE_KERNEL)); -} -EXPORT_SYMBOL(ioremap_wc); - -void __iomem *ioremap_wt(phys_addr_t addr, size_t size) -{ - return __ioremap(addr, size, pgprot_writethrough(PAGE_KERNEL)); -} -EXPORT_SYMBOL(ioremap_wt); - -void iounmap(volatile void __iomem *addr) -{ - if (static_branch_likely(&have_mio)) - vunmap((__force void *) ((unsigned long) addr & PAGE_MASK)); -} -EXPORT_SYMBOL(iounmap); - /* Create a virtual mapping cookie for a PCI BAR */ static void __iomem *pci_iomap_range_fh(struct pci_dev *pdev, int bar, unsigned long offset, unsigned long max) @@ -312,7 +253,10 @@ static void __iomem *pci_iomap_range_mio(struct pci_dev *pdev, int bar, struct zpci_dev *zdev = to_zpci(pdev); void __iomem *iova; - iova = ioremap((unsigned long) zdev->bars[bar].mio_wt, barsize); + if (!static_branch_unlikely(&have_mio)) + iova = (void __iomem *) zdev->bars[bar].mio_wt; + else + iova = ioremap((unsigned long) zdev->bars[bar].mio_wt, barsize); return iova ? iova + offset : iova; } @@ -342,7 +286,11 @@ static void __iomem *pci_iomap_wc_range_mio(struct pci_dev *pdev, int bar, struct zpci_dev *zdev = to_zpci(pdev); void __iomem *iova; - iova = ioremap((unsigned long) zdev->bars[bar].mio_wb, barsize); + if (!static_branch_unlikely(&have_mio)) + iova = (void __iomem *) zdev->bars[bar].mio_wb; + else + iova = ioremap((unsigned long) zdev->bars[bar].mio_wb, barsize); + return iova ? iova + offset : iova; } @@ -381,7 +329,8 @@ static void pci_iounmap_fh(struct pci_dev *pdev, void __iomem *addr) static void pci_iounmap_mio(struct pci_dev *pdev, void __iomem *addr) { - iounmap(addr); + if (static_branch_likely(&have_mio)) + iounmap(addr); } void pci_iounmap(struct pci_dev *pdev, void __iomem *addr) -- 2.17.1