ioremap.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * (C) Copyright 1995 1996 Linus Torvalds
  3. * (C) Copyright 2012 Regents of the University of California
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation, version 2.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/export.h>
  15. #include <linux/mm.h>
  16. #include <linux/vmalloc.h>
  17. #include <linux/io.h>
  18. #include <asm/pgtable.h>
  19. /*
  20. * Remap an arbitrary physical address space into the kernel virtual
  21. * address space. Needed when the kernel wants to access high addresses
  22. * directly.
  23. *
  24. * NOTE! We need to allow non-page-aligned mappings too: we will obviously
  25. * have to convert them into an offset in a page-aligned mapping, but the
  26. * caller shouldn't need to know that small detail.
  27. */
  28. static void __iomem *__ioremap_caller(phys_addr_t addr, size_t size,
  29. pgprot_t prot, void *caller)
  30. {
  31. phys_addr_t last_addr;
  32. unsigned long offset, vaddr;
  33. struct vm_struct *area;
  34. /* Disallow wrap-around or zero size */
  35. last_addr = addr + size - 1;
  36. if (!size || last_addr < addr)
  37. return NULL;
  38. /* Page-align mappings */
  39. offset = addr & (~PAGE_MASK);
  40. addr -= offset;
  41. size = PAGE_ALIGN(size + offset);
  42. area = get_vm_area_caller(size, VM_IOREMAP, caller);
  43. if (!area)
  44. return NULL;
  45. vaddr = (unsigned long)area->addr;
  46. if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
  47. free_vm_area(area);
  48. return NULL;
  49. }
  50. return (void __iomem *)(vaddr + offset);
  51. }
  52. /*
  53. * ioremap - map bus memory into CPU space
  54. * @offset: bus address of the memory
  55. * @size: size of the resource to map
  56. *
  57. * ioremap performs a platform specific sequence of operations to
  58. * make bus memory CPU accessible via the readb/readw/readl/writeb/
  59. * writew/writel functions and the other mmio helpers. The returned
  60. * address is not guaranteed to be usable directly as a virtual
  61. * address.
  62. *
  63. * Must be freed with iounmap.
  64. */
  65. void __iomem *ioremap(phys_addr_t offset, unsigned long size)
  66. {
  67. return __ioremap_caller(offset, size, PAGE_KERNEL,
  68. __builtin_return_address(0));
  69. }
  70. EXPORT_SYMBOL(ioremap);
  71. /**
  72. * iounmap - Free a IO remapping
  73. * @addr: virtual address from ioremap_*
  74. *
  75. * Caller must ensure there is only one unmapping for the same pointer.
  76. */
  77. void iounmap(volatile void __iomem *addr)
  78. {
  79. vunmap((void *)((unsigned long)addr & PAGE_MASK));
  80. }
  81. EXPORT_SYMBOL(iounmap);