mt_lp_rq.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * Copyright (c) 2023, MediaTek Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <stdint.h>
  7. #include <string.h>
  8. #include <common/debug.h>
  9. #include <drivers/console.h>
  10. #include <lib/spinlock.h>
  11. #include <lpm/mt_lp_rqm.h>
  12. struct mt_lp_res_req_m {
  13. unsigned int uname[MT_LP_RQ_USER_MAX];
  14. unsigned int user_num;
  15. unsigned int user_valid;
  16. unsigned int resource_num;
  17. unsigned int generic_resource_req;
  18. unsigned int flag;
  19. struct mt_resource_req_manager *plat_rqm;
  20. };
  21. static struct mt_lp_res_req_m plat_mt_rqm;
  22. static spinlock_t mt_lp_rq_lock;
  23. static int mt_lp_resource_request(struct mt_lp_resource_user *this, unsigned int resource)
  24. {
  25. int i;
  26. struct mt_lp_res_req *const *rs;
  27. if ((this == NULL) || (resource == 0) || (resource > MT_LP_RQ_ALL)) {
  28. ERROR("invalid request(%x)\n", resource);
  29. return MT_LP_RQ_STA_BAD;
  30. }
  31. spin_lock(&mt_lp_rq_lock);
  32. rs = (plat_mt_rqm.plat_rqm)->res;
  33. for (i = 0; i < plat_mt_rqm.resource_num; i++) {
  34. if ((resource & rs[i]->res_id) != 0) {
  35. rs[i]->res_usage |= this->umask;
  36. }
  37. }
  38. plat_mt_rqm.flag = MT_LP_RQ_FLAG_NEED_UPDATE;
  39. spin_unlock(&mt_lp_rq_lock);
  40. return MT_LP_RQ_STA_OK;
  41. }
  42. static int mt_lp_resource_release(struct mt_lp_resource_user *this)
  43. {
  44. int i;
  45. struct mt_lp_res_req *const *rs;
  46. if (this == NULL) {
  47. return MT_LP_RQ_STA_BAD;
  48. }
  49. spin_lock(&mt_lp_rq_lock);
  50. rs = (plat_mt_rqm.plat_rqm)->res;
  51. for (i = 0; i < plat_mt_rqm.resource_num; i++) {
  52. rs[i]->res_usage &= ~(this->umask);
  53. }
  54. plat_mt_rqm.flag = MT_LP_RQ_FLAG_NEED_UPDATE;
  55. spin_unlock(&mt_lp_rq_lock);
  56. return MT_LP_RQ_STA_OK;
  57. }
  58. int mt_lp_resource_request_manager_register(struct mt_resource_req_manager *rqm)
  59. {
  60. unsigned int count;
  61. struct mt_lp_res_req *const *rs;
  62. if ((rqm == NULL) || (rqm->res == NULL) || (plat_mt_rqm.plat_rqm != NULL)) {
  63. return MT_LP_RQ_STA_BAD;
  64. }
  65. rs = rqm->res;
  66. count = 0;
  67. while (*rs != NULL) {
  68. count++;
  69. rs++;
  70. }
  71. plat_mt_rqm.plat_rqm = rqm;
  72. plat_mt_rqm.resource_num = count;
  73. return MT_LP_RQ_STA_OK;
  74. }
  75. int mt_lp_resource_user_register(char *user, struct mt_lp_resource_user *ru)
  76. {
  77. int i, len;
  78. unsigned int uname;
  79. if ((plat_mt_rqm.plat_rqm == NULL) || (plat_mt_rqm.user_num >= MT_LP_RQ_USER_MAX) ||
  80. (user == NULL)) {
  81. ru->uid = MT_LP_RQ_USER_INVALID;
  82. ru->umask = 0;
  83. ru->request = NULL;
  84. ru->release = NULL;
  85. ERROR("rqm register user invalid\n");
  86. return MT_LP_RQ_STA_BAD;
  87. }
  88. len = strnlen(user, MT_LP_RQ_USER_NAME_LEN);
  89. uname = 0;
  90. for (i = 0; i < len; i++) {
  91. uname |= (user[i] << (MT_LP_RQ_USER_CHAR_U * i));
  92. }
  93. spin_lock(&mt_lp_rq_lock);
  94. i = plat_mt_rqm.user_num;
  95. plat_mt_rqm.user_num += 1;
  96. plat_mt_rqm.uname[i] = uname;
  97. plat_mt_rqm.user_valid |= BIT(i);
  98. spin_unlock(&mt_lp_rq_lock);
  99. ru->umask = BIT(i);
  100. ru->uid = i;
  101. ru->request = mt_lp_resource_request;
  102. ru->release = mt_lp_resource_release;
  103. INFO("%s register by %s, uid = %d\n", __func__, user, ru->uid);
  104. return MT_LP_RQ_STA_OK;
  105. }
  106. int mt_lp_rq_get_status(int type, void *p)
  107. {
  108. int i;
  109. unsigned int update_sta;
  110. struct mt_lp_res_req *const *rs;
  111. struct resource_req_status *rq_sta = (struct resource_req_status *)p;
  112. if (plat_mt_rqm.flag != 0) {
  113. spin_lock(&mt_lp_rq_lock);
  114. update_sta = 0;
  115. rs = (plat_mt_rqm.plat_rqm)->res;
  116. for (i = 0; i < plat_mt_rqm.resource_num; i++) {
  117. update_sta |= ((rs[i]->res_usage & plat_mt_rqm.user_valid) != 0) ?
  118. rs[i]->res_rq : 0;
  119. }
  120. plat_mt_rqm.generic_resource_req = update_sta;
  121. plat_mt_rqm.flag = MT_LP_RQ_FLAG_DONE;
  122. spin_unlock(&mt_lp_rq_lock);
  123. }
  124. switch (type) {
  125. case PLAT_RQ_REQ_USAGE:
  126. rs = (plat_mt_rqm.plat_rqm)->res;
  127. rq_sta->val = (rq_sta->id < plat_mt_rqm.resource_num) ?
  128. rs[rq_sta->id]->res_usage : plat_mt_rqm.generic_resource_req;
  129. break;
  130. case PLAT_RQ_USER_NUM:
  131. rq_sta->val = plat_mt_rqm.user_num;
  132. break;
  133. case PLAT_RQ_USER_VALID:
  134. rq_sta->val = plat_mt_rqm.user_valid;
  135. break;
  136. case PLAT_RQ_PER_USER_NAME:
  137. rq_sta->val = (rq_sta->id < plat_mt_rqm.user_num) ?
  138. plat_mt_rqm.uname[rq_sta->id] : 0;
  139. break;
  140. case PLAT_RQ_REQ_NUM:
  141. rq_sta->val = plat_mt_rqm.resource_num;
  142. break;
  143. default:
  144. break;
  145. }
  146. return MT_LP_RQ_STA_OK;
  147. }
  148. int mt_lp_rq_update_status(int type, void *p)
  149. {
  150. unsigned int user_mask;
  151. struct resource_req_status *rq_sta = (struct resource_req_status *)p;
  152. switch (type) {
  153. case PLAT_RQ_USER_VALID:
  154. if (rq_sta->id < plat_mt_rqm.user_num) {
  155. user_mask = BIT(rq_sta->id);
  156. spin_lock(&mt_lp_rq_lock);
  157. plat_mt_rqm.user_valid = (rq_sta->val == 0) ?
  158. (plat_mt_rqm.user_valid & ~(user_mask)) :
  159. (plat_mt_rqm.user_valid | user_mask);
  160. plat_mt_rqm.flag = MT_LP_RQ_FLAG_NEED_UPDATE;
  161. spin_unlock(&mt_lp_rq_lock);
  162. }
  163. break;
  164. default:
  165. break;
  166. }
  167. return MT_LP_RQ_STA_OK;
  168. }