io.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4. */
  5. #ifndef _ASM_IO_H
  6. #define _ASM_IO_H
  7. #include <linux/kernel.h>
  8. #include <linux/types.h>
  9. #include <asm/addrspace.h>
  10. #include <asm/cpu.h>
  11. #include <asm/page.h>
  12. #include <asm/pgtable-bits.h>
  13. #include <asm/string.h>
  14. extern void __init __iomem *early_ioremap(phys_addr_t phys_addr, unsigned long size);
  15. extern void __init early_iounmap(void __iomem *addr, unsigned long size);
  16. #define early_memremap early_ioremap
  17. #define early_memunmap early_iounmap
  18. #ifdef CONFIG_ARCH_IOREMAP
  19. static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
  20. pgprot_t prot)
  21. {
  22. if (offset > TO_PHYS_MASK)
  23. return NULL;
  24. switch (pgprot_val(prot) & _CACHE_MASK) {
  25. case _CACHE_CC:
  26. return (void __iomem *)(unsigned long)(CACHE_BASE + offset);
  27. case _CACHE_SUC:
  28. return (void __iomem *)(unsigned long)(UNCACHE_BASE + offset);
  29. case _CACHE_WUC:
  30. return (void __iomem *)(unsigned long)(WRITECOMBINE_BASE + offset);
  31. default:
  32. return NULL;
  33. }
  34. }
  35. #define ioremap(offset, size) \
  36. ioremap_prot((offset), (size), PAGE_KERNEL_SUC)
  37. #define iounmap(addr) ((void)(addr))
  38. #endif
  39. /*
  40. * On LoongArch, ioremap() has two variants, ioremap_wc() and ioremap_cache().
  41. * They map bus memory into CPU space, the mapped memory is marked uncachable
  42. * (_CACHE_SUC), uncachable but accelerated by write-combine (_CACHE_WUC) and
  43. * cachable (_CACHE_CC) respectively for CPU access.
  44. *
  45. * @offset: bus address of the memory
  46. * @size: size of the resource to map
  47. */
  48. #define ioremap_wc(offset, size) \
  49. ioremap_prot((offset), (size), \
  50. wc_enabled ? PAGE_KERNEL_WUC : PAGE_KERNEL_SUC)
  51. #define ioremap_cache(offset, size) \
  52. ioremap_prot((offset), (size), PAGE_KERNEL)
  53. #define mmiowb() wmb()
  54. #define __io_aw() mmiowb()
  55. #ifdef CONFIG_KFENCE
  56. #define virt_to_phys(kaddr) \
  57. ({ \
  58. (likely((unsigned long)kaddr < vm_map_base)) ? __pa((unsigned long)kaddr) : \
  59. page_to_phys(tlb_virt_to_page((unsigned long)kaddr)) + offset_in_page((unsigned long)kaddr);\
  60. })
  61. #define phys_to_virt(paddr) \
  62. ({ \
  63. extern char *__kfence_pool; \
  64. (unlikely(__kfence_pool == NULL)) ? __va((unsigned long)paddr) : \
  65. page_address(phys_to_page((unsigned long)paddr)) + offset_in_page((unsigned long)paddr);\
  66. })
  67. #endif
  68. #include <asm-generic/io.h>
  69. #define ARCH_HAS_VALID_PHYS_ADDR_RANGE
  70. extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
  71. extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
  72. #endif /* _ASM_IO_H */