ipa_rm_peers_list.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/slab.h>
  6. #include "ipa_rm_i.h"
  7. /**
  8. * ipa_rm_peers_list_get_resource_index() - resource name to index
  9. * of this resource in corresponding peers list
  10. * @resource_name: [in] resource name
  11. *
  12. * Returns: resource index mapping, IPA_RM_INDEX_INVALID
  13. * in case provided resource name isn't contained in enum
  14. * ipa_rm_resource_name.
  15. *
  16. */
  17. static int ipa_rm_peers_list_get_resource_index(
  18. enum ipa_rm_resource_name resource_name)
  19. {
  20. int resource_index = IPA_RM_INDEX_INVALID;
  21. if (IPA_RM_RESORCE_IS_PROD(resource_name))
  22. resource_index = ipa_rm_prod_index(resource_name);
  23. else if (IPA_RM_RESORCE_IS_CONS(resource_name))
  24. resource_index = ipa_rm_cons_index(resource_name);
  25. return resource_index;
  26. }
  27. static bool ipa_rm_peers_list_check_index(int index,
  28. struct ipa_rm_peers_list *peers_list)
  29. {
  30. return !(index > peers_list->max_peers || index < 0);
  31. }
  32. /**
  33. * ipa_rm_peers_list_create() - creates the peers list
  34. *
  35. * @max_peers: maximum number of peers in new list
  36. * @peers_list: [out] newly created peers list
  37. *
  38. * Returns: 0 in case of SUCCESS, negative otherwise
  39. */
  40. int ipa_rm_peers_list_create(int max_peers,
  41. struct ipa_rm_peers_list **peers_list)
  42. {
  43. int result;
  44. *peers_list = kzalloc(sizeof(**peers_list), GFP_ATOMIC);
  45. if (!*peers_list) {
  46. IPA_RM_ERR("no mem\n");
  47. result = -ENOMEM;
  48. goto bail;
  49. }
  50. (*peers_list)->max_peers = max_peers;
  51. (*peers_list)->peers = kzalloc((*peers_list)->max_peers *
  52. sizeof(*((*peers_list)->peers)), GFP_ATOMIC);
  53. if (!((*peers_list)->peers)) {
  54. IPA_RM_ERR("no mem\n");
  55. result = -ENOMEM;
  56. goto list_alloc_fail;
  57. }
  58. return 0;
  59. list_alloc_fail:
  60. kfree(*peers_list);
  61. bail:
  62. return result;
  63. }
  64. /**
  65. * ipa_rm_peers_list_delete() - deletes the peers list
  66. *
  67. * @peers_list: peers list
  68. *
  69. */
  70. void ipa_rm_peers_list_delete(struct ipa_rm_peers_list *peers_list)
  71. {
  72. if (peers_list) {
  73. kfree(peers_list->peers);
  74. kfree(peers_list);
  75. }
  76. }
  77. /**
  78. * ipa_rm_peers_list_remove_peer() - removes peer from the list
  79. *
  80. * @peers_list: peers list
  81. * @resource_name: name of the resource to remove
  82. *
  83. */
  84. void ipa_rm_peers_list_remove_peer(
  85. struct ipa_rm_peers_list *peers_list,
  86. enum ipa_rm_resource_name resource_name)
  87. {
  88. if (!peers_list)
  89. return;
  90. peers_list->peers[ipa_rm_peers_list_get_resource_index(
  91. resource_name)].resource = NULL;
  92. peers_list->peers[ipa_rm_peers_list_get_resource_index(
  93. resource_name)].userspace_dep = false;
  94. peers_list->peers_count--;
  95. }
  96. /**
  97. * ipa_rm_peers_list_add_peer() - adds peer to the list
  98. *
  99. * @peers_list: peers list
  100. * @resource: resource to add
  101. *
  102. */
  103. void ipa_rm_peers_list_add_peer(
  104. struct ipa_rm_peers_list *peers_list,
  105. struct ipa_rm_resource *resource,
  106. bool userspace_dep)
  107. {
  108. if (!peers_list || !resource)
  109. return;
  110. peers_list->peers[ipa_rm_peers_list_get_resource_index(
  111. resource->name)].resource = resource;
  112. peers_list->peers[ipa_rm_peers_list_get_resource_index(
  113. resource->name)].userspace_dep = userspace_dep;
  114. peers_list->peers_count++;
  115. }
  116. /**
  117. * ipa_rm_peers_list_is_empty() - checks
  118. * if resource peers list is empty
  119. *
  120. * @peers_list: peers list
  121. *
  122. * Returns: true if the list is empty, false otherwise
  123. */
  124. bool ipa_rm_peers_list_is_empty(struct ipa_rm_peers_list *peers_list)
  125. {
  126. bool result = true;
  127. if (!peers_list)
  128. goto bail;
  129. if (peers_list->peers_count > 0)
  130. result = false;
  131. bail:
  132. return result;
  133. }
  134. /**
  135. * ipa_rm_peers_list_has_last_peer() - checks
  136. * if resource peers list has exactly one peer
  137. *
  138. * @peers_list: peers list
  139. *
  140. * Returns: true if the list has exactly one peer, false otherwise
  141. */
  142. bool ipa_rm_peers_list_has_last_peer(
  143. struct ipa_rm_peers_list *peers_list)
  144. {
  145. bool result = false;
  146. if (!peers_list)
  147. goto bail;
  148. if (peers_list->peers_count == 1)
  149. result = true;
  150. bail:
  151. return result;
  152. }
  153. /**
  154. * ipa_rm_peers_list_check_dependency() - check dependency
  155. * between 2 peer lists
  156. * @resource_peers: first peers list
  157. * @resource_name: first peers list resource name
  158. * @depends_on_peers: second peers list
  159. * @depends_on_name: second peers list resource name
  160. * @userspace_dep: [out] dependency was created by userspace
  161. *
  162. * Returns: true if there is dependency, false otherwise
  163. *
  164. */
  165. bool ipa_rm_peers_list_check_dependency(
  166. struct ipa_rm_peers_list *resource_peers,
  167. enum ipa_rm_resource_name resource_name,
  168. struct ipa_rm_peers_list *depends_on_peers,
  169. enum ipa_rm_resource_name depends_on_name,
  170. bool *userspace_dep)
  171. {
  172. bool result = false;
  173. int resource_index;
  174. struct ipa_rm_resource_peer *peer_ptr;
  175. if (!resource_peers || !depends_on_peers || !userspace_dep)
  176. return result;
  177. resource_index = ipa_rm_peers_list_get_resource_index(depends_on_name);
  178. peer_ptr = &resource_peers->peers[resource_index];
  179. if (peer_ptr->resource != NULL) {
  180. result = true;
  181. *userspace_dep = peer_ptr->userspace_dep;
  182. }
  183. resource_index = ipa_rm_peers_list_get_resource_index(resource_name);
  184. peer_ptr = &depends_on_peers->peers[resource_index];
  185. if (peer_ptr->resource != NULL) {
  186. result = true;
  187. *userspace_dep = peer_ptr->userspace_dep;
  188. }
  189. return result;
  190. }
  191. /**
  192. * ipa_rm_peers_list_get_resource() - get resource by
  193. * resource index
  194. * @resource_index: resource index
  195. * @resource_peers: peers list
  196. *
  197. * Returns: the resource if found, NULL otherwise
  198. */
  199. struct ipa_rm_resource *ipa_rm_peers_list_get_resource(int resource_index,
  200. struct ipa_rm_peers_list *resource_peers)
  201. {
  202. struct ipa_rm_resource *result = NULL;
  203. if (!ipa_rm_peers_list_check_index(resource_index, resource_peers))
  204. goto bail;
  205. result = resource_peers->peers[resource_index].resource;
  206. bail:
  207. return result;
  208. }
  209. /**
  210. * ipa_rm_peers_list_get_userspace_dep() - returns whether resource dependency
  211. * was added by userspace
  212. * @resource_index: resource index
  213. * @resource_peers: peers list
  214. *
  215. * Returns: true if dependency was added by userspace, false by kernel
  216. */
  217. bool ipa_rm_peers_list_get_userspace_dep(int resource_index,
  218. struct ipa_rm_peers_list *resource_peers)
  219. {
  220. bool result = false;
  221. if (!ipa_rm_peers_list_check_index(resource_index, resource_peers))
  222. goto bail;
  223. result = resource_peers->peers[resource_index].userspace_dep;
  224. bail:
  225. return result;
  226. }
  227. /**
  228. * ipa_rm_peers_list_get_size() - get peers list sise
  229. *
  230. * @peers_list: peers list
  231. *
  232. * Returns: the size of the peers list
  233. */
  234. int ipa_rm_peers_list_get_size(struct ipa_rm_peers_list *peers_list)
  235. {
  236. return peers_list->max_peers;
  237. }