apr_tal_rpmsg.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/module.h>
  14. #include <linux/spinlock.h>
  15. #include <linux/mutex.h>
  16. #include <linux/wait.h>
  17. #include <linux/delay.h>
  18. #include <linux/rpmsg.h>
  19. #include <ipc/apr_tal.h>
  20. enum apr_channel_state {
  21. APR_CH_DISCONNECTED,
  22. APR_CH_CONNECTED,
  23. };
  24. #define APR_MAXIMUM_NUM_OF_RETRIES 2
  25. static struct apr_svc_ch_dev
  26. apr_svc_ch[APR_DL_MAX][APR_DEST_MAX][APR_CLIENT_MAX];
  27. /**
  28. * apr_tal_write() - Write a message across to the remote processor
  29. * @apr_ch: apr channel handle
  30. * @data: buffer that needs to be transferred over the channel
  31. * @pkt_priv: private data of the packet
  32. * @len: length of the buffer
  33. *
  34. * Returns len of buffer successfully transferred on success
  35. * and an appropriate error value on failure.
  36. */
  37. int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data,
  38. struct apr_pkt_priv *pkt_priv, int len)
  39. {
  40. int rc = 0, retries = 0;
  41. unsigned long flags;
  42. struct rpmsg_device *rpdev = NULL;
  43. if (!apr_ch || len > APR_MAX_BUF ||
  44. apr_ch->channel_state != APR_CH_CONNECTED)
  45. return -EINVAL;
  46. spin_lock_irqsave(&apr_ch->w_lock, flags);
  47. rpdev = apr_ch->handle;
  48. if (!rpdev) {
  49. spin_unlock_irqrestore(&apr_ch->w_lock, flags);
  50. return -EINVAL;
  51. }
  52. do {
  53. if (rc == -EAGAIN)
  54. udelay(50);
  55. rc = rpmsg_trysend(rpdev->ept, data, len);
  56. } while (rc == -EAGAIN && retries++ < APR_MAXIMUM_NUM_OF_RETRIES);
  57. spin_unlock_irqrestore(&apr_ch->w_lock, flags);
  58. if (rc)
  59. pr_err("%s: Unable to send the packet, rc:%d\n", __func__, rc);
  60. else
  61. rc = len;
  62. return rc;
  63. }
  64. EXPORT_SYMBOL(apr_tal_write);
  65. /**
  66. * apr_tal_rx_intents_config() - Configure glink intents for remote processor
  67. * @apr_ch: apr channel handle
  68. * @num_of_intents: number of intents
  69. * @size: size of the intents
  70. *
  71. * This api is not supported with RPMSG. Returns 0 to indicate success
  72. */
  73. int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch,
  74. int num_of_intents, uint32_t size)
  75. {
  76. pr_debug("%s: NO-OP\n", __func__);
  77. return 0;
  78. }
  79. EXPORT_SYMBOL(apr_tal_rx_intents_config);
  80. /**
  81. * apr_tal_start_rx_rt() - Set RT thread priority for APR RX transfer
  82. * @apr_ch: apr channel handle
  83. *
  84. * This api is not supported with RPMSG as message transfer occurs
  85. * in client's context. Returns 0 to indicate success.
  86. */
  87. int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch)
  88. {
  89. pr_debug("%s: NO-OP\n", __func__);
  90. return 0;
  91. }
  92. EXPORT_SYMBOL(apr_tal_start_rx_rt);
  93. /**
  94. * apr_tal_end_rx_rt() - Remove RT thread priority for APR RX transfer
  95. * @apr_ch: apr channel handle
  96. *
  97. * This api is not supported with RPMSG. Returns 0 to indicate success
  98. */
  99. int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch)
  100. {
  101. pr_debug("%s: NO-OP\n", __func__);
  102. return 0;
  103. }
  104. EXPORT_SYMBOL(apr_tal_end_rx_rt);
  105. /**
  106. * apr_tal_open() - Open a transport channel for data transfer
  107. * on remote processor.
  108. * @clnt: apr client, audio or voice
  109. * @dest: destination remote processor for which apr channel is requested for.
  110. * @dl: type of data link
  111. * @func: callback function to handle data transfer from remote processor
  112. * @priv: private data of the client
  113. *
  114. * Returns apr_svc_ch_dev handle on success and NULL on failure.
  115. */
  116. struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl,
  117. apr_svc_cb_fn func, void *priv)
  118. {
  119. int rc = 0;
  120. struct apr_svc_ch_dev *apr_ch = NULL;
  121. if ((clnt != APR_CLIENT_AUDIO) || (dest != APR_DEST_QDSP6) ||
  122. (dl != APR_DL_SMD)) {
  123. pr_err("%s: Invalid params, clnt:%d, dest:%d, dl:%d\n",
  124. __func__, clnt, dest, dl);
  125. return NULL;
  126. }
  127. apr_ch = &apr_svc_ch[APR_DL_SMD][APR_DEST_QDSP6][APR_CLIENT_AUDIO];
  128. mutex_lock(&apr_ch->m_lock);
  129. if (!apr_ch->handle) {
  130. rc = wait_event_timeout(apr_ch->wait,
  131. (apr_ch->channel_state == APR_CH_CONNECTED), 5 * HZ);
  132. if (rc == 0) {
  133. pr_err("%s: TIMEOUT for APR_CH_CONNECTED event\n",
  134. __func__);
  135. rc = -ETIMEDOUT;
  136. goto unlock;
  137. }
  138. }
  139. pr_debug("%s: Channel connected, returning handle :%pK\n",
  140. __func__, apr_ch->handle);
  141. apr_ch->func = func;
  142. apr_ch->priv = priv;
  143. unlock:
  144. mutex_unlock(&apr_ch->m_lock);
  145. return rc ? NULL : apr_ch;
  146. }
  147. EXPORT_SYMBOL(apr_tal_open);
  148. /**
  149. * apr_tal_close() - Close transport channel on remote processor.
  150. * @apr_ch: apr channel handle
  151. *
  152. * Returns 0 on success and an appropriate error value on failure.
  153. */
  154. int apr_tal_close(struct apr_svc_ch_dev *apr_ch)
  155. {
  156. int rc = 0;
  157. if (!apr_ch || !apr_ch->handle) {
  158. rc = -EINVAL;
  159. goto exit;
  160. }
  161. mutex_lock(&apr_ch->m_lock);
  162. apr_ch->func = NULL;
  163. apr_ch->priv = NULL;
  164. mutex_unlock(&apr_ch->m_lock);
  165. exit:
  166. return rc;
  167. }
  168. EXPORT_SYMBOL(apr_tal_close);
  169. static int apr_tal_rpmsg_callback(struct rpmsg_device *rpdev,
  170. void *data, int len, void *priv, u32 addr)
  171. {
  172. struct apr_svc_ch_dev *apr_ch = dev_get_drvdata(&rpdev->dev);
  173. unsigned long flags;
  174. if (!apr_ch || !data) {
  175. pr_err("%s: Invalid apr_ch or ptr\n", __func__);
  176. return -EINVAL;
  177. }
  178. dev_dbg(&rpdev->dev, "%s: Rx packet received, len:%d\n",
  179. __func__, len);
  180. spin_lock_irqsave(&apr_ch->r_lock, flags);
  181. if (apr_ch->func)
  182. apr_ch->func((void *)data, len, apr_ch->priv);
  183. spin_unlock_irqrestore(&apr_ch->r_lock, flags);
  184. return 0;
  185. }
  186. static int apr_tal_rpmsg_probe(struct rpmsg_device *rpdev)
  187. {
  188. struct apr_svc_ch_dev *apr_ch = NULL;
  189. if (!strcmp(rpdev->id.name, "apr_audio_svc")) {
  190. dev_info(&rpdev->dev, "%s: Channel[%s] state[Up]\n",
  191. __func__, rpdev->id.name);
  192. apr_ch =
  193. &apr_svc_ch[APR_DL_SMD][APR_DEST_QDSP6][APR_CLIENT_AUDIO];
  194. apr_ch->handle = rpdev;
  195. apr_ch->channel_state = APR_CH_CONNECTED;
  196. dev_set_drvdata(&rpdev->dev, apr_ch);
  197. wake_up(&apr_ch->wait);
  198. } else {
  199. dev_err(&rpdev->dev, "%s, Invalid Channel [%s]\n",
  200. __func__, rpdev->id.name);
  201. return -EINVAL;
  202. }
  203. return 0;
  204. }
  205. static void apr_tal_rpmsg_remove(struct rpmsg_device *rpdev)
  206. {
  207. struct apr_svc_ch_dev *apr_ch = dev_get_drvdata(&rpdev->dev);
  208. if (!apr_ch) {
  209. dev_err(&rpdev->dev, "%s: Invalid apr_ch\n", __func__);
  210. return;
  211. }
  212. dev_info(&rpdev->dev, "%s: Channel[%s] state[Down]\n",
  213. __func__, rpdev->id.name);
  214. apr_ch->handle = NULL;
  215. apr_ch->channel_state = APR_CH_DISCONNECTED;
  216. dev_set_drvdata(&rpdev->dev, NULL);
  217. }
  218. static const struct rpmsg_device_id apr_tal_rpmsg_match[] = {
  219. { "apr_audio_svc" },
  220. {}
  221. };
  222. static struct rpmsg_driver apr_tal_rpmsg_driver = {
  223. .probe = apr_tal_rpmsg_probe,
  224. .remove = apr_tal_rpmsg_remove,
  225. .callback = apr_tal_rpmsg_callback,
  226. .id_table = apr_tal_rpmsg_match,
  227. .drv = {
  228. .name = "apr_tal_rpmsg",
  229. },
  230. };
  231. /**
  232. * apr_tal_int() - Registers rpmsg driver with rpmsg framework.
  233. *
  234. * Returns 0 on success and an appropriate error value on failure.
  235. */
  236. int apr_tal_init(void)
  237. {
  238. int i, j, k;
  239. int ret;
  240. memset(apr_svc_ch, 0, sizeof(struct apr_svc_ch_dev));
  241. for (i = 0; i < APR_DL_MAX; i++) {
  242. for (j = 0; j < APR_DEST_MAX; j++) {
  243. for (k = 0; k < APR_CLIENT_MAX; k++) {
  244. init_waitqueue_head(&apr_svc_ch[i][j][k].wait);
  245. spin_lock_init(&apr_svc_ch[i][j][k].w_lock);
  246. spin_lock_init(&apr_svc_ch[i][j][k].r_lock);
  247. mutex_init(&apr_svc_ch[i][j][k].m_lock);
  248. }
  249. }
  250. }
  251. ret = register_rpmsg_driver(&apr_tal_rpmsg_driver);
  252. return ret;
  253. }
  254. EXPORT_SYMBOL(apr_tal_init);
  255. /**
  256. * apr_tal_exit() - De-register rpmsg driver with rpmsg framework.
  257. */
  258. void apr_tal_exit(void)
  259. {
  260. unregister_rpmsg_driver(&apr_tal_rpmsg_driver);
  261. }
  262. EXPORT_SYMBOL(apr_tal_exit);