cam_sync_synx.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #include "cam_sync_synx.h"
  6. /**
  7. * struct cam_synx_obj_row - Synx obj row
  8. */
  9. struct cam_synx_obj_row {
  10. char name[CAM_SYNX_OBJ_NAME_LEN];
  11. uint32_t synx_obj;
  12. enum cam_synx_obj_state state;
  13. cam_sync_callback_for_synx_obj sync_cb;
  14. bool cb_registered_for_sync;
  15. bool sync_signal_synx;
  16. int32_t sync_obj;
  17. };
  18. /**
  19. * struct cam_synx_obj_device - Synx obj device
  20. */
  21. struct cam_synx_obj_device {
  22. struct cam_synx_obj_row rows[CAM_SYNX_MAX_OBJS];
  23. spinlock_t row_spinlocks[CAM_SYNX_MAX_OBJS];
  24. struct synx_session *session_handle;
  25. struct mutex dev_lock;
  26. DECLARE_BITMAP(bitmap, CAM_SYNX_MAX_OBJS);
  27. };
  28. static struct cam_synx_obj_device *g_cam_synx_obj_dev;
  29. static char cam_synx_session_name[64] = "Camera_Generic_Synx_Session";
  30. static int __cam_synx_obj_map_sync_status_util(uint32_t sync_status,
  31. uint32_t *out_synx_status)
  32. {
  33. if (!out_synx_status)
  34. return -EINVAL;
  35. switch (sync_status) {
  36. case CAM_SYNC_STATE_SIGNALED_SUCCESS:
  37. *out_synx_status = SYNX_STATE_SIGNALED_SUCCESS;
  38. break;
  39. case CAM_SYNC_STATE_SIGNALED_CANCEL:
  40. default:
  41. *out_synx_status = SYNX_STATE_SIGNALED_CANCEL;
  42. break;
  43. }
  44. return 0;
  45. }
  46. static int __cam_synx_obj_release(int32_t row_idx)
  47. {
  48. struct cam_synx_obj_row *row = NULL;
  49. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  50. row = &g_cam_synx_obj_dev->rows[row_idx];
  51. if (row->state == CAM_SYNX_OBJ_STATE_ACTIVE) {
  52. CAM_WARN(CAM_SYNX,
  53. "Unsignaled synx obj being released name: %s synx_obj:%d",
  54. row->name, row->synx_obj);
  55. synx_signal(g_cam_synx_obj_dev->session_handle, row->synx_obj,
  56. SYNX_STATE_SIGNALED_CANCEL);
  57. }
  58. CAM_DBG(CAM_SYNX,
  59. "Releasing synx_obj: %d[%s] row_idx: %u",
  60. row->synx_obj, row->name, row_idx);
  61. synx_release(g_cam_synx_obj_dev->session_handle, row->synx_obj);
  62. /* deinit row */
  63. memset(row, 0, sizeof(struct cam_synx_obj_row));
  64. clear_bit(row_idx, g_cam_synx_obj_dev->bitmap);
  65. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  66. return 0;
  67. }
  68. static int __cam_synx_obj_find_free_idx(uint32_t *idx)
  69. {
  70. int rc = 0;
  71. *idx = find_first_zero_bit(g_cam_synx_obj_dev->bitmap, CAM_SYNX_MAX_OBJS);
  72. if (*idx < CAM_SYNX_MAX_OBJS)
  73. set_bit(*idx, g_cam_synx_obj_dev->bitmap);
  74. else
  75. rc = -ENOMEM;
  76. if (rc)
  77. CAM_ERR(CAM_SYNX, "No free synx idx");
  78. return rc;
  79. }
  80. static void __cam_synx_obj_init_row(uint32_t idx, const char *name,
  81. uint32_t synx_obj)
  82. {
  83. struct cam_synx_obj_row *row;
  84. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  85. row = &g_cam_synx_obj_dev->rows[idx];
  86. memset(row, 0, sizeof(*row));
  87. row->synx_obj = synx_obj;
  88. row->state = CAM_SYNX_OBJ_STATE_ACTIVE;
  89. strscpy(row->name, name, CAM_SYNX_OBJ_NAME_LEN);
  90. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  91. }
  92. static int __cam_synx_obj_release_row(int32_t row_idx)
  93. {
  94. if ((row_idx < 0) || (row_idx >= CAM_SYNX_MAX_OBJS)) {
  95. CAM_ERR(CAM_SYNX, "synx row idx: %d is invalid",
  96. row_idx);
  97. return -EINVAL;
  98. }
  99. return __cam_synx_obj_release(row_idx);
  100. }
  101. static void __cam_synx_obj_signal_cb(u32 h_synx, int status, void *data)
  102. {
  103. struct cam_synx_obj_signal_sync_obj signal_sync_obj;
  104. struct cam_synx_obj_row *synx_obj_row = NULL;
  105. if (!data) {
  106. CAM_ERR(CAM_SYNX,
  107. "Invalid data passed to synx obj : %d callback function.",
  108. synx_obj_row->synx_obj);
  109. return;
  110. }
  111. synx_obj_row = (struct cam_synx_obj_row *)data;
  112. /* If this synx obj is signaled by sync obj, skip cb */
  113. if (synx_obj_row->sync_signal_synx)
  114. return;
  115. if (synx_obj_row->synx_obj != h_synx) {
  116. CAM_ERR(CAM_SYNX,
  117. "Synx obj: %d callback does not match synx obj: %d in sync table.",
  118. h_synx, synx_obj_row->synx_obj);
  119. return;
  120. }
  121. if (synx_obj_row->state == CAM_SYNX_OBJ_STATE_INVALID) {
  122. CAM_ERR(CAM_SYNX,
  123. "Synx obj :%d is in invalid state: %d",
  124. synx_obj_row->synx_obj, synx_obj_row->state);
  125. return;
  126. }
  127. CAM_DBG(CAM_SYNX, "Synx obj: %d signaled, signal sync obj: %d",
  128. synx_obj_row->synx_obj, synx_obj_row->sync_obj);
  129. if ((synx_obj_row->cb_registered_for_sync) && (synx_obj_row->sync_cb)) {
  130. signal_sync_obj.synx_obj = synx_obj_row->synx_obj;
  131. switch (status) {
  132. case SYNX_STATE_SIGNALED_SUCCESS:
  133. signal_sync_obj.status = CAM_SYNC_STATE_SIGNALED_SUCCESS;
  134. break;
  135. case SYNX_STATE_SIGNALED_CANCEL:
  136. signal_sync_obj.status = CAM_SYNC_STATE_SIGNALED_CANCEL;
  137. break;
  138. default:
  139. CAM_WARN(CAM_SYNX,
  140. "Synx signal status %d is neither SUCCESS nor CANCEL, custom code?",
  141. status);
  142. signal_sync_obj.status = CAM_SYNC_STATE_SIGNALED_ERROR;
  143. break;
  144. }
  145. synx_obj_row->state = CAM_SYNX_OBJ_STATE_SIGNALED;
  146. synx_obj_row->sync_cb(synx_obj_row->sync_obj, &signal_sync_obj);
  147. }
  148. }
  149. int cam_synx_obj_find_obj_in_table(uint32_t synx_obj, int32_t *idx)
  150. {
  151. int i, rc = -EINVAL;
  152. struct cam_synx_obj_row *row = NULL;
  153. for (i = 0; i < CAM_SYNX_MAX_OBJS; i++) {
  154. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[i]);
  155. row = &g_cam_synx_obj_dev->rows[i];
  156. if ((row->state != CAM_SYNX_OBJ_STATE_INVALID) &&
  157. (row->synx_obj == synx_obj)) {
  158. *idx = i;
  159. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[i]);
  160. rc = 0;
  161. break;
  162. }
  163. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[i]);
  164. }
  165. return rc;
  166. }
  167. static int __cam_synx_obj_release_obj(uint32_t synx_obj)
  168. {
  169. int32_t idx;
  170. if (cam_synx_obj_find_obj_in_table(synx_obj, &idx)) {
  171. CAM_ERR(CAM_SYNX, "Failed to find synx obj: %d", synx_obj);
  172. return -EINVAL;
  173. }
  174. return __cam_synx_obj_release(idx);
  175. }
  176. static int __cam_synx_obj_import(const char *name,
  177. struct synx_import_params *params, int32_t *row_idx)
  178. {
  179. int rc = -1;
  180. uint32_t idx;
  181. if (__cam_synx_obj_find_free_idx(&idx))
  182. goto end;
  183. rc = synx_import(g_cam_synx_obj_dev->session_handle, params);
  184. if (rc) {
  185. CAM_ERR(CAM_SYNX, "Synx import failed for fence : %p",
  186. params->indv.fence);
  187. goto free_idx;
  188. }
  189. *row_idx = idx;
  190. __cam_synx_obj_init_row(idx, name, *params->indv.new_h_synx);
  191. CAM_DBG(CAM_SYNX, "Imported synx obj handle: %d[%s] row_idx: %u",
  192. *params->indv.new_h_synx, name, idx);
  193. return rc;
  194. free_idx:
  195. clear_bit(idx, g_cam_synx_obj_dev->bitmap);
  196. end:
  197. return rc;
  198. }
  199. static int __cam_synx_map_generic_flags_to_create(uint32_t generic_flags,
  200. struct synx_create_params *params)
  201. {
  202. if (!params) {
  203. CAM_ERR(CAM_SYNX, "Create parameters missing");
  204. return -EINVAL;
  205. }
  206. /*
  207. * Create Global Always - remove after userspace optimizes and
  208. * determines when global Vs local is needed
  209. */
  210. params->flags |= SYNX_CREATE_GLOBAL_FENCE;
  211. return 0;
  212. }
  213. static int __cam_synx_map_generic_flags_to_import(uint32_t generic_flags,
  214. struct synx_import_indv_params *params)
  215. {
  216. if (!params) {
  217. CAM_ERR(CAM_SYNX, "Import parameters missing");
  218. return -EINVAL;
  219. }
  220. /*
  221. * Create Global Always - remove after userspace optimizes and
  222. * determines when global Vs local is needed
  223. */
  224. params->flags |= SYNX_IMPORT_GLOBAL_FENCE;
  225. return 0;
  226. }
  227. int cam_synx_obj_create(const char *name, uint32_t flags, uint32_t *synx_obj,
  228. int32_t *row_idx)
  229. {
  230. int rc = -1;
  231. uint32_t idx;
  232. struct synx_create_params params;
  233. if (__cam_synx_obj_find_free_idx(&idx))
  234. goto end;
  235. params.fence = NULL;
  236. params.name = name;
  237. params.flags = 0;
  238. params.h_synx = synx_obj;
  239. rc = __cam_synx_map_generic_flags_to_create(flags, &params);
  240. if (rc) {
  241. CAM_ERR(CAM_SYNX, "Failed to generate create flags");
  242. goto free_idx;
  243. }
  244. rc = synx_create(g_cam_synx_obj_dev->session_handle, &params);
  245. if (rc) {
  246. CAM_ERR(CAM_SYNX, "Failed to create synx obj");
  247. goto free_idx;
  248. }
  249. *row_idx = idx;
  250. __cam_synx_obj_init_row(idx, name, *synx_obj);
  251. CAM_DBG(CAM_SYNX, "Created synx obj handle: %d[%s] row_idx: %u",
  252. *synx_obj, name, idx);
  253. return rc;
  254. free_idx:
  255. clear_bit(idx, g_cam_synx_obj_dev->bitmap);
  256. end:
  257. return rc;
  258. }
  259. int cam_synx_obj_import_dma_fence(const char *name, uint32_t flags, void *fence,
  260. uint32_t *synx_obj, int32_t *row_idx)
  261. {
  262. struct synx_import_params params;
  263. if (!fence) {
  264. CAM_ERR(CAM_SYNX,
  265. "Importing DMA fence failed - fence pointer is NULL");
  266. return -EINVAL;
  267. }
  268. params.indv.flags = 0;
  269. params.indv.fence = fence;
  270. params.indv.new_h_synx = synx_obj;
  271. params.type = SYNX_IMPORT_INDV_PARAMS;
  272. params.indv.flags |= SYNX_IMPORT_DMA_FENCE;
  273. if (__cam_synx_map_generic_flags_to_import(flags, &params.indv)) {
  274. CAM_ERR(CAM_SYNX,
  275. "Importing DMA fence failed - invalid synx import flags");
  276. return -EINVAL;
  277. }
  278. return __cam_synx_obj_import(name, &params, row_idx);
  279. }
  280. int cam_synx_obj_internal_signal(int32_t row_idx,
  281. struct cam_synx_obj_signal *signal_synx_obj)
  282. {
  283. int rc = 0;
  284. uint32_t signal_status;
  285. struct cam_synx_obj_row *row = NULL;
  286. if ((row_idx < 0) || (row_idx >= CAM_SYNX_MAX_OBJS)) {
  287. CAM_ERR(CAM_SYNX, "synx obj row idx: %d is invalid",
  288. row_idx);
  289. return -EINVAL;
  290. }
  291. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  292. row = &g_cam_synx_obj_dev->rows[row_idx];
  293. /* Ensures sync obj cb is not invoked */
  294. row->sync_signal_synx = true;
  295. if (row->state == CAM_SYNX_OBJ_STATE_SIGNALED) {
  296. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  297. CAM_WARN(CAM_SYNX, "synx obj fd: %d already in signaled state",
  298. signal_synx_obj->synx_obj);
  299. return 0;
  300. }
  301. rc = __cam_synx_obj_map_sync_status_util(signal_synx_obj->status,
  302. &signal_status);
  303. if (rc) {
  304. CAM_WARN(CAM_SYNX,
  305. "Signaling undefined status: %d for synx obj: %d",
  306. signal_synx_obj->status,
  307. signal_synx_obj->synx_obj);
  308. }
  309. rc = synx_signal(g_cam_synx_obj_dev->session_handle,
  310. signal_synx_obj->synx_obj, signal_status);
  311. if (rc)
  312. CAM_WARN(CAM_SYNX, "synx obj: %d already signaled rc: %d",
  313. row->synx_obj, rc);
  314. row->state = CAM_SYNX_OBJ_STATE_SIGNALED;
  315. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  316. CAM_DBG(CAM_SYNX, "synx obj: %d signaled with status: %d rc: %d",
  317. signal_synx_obj->synx_obj, signal_status, rc);
  318. return rc;
  319. }
  320. int cam_synx_obj_release(struct cam_synx_obj_release_params *release_params)
  321. {
  322. if (release_params->use_row_idx)
  323. return __cam_synx_obj_release_row(release_params->u.synx_row_idx);
  324. else
  325. return __cam_synx_obj_release_obj(release_params->u.synx_obj);
  326. }
  327. int cam_synx_obj_signal_obj(struct cam_synx_obj_signal *signal_synx_obj)
  328. {
  329. int rc = 0;
  330. uint32_t idx, signal_status = 0;
  331. struct cam_synx_obj_row *row = NULL;
  332. rc = cam_synx_obj_find_obj_in_table(
  333. signal_synx_obj->synx_obj, &idx);
  334. if (rc) {
  335. CAM_ERR(CAM_SYNX, "Failed to find synx obj: %d",
  336. signal_synx_obj->synx_obj);
  337. return -EINVAL;
  338. }
  339. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  340. row = &g_cam_synx_obj_dev->rows[idx];
  341. if (row->state == CAM_SYNX_OBJ_STATE_SIGNALED) {
  342. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  343. CAM_WARN(CAM_SYNX, "synx obj: %d already in signaled state",
  344. signal_synx_obj->synx_obj);
  345. return 0;
  346. }
  347. rc = __cam_synx_obj_map_sync_status_util(signal_synx_obj->status,
  348. &signal_status);
  349. if (rc) {
  350. CAM_WARN(CAM_SYNX,
  351. "Signaling undefined sync status: %d for synx obj: %d",
  352. signal_synx_obj->status,
  353. signal_synx_obj->synx_obj);
  354. }
  355. rc = synx_signal(g_cam_synx_obj_dev->session_handle,
  356. signal_synx_obj->synx_obj, signal_status);
  357. if (rc)
  358. CAM_WARN(CAM_SYNX, "synx obj: %d already signaled rc: %d",
  359. row->synx_obj, rc);
  360. row->state = CAM_SYNX_OBJ_STATE_SIGNALED;
  361. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[idx]);
  362. CAM_DBG(CAM_SYNX, "synx obj: %d signaled with status: %d rc: %d",
  363. signal_synx_obj->synx_obj, signal_status, rc);
  364. return rc;
  365. }
  366. int cam_synx_obj_register_cb(int32_t *sync_obj, int32_t row_idx,
  367. cam_sync_callback_for_synx_obj sync_cb)
  368. {
  369. int rc = 0;
  370. struct cam_synx_obj_row *row = NULL;
  371. struct synx_callback_params cb_params;
  372. if (!sync_obj || !sync_cb) {
  373. CAM_ERR(CAM_SYNX, "Invalid args sync_obj: %p sync_cb: %p",
  374. sync_obj, sync_cb);
  375. return -EINVAL;
  376. }
  377. if ((row_idx < 0) || (row_idx >= CAM_SYNX_MAX_OBJS)) {
  378. CAM_ERR(CAM_SYNX, "synx obj idx: %d is invalid",
  379. row_idx);
  380. return -EINVAL;
  381. }
  382. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  383. row = &g_cam_synx_obj_dev->rows[row_idx];
  384. if (row->state != CAM_SYNX_OBJ_STATE_ACTIVE) {
  385. CAM_ERR(CAM_SYNX,
  386. "synx obj at idx: %d handle: %d is not active, current state: %d",
  387. row_idx, row->synx_obj, row->state);
  388. rc = -EINVAL;
  389. goto end;
  390. }
  391. /**
  392. * If the cb is already registered, return
  393. */
  394. if (row->cb_registered_for_sync) {
  395. CAM_WARN(CAM_SYNX,
  396. "synx obj at idx: %d handle: %d has already registered a cb for sync: %d",
  397. row_idx, row->synx_obj, row->sync_obj);
  398. goto end;
  399. }
  400. cb_params.userdata = row;
  401. cb_params.cancel_cb_func = NULL;
  402. cb_params.h_synx = row->synx_obj;
  403. cb_params.cb_func = __cam_synx_obj_signal_cb;
  404. rc = synx_async_wait(g_cam_synx_obj_dev->session_handle, &cb_params);
  405. if (rc) {
  406. CAM_ERR(CAM_SYNX,
  407. "Failed to register cb for synx obj: %d rc: %d",
  408. row->synx_obj, rc);
  409. goto end;
  410. }
  411. row->sync_cb = sync_cb;
  412. row->sync_obj = *sync_obj;
  413. row->cb_registered_for_sync = true;
  414. CAM_DBG(CAM_SYNX,
  415. "CB successfully registered for synx obj: %d for sync_obj: %d",
  416. row->synx_obj, *sync_obj);
  417. end:
  418. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[row_idx]);
  419. return rc;
  420. }
  421. int __cam_synx_init_session(void)
  422. {
  423. struct synx_queue_desc queue_desc;
  424. struct synx_initialization_params params;
  425. params.name = cam_synx_session_name;
  426. params.ptr = &queue_desc;
  427. params.flags = SYNX_INIT_MAX;
  428. params.id = SYNX_CLIENT_NATIVE;
  429. g_cam_synx_obj_dev->session_handle = synx_initialize(&params);
  430. if (!g_cam_synx_obj_dev->session_handle) {
  431. CAM_ERR(CAM_SYNX, "Synx session initialization failed");
  432. return -EINVAL;
  433. }
  434. CAM_DBG(CAM_SYNX, "Synx session initialized: %p",
  435. g_cam_synx_obj_dev->session_handle);
  436. return 0;
  437. }
  438. void cam_synx_obj_close(void)
  439. {
  440. int i, rc = 0;
  441. struct cam_synx_obj_row *row = NULL;
  442. struct synx_callback_params cb_params;
  443. mutex_lock(&g_cam_synx_obj_dev->dev_lock);
  444. for (i = 0; i < CAM_SYNX_MAX_OBJS; i++) {
  445. spin_lock_bh(&g_cam_synx_obj_dev->row_spinlocks[i]);
  446. row = &g_cam_synx_obj_dev->rows[i];
  447. if (row->state == CAM_SYNX_OBJ_STATE_INVALID) {
  448. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[i]);
  449. continue;
  450. }
  451. CAM_DBG(CAM_SYNX, "Releasing synx_obj: %d[%s]",
  452. row->synx_obj, row->name);
  453. /* If registered for cb, remove cb */
  454. if (row->cb_registered_for_sync) {
  455. cb_params.userdata = row;
  456. cb_params.cancel_cb_func = NULL;
  457. cb_params.h_synx = row->synx_obj;
  458. cb_params.cb_func = __cam_synx_obj_signal_cb;
  459. rc = synx_cancel_async_wait(
  460. g_cam_synx_obj_dev->session_handle,
  461. &cb_params);
  462. if (rc) {
  463. CAM_WARN(CAM_SYNX,
  464. "Registered callback could not be canceled for synx obj : %d",
  465. cb_params.h_synx);
  466. }
  467. }
  468. /* Signal and release the synx obj */
  469. if (row->state != CAM_SYNX_OBJ_STATE_SIGNALED)
  470. synx_signal(g_cam_synx_obj_dev->session_handle,
  471. row->synx_obj, SYNX_STATE_SIGNALED_CANCEL);
  472. synx_release(g_cam_synx_obj_dev->session_handle,
  473. row->synx_obj);
  474. memset(row, 0, sizeof(struct cam_synx_obj_row));
  475. clear_bit(i, g_cam_synx_obj_dev->bitmap);
  476. spin_unlock_bh(&g_cam_synx_obj_dev->row_spinlocks[i]);
  477. }
  478. mutex_unlock(&g_cam_synx_obj_dev->dev_lock);
  479. CAM_DBG(CAM_SYNX, "Close on Camera SYNX driver");
  480. }
  481. int cam_synx_obj_driver_init(void)
  482. {
  483. int i;
  484. g_cam_synx_obj_dev = kzalloc(sizeof(struct cam_synx_obj_device), GFP_KERNEL);
  485. if (!g_cam_synx_obj_dev)
  486. return -ENOMEM;
  487. if (__cam_synx_init_session())
  488. goto deinit_driver;
  489. mutex_init(&g_cam_synx_obj_dev->dev_lock);
  490. for (i = 0; i < CAM_SYNX_MAX_OBJS; i++)
  491. spin_lock_init(&g_cam_synx_obj_dev->row_spinlocks[i]);
  492. memset(&g_cam_synx_obj_dev->rows, 0, sizeof(g_cam_synx_obj_dev->rows));
  493. memset(&g_cam_synx_obj_dev->bitmap, 0, sizeof(g_cam_synx_obj_dev->bitmap));
  494. bitmap_zero(g_cam_synx_obj_dev->bitmap, CAM_SYNX_MAX_OBJS);
  495. CAM_DBG(CAM_SYNX, "Camera synx obj driver initialized");
  496. return 0;
  497. deinit_driver:
  498. CAM_ERR(CAM_SYNX, "Camera synx obj driver initialization failed");
  499. kfree(g_cam_synx_obj_dev);
  500. g_cam_synx_obj_dev = NULL;
  501. return -EINVAL;
  502. }
  503. void cam_synx_obj_driver_deinit(void)
  504. {
  505. int rc;
  506. if (g_cam_synx_obj_dev->session_handle) {
  507. rc = synx_uninitialize(g_cam_synx_obj_dev->session_handle);
  508. if (rc) {
  509. CAM_ERR(CAM_SYNX,
  510. "Synx failed to uninitialize session: %p, rc: %d",
  511. g_cam_synx_obj_dev->session_handle, rc);
  512. }
  513. }
  514. kfree(g_cam_synx_obj_dev);
  515. g_cam_synx_obj_dev = NULL;
  516. CAM_DBG(CAM_SYNX, "Camera synx obj driver deinitialized");
  517. }