ioremap.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * ioremap implementation.
  4. *
  5. * Copyright (C) 2015 Cadence Design Systems Inc.
  6. */
  7. #include <linux/io.h>
  8. #include <linux/vmalloc.h>
  9. #include <linux/pgtable.h>
  10. #include <asm/cacheflush.h>
  11. #include <asm/io.h>
  12. static void __iomem *xtensa_ioremap(unsigned long paddr, unsigned long size,
  13. pgprot_t prot)
  14. {
  15. unsigned long offset = paddr & ~PAGE_MASK;
  16. unsigned long pfn = __phys_to_pfn(paddr);
  17. struct vm_struct *area;
  18. unsigned long vaddr;
  19. int err;
  20. paddr &= PAGE_MASK;
  21. WARN_ON(pfn_valid(pfn));
  22. size = PAGE_ALIGN(offset + size);
  23. area = get_vm_area(size, VM_IOREMAP);
  24. if (!area)
  25. return NULL;
  26. vaddr = (unsigned long)area->addr;
  27. area->phys_addr = paddr;
  28. err = ioremap_page_range(vaddr, vaddr + size, paddr, prot);
  29. if (err) {
  30. vunmap((void *)vaddr);
  31. return NULL;
  32. }
  33. flush_cache_vmap(vaddr, vaddr + size);
  34. return (void __iomem *)(offset + vaddr);
  35. }
  36. void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size)
  37. {
  38. return xtensa_ioremap(addr, size, pgprot_noncached(PAGE_KERNEL));
  39. }
  40. EXPORT_SYMBOL(xtensa_ioremap_nocache);
  41. void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size)
  42. {
  43. return xtensa_ioremap(addr, size, PAGE_KERNEL);
  44. }
  45. EXPORT_SYMBOL(xtensa_ioremap_cache);
  46. void xtensa_iounmap(volatile void __iomem *io_addr)
  47. {
  48. void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
  49. vunmap(addr);
  50. }
  51. EXPORT_SYMBOL(xtensa_iounmap);