ioremap.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. * arch/s390/mm/ioremap.c
  3. *
  4. * S390 version
  5. * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6. * Author(s): Hartmut Penner (hp@de.ibm.com)
  7. *
  8. * Derived from "arch/i386/mm/extable.c"
  9. * (C) Copyright 1995 1996 Linus Torvalds
  10. *
  11. * Re-map IO memory to kernel address space so that we can access it.
  12. * This is needed for high PCI addresses that aren't mapped in the
  13. * 640k-1MB IO memory area on PC's
  14. */
  15. #include <linux/vmalloc.h>
  16. #include <linux/mm.h>
  17. #include <linux/io.h>
  18. #include <asm/pgalloc.h>
  19. /*
  20. * Generic mapping function (not visible outside):
  21. */
  22. /*
  23. * Remap an arbitrary physical address space into the kernel virtual
  24. * address space. Needed when the kernel wants to access high addresses
  25. * directly.
  26. */
  27. void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
  28. {
  29. void * addr;
  30. struct vm_struct * area;
  31. if (phys_addr < virt_to_phys(high_memory))
  32. return phys_to_virt(phys_addr);
  33. if (phys_addr & ~PAGE_MASK)
  34. return NULL;
  35. size = PAGE_ALIGN(size);
  36. if (!size || size > phys_addr + size)
  37. return NULL;
  38. area = get_vm_area(size, VM_IOREMAP);
  39. if (!area)
  40. return NULL;
  41. addr = area->addr;
  42. if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
  43. phys_addr, __pgprot(flags))) {
  44. vfree(addr);
  45. return NULL;
  46. }
  47. return addr;
  48. }
  49. void iounmap(void *addr)
  50. {
  51. if (addr > high_memory)
  52. vfree(addr);
  53. }