ioremap.c 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * I/O remap functions for Hexagon
  4. *
  5. * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  6. */
  7. #include <linux/io.h>
  8. #include <linux/vmalloc.h>
  9. #include <linux/mm.h>
  10. void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
  11. {
  12. unsigned long last_addr, addr;
  13. unsigned long offset = phys_addr & ~PAGE_MASK;
  14. struct vm_struct *area;
  15. pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE
  16. |(__HEXAGON_C_DEV << 6));
  17. last_addr = phys_addr + size - 1;
  18. /* Wrapping not allowed */
  19. if (!size || (last_addr < phys_addr))
  20. return NULL;
  21. /* Rounds up to next page size, including whole-page offset */
  22. size = PAGE_ALIGN(offset + size);
  23. area = get_vm_area(size, VM_IOREMAP);
  24. addr = (unsigned long)area->addr;
  25. if (ioremap_page_range(addr, addr+size, phys_addr, prot)) {
  26. vunmap((void *)addr);
  27. return NULL;
  28. }
  29. return (void __iomem *) (offset + addr);
  30. }
  31. void iounmap(const volatile void __iomem *addr)
  32. {
  33. vunmap((void *) ((unsigned long) addr & PAGE_MASK));
  34. }