msm_audio_ion.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/init.h>
  7. #include <linux/kernel.h>
  8. #include <linux/module.h>
  9. #include <linux/err.h>
  10. #include <linux/delay.h>
  11. #include <linux/slab.h>
  12. #include <linux/mutex.h>
  13. #include <linux/list.h>
  14. #include <linux/dma-mapping.h>
  15. #include <linux/dma-buf.h>
  16. #include <linux/dma-buf-map.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/of_device.h>
  19. #include <linux/export.h>
  20. #include <linux/ioctl.h>
  21. #include <linux/cdev.h>
  22. #include <linux/fs.h>
  23. #include <linux/device.h>
  24. #ifndef CONFIG_SPF_CORE
  25. #include <ipc/apr.h>
  26. #endif
  27. #include <dsp/msm_audio_ion.h>
  28. #include <linux/msm_audio.h>
  29. #include <soc/qcom/secure_buffer.h>
  30. #define MSM_AUDIO_ION_PROBED (1 << 0)
  31. #define MSM_AUDIO_ION_PHYS_ADDR(alloc_data) \
  32. alloc_data->table->sgl->dma_address
  33. #define MSM_AUDIO_SMMU_SID_OFFSET 32
  34. #define TZ_PIL_PROTECT_MEM_SUBSYS_ID 0x0C
  35. #define TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID 0x0D
  36. #define MSM_AUDIO_ION_DRIVER_NAME "msm_audio_ion"
  37. #define MINOR_NUMBER_COUNT 1
  38. struct msm_audio_ion_private {
  39. bool smmu_enabled;
  40. struct device *cb_dev;
  41. u8 device_status;
  42. struct list_head alloc_list;
  43. struct mutex list_mutex;
  44. u64 smmu_sid_bits;
  45. u32 smmu_version;
  46. bool is_non_hypervisor;
  47. char *driver_name;
  48. /*char dev related data */
  49. dev_t ion_major;
  50. struct class *ion_class;
  51. struct device *chardev;
  52. struct cdev cdev;
  53. };
  54. struct msm_audio_alloc_data {
  55. size_t len;
  56. struct dma_buf_map *vmap;
  57. struct dma_buf *dma_buf;
  58. struct dma_buf_attachment *attach;
  59. struct sg_table *table;
  60. struct list_head list;
  61. };
  62. struct msm_audio_ion_fd_list_private {
  63. struct mutex list_mutex;
  64. /*list to store fd, phy. addr and handle data */
  65. struct list_head fd_list;
  66. };
  67. static struct msm_audio_ion_fd_list_private msm_audio_ion_fd_list = {0,};
  68. static bool msm_audio_ion_fd_list_init = false;
  69. struct msm_audio_fd_data {
  70. int fd;
  71. size_t plen;
  72. void *handle;
  73. dma_addr_t paddr;
  74. struct device *dev;
  75. struct list_head list;
  76. };
  77. static void msm_audio_ion_add_allocation(
  78. struct msm_audio_ion_private *msm_audio_ion_data,
  79. struct msm_audio_alloc_data *alloc_data)
  80. {
  81. /*
  82. * Since these APIs can be invoked by multiple
  83. * clients, there is need to make sure the list
  84. * of allocations is always protected
  85. */
  86. mutex_lock(&(msm_audio_ion_data->list_mutex));
  87. list_add_tail(&(alloc_data->list),
  88. &(msm_audio_ion_data->alloc_list));
  89. mutex_unlock(&(msm_audio_ion_data->list_mutex));
  90. }
  91. static int msm_audio_ion_map_kernel(struct dma_buf *dma_buf,
  92. struct msm_audio_ion_private *ion_data, struct dma_buf_map *dma_vmap)
  93. {
  94. int rc = 0;
  95. struct msm_audio_alloc_data *alloc_data = NULL;
  96. rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
  97. if (rc) {
  98. pr_err("%s: kmap dma_buf_begin_cpu_access fail\n", __func__);
  99. goto exit;
  100. }
  101. rc = dma_buf_vmap(dma_buf, dma_vmap);
  102. if (rc) {
  103. pr_err("%s: kernel mapping of dma_buf failed\n",
  104. __func__);
  105. goto exit;
  106. }
  107. /*
  108. * TBD: remove the below section once new API
  109. * for mapping kernel virtual address is available.
  110. */
  111. mutex_lock(&(ion_data->list_mutex));
  112. list_for_each_entry(alloc_data, &(ion_data->alloc_list),
  113. list) {
  114. if (alloc_data->dma_buf == dma_buf) {
  115. alloc_data->vmap = dma_vmap;
  116. break;
  117. }
  118. }
  119. mutex_unlock(&(ion_data->list_mutex));
  120. exit:
  121. return rc;
  122. }
  123. static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
  124. dma_addr_t *addr, size_t *len, bool is_iova,
  125. struct msm_audio_ion_private *ion_data)
  126. {
  127. struct msm_audio_alloc_data *alloc_data = NULL;
  128. int rc = 0;
  129. struct dma_buf_map dma_vmap;
  130. struct device *cb_dev = ion_data->cb_dev;
  131. /* Data required per buffer mapping */
  132. alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL);
  133. if (!alloc_data)
  134. return -ENOMEM;
  135. alloc_data->dma_buf = dma_buf;
  136. alloc_data->len = dma_buf->size;
  137. *len = dma_buf->size;
  138. /* Attach the dma_buf to context bank device */
  139. alloc_data->attach = dma_buf_attach(alloc_data->dma_buf,
  140. cb_dev);
  141. if (IS_ERR(alloc_data->attach)) {
  142. rc = PTR_ERR(alloc_data->attach);
  143. dev_err(cb_dev,
  144. "%s: Fail to attach dma_buf to CB, rc = %d\n",
  145. __func__, rc);
  146. goto free_alloc_data;
  147. }
  148. /*
  149. * Get the scatter-gather list.
  150. * There is no info as this is a write buffer or
  151. * read buffer, hence the request is bi-directional
  152. * to accommodate both read and write mappings.
  153. */
  154. alloc_data->table = dma_buf_map_attachment(alloc_data->attach,
  155. DMA_BIDIRECTIONAL);
  156. if (IS_ERR(alloc_data->table)) {
  157. rc = PTR_ERR(alloc_data->table);
  158. dev_err(cb_dev,
  159. "%s: Fail to map attachment, rc = %d\n",
  160. __func__, rc);
  161. goto detach_dma_buf;
  162. }
  163. /* physical address from mapping */
  164. if (!is_iova) {
  165. *addr = sg_phys(alloc_data->table->sgl);
  166. rc = msm_audio_ion_map_kernel((void *)dma_buf, ion_data, &dma_vmap);
  167. if (rc) {
  168. pr_err("%s: ION memory mapping for AUDIO failed, err:%d\n",
  169. __func__, rc);
  170. rc = -ENOMEM;
  171. goto detach_dma_buf;
  172. }
  173. alloc_data->vmap = &dma_vmap;
  174. } else {
  175. *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data);
  176. }
  177. msm_audio_ion_add_allocation(ion_data, alloc_data);
  178. return rc;
  179. detach_dma_buf:
  180. dma_buf_detach(alloc_data->dma_buf,
  181. alloc_data->attach);
  182. free_alloc_data:
  183. kfree(alloc_data);
  184. alloc_data = NULL;
  185. return rc;
  186. }
  187. static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, struct msm_audio_ion_private *ion_data)
  188. {
  189. int rc = 0;
  190. struct msm_audio_alloc_data *alloc_data = NULL;
  191. struct list_head *ptr, *next;
  192. bool found = false;
  193. struct device *cb_dev = ion_data->cb_dev;
  194. /*
  195. * Though list_for_each_safe is delete safe, lock
  196. * should be explicitly acquired to avoid race condition
  197. * on adding elements to the list.
  198. */
  199. mutex_lock(&(ion_data->list_mutex));
  200. list_for_each_safe(ptr, next,
  201. &(ion_data->alloc_list)) {
  202. alloc_data = list_entry(ptr, struct msm_audio_alloc_data,
  203. list);
  204. if (alloc_data->dma_buf == dma_buf) {
  205. found = true;
  206. dma_buf_unmap_attachment(alloc_data->attach,
  207. alloc_data->table,
  208. DMA_BIDIRECTIONAL);
  209. dma_buf_detach(alloc_data->dma_buf,
  210. alloc_data->attach);
  211. dma_buf_put(alloc_data->dma_buf);
  212. list_del(&(alloc_data->list));
  213. kfree(alloc_data);
  214. alloc_data = NULL;
  215. break;
  216. }
  217. }
  218. mutex_unlock(&(ion_data->list_mutex));
  219. if (!found) {
  220. dev_err(cb_dev,
  221. "%s: cannot find allocation, dma_buf %pK",
  222. __func__, dma_buf);
  223. rc = -EINVAL;
  224. }
  225. return rc;
  226. }
  227. static int msm_audio_ion_get_phys(struct dma_buf *dma_buf,
  228. dma_addr_t *addr, size_t *len, bool is_iova,
  229. struct msm_audio_ion_private *ion_data)
  230. {
  231. int rc = 0;
  232. rc = msm_audio_dma_buf_map(dma_buf, addr, len, is_iova, ion_data);
  233. if (rc) {
  234. pr_err("%s: failed to map DMA buf, err = %d\n",
  235. __func__, rc);
  236. goto err;
  237. }
  238. if (ion_data->smmu_enabled && is_iova) {
  239. /* Append the SMMU SID information to the IOVA address */
  240. *addr |= ion_data->smmu_sid_bits;
  241. }
  242. pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc);
  243. err:
  244. return rc;
  245. }
  246. static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf, struct msm_audio_ion_private *ion_data)
  247. {
  248. int rc = 0;
  249. struct dma_buf_map *dma_vmap = NULL;
  250. struct msm_audio_alloc_data *alloc_data = NULL;
  251. struct device *cb_dev = ion_data->cb_dev;
  252. /*
  253. * TBD: remove the below section once new API
  254. * for unmapping kernel virtual address is available.
  255. */
  256. mutex_lock(&(ion_data->list_mutex));
  257. list_for_each_entry(alloc_data, &(ion_data->alloc_list),
  258. list) {
  259. if (alloc_data->dma_buf == dma_buf) {
  260. dma_vmap = alloc_data->vmap;
  261. break;
  262. }
  263. }
  264. mutex_unlock(&(ion_data->list_mutex));
  265. if (!dma_vmap) {
  266. dev_err(cb_dev,
  267. "%s: cannot find allocation for dma_buf %pK",
  268. __func__, dma_buf);
  269. rc = -EINVAL;
  270. goto err;
  271. }
  272. dma_buf_vunmap(dma_buf, dma_vmap);
  273. rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
  274. if (rc) {
  275. dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n",
  276. __func__);
  277. goto err;
  278. }
  279. err:
  280. return rc;
  281. }
  282. static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
  283. size_t *plen, struct dma_buf_map *dma_vmap,
  284. struct msm_audio_ion_private *ion_data)
  285. {
  286. int rc = 0;
  287. bool is_iova = true;
  288. if (!dma_buf || !paddr || !plen) {
  289. pr_err("%s: Invalid params\n", __func__);
  290. return -EINVAL;
  291. }
  292. rc = msm_audio_ion_get_phys(dma_buf, paddr, plen, is_iova, ion_data);
  293. if (rc) {
  294. pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
  295. __func__, rc);
  296. dma_buf_put(dma_buf);
  297. goto err;
  298. }
  299. rc = msm_audio_ion_map_kernel(dma_buf, ion_data, dma_vmap);
  300. if (rc) {
  301. pr_err("%s: ION memory mapping for AUDIO failed, err:%d\n",
  302. __func__, rc);
  303. rc = -ENOMEM;
  304. msm_audio_dma_buf_unmap(dma_buf, ion_data);
  305. goto err;
  306. }
  307. err:
  308. return rc;
  309. }
  310. void msm_audio_fd_list_debug(void)
  311. {
  312. struct msm_audio_fd_data *msm_audio_fd_data = NULL;
  313. list_for_each_entry(msm_audio_fd_data,
  314. &msm_audio_ion_fd_list.fd_list, list) {
  315. pr_debug("%s fd %d handle %pK phy. addr %pK\n", __func__,
  316. msm_audio_fd_data->fd, msm_audio_fd_data->handle,
  317. (void *)msm_audio_fd_data->paddr);
  318. }
  319. }
  320. void msm_audio_update_fd_list(struct msm_audio_fd_data *msm_audio_fd_data)
  321. {
  322. struct msm_audio_fd_data *msm_audio_fd_data1 = NULL;
  323. mutex_lock(&(msm_audio_ion_fd_list.list_mutex));
  324. list_for_each_entry(msm_audio_fd_data1,
  325. &msm_audio_ion_fd_list.fd_list, list) {
  326. if (msm_audio_fd_data1->fd == msm_audio_fd_data->fd) {
  327. pr_err("%s fd already present, not updating the list",
  328. __func__);
  329. mutex_unlock(&(msm_audio_ion_fd_list.list_mutex));
  330. return;
  331. }
  332. }
  333. list_add_tail(&msm_audio_fd_data->list, &msm_audio_ion_fd_list.fd_list);
  334. mutex_unlock(&(msm_audio_ion_fd_list.list_mutex));
  335. }
  336. void msm_audio_delete_fd_entry(void *handle)
  337. {
  338. struct msm_audio_fd_data *msm_audio_fd_data = NULL;
  339. struct list_head *ptr, *next;
  340. mutex_lock(&(msm_audio_ion_fd_list.list_mutex));
  341. list_for_each_safe(ptr, next,
  342. &msm_audio_ion_fd_list.fd_list) {
  343. msm_audio_fd_data = list_entry(ptr, struct msm_audio_fd_data,
  344. list);
  345. if (msm_audio_fd_data->handle == handle) {
  346. pr_debug("%s deleting handle %pK entry from list\n",
  347. __func__, handle);
  348. list_del(&(msm_audio_fd_data->list));
  349. kfree(msm_audio_fd_data);
  350. break;
  351. }
  352. }
  353. mutex_unlock(&(msm_audio_ion_fd_list.list_mutex));
  354. }
  355. int msm_audio_get_phy_addr(int fd, dma_addr_t *paddr, size_t *pa_len)
  356. {
  357. struct msm_audio_fd_data *msm_audio_fd_data = NULL;
  358. int status = -EINVAL;
  359. if (!paddr) {
  360. pr_err("%s Invalid paddr param status %d\n", __func__, status);
  361. return status;
  362. }
  363. pr_debug("%s, fd %d\n", __func__, fd);
  364. mutex_lock(&(msm_audio_ion_fd_list.list_mutex));
  365. list_for_each_entry(msm_audio_fd_data,
  366. &msm_audio_ion_fd_list.fd_list, list) {
  367. if (msm_audio_fd_data->fd == fd) {
  368. *paddr = msm_audio_fd_data->paddr;
  369. *pa_len = msm_audio_fd_data->plen;
  370. status = 0;
  371. pr_debug("%s Found fd %d paddr %pK\n",
  372. __func__, fd, paddr);
  373. mutex_unlock(&(msm_audio_ion_fd_list.list_mutex));
  374. return status;
  375. }
  376. }
  377. mutex_unlock(&(msm_audio_ion_fd_list.list_mutex));
  378. return status;
  379. }
  380. EXPORT_SYMBOL(msm_audio_get_phy_addr);
  381. void msm_audio_get_handle(int fd, void **handle)
  382. {
  383. struct msm_audio_fd_data *msm_audio_fd_data = NULL;
  384. pr_debug("%s fd %d\n", __func__, fd);
  385. mutex_lock(&(msm_audio_ion_fd_list.list_mutex));
  386. list_for_each_entry(msm_audio_fd_data,
  387. &msm_audio_ion_fd_list.fd_list, list) {
  388. if (msm_audio_fd_data->fd == fd) {
  389. *handle = (struct dma_buf *)msm_audio_fd_data->handle;
  390. pr_debug("%s handle %pK\n", __func__, *handle);
  391. break;
  392. }
  393. }
  394. mutex_unlock(&(msm_audio_ion_fd_list.list_mutex));
  395. }
  396. /**
  397. * msm_audio_ion_import-
  398. * Import ION buffer with given file descriptor
  399. *
  400. * @dma_buf: dma_buf for the ION memory
  401. * @fd: file descriptor for the ION memory
  402. * @ionflag: flags associated with ION buffer
  403. * @bufsz: buffer size
  404. * @paddr: Physical address to be assigned with allocated region
  405. * @plen: length of allocated region to be assigned
  406. * @dma_vmap: Virtual mapping vmap pointer to be assigned
  407. *
  408. * Returns 0 on success or error on failure
  409. */
  410. static int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
  411. unsigned long *ionflag, size_t bufsz,
  412. dma_addr_t *paddr, size_t *plen, struct dma_buf_map *dma_vmap,
  413. struct msm_audio_ion_private *ion_data)
  414. {
  415. int rc = 0;
  416. if (!(ion_data->device_status & MSM_AUDIO_ION_PROBED)) {
  417. pr_debug("%s: probe is not done, deferred\n", __func__);
  418. return -EPROBE_DEFER;
  419. }
  420. if (!dma_buf || !paddr || !plen) {
  421. pr_err("%s: Invalid params\n", __func__);
  422. return -EINVAL;
  423. }
  424. /* bufsz should be 0 and fd shouldn't be 0 as of now */
  425. *dma_buf = dma_buf_get(fd);
  426. pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd);
  427. if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
  428. pr_err("%s: dma_buf_get failed\n", __func__);
  429. rc = -EINVAL;
  430. goto err;
  431. }
  432. if (ionflag != NULL) {
  433. rc = dma_buf_get_flags(*dma_buf, ionflag);
  434. if (rc) {
  435. pr_err("%s: could not get flags for the dma_buf\n",
  436. __func__);
  437. goto err_ion_flag;
  438. }
  439. }
  440. if (ion_data->smmu_enabled) {
  441. rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, dma_vmap, ion_data);
  442. if (rc) {
  443. pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
  444. goto err;
  445. }
  446. pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
  447. dma_vmap->vaddr, bufsz);
  448. } else {
  449. msm_audio_dma_buf_map(*dma_buf, paddr, plen, true, ion_data);
  450. }
  451. return 0;
  452. err_ion_flag:
  453. dma_buf_put(*dma_buf);
  454. err:
  455. *dma_buf = NULL;
  456. return rc;
  457. }
  458. /**
  459. * msm_audio_ion_free -
  460. * fress ION memory for given client and handle
  461. *
  462. * @dma_buf: dma_buf for the ION memory
  463. *
  464. * Returns 0 on success or error on failure
  465. */
  466. static int msm_audio_ion_free(struct dma_buf *dma_buf, struct msm_audio_ion_private *ion_data)
  467. {
  468. int ret = 0;
  469. if (!dma_buf) {
  470. pr_err("%s: dma_buf invalid\n", __func__);
  471. return -EINVAL;
  472. }
  473. if (ion_data->smmu_enabled) {
  474. ret = msm_audio_ion_unmap_kernel(dma_buf, ion_data);
  475. if (ret)
  476. return ret;
  477. }
  478. msm_audio_dma_buf_unmap(dma_buf, ion_data);
  479. return 0;
  480. }
  481. /**
  482. * msm_audio_ion_crash_handler -
  483. * handles cleanup after userspace crashes.
  484. *
  485. * To be called from machine driver.
  486. */
  487. void msm_audio_ion_crash_handler(void)
  488. {
  489. struct msm_audio_fd_data *msm_audio_fd_data = NULL;
  490. struct list_head *ptr, *next;
  491. void *handle = NULL;
  492. struct msm_audio_ion_private *ion_data = NULL;
  493. pr_debug("Inside %s\n", __func__);
  494. mutex_lock(&(msm_audio_ion_fd_list.list_mutex));
  495. list_for_each_entry(msm_audio_fd_data,
  496. &msm_audio_ion_fd_list.fd_list, list) {
  497. handle = msm_audio_fd_data->handle;
  498. ion_data = dev_get_drvdata(msm_audio_fd_data->dev);
  499. msm_audio_ion_free(handle, ion_data);
  500. }
  501. list_for_each_safe(ptr, next,
  502. &msm_audio_ion_fd_list.fd_list) {
  503. msm_audio_fd_data = list_entry(ptr, struct msm_audio_fd_data,
  504. list);
  505. list_del(&(msm_audio_fd_data->list));
  506. kfree(msm_audio_fd_data);
  507. }
  508. mutex_unlock(&(msm_audio_ion_fd_list.list_mutex));
  509. }
  510. EXPORT_SYMBOL(msm_audio_ion_crash_handler);
  511. static int msm_audio_ion_open(struct inode *inode, struct file *file)
  512. {
  513. int ret = 0;
  514. struct msm_audio_ion_private *ion_data = container_of(inode->i_cdev,
  515. struct msm_audio_ion_private,
  516. cdev);
  517. struct device *dev = ion_data->chardev;
  518. pr_debug("Inside %s\n", __func__);
  519. get_device(dev);
  520. return ret;
  521. }
  522. static int msm_audio_ion_release(struct inode *inode, struct file *file)
  523. {
  524. struct msm_audio_ion_private *ion_data = container_of(inode->i_cdev,
  525. struct msm_audio_ion_private,
  526. cdev);
  527. struct device *dev = ion_data->chardev;
  528. pr_debug("Inside %s\n", __func__);
  529. put_device(dev);
  530. return 0;
  531. }
  532. static long msm_audio_ion_ioctl(struct file *file, unsigned int ioctl_num,
  533. unsigned long __user ioctl_param)
  534. {
  535. void *mem_handle;
  536. dma_addr_t paddr;
  537. size_t pa_len = 0;
  538. struct dma_buf_map dma_vmap;
  539. int ret = 0;
  540. int dest_perms_map[2] = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE};
  541. int source_vm_map[1] = {VMID_HLOS};
  542. int dest_vm_map[3] = {VMID_LPASS, VMID_ADSP_HEAP, VMID_HLOS};
  543. int dest_perms_unmap[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
  544. int source_vm_unmap[3] = {VMID_LPASS, VMID_ADSP_HEAP, VMID_HLOS};
  545. int dest_vm_unmap[1] = {VMID_HLOS};
  546. struct msm_audio_fd_data *msm_audio_fd_data = NULL;
  547. struct msm_audio_ion_private *ion_data =
  548. container_of(file->f_inode->i_cdev, struct msm_audio_ion_private, cdev);
  549. pr_debug("%s ioctl num %u\n", __func__, ioctl_num);
  550. switch (ioctl_num) {
  551. case IOCTL_MAP_PHYS_ADDR:
  552. msm_audio_fd_data = kzalloc((sizeof(struct msm_audio_fd_data)),
  553. GFP_KERNEL);
  554. if (!msm_audio_fd_data)
  555. return -ENOMEM;
  556. ret = msm_audio_ion_import((struct dma_buf **)&mem_handle, (int)ioctl_param,
  557. NULL, 0, &paddr, &pa_len, &dma_vmap, ion_data);
  558. if (ret < 0) {
  559. pr_err("%s Memory map Failed %d\n", __func__, ret);
  560. kfree(msm_audio_fd_data);
  561. return ret;
  562. }
  563. msm_audio_fd_data->fd = (int)ioctl_param;
  564. msm_audio_fd_data->handle = mem_handle;
  565. msm_audio_fd_data->paddr = paddr;
  566. msm_audio_fd_data->plen = pa_len;
  567. msm_audio_fd_data->dev = ion_data->cb_dev;
  568. msm_audio_update_fd_list(msm_audio_fd_data);
  569. break;
  570. case IOCTL_UNMAP_PHYS_ADDR:
  571. msm_audio_get_handle((int)ioctl_param, &mem_handle);
  572. ret = msm_audio_ion_free(mem_handle, ion_data);
  573. if (ret < 0) {
  574. pr_err("%s Ion free failed %d\n", __func__, ret);
  575. return ret;
  576. }
  577. msm_audio_delete_fd_entry(mem_handle);
  578. break;
  579. case IOCTL_MAP_HYP_ASSIGN:
  580. ret = msm_audio_get_phy_addr((int)ioctl_param, &paddr, &pa_len);
  581. if (ret < 0) {
  582. pr_err("%s get phys addr failed %d\n", __func__, ret);
  583. return ret;
  584. }
  585. ret = hyp_assign_phys(paddr, pa_len, source_vm_map, 1,
  586. dest_vm_map, dest_perms_map, 2);
  587. if (ret < 0) {
  588. pr_err("%s: hyp_assign_phys failed result = %d addr = 0x%pK size = %d\n",
  589. __func__, ret, paddr, pa_len);
  590. return ret;
  591. }
  592. pr_err("%s: hyp_assign_phys success\n", __func__);
  593. break;
  594. case IOCTL_UNMAP_HYP_ASSIGN:
  595. ret = msm_audio_get_phy_addr((int)ioctl_param, &paddr, &pa_len);
  596. if (ret < 0) {
  597. pr_err("%s get phys addr failed %d\n", __func__, ret);
  598. return ret;
  599. }
  600. ret = hyp_assign_phys(paddr, pa_len, source_vm_unmap, 2,
  601. dest_vm_unmap, dest_perms_unmap, 1);
  602. if (ret < 0) {
  603. pr_err("%s: hyp_assign_phys failed result = %d addr = 0x%pK size = %d\n",
  604. __func__, ret, paddr, pa_len);
  605. return ret;
  606. }
  607. pr_err("%s: hyp_assign_phys success\n", __func__);
  608. break;
  609. default:
  610. pr_err("%s Entered default. Invalid ioctl num %u",
  611. __func__, ioctl_num);
  612. ret = -EINVAL;
  613. break;
  614. }
  615. return ret;
  616. }
  617. static const struct of_device_id msm_audio_ion_dt_match[] = {
  618. { .compatible = "qcom,msm-audio-ion" },
  619. { .compatible = "qcom,msm-audio-ion-cma"},
  620. { }
  621. };
  622. MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match);
  623. static const struct file_operations msm_audio_ion_fops = {
  624. .owner = THIS_MODULE,
  625. .open = msm_audio_ion_open,
  626. .release = msm_audio_ion_release,
  627. .unlocked_ioctl = msm_audio_ion_ioctl,
  628. };
  629. static int msm_audio_ion_reg_chrdev(struct msm_audio_ion_private *ion_data)
  630. {
  631. int ret = 0;
  632. ret = alloc_chrdev_region(&ion_data->ion_major, 0,
  633. MINOR_NUMBER_COUNT, ion_data->driver_name);
  634. if (ret < 0) {
  635. pr_err("%s alloc_chr_dev_region failed ret : %d\n",
  636. __func__, ret);
  637. return ret;
  638. }
  639. pr_debug("%s major number %d", __func__, MAJOR(ion_data->ion_major));
  640. ion_data->ion_class = class_create(THIS_MODULE,
  641. ion_data->driver_name);
  642. if (IS_ERR(ion_data->ion_class)) {
  643. ret = PTR_ERR(ion_data->ion_class);
  644. pr_err("%s class create failed. ret : %d", __func__, ret);
  645. goto err_class;
  646. }
  647. ion_data->chardev = device_create(ion_data->ion_class, NULL,
  648. ion_data->ion_major, NULL,
  649. ion_data->driver_name);
  650. if (IS_ERR(ion_data->chardev)) {
  651. ret = PTR_ERR(ion_data->chardev);
  652. pr_err("%s device create failed ret : %d\n", __func__, ret);
  653. goto err_device;
  654. }
  655. cdev_init(&ion_data->cdev, &msm_audio_ion_fops);
  656. ret = cdev_add(&ion_data->cdev, ion_data->ion_major, 1);
  657. if (ret) {
  658. pr_err("%s cdev add failed, ret : %d\n", __func__, ret);
  659. goto err_cdev;
  660. }
  661. return ret;
  662. err_cdev:
  663. device_destroy(ion_data->ion_class, ion_data->ion_major);
  664. err_device:
  665. class_destroy(ion_data->ion_class);
  666. err_class:
  667. unregister_chrdev_region(0, MINOR_NUMBER_COUNT);
  668. return ret;
  669. }
  670. static int msm_audio_ion_unreg_chrdev(struct msm_audio_ion_private *ion_data)
  671. {
  672. cdev_del(&ion_data->cdev);
  673. device_destroy(ion_data->ion_class, ion_data->ion_major);
  674. class_destroy(ion_data->ion_class);
  675. unregister_chrdev_region(0, MINOR_NUMBER_COUNT);
  676. return 0;
  677. }
  678. static int msm_audio_ion_probe(struct platform_device *pdev)
  679. {
  680. int rc = 0;
  681. u64 smmu_sid = 0;
  682. u64 smmu_sid_mask = 0;
  683. const char *msm_audio_ion_dt = "qcom,smmu-enabled";
  684. const char *msm_audio_ion_non_hyp = "qcom,non-hyp-assign";
  685. const char *msm_audio_ion_smmu = "qcom,smmu-version";
  686. const char *msm_audio_ion_smmu_sid_mask = "qcom,smmu-sid-mask";
  687. bool smmu_enabled;
  688. bool is_non_hypervisor_en;
  689. struct device *dev = &pdev->dev;
  690. struct of_phandle_args iommuspec;
  691. struct msm_audio_ion_private *msm_audio_ion_data = NULL;
  692. #ifndef CONFIG_SPF_CORE
  693. enum apr_subsys_state q6_state;
  694. #endif
  695. dev_err(dev, "%s: msm_audio_ion_probe\n", __func__);
  696. if (dev->of_node == NULL) {
  697. dev_err(dev,
  698. "%s: device tree is not found\n",
  699. __func__);
  700. return 0;
  701. }
  702. msm_audio_ion_data = devm_kzalloc(&pdev->dev, (sizeof(struct msm_audio_ion_private)),
  703. GFP_KERNEL);
  704. if (!msm_audio_ion_data)
  705. return -ENOMEM;
  706. is_non_hypervisor_en = of_property_read_bool(dev->of_node,
  707. msm_audio_ion_non_hyp);
  708. msm_audio_ion_data->is_non_hypervisor = is_non_hypervisor_en;
  709. smmu_enabled = of_property_read_bool(dev->of_node,
  710. msm_audio_ion_dt);
  711. msm_audio_ion_data->smmu_enabled = smmu_enabled;
  712. if (!smmu_enabled)
  713. dev_dbg(dev, "%s: SMMU is Disabled\n", __func__);
  714. #ifndef CONFIG_SPF_CORE
  715. q6_state = apr_get_q6_state();
  716. if (q6_state == APR_SUBSYS_DOWN) {
  717. dev_info(dev,
  718. "defering %s, adsp_state %d\n",
  719. __func__, q6_state);
  720. return -EPROBE_DEFER;
  721. }
  722. #endif
  723. dev_dbg(dev, "%s: adsp is ready\n", __func__);
  724. if (smmu_enabled) {
  725. msm_audio_ion_data->driver_name = "msm_audio_ion";
  726. rc = of_property_read_u32(dev->of_node,
  727. msm_audio_ion_smmu,
  728. &(msm_audio_ion_data->smmu_version));
  729. if (rc) {
  730. dev_err(dev,
  731. "%s: qcom,smmu_version missing in DT node\n",
  732. __func__);
  733. return rc;
  734. }
  735. dev_dbg(dev, "%s: SMMU is Enabled. SMMU version is (%d)",
  736. __func__, msm_audio_ion_data->smmu_version);
  737. /* Get SMMU SID information from Devicetree */
  738. rc = of_property_read_u64(dev->of_node,
  739. msm_audio_ion_smmu_sid_mask,
  740. &smmu_sid_mask);
  741. if (rc) {
  742. dev_err(dev,
  743. "%s: qcom,smmu-sid-mask missing in DT node, using default\n",
  744. __func__);
  745. smmu_sid_mask = 0xFFFFFFFFFFFFFFFF;
  746. }
  747. rc = of_parse_phandle_with_args(dev->of_node, "iommus",
  748. "#iommu-cells", 0, &iommuspec);
  749. if (rc)
  750. dev_err(dev, "%s: could not get smmu SID, ret = %d\n",
  751. __func__, rc);
  752. else
  753. smmu_sid = (iommuspec.args[0] & smmu_sid_mask);
  754. msm_audio_ion_data->smmu_sid_bits =
  755. smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET;
  756. } else {
  757. msm_audio_ion_data->driver_name = "msm_audio_ion_cma";
  758. }
  759. if (!rc)
  760. msm_audio_ion_data->device_status |= MSM_AUDIO_ION_PROBED;
  761. msm_audio_ion_data->cb_dev = dev;
  762. dev_set_drvdata(dev, msm_audio_ion_data);
  763. if (!msm_audio_ion_fd_list_init) {
  764. INIT_LIST_HEAD(&msm_audio_ion_fd_list.fd_list);
  765. mutex_init(&(msm_audio_ion_fd_list.list_mutex));
  766. msm_audio_ion_fd_list_init = true;
  767. }
  768. INIT_LIST_HEAD(&msm_audio_ion_data->alloc_list);
  769. mutex_init(&(msm_audio_ion_data->list_mutex));
  770. rc = msm_audio_ion_reg_chrdev(msm_audio_ion_data);
  771. if (rc) {
  772. pr_err("%s register char dev failed, rc : %d", __func__, rc);
  773. return rc;
  774. }
  775. return rc;
  776. }
  777. static int msm_audio_ion_remove(struct platform_device *pdev)
  778. {
  779. struct msm_audio_ion_private *ion_data = dev_get_drvdata(&pdev->dev);
  780. ion_data->smmu_enabled = 0;
  781. ion_data->device_status = 0;
  782. msm_audio_ion_unreg_chrdev(ion_data);
  783. return 0;
  784. }
  785. static struct platform_driver msm_audio_ion_driver = {
  786. .driver = {
  787. .name = "msm-audio-ion",
  788. .owner = THIS_MODULE,
  789. .of_match_table = msm_audio_ion_dt_match,
  790. .suppress_bind_attrs = true,
  791. },
  792. .probe = msm_audio_ion_probe,
  793. .remove = msm_audio_ion_remove,
  794. };
  795. int __init msm_audio_ion_init(void)
  796. {
  797. pr_debug("%s: msm_audio_ion_init called \n",__func__);
  798. return platform_driver_register(&msm_audio_ion_driver);
  799. }
  800. void msm_audio_ion_exit(void)
  801. {
  802. platform_driver_unregister(&msm_audio_ion_driver);
  803. }
  804. module_init(msm_audio_ion_init);
  805. module_exit(msm_audio_ion_exit);
  806. MODULE_DESCRIPTION("MSM Audio ION module");
  807. MODULE_LICENSE("GPL v2");