cam_lrme_dev.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/device.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/slab.h>
  9. #include <linux/module.h>
  10. #include <linux/kernel.h>
  11. #include "cam_subdev.h"
  12. #include "cam_node.h"
  13. #include "cam_lrme_context.h"
  14. #include "cam_lrme_hw_mgr.h"
  15. #include "cam_lrme_hw_mgr_intf.h"
  16. #include "camera_main.h"
  17. #define CAM_LRME_DEV_NAME "cam-lrme"
  18. /**
  19. * struct cam_lrme_dev
  20. *
  21. * @sd : Subdev information
  22. * @ctx : List of base contexts
  23. * @lrme_ctx : List of LRME contexts
  24. * @lock : Mutex for LRME subdev
  25. * @open_cnt : Open count of LRME subdev
  26. */
  27. struct cam_lrme_dev {
  28. struct cam_subdev sd;
  29. struct cam_context ctx[CAM_CTX_MAX];
  30. struct cam_lrme_context lrme_ctx[CAM_CTX_MAX];
  31. struct mutex lock;
  32. uint32_t open_cnt;
  33. };
  34. static struct cam_lrme_dev *g_lrme_dev;
  35. static int cam_lrme_dev_buf_done_cb(void *ctxt_to_hw_map, uint32_t evt_id,
  36. void *evt_data)
  37. {
  38. uint64_t index;
  39. struct cam_context *ctx;
  40. int rc;
  41. index = CAM_LRME_DECODE_CTX_INDEX(ctxt_to_hw_map);
  42. CAM_DBG(CAM_LRME, "ctx index %llu, evt_id %u\n", index, evt_id);
  43. ctx = &g_lrme_dev->ctx[index];
  44. rc = ctx->irq_cb_intf(ctx, evt_id, evt_data);
  45. if (rc)
  46. CAM_ERR(CAM_LRME, "irq callback failed");
  47. return rc;
  48. }
  49. static int cam_lrme_dev_open(struct v4l2_subdev *sd,
  50. struct v4l2_subdev_fh *fh)
  51. {
  52. struct cam_lrme_dev *lrme_dev = g_lrme_dev;
  53. cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);
  54. if (!lrme_dev) {
  55. CAM_ERR(CAM_LRME,
  56. "LRME Dev not initialized, dev=%pK", lrme_dev);
  57. cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
  58. return -ENODEV;
  59. }
  60. mutex_lock(&lrme_dev->lock);
  61. lrme_dev->open_cnt++;
  62. mutex_unlock(&lrme_dev->lock);
  63. cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
  64. return 0;
  65. }
  66. static int cam_lrme_dev_close_internal(struct v4l2_subdev *sd,
  67. struct v4l2_subdev_fh *fh)
  68. {
  69. int rc = 0;
  70. struct cam_lrme_dev *lrme_dev = g_lrme_dev;
  71. struct cam_node *node = v4l2_get_subdevdata(sd);
  72. if (!lrme_dev) {
  73. CAM_ERR(CAM_LRME, "Invalid args");
  74. return -ENODEV;
  75. }
  76. mutex_lock(&lrme_dev->lock);
  77. if (lrme_dev->open_cnt <= 0) {
  78. CAM_DBG(CAM_LRME, "LRME subdev is already closed");
  79. rc = -EINVAL;
  80. goto end;
  81. }
  82. lrme_dev->open_cnt--;
  83. if (!node) {
  84. CAM_ERR(CAM_LRME, "Node is NULL");
  85. rc = -EINVAL;
  86. goto end;
  87. }
  88. if (lrme_dev->open_cnt == 0)
  89. cam_node_shutdown(node);
  90. end:
  91. mutex_unlock(&lrme_dev->lock);
  92. return rc;
  93. }
  94. static int cam_lrme_dev_close(struct v4l2_subdev *sd,
  95. struct v4l2_subdev_fh *fh)
  96. {
  97. bool crm_active = cam_req_mgr_is_open();
  98. if (crm_active) {
  99. CAM_DBG(CAM_LRME, "CRM is ACTIVE, close should be from CRM");
  100. return 0;
  101. }
  102. return cam_lrme_dev_close_internal(sd, fh);
  103. }
  104. static const struct v4l2_subdev_internal_ops cam_lrme_subdev_internal_ops = {
  105. .open = cam_lrme_dev_open,
  106. .close = cam_lrme_dev_close,
  107. };
  108. static int cam_lrme_component_bind(struct device *dev,
  109. struct device *master_dev, void *data)
  110. {
  111. int rc;
  112. int i;
  113. struct cam_hw_mgr_intf hw_mgr_intf;
  114. struct cam_node *node;
  115. struct platform_device *pdev = to_platform_device(dev);
  116. g_lrme_dev = kzalloc(sizeof(struct cam_lrme_dev), GFP_KERNEL);
  117. if (!g_lrme_dev) {
  118. CAM_ERR(CAM_LRME, "No memory");
  119. return -ENOMEM;
  120. }
  121. g_lrme_dev->sd.internal_ops = &cam_lrme_subdev_internal_ops;
  122. g_lrme_dev->sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
  123. mutex_init(&g_lrme_dev->lock);
  124. rc = cam_subdev_probe(&g_lrme_dev->sd, pdev, CAM_LRME_DEV_NAME,
  125. CAM_LRME_DEVICE_TYPE);
  126. if (rc) {
  127. CAM_ERR(CAM_LRME, "LRME cam_subdev_probe failed");
  128. goto free_mem;
  129. }
  130. node = (struct cam_node *)g_lrme_dev->sd.token;
  131. rc = cam_lrme_hw_mgr_init(&hw_mgr_intf, cam_lrme_dev_buf_done_cb);
  132. if (rc) {
  133. CAM_ERR(CAM_LRME, "Can not initialized LRME HW manager");
  134. goto unregister;
  135. }
  136. for (i = 0; i < CAM_CTX_MAX; i++) {
  137. rc = cam_lrme_context_init(&g_lrme_dev->lrme_ctx[i],
  138. &g_lrme_dev->ctx[i],
  139. &node->hw_mgr_intf, i, -1);
  140. if (rc) {
  141. CAM_ERR(CAM_LRME, "LRME context init failed");
  142. goto deinit_ctx;
  143. }
  144. }
  145. rc = cam_node_init(node, &hw_mgr_intf, g_lrme_dev->ctx, CAM_CTX_MAX,
  146. CAM_LRME_DEV_NAME);
  147. if (rc) {
  148. CAM_ERR(CAM_LRME, "LRME node init failed");
  149. goto deinit_ctx;
  150. }
  151. node->sd_handler = cam_lrme_dev_close_internal;
  152. CAM_DBG(CAM_LRME, "Component bound successfully");
  153. return 0;
  154. deinit_ctx:
  155. for (--i; i >= 0; i--) {
  156. if (cam_lrme_context_deinit(&g_lrme_dev->lrme_ctx[i]))
  157. CAM_ERR(CAM_LRME, "LRME context %d deinit failed", i);
  158. }
  159. unregister:
  160. if (cam_subdev_remove(&g_lrme_dev->sd))
  161. CAM_ERR(CAM_LRME, "Failed in subdev remove");
  162. free_mem:
  163. kfree(g_lrme_dev);
  164. return rc;
  165. }
  166. static void cam_lrme_component_unbind(struct device *dev,
  167. struct device *master_dev, void *data)
  168. {
  169. int i;
  170. int rc = 0;
  171. for (i = 0; i < CAM_CTX_MAX; i++) {
  172. rc = cam_lrme_context_deinit(&g_lrme_dev->lrme_ctx[i]);
  173. if (rc)
  174. CAM_ERR(CAM_LRME, "LRME context %d deinit failed", i);
  175. }
  176. rc = cam_lrme_hw_mgr_deinit();
  177. if (rc)
  178. CAM_ERR(CAM_LRME, "Failed in hw mgr deinit, rc=%d", rc);
  179. rc = cam_subdev_remove(&g_lrme_dev->sd);
  180. if (rc)
  181. CAM_ERR(CAM_LRME, "Unregister failed rc: %d", rc);
  182. mutex_destroy(&g_lrme_dev->lock);
  183. kfree(g_lrme_dev);
  184. g_lrme_dev = NULL;
  185. }
  186. const static struct component_ops cam_lrme_component_ops = {
  187. .bind = cam_lrme_component_bind,
  188. .unbind = cam_lrme_component_unbind,
  189. };
  190. static int cam_lrme_dev_probe(struct platform_device *pdev)
  191. {
  192. int rc = 0;
  193. CAM_DBG(CAM_LRME, "Adding LRME component");
  194. rc = component_add(&pdev->dev, &cam_lrme_component_ops);
  195. if (rc)
  196. CAM_ERR(CAM_LRME, "failed to add component rc: %d", rc);
  197. return rc;
  198. }
  199. static int cam_lrme_dev_remove(struct platform_device *pdev)
  200. {
  201. component_del(&pdev->dev, &cam_lrme_component_ops);
  202. return 0;
  203. }
  204. static const struct of_device_id cam_lrme_dt_match[] = {
  205. {
  206. .compatible = "qcom,cam-lrme"
  207. },
  208. {}
  209. };
  210. struct platform_driver cam_lrme_driver = {
  211. .probe = cam_lrme_dev_probe,
  212. .remove = cam_lrme_dev_remove,
  213. .driver = {
  214. .name = "cam_lrme",
  215. .owner = THIS_MODULE,
  216. .of_match_table = cam_lrme_dt_match,
  217. .suppress_bind_attrs = true,
  218. },
  219. };
  220. int cam_lrme_dev_init_module(void)
  221. {
  222. return platform_driver_register(&cam_lrme_driver);
  223. }
  224. void cam_lrme_dev_exit_module(void)
  225. {
  226. platform_driver_unregister(&cam_lrme_driver);
  227. }
  228. MODULE_DESCRIPTION("MSM LRME driver");
  229. MODULE_LICENSE("GPL v2");