msm_audio_ion.c 24 KB

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