de_heap_ion_example.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * de_heap_ion_example.c
  3. */
  4. #include "de_heap_ion.h"
  5. #include <linux/sizes.h>
  6. #include <linux/slab.h>
  7. #include <linux/version.h>
  8. #undef linux
  9. #include IMG_KERNEL_ION_HEADER
  10. #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))
  11. #include IMG_KERNEL_ION_PRIV_HEADER
  12. #endif
  13. #define linux 1
  14. #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))
  15. static struct ion_device *idev;
  16. static struct ion_client *client=NULL;
  17. static struct ion_heap **heaps;
  18. #endif
  19. #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))
  20. static void *carveout_ptr;
  21. static void *chunk_ptr;
  22. static struct ion_platform_heap dummy_heaps[] = {
  23. {
  24. .id = ION_HEAP_TYPE_SYSTEM,
  25. .type = ION_HEAP_TYPE_SYSTEM,
  26. .name = "system",
  27. },
  28. {
  29. .id = ION_HEAP_TYPE_SYSTEM_CONTIG,
  30. .type = ION_HEAP_TYPE_SYSTEM_CONTIG,
  31. .name = "system contig",
  32. },
  33. {
  34. .id = ION_HEAP_TYPE_CARVEOUT,
  35. .type = ION_HEAP_TYPE_CARVEOUT,
  36. .name = "carveout",
  37. .size = SZ_4M,
  38. },
  39. {
  40. .id = ION_HEAP_TYPE_CHUNK,
  41. .type = ION_HEAP_TYPE_CHUNK,
  42. .name = "chunk",
  43. .size = SZ_4M,
  44. .align = SZ_16K,
  45. .priv = (void *)(SZ_16K),
  46. },
  47. };
  48. static struct ion_platform_data dummy_ion_pdata = {
  49. .nr = ARRAY_SIZE(dummy_heaps),
  50. .heaps = dummy_heaps,
  51. };
  52. #endif
  53. unsigned int de_heap_ion_get_heap_mask(void)
  54. {
  55. return 0x42;
  56. }
  57. #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)))
  58. unsigned int de_heap_ion_get_heap_id_mask(void)
  59. {
  60. return 1<<ION_HEAP_TYPE_SYSTEM;
  61. }
  62. #endif
  63. unsigned int de_heap_ion_get_heap_flags(void)
  64. {
  65. return 0;
  66. }
  67. #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))
  68. struct ion_client *de_heap_ion_create_ion_client(void)
  69. {
  70. int i, err;
  71. pr_info("%s:\n", __func__);
  72. /*
  73. * usually involves fetching an ion_device from the system
  74. * and calling ion_client_create()
  75. */
  76. pr_info("%s:check ion_device_create \n", __func__);
  77. idev = ion_device_create(NULL);
  78. if (IS_ERR(idev)) {
  79. pr_err("%s:ion ion_device_create failed %li \n", __func__, PTR_ERR(idev));
  80. return (struct ion_client *)idev;
  81. }
  82. pr_info("%s:check kcalloc \n", __func__);
  83. heaps = kcalloc(dummy_ion_pdata.nr, sizeof(struct ion_heap *),
  84. GFP_KERNEL);
  85. pr_info("%s:heaps = %lx \n", __func__, (long unsigned int)heaps);
  86. if (!heaps) {
  87. pr_err("%s:ion kcalloc heaps = %lx \n", __func__, (long unsigned int)heaps);
  88. ion_device_destroy(idev);
  89. return ERR_PTR(-ENOMEM);
  90. }
  91. /* Allocate a dummy carveout heap */
  92. carveout_ptr = alloc_pages_exact(dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size,
  93. GFP_KERNEL);
  94. if (carveout_ptr) {
  95. dummy_heaps[ION_HEAP_TYPE_CARVEOUT].base = virt_to_phys(carveout_ptr);
  96. } else {
  97. pr_err("ion_dummy: Could not allocate carveout\n");
  98. }
  99. /* Allocate a dummy chunk heap */
  100. chunk_ptr = alloc_pages_exact(dummy_heaps[ION_HEAP_TYPE_CHUNK].size,
  101. GFP_KERNEL);
  102. if (chunk_ptr) {
  103. dummy_heaps[ION_HEAP_TYPE_CHUNK].base = virt_to_phys(chunk_ptr);
  104. } else {
  105. pr_err("ion_dummy: Could not allocate chunk\n");
  106. }
  107. for (i = 0; i < dummy_ion_pdata.nr; i++) {
  108. struct ion_platform_heap *heap_data = &dummy_ion_pdata.heaps[i];
  109. if (heap_data->type == ION_HEAP_TYPE_CARVEOUT && !heap_data->base) {
  110. pr_info("ion_dummy: ION_HEAP_TYPE_CARVEOUT skipped heap_data->base == %lx \n", heap_data->base);
  111. continue;
  112. }
  113. if (heap_data->type == ION_HEAP_TYPE_CHUNK && !heap_data->base) {
  114. pr_info("ion_dummy: ION_HEAP_TYPE_CHUNK skipped heap_data->base == %lx \n", heap_data->base);
  115. continue;
  116. }
  117. heaps[i] = ion_heap_create(heap_data);
  118. if (IS_ERR_OR_NULL(heaps[i])) {
  119. pr_info("ion_dummy: ion_heap_create failed, returned = %lx, for heap id = %d \n", (unsigned long)(heaps[i]), i);
  120. err = PTR_ERR(heaps[i]);
  121. goto err;
  122. }
  123. ion_device_add_heap(idev, heaps[i]);
  124. }
  125. pr_info("%s:ion ion_device_create success idev = %lx \n", __func__, (long)idev);
  126. client = ion_client_create(idev, "ion_client");
  127. if (IS_ERR_OR_NULL(client)) {
  128. pr_info("%s:ion ion_client_create failed idev = %lx client = %li\n", __func__, (long)idev, PTR_ERR(client));
  129. ion_device_destroy(idev);
  130. return (client);
  131. }
  132. return client;
  133. err:
  134. for (i = 0; i < dummy_ion_pdata.nr; ++i)
  135. ion_heap_destroy(heaps[i]);
  136. kfree(heaps);
  137. if (carveout_ptr) {
  138. free_pages_exact(carveout_ptr,
  139. dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size);
  140. carveout_ptr = NULL;
  141. }
  142. if (chunk_ptr) {
  143. free_pages_exact(chunk_ptr,
  144. dummy_heaps[ION_HEAP_TYPE_CHUNK].size);
  145. chunk_ptr = NULL;
  146. }
  147. ion_device_destroy(idev);
  148. return ERR_PTR(err);
  149. return client;
  150. }
  151. /*
  152. * returns error code or success (0)
  153. */
  154. struct ion_client *de_heap_ion_destroy_ion_client(struct ion_client *dmabuf_ion_client)
  155. {
  156. pr_info("%s:de_heap_ion_destroy_ion_client \n", __func__);
  157. if (IS_ERR(idev) || idev == NULL) {
  158. pr_err("%s:ion device not present idev = %li \n", __func__, (idev==NULL) ? (long)NULL : PTR_ERR(idev));
  159. return (struct ion_client *)(idev);
  160. }
  161. if (dmabuf_ion_client>0) {
  162. ion_client_destroy(dmabuf_ion_client);
  163. }
  164. ion_device_destroy(idev);
  165. idev = NULL;
  166. return NULL;
  167. }
  168. #elif ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)))
  169. #else
  170. #error "Linux kernel not supported"
  171. #endif
  172. /*
  173. * coding style for emacs
  174. *
  175. * Local variables:
  176. * indent-tabs-mode: t
  177. * tab-width: 8
  178. * c-basic-offset: 8
  179. * End:
  180. */