ioremap.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /*
  2. * ioremap implementation.
  3. *
  4. * Copyright (C) 2015 Cadence Design Systems Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/io.h>
  11. #include <linux/vmalloc.h>
  12. #include <asm/cacheflush.h>
  13. #include <asm/io.h>
  14. #include <asm/pgtable.h>
  15. static void __iomem *xtensa_ioremap(unsigned long paddr, unsigned long size,
  16. pgprot_t prot)
  17. {
  18. unsigned long offset = paddr & ~PAGE_MASK;
  19. unsigned long pfn = __phys_to_pfn(paddr);
  20. struct vm_struct *area;
  21. unsigned long vaddr;
  22. int err;
  23. paddr &= PAGE_MASK;
  24. WARN_ON(pfn_valid(pfn));
  25. size = PAGE_ALIGN(offset + size);
  26. area = get_vm_area(size, VM_IOREMAP);
  27. if (!area)
  28. return NULL;
  29. vaddr = (unsigned long)area->addr;
  30. area->phys_addr = paddr;
  31. err = ioremap_page_range(vaddr, vaddr + size, paddr, prot);
  32. if (err) {
  33. vunmap((void *)vaddr);
  34. return NULL;
  35. }
  36. flush_cache_vmap(vaddr, vaddr + size);
  37. return (void __iomem *)(offset + vaddr);
  38. }
  39. void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size)
  40. {
  41. return xtensa_ioremap(addr, size, pgprot_noncached(PAGE_KERNEL));
  42. }
  43. EXPORT_SYMBOL(xtensa_ioremap_nocache);
  44. void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size)
  45. {
  46. return xtensa_ioremap(addr, size, PAGE_KERNEL);
  47. }
  48. EXPORT_SYMBOL(xtensa_ioremap_cache);
  49. void xtensa_iounmap(volatile void __iomem *io_addr)
  50. {
  51. void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
  52. vunmap(addr);
  53. }
  54. EXPORT_SYMBOL(xtensa_iounmap);