blob: 9a93feba1ac5afbf68a4c981d6b8e9ec00abd21f [file] [log] [blame]
Venkat Chinta686c9e52018-01-20 14:33:25 -08001/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -08002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -080013#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/platform_device.h>
16#include <media/v4l2-fh.h>
17#include <media/v4l2-device.h>
18#include <media/v4l2-event.h>
19#include <media/v4l2-ioctl.h>
20#include <media/cam_req_mgr.h>
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -070021#include <media/cam_defs.h>
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -080022#include "cam_req_mgr_dev.h"
Sagar Gore8d91a622017-02-23 14:57:18 -080023#include "cam_req_mgr_util.h"
24#include "cam_req_mgr_core.h"
Jing Zhou076a3092017-02-27 02:43:03 -080025#include "cam_subdev.h"
Seemanta Dutta1c827da2017-04-05 17:34:05 -070026#include "cam_mem_mgr.h"
Jigarkumar Zala36ad7172017-07-18 19:52:14 -070027#include "cam_debug_util.h"
Venkat Chinta686c9e52018-01-20 14:33:25 -080028#include <linux/slub_def.h>
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -080029
30#define CAM_REQ_MGR_EVENT_MAX 30
31
32static struct cam_req_mgr_device g_dev;
Venkat Chinta686c9e52018-01-20 14:33:25 -080033struct kmem_cache *g_cam_req_mgr_timer_cachep;
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -080034
35static int cam_media_device_setup(struct device *dev)
36{
37 int rc;
38
39 g_dev.v4l2_dev->mdev = kzalloc(sizeof(*g_dev.v4l2_dev->mdev),
40 GFP_KERNEL);
41 if (!g_dev.v4l2_dev->mdev) {
42 rc = -ENOMEM;
43 goto mdev_fail;
44 }
45
46 media_device_init(g_dev.v4l2_dev->mdev);
47 g_dev.v4l2_dev->mdev->dev = dev;
48 strlcpy(g_dev.v4l2_dev->mdev->model, CAM_REQ_MGR_VNODE_NAME,
49 sizeof(g_dev.v4l2_dev->mdev->model));
50
51 rc = media_device_register(g_dev.v4l2_dev->mdev);
52 if (rc)
53 goto media_fail;
54
55 return rc;
56
57media_fail:
58 kfree(g_dev.v4l2_dev->mdev);
59 g_dev.v4l2_dev->mdev = NULL;
60mdev_fail:
61 return rc;
62}
63
64static void cam_media_device_cleanup(void)
65{
66 media_entity_cleanup(&g_dev.video->entity);
67 media_device_unregister(g_dev.v4l2_dev->mdev);
68 kfree(g_dev.v4l2_dev->mdev);
69 g_dev.v4l2_dev->mdev = NULL;
70}
71
72static int cam_v4l2_device_setup(struct device *dev)
73{
74 int rc;
75
76 g_dev.v4l2_dev = kzalloc(sizeof(*g_dev.v4l2_dev),
77 GFP_KERNEL);
78 if (!g_dev.v4l2_dev)
79 return -ENOMEM;
80
81 rc = v4l2_device_register(dev, g_dev.v4l2_dev);
82 if (rc)
83 goto reg_fail;
84
85 return rc;
86
87reg_fail:
88 kfree(g_dev.v4l2_dev);
89 g_dev.v4l2_dev = NULL;
90 return rc;
91}
92
93static void cam_v4l2_device_cleanup(void)
94{
95 v4l2_device_unregister(g_dev.v4l2_dev);
96 kfree(g_dev.v4l2_dev);
97 g_dev.v4l2_dev = NULL;
98}
99
Sagar Gore8d91a622017-02-23 14:57:18 -0800100static int cam_req_mgr_open(struct file *filep)
101{
102 int rc;
103
104 mutex_lock(&g_dev.cam_lock);
105 if (g_dev.open_cnt >= 1) {
106 rc = -EALREADY;
107 goto end;
108 }
109
110 rc = v4l2_fh_open(filep);
111 if (rc) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700112 CAM_ERR(CAM_CRM, "v4l2_fh_open failed: %d", rc);
Sagar Gore8d91a622017-02-23 14:57:18 -0800113 goto end;
114 }
115
116 spin_lock_bh(&g_dev.cam_eventq_lock);
117 g_dev.cam_eventq = filep->private_data;
118 spin_unlock_bh(&g_dev.cam_eventq_lock);
119
120 g_dev.open_cnt++;
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700121 rc = cam_mem_mgr_init();
122 if (rc) {
123 g_dev.open_cnt--;
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700124 CAM_ERR(CAM_CRM, "mem mgr init failed");
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700125 goto mem_mgr_init_fail;
126 }
Sagar Gore8d91a622017-02-23 14:57:18 -0800127
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700128 mutex_unlock(&g_dev.cam_lock);
129 return rc;
130
131mem_mgr_init_fail:
132 v4l2_fh_release(filep);
Sagar Gore8d91a622017-02-23 14:57:18 -0800133end:
134 mutex_unlock(&g_dev.cam_lock);
135 return rc;
136}
137
138static unsigned int cam_req_mgr_poll(struct file *f,
139 struct poll_table_struct *pll_table)
140{
141 int rc = 0;
142 struct v4l2_fh *eventq = f->private_data;
143
144 if (!eventq)
145 return -EINVAL;
146
147 poll_wait(f, &eventq->wait, pll_table);
148 if (v4l2_event_pending(eventq))
149 rc = POLLPRI;
150
151 return rc;
152}
153
154static int cam_req_mgr_close(struct file *filep)
155{
156 mutex_lock(&g_dev.cam_lock);
157
158 if (g_dev.open_cnt <= 0) {
159 mutex_unlock(&g_dev.cam_lock);
160 return -EINVAL;
161 }
162
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700163 cam_req_mgr_handle_core_shutdown();
Sagar Gore8d91a622017-02-23 14:57:18 -0800164 g_dev.open_cnt--;
165 v4l2_fh_release(filep);
166
167 spin_lock_bh(&g_dev.cam_eventq_lock);
168 g_dev.cam_eventq = NULL;
169 spin_unlock_bh(&g_dev.cam_eventq_lock);
170
171 cam_req_mgr_util_free_hdls();
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700172 cam_mem_mgr_deinit();
Sagar Gore8d91a622017-02-23 14:57:18 -0800173 mutex_unlock(&g_dev.cam_lock);
174
175 return 0;
176}
177
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800178static struct v4l2_file_operations g_cam_fops = {
179 .owner = THIS_MODULE,
Sagar Gore8d91a622017-02-23 14:57:18 -0800180 .open = cam_req_mgr_open,
181 .poll = cam_req_mgr_poll,
182 .release = cam_req_mgr_close,
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800183 .unlocked_ioctl = video_ioctl2,
184#ifdef CONFIG_COMPAT
185 .compat_ioctl32 = video_ioctl2,
186#endif
187};
188
189static int cam_subscribe_event(struct v4l2_fh *fh,
190 const struct v4l2_event_subscription *sub)
191{
192 return v4l2_event_subscribe(fh, sub, CAM_REQ_MGR_EVENT_MAX, NULL);
193}
194
195static int cam_unsubscribe_event(struct v4l2_fh *fh,
196 const struct v4l2_event_subscription *sub)
197{
198 return v4l2_event_unsubscribe(fh, sub);
199}
200
Sagar Gore8d91a622017-02-23 14:57:18 -0800201static long cam_private_ioctl(struct file *file, void *fh,
202 bool valid_prio, unsigned int cmd, void *arg)
203{
204 int rc;
205 struct cam_control *k_ioctl;
206
207 if ((!arg) || (cmd != VIDIOC_CAM_CONTROL))
208 return -EINVAL;
209
210 k_ioctl = (struct cam_control *)arg;
211
212 if (!k_ioctl->handle)
213 return -EINVAL;
214
215 switch (k_ioctl->op_code) {
216 case CAM_REQ_MGR_CREATE_SESSION: {
217 struct cam_req_mgr_session_info ses_info;
218
219 if (k_ioctl->size != sizeof(ses_info))
220 return -EINVAL;
221
222 if (copy_from_user(&ses_info,
223 (void *)k_ioctl->handle,
224 k_ioctl->size)) {
225 return -EFAULT;
226 }
227
228 rc = cam_req_mgr_create_session(&ses_info);
229 if (!rc)
230 if (copy_to_user((void *)k_ioctl->handle,
231 &ses_info, k_ioctl->size))
232 rc = -EFAULT;
233 }
234 break;
235
236 case CAM_REQ_MGR_DESTROY_SESSION: {
237 struct cam_req_mgr_session_info ses_info;
238
239 if (k_ioctl->size != sizeof(ses_info))
240 return -EINVAL;
241
242 if (copy_from_user(&ses_info,
243 (void *)k_ioctl->handle,
244 k_ioctl->size)) {
245 return -EFAULT;
246 }
247
248 rc = cam_req_mgr_destroy_session(&ses_info);
249 }
250 break;
251
252 case CAM_REQ_MGR_LINK: {
253 struct cam_req_mgr_link_info link_info;
254
255 if (k_ioctl->size != sizeof(link_info))
256 return -EINVAL;
257
258 if (copy_from_user(&link_info,
259 (void *)k_ioctl->handle,
260 k_ioctl->size)) {
261 return -EFAULT;
262 }
263
264 rc = cam_req_mgr_link(&link_info);
265 if (!rc)
266 if (copy_to_user((void *)k_ioctl->handle,
267 &link_info, k_ioctl->size))
268 rc = -EFAULT;
269 }
270 break;
271
272 case CAM_REQ_MGR_UNLINK: {
273 struct cam_req_mgr_unlink_info unlink_info;
274
275 if (k_ioctl->size != sizeof(unlink_info))
276 return -EINVAL;
277
278 if (copy_from_user(&unlink_info,
279 (void *)k_ioctl->handle,
280 k_ioctl->size)) {
281 return -EFAULT;
282 }
283
284 rc = cam_req_mgr_unlink(&unlink_info);
285 }
286 break;
287
288 case CAM_REQ_MGR_SCHED_REQ: {
289 struct cam_req_mgr_sched_request sched_req;
290
291 if (k_ioctl->size != sizeof(sched_req))
292 return -EINVAL;
293
294 if (copy_from_user(&sched_req,
295 (void *)k_ioctl->handle,
296 k_ioctl->size)) {
297 return -EFAULT;
298 }
299
300 rc = cam_req_mgr_schedule_request(&sched_req);
301 }
302 break;
303
304 case CAM_REQ_MGR_FLUSH_REQ: {
305 struct cam_req_mgr_flush_info flush_info;
306
307 if (k_ioctl->size != sizeof(flush_info))
308 return -EINVAL;
309
310 if (copy_from_user(&flush_info,
311 (void *)k_ioctl->handle,
312 k_ioctl->size)) {
313 return -EFAULT;
314 }
315
316 rc = cam_req_mgr_flush_requests(&flush_info);
317 }
318 break;
319
320 case CAM_REQ_MGR_SYNC_MODE: {
Pavan Kumar Chilamkurthi1fd03442017-11-07 17:07:21 -0800321 struct cam_req_mgr_sync_mode sync_info;
Sagar Gore8d91a622017-02-23 14:57:18 -0800322
Pavan Kumar Chilamkurthi1fd03442017-11-07 17:07:21 -0800323 if (k_ioctl->size != sizeof(sync_info))
Sagar Gore8d91a622017-02-23 14:57:18 -0800324 return -EINVAL;
325
Pavan Kumar Chilamkurthi1fd03442017-11-07 17:07:21 -0800326 if (copy_from_user(&sync_info,
Sagar Gore8d91a622017-02-23 14:57:18 -0800327 (void *)k_ioctl->handle,
328 k_ioctl->size)) {
329 return -EFAULT;
330 }
331
Pavan Kumar Chilamkurthi1fd03442017-11-07 17:07:21 -0800332 rc = cam_req_mgr_sync_config(&sync_info);
Sagar Gore8d91a622017-02-23 14:57:18 -0800333 }
334 break;
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700335 case CAM_REQ_MGR_ALLOC_BUF: {
336 struct cam_mem_mgr_alloc_cmd cmd;
337
338 if (k_ioctl->size != sizeof(cmd))
339 return -EINVAL;
340
341 if (copy_from_user(&cmd,
342 (void *)k_ioctl->handle,
343 k_ioctl->size)) {
344 rc = -EFAULT;
345 break;
346 }
347
348 rc = cam_mem_mgr_alloc_and_map(&cmd);
349 if (!rc)
350 if (copy_to_user((void *)k_ioctl->handle,
351 &cmd, k_ioctl->size)) {
352 rc = -EFAULT;
353 break;
354 }
355 }
356 break;
357 case CAM_REQ_MGR_MAP_BUF: {
358 struct cam_mem_mgr_map_cmd cmd;
359
360 if (k_ioctl->size != sizeof(cmd))
361 return -EINVAL;
362
363 if (copy_from_user(&cmd,
364 (void *)k_ioctl->handle,
365 k_ioctl->size)) {
366 rc = -EFAULT;
367 break;
368 }
369
370 rc = cam_mem_mgr_map(&cmd);
371 if (!rc)
372 if (copy_to_user((void *)k_ioctl->handle,
373 &cmd, k_ioctl->size)) {
374 rc = -EFAULT;
375 break;
376 }
377 }
378 break;
379 case CAM_REQ_MGR_RELEASE_BUF: {
380 struct cam_mem_mgr_release_cmd cmd;
381
382 if (k_ioctl->size != sizeof(cmd))
383 return -EINVAL;
384
385 if (copy_from_user(&cmd,
386 (void *)k_ioctl->handle,
387 k_ioctl->size)) {
388 rc = -EFAULT;
389 break;
390 }
391
392 rc = cam_mem_mgr_release(&cmd);
393 }
394 break;
395 case CAM_REQ_MGR_CACHE_OPS: {
396 struct cam_mem_cache_ops_cmd cmd;
397
398 if (k_ioctl->size != sizeof(cmd))
399 return -EINVAL;
400
401 if (copy_from_user(&cmd,
402 (void *)k_ioctl->handle,
403 k_ioctl->size)) {
404 rc = -EFAULT;
405 break;
406 }
407
408 rc = cam_mem_mgr_cache_ops(&cmd);
409 if (rc)
410 rc = -EINVAL;
411 }
412 break;
Jing Zhou0f645332017-11-17 12:16:40 -0800413 case CAM_REQ_MGR_LINK_CONTROL: {
414 struct cam_req_mgr_link_control cmd;
415
416 if (k_ioctl->size != sizeof(cmd))
417 return -EINVAL;
418
419 if (copy_from_user(&cmd,
420 (void __user *)k_ioctl->handle,
421 k_ioctl->size)) {
422 rc = -EFAULT;
423 break;
424 }
425
426 rc = cam_req_mgr_link_control(&cmd);
427 if (rc)
428 rc = -EINVAL;
429 }
430 break;
Sagar Gore8d91a622017-02-23 14:57:18 -0800431 default:
432 return -ENOIOCTLCMD;
433 }
434
435 return rc;
436}
437
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800438static const struct v4l2_ioctl_ops g_cam_ioctl_ops = {
439 .vidioc_subscribe_event = cam_subscribe_event,
440 .vidioc_unsubscribe_event = cam_unsubscribe_event,
Sagar Gore8d91a622017-02-23 14:57:18 -0800441 .vidioc_default = cam_private_ioctl,
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800442};
443
444static int cam_video_device_setup(void)
445{
446 int rc;
447
448 g_dev.video = video_device_alloc();
449 if (!g_dev.video) {
450 rc = -ENOMEM;
451 goto video_fail;
452 }
453
454 g_dev.video->v4l2_dev = g_dev.v4l2_dev;
455
456 strlcpy(g_dev.video->name, "cam-req-mgr",
457 sizeof(g_dev.video->name));
458 g_dev.video->release = video_device_release;
459 g_dev.video->fops = &g_cam_fops;
460 g_dev.video->ioctl_ops = &g_cam_ioctl_ops;
461 g_dev.video->minor = -1;
462 g_dev.video->vfl_type = VFL_TYPE_GRABBER;
463 rc = video_register_device(g_dev.video, VFL_TYPE_GRABBER, -1);
464 if (rc)
465 goto v4l2_fail;
466
467 rc = media_entity_pads_init(&g_dev.video->entity, 0, NULL);
468 if (rc)
469 goto entity_fail;
470
471 g_dev.video->entity.function = CAM_VNODE_DEVICE_TYPE;
472 g_dev.video->entity.name = video_device_node_name(g_dev.video);
473
474 return rc;
475
476entity_fail:
477 video_unregister_device(g_dev.video);
478v4l2_fail:
479 video_device_release(g_dev.video);
480 g_dev.video = NULL;
481video_fail:
482 return rc;
483}
484
Harsh Shah67fa2312017-10-30 04:03:07 -0700485int cam_req_mgr_notify_message(struct cam_req_mgr_message *msg,
Seemanta Dutta85afac72017-05-05 11:45:57 -0700486 uint32_t id,
487 uint32_t type)
488{
489 struct v4l2_event event;
490 struct cam_req_mgr_message *ev_header;
491
492 if (!msg)
493 return -EINVAL;
494
495 event.id = id;
496 event.type = type;
497 ev_header = CAM_REQ_MGR_GET_PAYLOAD_PTR(event,
498 struct cam_req_mgr_message);
499 memcpy(ev_header, msg, sizeof(struct cam_req_mgr_message));
500 v4l2_event_queue(g_dev.video, &event);
501
502 return 0;
503}
Harsh Shah67fa2312017-10-30 04:03:07 -0700504EXPORT_SYMBOL(cam_req_mgr_notify_message);
Seemanta Dutta85afac72017-05-05 11:45:57 -0700505
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800506void cam_video_device_cleanup(void)
507{
508 video_unregister_device(g_dev.video);
509 video_device_release(g_dev.video);
510 g_dev.video = NULL;
511}
512
Viswanadha Raju Thotakura08b50812017-08-25 14:52:32 -0700513void cam_register_subdev_fops(struct v4l2_file_operations *fops)
514{
515 *fops = v4l2_subdev_fops;
516}
517EXPORT_SYMBOL(cam_register_subdev_fops);
518
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800519int cam_register_subdev(struct cam_subdev *csd)
520{
521 struct v4l2_subdev *sd;
522 int rc;
523
524 if (g_dev.state != true) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700525 CAM_ERR(CAM_CRM, "camera root device not ready yet");
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800526 return -ENODEV;
527 }
528
529 if (!csd || !csd->name) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700530 CAM_ERR(CAM_CRM, "invalid arguments");
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800531 return -EINVAL;
532 }
533
534 mutex_lock(&g_dev.dev_lock);
535 if ((g_dev.subdev_nodes_created) &&
536 (csd->sd_flags & V4L2_SUBDEV_FL_HAS_DEVNODE)) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700537 CAM_ERR(CAM_CRM,
538 "dynamic node is not allowed, name: %s, type :%d",
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800539 csd->name, csd->ent_function);
540 rc = -EINVAL;
541 goto reg_fail;
542 }
543
544 sd = &csd->sd;
545 v4l2_subdev_init(sd, csd->ops);
546 sd->internal_ops = csd->internal_ops;
547 snprintf(sd->name, ARRAY_SIZE(sd->name), csd->name);
548 v4l2_set_subdevdata(sd, csd->token);
549
550 sd->flags = csd->sd_flags;
551 sd->entity.num_pads = 0;
552 sd->entity.pads = NULL;
553 sd->entity.function = csd->ent_function;
554
555 rc = v4l2_device_register_subdev(g_dev.v4l2_dev, sd);
556 if (rc) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700557 CAM_ERR(CAM_CRM, "register subdev failed");
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800558 goto reg_fail;
559 }
560 g_dev.count++;
561
562reg_fail:
563 mutex_unlock(&g_dev.dev_lock);
564 return rc;
565}
566EXPORT_SYMBOL(cam_register_subdev);
567
568int cam_unregister_subdev(struct cam_subdev *csd)
569{
570 if (g_dev.state != true) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700571 CAM_ERR(CAM_CRM, "camera root device not ready yet");
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800572 return -ENODEV;
573 }
574
575 mutex_lock(&g_dev.dev_lock);
576 v4l2_device_unregister_subdev(&csd->sd);
577 g_dev.count--;
578 mutex_unlock(&g_dev.dev_lock);
579
580 return 0;
581}
582EXPORT_SYMBOL(cam_unregister_subdev);
583
584static int cam_req_mgr_remove(struct platform_device *pdev)
585{
Sagar Gore8d91a622017-02-23 14:57:18 -0800586 cam_req_mgr_core_device_deinit();
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700587 cam_mem_mgr_deinit();
Sagar Gore8d91a622017-02-23 14:57:18 -0800588 cam_req_mgr_util_deinit();
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800589 cam_media_device_cleanup();
590 cam_video_device_cleanup();
591 cam_v4l2_device_cleanup();
592 mutex_destroy(&g_dev.dev_lock);
593 g_dev.state = false;
594
595 return 0;
596}
597
598static int cam_req_mgr_probe(struct platform_device *pdev)
599{
600 int rc;
601
602 rc = cam_v4l2_device_setup(&pdev->dev);
603 if (rc)
604 return rc;
605
606 rc = cam_media_device_setup(&pdev->dev);
607 if (rc)
608 goto media_setup_fail;
609
610 rc = cam_video_device_setup();
611 if (rc)
612 goto video_setup_fail;
613
Sagar Gore8d91a622017-02-23 14:57:18 -0800614 g_dev.open_cnt = 0;
615 mutex_init(&g_dev.cam_lock);
616 spin_lock_init(&g_dev.cam_eventq_lock);
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800617 g_dev.subdev_nodes_created = false;
618 mutex_init(&g_dev.dev_lock);
Sagar Gore8d91a622017-02-23 14:57:18 -0800619
620 rc = cam_req_mgr_util_init();
621 if (rc) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700622 CAM_ERR(CAM_CRM, "cam req mgr util init is failed");
Sagar Gore8d91a622017-02-23 14:57:18 -0800623 goto req_mgr_util_fail;
624 }
625
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700626 rc = cam_mem_mgr_init();
627 if (rc) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700628 CAM_ERR(CAM_CRM, "mem mgr init failed");
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700629 goto mem_mgr_init_fail;
630 }
631
Sagar Gore8d91a622017-02-23 14:57:18 -0800632 rc = cam_req_mgr_core_device_init();
633 if (rc) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700634 CAM_ERR(CAM_CRM, "core device setup failed");
Sagar Gore8d91a622017-02-23 14:57:18 -0800635 goto req_mgr_core_fail;
636 }
637
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800638 g_dev.state = true;
639
Venkat Chinta686c9e52018-01-20 14:33:25 -0800640 if (g_cam_req_mgr_timer_cachep == NULL) {
641 g_cam_req_mgr_timer_cachep = kmem_cache_create("crm_timer",
642 sizeof(struct cam_req_mgr_timer), 64,
643 SLAB_CONSISTENCY_CHECKS | SLAB_RED_ZONE |
644 SLAB_POISON | SLAB_STORE_USER, NULL);
645 if (!g_cam_req_mgr_timer_cachep)
646 CAM_ERR(CAM_CRM,
647 "Failed to create kmem_cache for crm_timer");
648 else
649 CAM_DBG(CAM_CRM, "Name : %s",
650 g_cam_req_mgr_timer_cachep->name);
651 }
652
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800653 return rc;
654
Sagar Gore8d91a622017-02-23 14:57:18 -0800655req_mgr_core_fail:
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700656 cam_mem_mgr_deinit();
657mem_mgr_init_fail:
Sagar Gore8d91a622017-02-23 14:57:18 -0800658 cam_req_mgr_util_deinit();
659req_mgr_util_fail:
Seemanta Dutta1c827da2017-04-05 17:34:05 -0700660 mutex_destroy(&g_dev.dev_lock);
661 mutex_destroy(&g_dev.cam_lock);
Sagar Gore8d91a622017-02-23 14:57:18 -0800662 cam_video_device_cleanup();
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800663video_setup_fail:
664 cam_media_device_cleanup();
665media_setup_fail:
666 cam_v4l2_device_cleanup();
667 return rc;
668}
669
670static const struct of_device_id cam_req_mgr_dt_match[] = {
671 {.compatible = "qcom,cam-req-mgr"},
672 {}
673};
674MODULE_DEVICE_TABLE(of, cam_dt_match);
675
676static struct platform_driver cam_req_mgr_driver = {
677 .probe = cam_req_mgr_probe,
678 .remove = cam_req_mgr_remove,
679 .driver = {
680 .name = "cam_req_mgr",
681 .owner = THIS_MODULE,
682 .of_match_table = cam_req_mgr_dt_match,
683 },
684};
685
686int cam_dev_mgr_create_subdev_nodes(void)
687{
688 int rc;
689 struct v4l2_subdev *sd;
690
691 if (!g_dev.v4l2_dev)
692 return -EINVAL;
693
694 if (g_dev.state != true) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700695 CAM_ERR(CAM_CRM, "camera root device not ready yet");
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800696 return -ENODEV;
697 }
698
699 mutex_lock(&g_dev.dev_lock);
700 if (g_dev.subdev_nodes_created) {
701 rc = -EEXIST;
702 goto create_fail;
703 }
704
705 rc = v4l2_device_register_subdev_nodes(g_dev.v4l2_dev);
706 if (rc) {
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700707 CAM_ERR(CAM_CRM, "failed to register the sub devices");
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800708 goto create_fail;
709 }
710
711 list_for_each_entry(sd, &g_dev.v4l2_dev->subdevs, list) {
712 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
713 continue;
714 sd->entity.name = video_device_node_name(sd->devnode);
Jigarkumar Zala36ad7172017-07-18 19:52:14 -0700715 CAM_DBG(CAM_CRM, "created node :%s", sd->entity.name);
Lakshmi Narayana Kalavalabda14e22017-02-06 19:07:52 -0800716 }
717
718 g_dev.subdev_nodes_created = true;
719
720create_fail:
721 mutex_unlock(&g_dev.dev_lock);
722 return rc;
723}
724
725static int __init cam_req_mgr_init(void)
726{
727 return platform_driver_register(&cam_req_mgr_driver);
728}
729
730static int __init cam_req_mgr_late_init(void)
731{
732 return cam_dev_mgr_create_subdev_nodes();
733}
734
735static void __exit cam_req_mgr_exit(void)
736{
737 platform_driver_unregister(&cam_req_mgr_driver);
738}
739
740module_init(cam_req_mgr_init);
741late_initcall(cam_req_mgr_late_init);
742module_exit(cam_req_mgr_exit);
743MODULE_DESCRIPTION("Camera Request Manager");
744MODULE_LICENSE("GPL v2");