pci-epc-mem.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // SPDX-License-Identifier: GPL-2.0
  2. /**
  3. * PCI Endpoint *Controller* Address Space Management
  4. *
  5. * Copyright (C) 2017 Texas Instruments
  6. * Author: Kishon Vijay Abraham I <kishon@ti.com>
  7. */
  8. #include <linux/io.h>
  9. #include <linux/module.h>
  10. #include <linux/slab.h>
  11. #include <linux/pci-epc.h>
  12. /**
  13. * pci_epc_mem_get_order() - determine the allocation order of a memory size
  14. * @mem: address space of the endpoint controller
  15. * @size: the size for which to get the order
  16. *
  17. * Reimplement get_order() for mem->page_size since the generic get_order
  18. * always gets order with a constant PAGE_SIZE.
  19. */
  20. static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size)
  21. {
  22. int order;
  23. unsigned int page_shift = ilog2(mem->page_size);
  24. size--;
  25. size >>= page_shift;
  26. #if BITS_PER_LONG == 32
  27. order = fls(size);
  28. #else
  29. order = fls64(size);
  30. #endif
  31. return order;
  32. }
  33. /**
  34. * __pci_epc_mem_init() - initialize the pci_epc_mem structure
  35. * @epc: the EPC device that invoked pci_epc_mem_init
  36. * @phys_base: the physical address of the base
  37. * @size: the size of the address space
  38. * @page_size: size of each page
  39. *
  40. * Invoke to initialize the pci_epc_mem structure used by the
  41. * endpoint functions to allocate mapped PCI address.
  42. */
  43. int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size,
  44. size_t page_size)
  45. {
  46. int ret;
  47. struct pci_epc_mem *mem;
  48. unsigned long *bitmap;
  49. unsigned int page_shift;
  50. int pages;
  51. int bitmap_size;
  52. if (page_size < PAGE_SIZE)
  53. page_size = PAGE_SIZE;
  54. page_shift = ilog2(page_size);
  55. pages = size >> page_shift;
  56. bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
  57. mem = kzalloc(sizeof(*mem), GFP_KERNEL);
  58. if (!mem) {
  59. ret = -ENOMEM;
  60. goto err;
  61. }
  62. bitmap = kzalloc(bitmap_size, GFP_KERNEL);
  63. if (!bitmap) {
  64. ret = -ENOMEM;
  65. goto err_mem;
  66. }
  67. mem->bitmap = bitmap;
  68. mem->phys_base = phys_base;
  69. mem->page_size = page_size;
  70. mem->pages = pages;
  71. mem->size = size;
  72. mutex_init(&mem->lock);
  73. epc->mem = mem;
  74. return 0;
  75. err_mem:
  76. kfree(mem);
  77. err:
  78. return ret;
  79. }
  80. EXPORT_SYMBOL_GPL(__pci_epc_mem_init);
  81. /**
  82. * pci_epc_mem_exit() - cleanup the pci_epc_mem structure
  83. * @epc: the EPC device that invoked pci_epc_mem_exit
  84. *
  85. * Invoke to cleanup the pci_epc_mem structure allocated in
  86. * pci_epc_mem_init().
  87. */
  88. void pci_epc_mem_exit(struct pci_epc *epc)
  89. {
  90. struct pci_epc_mem *mem = epc->mem;
  91. epc->mem = NULL;
  92. kfree(mem->bitmap);
  93. kfree(mem);
  94. }
  95. EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
  96. /**
  97. * pci_epc_mem_alloc_addr() - allocate memory address from EPC addr space
  98. * @epc: the EPC device on which memory has to be allocated
  99. * @phys_addr: populate the allocated physical address here
  100. * @size: the size of the address space that has to be allocated
  101. *
  102. * Invoke to allocate memory address from the EPC address space. This
  103. * is usually done to map the remote RC address into the local system.
  104. */
  105. void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
  106. phys_addr_t *phys_addr, size_t size)
  107. {
  108. int pageno;
  109. void __iomem *virt_addr = NULL;
  110. struct pci_epc_mem *mem = epc->mem;
  111. unsigned int page_shift = ilog2(mem->page_size);
  112. int order;
  113. size = ALIGN(size, mem->page_size);
  114. order = pci_epc_mem_get_order(mem, size);
  115. mutex_lock(&mem->lock);
  116. pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
  117. if (pageno < 0)
  118. goto ret;
  119. *phys_addr = mem->phys_base + (pageno << page_shift);
  120. virt_addr = ioremap(*phys_addr, size);
  121. if (!virt_addr)
  122. bitmap_release_region(mem->bitmap, pageno, order);
  123. ret:
  124. mutex_unlock(&mem->lock);
  125. return virt_addr;
  126. }
  127. EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
  128. /**
  129. * pci_epc_mem_free_addr() - free the allocated memory address
  130. * @epc: the EPC device on which memory was allocated
  131. * @phys_addr: the allocated physical address
  132. * @virt_addr: virtual address of the allocated mem space
  133. * @size: the size of the allocated address space
  134. *
  135. * Invoke to free the memory allocated using pci_epc_mem_alloc_addr.
  136. */
  137. void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
  138. void __iomem *virt_addr, size_t size)
  139. {
  140. int pageno;
  141. struct pci_epc_mem *mem = epc->mem;
  142. unsigned int page_shift = ilog2(mem->page_size);
  143. int order;
  144. iounmap(virt_addr);
  145. pageno = (phys_addr - mem->phys_base) >> page_shift;
  146. size = ALIGN(size, mem->page_size);
  147. order = pci_epc_mem_get_order(mem, size);
  148. mutex_lock(&mem->lock);
  149. bitmap_release_region(mem->bitmap, pageno, order);
  150. mutex_unlock(&mem->lock);
  151. }
  152. EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr);
  153. MODULE_DESCRIPTION("PCI EPC Address Space Management");
  154. MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
  155. MODULE_LICENSE("GPL v2");