pci-epc-mem.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /**
  2. * PCI Endpoint *Controller* Address Space Management
  3. *
  4. * Copyright (C) 2017 Texas Instruments
  5. * Author: Kishon Vijay Abraham I <kishon@ti.com>
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 of
  9. * the License as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <linux/io.h>
  20. #include <linux/module.h>
  21. #include <linux/slab.h>
  22. #include <linux/pci-epc.h>
  23. /**
  24. * pci_epc_mem_init() - initialize the pci_epc_mem structure
  25. * @epc: the EPC device that invoked pci_epc_mem_init
  26. * @phys_base: the physical address of the base
  27. * @size: the size of the address space
  28. *
  29. * Invoke to initialize the pci_epc_mem structure used by the
  30. * endpoint functions to allocate mapped PCI address.
  31. */
  32. int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size)
  33. {
  34. int ret;
  35. struct pci_epc_mem *mem;
  36. unsigned long *bitmap;
  37. int pages = size >> PAGE_SHIFT;
  38. int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
  39. mem = kzalloc(sizeof(*mem), GFP_KERNEL);
  40. if (!mem) {
  41. ret = -ENOMEM;
  42. goto err;
  43. }
  44. bitmap = kzalloc(bitmap_size, GFP_KERNEL);
  45. if (!bitmap) {
  46. ret = -ENOMEM;
  47. goto err_mem;
  48. }
  49. mem->bitmap = bitmap;
  50. mem->phys_base = phys_base;
  51. mem->pages = pages;
  52. mem->size = size;
  53. epc->mem = mem;
  54. return 0;
  55. err_mem:
  56. kfree(mem);
  57. err:
  58. return ret;
  59. }
  60. EXPORT_SYMBOL_GPL(pci_epc_mem_init);
  61. /**
  62. * pci_epc_mem_exit() - cleanup the pci_epc_mem structure
  63. * @epc: the EPC device that invoked pci_epc_mem_exit
  64. *
  65. * Invoke to cleanup the pci_epc_mem structure allocated in
  66. * pci_epc_mem_init().
  67. */
  68. void pci_epc_mem_exit(struct pci_epc *epc)
  69. {
  70. struct pci_epc_mem *mem = epc->mem;
  71. epc->mem = NULL;
  72. kfree(mem->bitmap);
  73. kfree(mem);
  74. }
  75. EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
  76. /**
  77. * pci_epc_mem_alloc_addr() - allocate memory address from EPC addr space
  78. * @epc: the EPC device on which memory has to be allocated
  79. * @phys_addr: populate the allocated physical address here
  80. * @size: the size of the address space that has to be allocated
  81. *
  82. * Invoke to allocate memory address from the EPC address space. This
  83. * is usually done to map the remote RC address into the local system.
  84. */
  85. void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
  86. phys_addr_t *phys_addr, size_t size)
  87. {
  88. int pageno;
  89. void __iomem *virt_addr;
  90. struct pci_epc_mem *mem = epc->mem;
  91. int order = get_order(size);
  92. pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
  93. if (pageno < 0)
  94. return NULL;
  95. *phys_addr = mem->phys_base + (pageno << PAGE_SHIFT);
  96. virt_addr = ioremap(*phys_addr, size);
  97. if (!virt_addr)
  98. bitmap_release_region(mem->bitmap, pageno, order);
  99. return virt_addr;
  100. }
  101. EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
  102. /**
  103. * pci_epc_mem_free_addr() - free the allocated memory address
  104. * @epc: the EPC device on which memory was allocated
  105. * @phys_addr: the allocated physical address
  106. * @virt_addr: virtual address of the allocated mem space
  107. * @size: the size of the allocated address space
  108. *
  109. * Invoke to free the memory allocated using pci_epc_mem_alloc_addr.
  110. */
  111. void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
  112. void __iomem *virt_addr, size_t size)
  113. {
  114. int pageno;
  115. int order = get_order(size);
  116. struct pci_epc_mem *mem = epc->mem;
  117. iounmap(virt_addr);
  118. pageno = (phys_addr - mem->phys_base) >> PAGE_SHIFT;
  119. bitmap_release_region(mem->bitmap, pageno, order);
  120. }
  121. EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr);
  122. MODULE_DESCRIPTION("PCI EPC Address Space Management");
  123. MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
  124. MODULE_LICENSE("GPL v2");