ioremap.c 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
  3. #include <linux/export.h>
  4. #include <linux/mm.h>
  5. #include <linux/vmalloc.h>
  6. #include <linux/io.h>
  7. #include <asm/pgtable.h>
  8. void __iomem *ioremap(phys_addr_t addr, size_t size)
  9. {
  10. phys_addr_t last_addr;
  11. unsigned long offset, vaddr;
  12. struct vm_struct *area;
  13. pgprot_t prot;
  14. last_addr = addr + size - 1;
  15. if (!size || last_addr < addr)
  16. return NULL;
  17. offset = addr & (~PAGE_MASK);
  18. addr &= PAGE_MASK;
  19. size = PAGE_ALIGN(size + offset);
  20. area = get_vm_area_caller(size, VM_ALLOC, __builtin_return_address(0));
  21. if (!area)
  22. return NULL;
  23. vaddr = (unsigned long)area->addr;
  24. prot = __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE |
  25. _PAGE_GLOBAL | _CACHE_UNCACHED);
  26. if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
  27. free_vm_area(area);
  28. return NULL;
  29. }
  30. return (void __iomem *)(vaddr + offset);
  31. }
  32. EXPORT_SYMBOL(ioremap);
  33. void iounmap(void __iomem *addr)
  34. {
  35. vunmap((void *)((unsigned long)addr & PAGE_MASK));
  36. }
  37. EXPORT_SYMBOL(iounmap);