OSDN Git Service

a3a742182e764146b8668555a15f6a28e03973af
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / drivers / media / platform / msm / ais / msm.c
1 /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
2  *
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
13 #include <linux/of.h>
14 #include <linux/module.h>
15 #include <linux/workqueue.h>
16 #include <linux/delay.h>
17 #include <linux/types.h>
18 #include <linux/list.h>
19 #include <linux/ioctl.h>
20 #include <linux/spinlock.h>
21 #include <linux/proc_fs.h>
22 #include <linux/atomic.h>
23 #include <linux/videodev2.h>
24 #include <linux/msm_ion.h>
25 #include <linux/iommu.h>
26 #include <linux/platform_device.h>
27 #include <linux/debugfs.h>
28 #include <media/v4l2-fh.h>
29 #include "msm.h"
30 #include "msm_vb2.h"
31 #include "msm_sd.h"
32 #include "cam_hw_ops.h"
33 #include <media/ais/msm_ais_buf_mgr.h>
34
35
36 static struct v4l2_device *msm_v4l2_dev;
37 static struct list_head    ordered_sd_list;
38
39 static struct pm_qos_request msm_v4l2_pm_qos_request;
40
41 static struct msm_queue_head *msm_session_q;
42
43 /* This variable represent daemon status
44  * true = daemon present (default state)
45  * false = daemon is NOT present
46  */
47 bool is_daemon_status = true;
48
49 /* config node envent queue */
50 static struct v4l2_fh  *msm_eventq;
51 static spinlock_t msm_eventq_lock;
52
53 static struct pid *msm_pid;
54 static spinlock_t msm_pid_lock;
55
56 /*
57  * It takes 20 bytes + NULL character to write the
58  * largest decimal value of an uint64_t
59  */
60 #define LOGSYNC_PACKET_SIZE 21
61
62 #define msm_dequeue(queue, type, member) ({                             \
63         unsigned long flags;                                    \
64         struct msm_queue_head *__q = (queue);                   \
65         type *node = NULL;                              \
66         spin_lock_irqsave(&__q->lock, flags);                   \
67         if (!list_empty(&__q->list)) {                          \
68                 __q->len--;                                     \
69                 node = list_first_entry(&__q->list,             \
70                                 type, member);  \
71                 if ((node) && (&node->member) && (&node->member.next))  \
72                         list_del_init(&node->member);                   \
73         }                                                       \
74         spin_unlock_irqrestore(&__q->lock, flags);      \
75         node;                                                   \
76 })
77
78 #define msm_delete_sd_entry(queue, type, member, q_node) ({             \
79         unsigned long flags;                                    \
80         struct msm_queue_head *__q = (queue);                   \
81         type *node = NULL;                              \
82         spin_lock_irqsave(&__q->lock, flags);                   \
83         if (!list_empty(&__q->list)) {                          \
84                 list_for_each_entry(node, &__q->list, member)   \
85                         if (node->sd == q_node) {               \
86                                 __q->len--;                     \
87                                 list_del_init(&node->member);   \
88                                 kzfree(node);                   \
89                                 break;                          \
90                         }                                       \
91         }                                                       \
92         spin_unlock_irqrestore(&__q->lock, flags);              \
93 })
94
95 #define msm_delete_entry(queue, type, member, q_node) ({                \
96         unsigned long flags;                                    \
97         struct msm_queue_head *__q = (queue);                   \
98         type *node = NULL;                              \
99         spin_lock_irqsave(&__q->lock, flags);                   \
100         if (!list_empty(&__q->list)) {                          \
101                 list_for_each_entry(node, &__q->list, member)   \
102                         if (node == q_node) {                   \
103                                 __q->len--;                     \
104                                 list_del_init(&node->member);   \
105                                 kzfree(node);                   \
106                                 break;                          \
107                         }                                       \
108         }                                                       \
109         spin_unlock_irqrestore(&__q->lock, flags);              \
110 })
111
112 #define msm_queue_drain(queue, type, member) do {                       \
113         unsigned long flags;                                    \
114         struct msm_queue_head *__q = (queue);                   \
115         type *node;                             \
116         spin_lock_irqsave(&__q->lock, flags);                   \
117         while (!list_empty(&__q->list)) {                       \
118                 __q->len--;                                     \
119                 node = list_first_entry(&__q->list,             \
120                         type, member);          \
121                 if (node) {                                     \
122                         if (&node->member) \
123                                 list_del_init(&node->member);           \
124                         kzfree(node);   \
125                 }       \
126         }       \
127         spin_unlock_irqrestore(&__q->lock, flags);              \
128 } while (0)
129
130 typedef int (*msm_queue_func)(void *d1, void *d2);
131 #define msm_queue_traverse_action(queue, type, member, func, data) do {\
132         unsigned long flags;                                    \
133         struct msm_queue_head *__q = (queue);                   \
134         type *node = NULL; \
135         msm_queue_func __f = (func); \
136         spin_lock_irqsave(&__q->lock, flags);                   \
137         if (!list_empty(&__q->list)) { \
138                 list_for_each_entry(node, &__q->list, member) \
139                         if (node && __f)  { \
140                                 __f(node, data); \
141                         } \
142         } \
143         spin_unlock_irqrestore(&__q->lock, flags);                      \
144 } while (0)
145
146 typedef int (*msm_queue_find_func)(void *d1, void *d2);
147 #define msm_queue_find(queue, type, member, func, data) ({\
148         unsigned long flags;                                    \
149         struct msm_queue_head *__q = (queue);                   \
150         type *node = NULL; \
151         typeof(node) __ret = NULL; \
152         msm_queue_find_func __f = (func); \
153         spin_lock_irqsave(&__q->lock, flags);                   \
154         if (!list_empty(&__q->list)) { \
155                 list_for_each_entry(node, &__q->list, member) \
156                         if ((__f) && __f(node, data)) { \
157                                 __ret = node; \
158                                 break; \
159                         } \
160         } \
161         spin_unlock_irqrestore(&__q->lock, flags); \
162         __ret; \
163 })
164
165 static void msm_init_queue(struct msm_queue_head *qhead)
166 {
167         if (WARN_ON(!qhead))
168                 return;
169
170         INIT_LIST_HEAD(&qhead->list);
171         spin_lock_init(&qhead->lock);
172         qhead->len = 0;
173         qhead->max = 0;
174 }
175
176 static void msm_enqueue(struct msm_queue_head *qhead,
177                 struct list_head *entry)
178 {
179         unsigned long flags;
180
181         spin_lock_irqsave(&qhead->lock, flags);
182         qhead->len++;
183         if (qhead->len > qhead->max)
184                 qhead->max = qhead->len;
185         list_add_tail(entry, &qhead->list);
186         spin_unlock_irqrestore(&qhead->lock, flags);
187 }
188
189 void msm_cam_copy_v4l2_subdev_fops(struct v4l2_file_operations *d1)
190 {
191         *d1 = v4l2_subdev_fops;
192 }
193 EXPORT_SYMBOL(msm_cam_copy_v4l2_subdev_fops);
194
195 static const struct v4l2_file_operations *msm_cam_get_v4l2_subdev_fops_ptr(
196         void)
197 {
198         return &v4l2_subdev_fops;
199 }
200
201 /* index = session id */
202 static inline int __msm_queue_find_session(void *d1, void *d2)
203 {
204         struct msm_session *session = d1;
205
206         return (session->session_id == *(unsigned int *)d2) ? 1 : 0;
207 }
208
209 static inline int __msm_queue_find_stream(void *d1, void *d2)
210 {
211         struct msm_stream *stream = d1;
212
213         return (stream->stream_id == *(unsigned int *)d2) ? 1 : 0;
214 }
215
216 static inline int __msm_queue_find_command_ack_q(void *d1, void *d2)
217 {
218         struct msm_command_ack *ack = d1;
219
220         return (ack->stream_id == *(unsigned int *)d2) ? 1 : 0;
221 }
222
223 static void msm_pm_qos_add_request(void)
224 {
225         pr_info("%s: add request", __func__);
226         pm_qos_add_request(&msm_v4l2_pm_qos_request, PM_QOS_CPU_DMA_LATENCY,
227         PM_QOS_DEFAULT_VALUE);
228 }
229
230 static void msm_pm_qos_remove_request(void)
231 {
232         pr_info("%s: remove request", __func__);
233         pm_qos_remove_request(&msm_v4l2_pm_qos_request);
234 }
235
236 void msm_pm_qos_update_request(int val)
237 {
238         pr_info("%s: update request %d", __func__, val);
239         pm_qos_update_request(&msm_v4l2_pm_qos_request, val);
240 }
241
242 struct msm_session *msm_session_find(unsigned int session_id)
243 {
244         struct msm_session *session;
245
246         session = msm_queue_find(msm_session_q, struct msm_session,
247                 list, __msm_queue_find_session, &session_id);
248         if (WARN_ON(!session))
249                 return NULL;
250         return session;
251 }
252 EXPORT_SYMBOL(msm_session_find);
253
254 int msm_create_stream(unsigned int session_id,
255         unsigned int stream_id, struct vb2_queue *q)
256 {
257         struct msm_session *session;
258         struct msm_stream  *stream;
259
260         session = msm_queue_find(msm_session_q, struct msm_session,
261                 list, __msm_queue_find_session, &session_id);
262         if (!session)
263                 return -EINVAL;
264
265         stream = kzalloc(sizeof(*stream), GFP_KERNEL);
266         if (!stream)
267                 return -ENOMEM;
268
269         stream->stream_id = stream_id;
270         stream->vb2_q = q;
271         spin_lock_init(&stream->stream_lock);
272         msm_enqueue(&session->stream_q, &stream->list);
273         session->stream_q.len++;
274
275         INIT_LIST_HEAD(&stream->queued_list);
276
277         return 0;
278 }
279 EXPORT_SYMBOL(msm_create_stream);
280
281 void msm_delete_stream(unsigned int session_id, unsigned int stream_id)
282 {
283         struct msm_session *session = NULL;
284         struct msm_stream  *stream = NULL;
285         unsigned long flags;
286         int try_count = 0;
287
288         session = msm_queue_find(msm_session_q, struct msm_session,
289                 list, __msm_queue_find_session, &session_id);
290
291         if (!session)
292                 return;
293
294         while (1) {
295
296                 if (try_count > 5) {
297                         pr_err("%s : not able to delete stream %d\n",
298                                 __func__, __LINE__);
299                         break;
300                 }
301
302                 write_lock(&session->stream_rwlock);
303                 try_count++;
304                 stream = msm_queue_find(&session->stream_q, struct msm_stream,
305                         list, __msm_queue_find_stream, &stream_id);
306
307                 if (!stream) {
308                         write_unlock(&session->stream_rwlock);
309                         return;
310                 }
311
312                 if (msm_vb2_get_stream_state(stream) != 1) {
313                         write_unlock(&session->stream_rwlock);
314                         continue;
315                 }
316
317                 spin_lock_irqsave(&(session->stream_q.lock), flags);
318                 list_del_init(&stream->list);
319                 session->stream_q.len--;
320                 kfree(stream);
321                 stream = NULL;
322                 spin_unlock_irqrestore(&(session->stream_q.lock), flags);
323                 write_unlock(&session->stream_rwlock);
324                 break;
325         }
326
327 }
328 EXPORT_SYMBOL(msm_delete_stream);
329
330 static void msm_sd_unregister_subdev(struct video_device *vdev)
331 {
332         struct v4l2_subdev *sd = video_get_drvdata(vdev);
333
334         sd->devnode = NULL;
335         kzfree(vdev);
336 }
337
338 static inline int __msm_sd_register_subdev(struct v4l2_subdev *sd)
339 {
340         int rc = 0;
341         struct video_device *vdev;
342
343         if (!msm_v4l2_dev || !sd || !sd->name[0])
344                 return -EINVAL;
345
346         rc = v4l2_device_register_subdev(msm_v4l2_dev, sd);
347         if (rc < 0)
348                 return rc;
349
350         /* Register a device node for every subdev marked with the
351          * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
352          */
353         if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
354                 return rc;
355
356         vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
357         if (!vdev) {
358                 rc = -ENOMEM;
359                 goto clean_up;
360         }
361
362         video_set_drvdata(vdev, sd);
363         strlcpy(vdev->name, sd->name, sizeof(vdev->name));
364         vdev->v4l2_dev = msm_v4l2_dev;
365         vdev->fops = msm_cam_get_v4l2_subdev_fops_ptr();
366         vdev->release = msm_sd_unregister_subdev;
367         rc = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
368                   sd->owner);
369         if (rc < 0) {
370                 kzfree(vdev);
371                 goto clean_up;
372         }
373
374 #if defined(CONFIG_MEDIA_CONTROLLER)
375         sd->entity.info.dev.major = VIDEO_MAJOR;
376         sd->entity.info.dev.minor = vdev->minor;
377         sd->entity.name = video_device_node_name(vdev);
378 #endif
379         sd->devnode = vdev;
380         return 0;
381
382 clean_up:
383         if (sd->devnode)
384                 video_unregister_device(sd->devnode);
385         return rc;
386 }
387
388 static void msm_add_sd_in_position(struct msm_sd_subdev *msm_subdev,
389         struct list_head *sd_list)
390 {
391         struct msm_sd_subdev *temp_sd;
392
393         list_for_each_entry(temp_sd, sd_list, list) {
394                 if (temp_sd == msm_subdev) {
395                         return;
396                 }
397                 if (msm_subdev->close_seq < temp_sd->close_seq) {
398                         list_add_tail(&msm_subdev->list, &temp_sd->list);
399                         return;
400                 }
401         }
402         list_add_tail(&msm_subdev->list, sd_list);
403 }
404
405 int msm_sd_register(struct msm_sd_subdev *msm_subdev)
406 {
407         if (WARN_ON(!msm_subdev))
408                 return -EINVAL;
409
410         if (WARN_ON(!msm_v4l2_dev) || WARN_ON(!msm_v4l2_dev->dev))
411                 return -EIO;
412
413         msm_add_sd_in_position(msm_subdev, &ordered_sd_list);
414         return __msm_sd_register_subdev(&msm_subdev->sd);
415 }
416 EXPORT_SYMBOL(msm_sd_register);
417
418 int msm_sd_unregister(struct msm_sd_subdev *msm_subdev)
419 {
420         if (WARN_ON(!msm_subdev))
421                 return -EINVAL;
422
423         v4l2_device_unregister_subdev(&msm_subdev->sd);
424         return 0;
425 }
426 EXPORT_SYMBOL(msm_sd_unregister);
427
428 static struct v4l2_subdev *msm_sd_find(const char *name)
429 {
430         unsigned long flags;
431         struct v4l2_subdev *subdev = NULL;
432         struct v4l2_subdev *subdev_out = NULL;
433
434         spin_lock_irqsave(&msm_v4l2_dev->lock, flags);
435         if (!list_empty(&msm_v4l2_dev->subdevs)) {
436                 list_for_each_entry(subdev, &msm_v4l2_dev->subdevs, list)
437                         if (!strcmp(name, subdev->name)) {
438                                 subdev_out = subdev;
439                                 break;
440                         }
441         }
442         spin_unlock_irqrestore(&msm_v4l2_dev->lock, flags);
443
444         return subdev_out;
445 }
446
447 int msm_create_session(unsigned int session_id, struct video_device *vdev)
448 {
449         struct msm_session *session = NULL;
450
451         if (!msm_session_q) {
452                 pr_err("%s : session queue not available Line %d\n",
453                                 __func__, __LINE__);
454                 return -ENODEV;
455         }
456
457         session = msm_queue_find(msm_session_q, struct msm_session,
458                 list, __msm_queue_find_session, &session_id);
459         if (session) {
460                 pr_err("%s: Session exist session_id=%d\n",
461                                 __func__, session_id);
462                 return -EINVAL;
463         }
464
465         session = kzalloc(sizeof(*session), GFP_KERNEL);
466         if (!session)
467                 return -ENOMEM;
468
469         session->session_id = session_id;
470         session->event_q.vdev = vdev;
471         msm_init_queue(&session->command_ack_q);
472         msm_init_queue(&session->stream_q);
473         msm_enqueue(msm_session_q, &session->list);
474         mutex_init(&session->lock);
475         mutex_init(&session->lock_q);
476         mutex_init(&session->close_lock);
477         rwlock_init(&session->stream_rwlock);
478         return 0;
479 }
480 EXPORT_SYMBOL(msm_create_session);
481
482 int msm_create_command_ack_q(unsigned int session_id, unsigned int stream_id)
483 {
484         struct msm_session *session;
485         struct msm_command_ack *cmd_ack;
486
487         if (!msm_session_q) {
488                 pr_err("%s : Session queue not available Line %d\n",
489                                 __func__, __LINE__);
490                 return -ENODEV;
491         }
492
493         session = msm_queue_find(msm_session_q, struct msm_session,
494                 list, __msm_queue_find_session, &session_id);
495         if (!session) {
496                 pr_err("%s : Session not found Line %d\n",
497                                 __func__, __LINE__);
498                 return -EINVAL;
499         }
500         mutex_lock(&session->lock);
501         cmd_ack = kzalloc(sizeof(*cmd_ack), GFP_KERNEL);
502         if (!cmd_ack) {
503                 mutex_unlock(&session->lock);
504                 pr_err("%s : memory not available Line %d\n",
505                                 __func__, __LINE__);
506                 return -ENOMEM;
507         }
508
509         msm_init_queue(&cmd_ack->command_q);
510         INIT_LIST_HEAD(&cmd_ack->list);
511         init_completion(&cmd_ack->wait_complete);
512         cmd_ack->stream_id = stream_id;
513
514         msm_enqueue(&session->command_ack_q, &cmd_ack->list);
515         session->command_ack_q.len++;
516         mutex_unlock(&session->lock);
517         return 0;
518 }
519 EXPORT_SYMBOL(msm_create_command_ack_q);
520
521 void msm_delete_command_ack_q(unsigned int session_id, unsigned int stream_id)
522 {
523         struct msm_session *session;
524         struct msm_command_ack *cmd_ack;
525         unsigned long flags;
526
527         session = msm_queue_find(msm_session_q, struct msm_session,
528                 list, __msm_queue_find_session, &session_id);
529         if (!session)
530                 return;
531         mutex_lock(&session->lock);
532
533         cmd_ack = msm_queue_find(&session->command_ack_q,
534                 struct msm_command_ack, list, __msm_queue_find_command_ack_q,
535                 &stream_id);
536         if (!cmd_ack) {
537                 mutex_unlock(&session->lock);
538                 return;
539         }
540
541         msm_queue_drain(&cmd_ack->command_q, struct msm_command, list);
542
543         spin_lock_irqsave(&(session->command_ack_q.lock), flags);
544         list_del_init(&cmd_ack->list);
545         kzfree(cmd_ack);
546         session->command_ack_q.len--;
547         spin_unlock_irqrestore(&(session->command_ack_q.lock), flags);
548         mutex_unlock(&session->lock);
549 }
550 EXPORT_SYMBOL(msm_delete_command_ack_q);
551
552 static inline int __msm_sd_close_subdevs(struct msm_sd_subdev *msm_sd,
553         struct msm_sd_close_ioctl *sd_close)
554 {
555         struct v4l2_subdev *sd;
556
557         sd = &msm_sd->sd;
558         pr_debug("%s: Shutting down subdev %s", __func__, sd->name);
559
560         v4l2_subdev_call(sd, core, ioctl, MSM_SD_SHUTDOWN, sd_close);
561         v4l2_subdev_call(sd, core, s_power, 0);
562
563         return 0;
564 }
565
566 static inline int __msm_sd_notify_freeze_subdevs(struct msm_sd_subdev *msm_sd,
567         int enable)
568 {
569         struct v4l2_subdev *sd;
570
571         sd = &msm_sd->sd;
572
573         if (enable)
574                 v4l2_subdev_call(sd, core, ioctl, MSM_SD_NOTIFY_FREEZE, NULL);
575         else
576                 v4l2_subdev_call(sd, core, ioctl, MSM_SD_UNNOTIFY_FREEZE, NULL);
577
578         return 0;
579 }
580
581 static inline int __msm_destroy_session_streams(void *d1, void *d2)
582 {
583         struct msm_stream *stream = d1;
584         unsigned long flags;
585
586         pr_err("%s: Error: Destroyed list is not empty\n", __func__);
587         spin_lock_irqsave(&stream->stream_lock, flags);
588         INIT_LIST_HEAD(&stream->queued_list);
589         spin_unlock_irqrestore(&stream->stream_lock, flags);
590         return 0;
591 }
592
593 static void msm_destroy_session_streams(struct msm_session *session)
594 {
595
596         if (!session)
597                 return;
598
599         msm_queue_traverse_action(&session->stream_q, struct msm_stream, list,
600                 __msm_destroy_session_streams, NULL);
601
602         msm_queue_drain(&session->stream_q, struct msm_stream, list);
603 }
604
605 static inline int __msm_remove_session_cmd_ack_q(void *d1, void *d2)
606 {
607         struct msm_command_ack *cmd_ack = d1;
608
609         if (!(&cmd_ack->command_q))
610                 return 0;
611
612         msm_queue_drain(&cmd_ack->command_q, struct msm_command, list);
613
614         return 0;
615 }
616
617 static void msm_remove_session_cmd_ack_q(struct msm_session *session)
618 {
619         if ((!session) || !(&session->command_ack_q))
620                 return;
621
622         mutex_lock(&session->lock);
623         /* to ensure error handling purpose, it needs to detach all subdevs
624          * which are being connected to streams
625          */
626         msm_queue_traverse_action(&session->command_ack_q,
627                 struct msm_command_ack, list,
628                 __msm_remove_session_cmd_ack_q, NULL);
629
630         msm_queue_drain(&session->command_ack_q, struct msm_command_ack, list);
631
632         mutex_unlock(&session->lock);
633 }
634
635 int msm_destroy_session(unsigned int session_id)
636 {
637         struct msm_session *session;
638         struct v4l2_subdev *buf_mgr_subdev;
639         struct msm_sd_close_ioctl session_info;
640
641         session = msm_queue_find(msm_session_q, struct msm_session,
642                 list, __msm_queue_find_session, &session_id);
643         if (!session)
644                 return -EINVAL;
645
646         msm_destroy_session_streams(session);
647         msm_remove_session_cmd_ack_q(session);
648         mutex_destroy(&session->lock);
649         mutex_destroy(&session->lock_q);
650         mutex_destroy(&session->close_lock);
651         msm_delete_entry(msm_session_q, struct msm_session,
652                 list, session);
653         buf_mgr_subdev = msm_sd_find("msm_buf_mngr");
654         if (buf_mgr_subdev) {
655                 session_info.session = session_id;
656                 session_info.stream = 0;
657                 v4l2_subdev_call(buf_mgr_subdev, core, ioctl,
658                         MSM_SD_SHUTDOWN, &session_info);
659         } else {
660                 pr_err("%s: Buff manger device node is NULL\n", __func__);
661         }
662
663         return 0;
664 }
665 EXPORT_SYMBOL(msm_destroy_session);
666
667 static int __msm_close_destry_session_notify_apps(void *d1, void *d2)
668 {
669         struct v4l2_event event;
670         struct msm_v4l2_event_data *event_data =
671                 (struct msm_v4l2_event_data *)&event.u.data[0];
672         struct msm_session *session = d1;
673
674         event.type = MSM_CAMERA_V4L2_EVENT_TYPE;
675         event.id   = MSM_CAMERA_MSM_NOTIFY;
676         event_data->command = MSM_CAMERA_PRIV_SHUTDOWN;
677
678         v4l2_event_queue(session->event_q.vdev, &event);
679
680         return 0;
681 }
682
683 static int __msm_wakeup_all_cmdack_session_stream(void *d1, void *d2)
684 {
685         struct msm_stream *stream = d1;
686         struct msm_session *session = d2;
687         struct msm_command_ack *cmd_ack = NULL;
688         unsigned long spin_flags = 0;
689
690         cmd_ack = msm_queue_find(&session->command_ack_q,
691                 struct msm_command_ack, list,
692                 __msm_queue_find_command_ack_q,
693                 &stream->stream_id);
694         if (cmd_ack) {
695                 spin_lock_irqsave(&(session->command_ack_q.lock),
696                         spin_flags);
697                 complete(&cmd_ack->wait_complete);
698                 spin_unlock_irqrestore(&(session->command_ack_q.lock),
699                         spin_flags);
700         }
701         return 0;
702 }
703
704 static int __msm_close_wakeup_all_cmdack_session(void *d1, void *d2)
705 {
706         struct msm_stream  *stream = NULL;
707         struct msm_session *session = d1;
708
709         stream = msm_queue_find(&session->stream_q, struct msm_stream,
710                 list, __msm_wakeup_all_cmdack_session_stream, d1);
711         return 0;
712 }
713
714 static long msm_private_ioctl(struct file *file, void *fh,
715         bool valid_prio, unsigned int cmd, void *arg)
716 {
717         int rc = 0;
718         struct msm_v4l2_event_data *event_data = arg;
719         struct v4l2_event event;
720         struct msm_session *session;
721         unsigned int session_id;
722         unsigned int stream_id;
723         unsigned long spin_flags = 0;
724         struct msm_sd_subdev *msm_sd;
725
726         if (cmd == MSM_CAM_V4L2_IOCTL_DAEMON_DISABLED) {
727                 is_daemon_status = false;
728                 return 0;
729         }
730
731         if (!event_data)
732                 return -EINVAL;
733
734         memset(&event, 0, sizeof(struct v4l2_event));
735         session_id = event_data->session_id;
736         stream_id = event_data->stream_id;
737
738         session = msm_queue_find(msm_session_q, struct msm_session,
739                 list, __msm_queue_find_session, &session_id);
740
741         if (!session)
742                 return -EINVAL;
743
744         switch (cmd) {
745         case MSM_CAM_V4L2_IOCTL_NOTIFY: {
746                 if (WARN_ON(!session->event_q.vdev)) {
747                         rc = -EFAULT;
748                         break;
749                 }
750                 event.type = event_data->v4l2_event_type;
751                 event.id = event_data->v4l2_event_id;
752                 memcpy(&event.u.data, event_data,
753                         sizeof(struct msm_v4l2_event_data));
754                 v4l2_event_queue(session->event_q.vdev,
755                         &event);
756         }
757                 break;
758
759         case MSM_CAM_V4L2_IOCTL_CMD_ACK: {
760                 struct msm_command_ack *cmd_ack;
761                 struct msm_command *ret_cmd;
762
763                 ret_cmd = kzalloc(sizeof(*ret_cmd), GFP_KERNEL);
764                 if (!ret_cmd) {
765                         rc = -ENOMEM;
766                         break;
767                 }
768
769                 cmd_ack = msm_queue_find(&session->command_ack_q,
770                         struct msm_command_ack, list,
771                         __msm_queue_find_command_ack_q,
772                         &stream_id);
773                 if (WARN_ON(!cmd_ack)) {
774                         kzfree(ret_cmd);
775                         rc = -EFAULT;
776                         break;
777                 }
778
779                 spin_lock_irqsave(&(session->command_ack_q.lock),
780                    spin_flags);
781                 event.type = event_data->v4l2_event_type;
782                 event.id = event_data->v4l2_event_id;
783                 memcpy(&event.u.data, event_data,
784                         sizeof(struct msm_v4l2_event_data));
785                 memcpy(&ret_cmd->event, &event, sizeof(struct v4l2_event));
786                 msm_enqueue(&cmd_ack->command_q, &ret_cmd->list);
787                 complete(&cmd_ack->wait_complete);
788                 spin_unlock_irqrestore(&(session->command_ack_q.lock),
789                    spin_flags);
790         }
791                 break;
792
793         case MSM_CAM_V4L2_IOCTL_NOTIFY_DEBUG: {
794                 if (event_data->status) {
795                         pr_err("%s:Notifying subdevs about potential sof freeze\n",
796                                 __func__);
797                 } else {
798                         pr_err("%s:Notifying subdevs about sof recover\n",
799                                 __func__);
800                 }
801
802                 if (!list_empty(&msm_v4l2_dev->subdevs)) {
803                         list_for_each_entry(msm_sd, &ordered_sd_list, list)
804                                 __msm_sd_notify_freeze_subdevs(msm_sd,
805                                         event_data->status);
806                 }
807         }
808                 break;
809
810         case MSM_CAM_V4L2_IOCTL_NOTIFY_ERROR:
811                 /* send v4l2_event to HAL next*/
812                 msm_queue_traverse_action(msm_session_q,
813                         struct msm_session, list,
814                         __msm_close_destry_session_notify_apps, NULL);
815                 break;
816
817         default:
818                 rc = -ENOTTY;
819                 break;
820         }
821
822         return rc;
823 }
824
825 static int msm_unsubscribe_event(struct v4l2_fh *fh,
826         const struct v4l2_event_subscription *sub)
827 {
828         return v4l2_event_unsubscribe(fh, sub);
829 }
830
831 static int msm_subscribe_event(struct v4l2_fh *fh,
832         const struct v4l2_event_subscription *sub)
833 {
834         return v4l2_event_subscribe(fh, sub, 5, NULL);
835 }
836
837 static const struct v4l2_ioctl_ops g_msm_ioctl_ops = {
838         .vidioc_subscribe_event = msm_subscribe_event,
839         .vidioc_unsubscribe_event = msm_unsubscribe_event,
840         .vidioc_default = msm_private_ioctl,
841 };
842
843 static unsigned int msm_poll(struct file *f,
844         struct poll_table_struct *pll_table)
845 {
846         int rc = 0;
847         struct v4l2_fh *eventq = f->private_data;
848
849         if (WARN_ON(!eventq))
850                 return 0;
851
852         poll_wait(f, &eventq->wait, pll_table);
853
854         if (v4l2_event_pending(eventq))
855                 rc = POLLIN | POLLRDNORM;
856
857         return rc;
858 }
859
860 static void msm_print_event_error(struct v4l2_event *event)
861 {
862         struct msm_v4l2_event_data *event_data =
863                 (struct msm_v4l2_event_data *)&event->u.data[0];
864
865         pr_err("Evt_type=%x Evt_id=%d Evt_cmd=%x\n", event->type,
866                 event->id, event_data->command);
867         pr_err("Evt_session_id=%d Evt_stream_id=%d Evt_arg=%d\n",
868                 event_data->session_id, event_data->stream_id,
869                 event_data->arg_value);
870 }
871
872 /* something seriously wrong if msm_close is triggered
873  *   !!! user space imaging server is shutdown !!!
874  */
875 int msm_post_event(struct v4l2_event *event, int timeout)
876 {
877         int rc = 0;
878         struct video_device *vdev;
879         struct msm_session *session;
880         struct msm_v4l2_event_data *event_data =
881                 (struct msm_v4l2_event_data *)&event->u.data[0];
882         struct msm_command_ack *cmd_ack;
883         struct msm_command *cmd;
884         int session_id, stream_id;
885         unsigned long flags = 0;
886
887         session_id = event_data->session_id;
888         stream_id = event_data->stream_id;
889
890         spin_lock_irqsave(&msm_eventq_lock, flags);
891         if (!msm_eventq) {
892                 spin_unlock_irqrestore(&msm_eventq_lock, flags);
893                 pr_err("%s : msm event queue not available Line %d\n",
894                                 __func__, __LINE__);
895                 return -ENODEV;
896         }
897         spin_unlock_irqrestore(&msm_eventq_lock, flags);
898
899         vdev = msm_eventq->vdev;
900
901         /* send to imaging server and wait for ACK */
902         session = msm_queue_find(msm_session_q, struct msm_session,
903                 list, __msm_queue_find_session, &session_id);
904         if (WARN_ON(!session)) {
905                 pr_err("%s : session not found Line %d\n",
906                                 __func__, __LINE__);
907                 return -EIO;
908         }
909         mutex_lock(&session->lock);
910         cmd_ack = msm_queue_find(&session->command_ack_q,
911                 struct msm_command_ack, list,
912                 __msm_queue_find_command_ack_q, &stream_id);
913         if (WARN_ON(!cmd_ack)) {
914                 mutex_unlock(&session->lock);
915                 pr_err("%s : cmd_ack not found Line %d\n",
916                                 __func__, __LINE__);
917                 return -EIO;
918         }
919
920         /* re-init wait_complete */
921         reinit_completion(&cmd_ack->wait_complete);
922
923         v4l2_event_queue(vdev, event);
924
925         if (timeout < 0) {
926                 mutex_unlock(&session->lock);
927                 pr_debug("%s : timeout cannot be negative Line %d\n",
928                                 __func__, __LINE__);
929                 return rc;
930         }
931
932         /* should wait on session based condition */
933         rc = wait_for_completion_timeout(&cmd_ack->wait_complete,
934                         msecs_to_jiffies(timeout));
935
936
937         if (list_empty_careful(&cmd_ack->command_q.list)) {
938                 if (!rc) {
939                         pr_err("%s: Timed out\n", __func__);
940                         msm_print_event_error(event);
941                         mutex_unlock(&session->lock);
942                         return -ETIMEDOUT;
943                 }
944                 pr_err("%s: Error: No timeout but list empty!", __func__);
945                 msm_print_event_error(event);
946                 mutex_unlock(&session->lock);
947                 return -EINVAL;
948         }
949
950         cmd = msm_dequeue(&cmd_ack->command_q,
951                 struct msm_command, list);
952         if (!cmd) {
953                 mutex_unlock(&session->lock);
954                 pr_err("%s : cmd dequeue failed Line %d\n",
955                                 __func__, __LINE__);
956                 return -EINVAL;
957         }
958
959         event_data = (struct msm_v4l2_event_data *)cmd->event.u.data;
960
961         /* compare cmd_ret and event */
962         if (WARN_ON(event->type != cmd->event.type) ||
963                         WARN_ON(event->id != cmd->event.id)) {
964                 pr_err("%s : Either event type or id didnot match Line %d\n",
965                                 __func__, __LINE__);
966                 pr_err("%s : event->type %d event->id %d\n", __func__,
967                                 event->type, event->id);
968                 pr_err("%s : cmd->event.type %d cmd->event.id %d\n", __func__,
969                                 cmd->event.type, cmd->event.id);
970                 rc = -EINVAL;
971         }
972
973         *event = cmd->event;
974
975         kzfree(cmd);
976         mutex_unlock(&session->lock);
977         return rc;
978 }
979 EXPORT_SYMBOL(msm_post_event);
980
981 static int msm_close(struct file *filep)
982 {
983         int rc = 0;
984         unsigned long flags;
985         struct msm_video_device *pvdev = video_drvdata(filep);
986         struct msm_sd_close_ioctl sd_close;
987         struct msm_sd_subdev *msm_sd;
988
989         /* stop all hardware blocks immediately */
990         if (!list_empty(&msm_v4l2_dev->subdevs))
991                 list_for_each_entry(msm_sd, &ordered_sd_list, list)
992                         __msm_sd_close_subdevs(msm_sd, &sd_close);
993
994         /* remove msm_v4l2_pm_qos_request */
995         msm_pm_qos_remove_request();
996
997         /* send v4l2_event to HAL next*/
998         msm_queue_traverse_action(msm_session_q, struct msm_session, list,
999                 __msm_close_destry_session_notify_apps, NULL);
1000
1001         msm_queue_traverse_action(msm_session_q, struct msm_session, list,
1002                 __msm_close_wakeup_all_cmdack_session, NULL);
1003
1004         spin_lock_irqsave(&msm_eventq_lock, flags);
1005         msm_eventq = NULL;
1006         spin_unlock_irqrestore(&msm_eventq_lock, flags);
1007         v4l2_fh_release(filep);
1008
1009         spin_lock_irqsave(&msm_pid_lock, flags);
1010         put_pid(msm_pid);
1011         msm_pid = NULL;
1012         spin_unlock_irqrestore(&msm_pid_lock, flags);
1013
1014         atomic_set(&pvdev->opened, 0);
1015
1016         return rc;
1017 }
1018
1019 static inline void msm_list_switch(struct list_head *l1,
1020         struct list_head *l2)
1021 {
1022         l1->next = l2->next;
1023         l2->prev = l1->prev;
1024         l1->prev->next = l2;
1025         l2->next->prev = l1;
1026         l1->prev = l2;
1027         l2->next = l1;
1028 }
1029
1030 static int msm_open(struct file *filep)
1031 {
1032         int rc;
1033         unsigned long flags;
1034         struct msm_video_device *pvdev = video_drvdata(filep);
1035
1036         if (WARN_ON(!pvdev))
1037                 return -EIO;
1038
1039         /* !!! only ONE open is allowed !!! */
1040         if (atomic_read(&pvdev->opened))
1041                 return -EBUSY;
1042
1043         atomic_set(&pvdev->opened, 1);
1044
1045         spin_lock_irqsave(&msm_pid_lock, flags);
1046         msm_pid = get_pid(task_pid(current));
1047         spin_unlock_irqrestore(&msm_pid_lock, flags);
1048
1049         /* create event queue */
1050         rc = v4l2_fh_open(filep);
1051         if (rc  < 0)
1052                 return rc;
1053
1054         spin_lock_irqsave(&msm_eventq_lock, flags);
1055         msm_eventq = filep->private_data;
1056         spin_unlock_irqrestore(&msm_eventq_lock, flags);
1057
1058         /* register msm_v4l2_pm_qos_request */
1059         msm_pm_qos_add_request();
1060
1061         return rc;
1062 }
1063
1064 static struct v4l2_file_operations msm_fops = {
1065         .owner  = THIS_MODULE,
1066         .open   = msm_open,
1067         .poll   = msm_poll,
1068         .release = msm_close,
1069         .unlocked_ioctl   = video_ioctl2,
1070 #ifdef CONFIG_COMPAT
1071         .compat_ioctl32 = video_ioctl2,
1072 #endif
1073 };
1074
1075 struct msm_session *msm_get_session(unsigned int session_id)
1076 {
1077         struct msm_session *session;
1078
1079         session = msm_queue_find(msm_session_q, struct msm_session,
1080                 list, __msm_queue_find_session, &session_id);
1081         if (!session)
1082                 return ERR_PTR(-EINVAL);
1083
1084         return session;
1085 }
1086 EXPORT_SYMBOL(msm_get_session);
1087
1088
1089 struct msm_stream *msm_get_stream(struct msm_session *session,
1090         unsigned int stream_id)
1091 {
1092         struct msm_stream *stream;
1093
1094         stream = msm_queue_find(&session->stream_q, struct msm_stream,
1095                 list, __msm_queue_find_stream, &stream_id);
1096
1097         if (!stream)
1098                 return ERR_PTR(-EINVAL);
1099
1100         return stream;
1101 }
1102 EXPORT_SYMBOL(msm_get_stream);
1103
1104 struct vb2_queue *msm_get_stream_vb2q(unsigned int session_id,
1105         unsigned int stream_id)
1106 {
1107         struct msm_session *session;
1108         struct msm_stream *stream;
1109
1110         session = msm_queue_find(msm_session_q, struct msm_session,
1111                 list, __msm_queue_find_session, &session_id);
1112         if (!session)
1113                 return NULL;
1114
1115         stream = msm_queue_find(&session->stream_q, struct msm_stream,
1116                 list, __msm_queue_find_stream, &stream_id);
1117         if (!stream)
1118                 return NULL;
1119
1120         return stream->vb2_q;
1121 }
1122 EXPORT_SYMBOL(msm_get_stream_vb2q);
1123
1124 struct msm_stream *msm_get_stream_from_vb2q(struct vb2_queue *q)
1125 {
1126         struct msm_session *session;
1127         struct msm_stream *stream;
1128         unsigned long flags1;
1129         unsigned long flags2;
1130
1131         spin_lock_irqsave(&msm_session_q->lock, flags1);
1132         list_for_each_entry(session, &(msm_session_q->list), list) {
1133                 spin_lock_irqsave(&(session->stream_q.lock), flags2);
1134                 list_for_each_entry(
1135                         stream, &(session->stream_q.list), list) {
1136                         if (stream->vb2_q == q) {
1137                                 spin_unlock_irqrestore
1138                                         (&(session->stream_q.lock), flags2);
1139                                 spin_unlock_irqrestore
1140                                         (&msm_session_q->lock, flags1);
1141                                 return stream;
1142                         }
1143                 }
1144                 spin_unlock_irqrestore(&(session->stream_q.lock), flags2);
1145         }
1146         spin_unlock_irqrestore(&msm_session_q->lock, flags1);
1147         return NULL;
1148 }
1149 EXPORT_SYMBOL(msm_get_stream_from_vb2q);
1150
1151 struct msm_session *msm_get_session_from_vb2q(struct vb2_queue *q)
1152 {
1153         struct msm_session *session;
1154         struct msm_stream *stream;
1155         unsigned long flags1;
1156         unsigned long flags2;
1157
1158         spin_lock_irqsave(&msm_session_q->lock, flags1);
1159         list_for_each_entry(session, &(msm_session_q->list), list) {
1160                 spin_lock_irqsave(&(session->stream_q.lock), flags2);
1161                 list_for_each_entry(
1162                         stream, &(session->stream_q.list), list) {
1163                         if (stream->vb2_q == q) {
1164                                 spin_unlock_irqrestore
1165                                         (&(session->stream_q.lock), flags2);
1166                                 spin_unlock_irqrestore
1167                                         (&msm_session_q->lock, flags1);
1168                                 return session;
1169                         }
1170                 }
1171                 spin_unlock_irqrestore(&(session->stream_q.lock), flags2);
1172         }
1173         spin_unlock_irqrestore(&msm_session_q->lock, flags1);
1174         return NULL;
1175 }
1176 EXPORT_SYMBOL(msm_get_session_from_vb2q);
1177
1178
1179 #ifdef CONFIG_COMPAT
1180 long msm_copy_camera_private_ioctl_args(unsigned long arg,
1181         struct msm_camera_private_ioctl_arg *k_ioctl,
1182         void __user **tmp_compat_ioctl_ptr)
1183 {
1184         struct msm_camera_private_ioctl_arg up_ioctl;
1185
1186         if (WARN_ON(!arg || !k_ioctl || !tmp_compat_ioctl_ptr))
1187                 return -EIO;
1188
1189         if (copy_from_user(&up_ioctl,
1190                 (void __user *)arg,
1191                 sizeof(struct msm_camera_private_ioctl_arg)))
1192                 return -EFAULT;
1193
1194         k_ioctl->id = up_ioctl.id;
1195         k_ioctl->size = up_ioctl.size;
1196         k_ioctl->result = up_ioctl.result;
1197         k_ioctl->reserved = up_ioctl.reserved;
1198         *tmp_compat_ioctl_ptr = compat_ptr(up_ioctl.ioctl_ptr);
1199
1200         return 0;
1201 }
1202 EXPORT_SYMBOL(msm_copy_camera_private_ioctl_args);
1203 #endif
1204
1205 static void msm_sd_notify(struct v4l2_subdev *sd,
1206         unsigned int notification, void *arg)
1207 {
1208         int rc = 0;
1209         struct v4l2_subdev *subdev = NULL;
1210
1211         if (WARN_ON(!sd) || WARN_ON(!arg))
1212                 return;
1213
1214         /* Check if subdev exists before processing*/
1215         if (!msm_sd_find(sd->name))
1216                 return;
1217
1218         switch (notification) {
1219         case MSM_SD_NOTIFY_GET_SD: {
1220                 struct msm_sd_req_sd *get_sd = arg;
1221
1222                 get_sd->subdev = msm_sd_find(get_sd->name);
1223                 /* TODO: might need to add ref count on ret_sd */
1224         }
1225                 break;
1226
1227         case MSM_SD_NOTIFY_PUT_SD: {
1228                 struct msm_sd_req_sd *put_sd = arg;
1229
1230                 subdev = msm_sd_find(put_sd->name);
1231         }
1232                 break;
1233
1234         case MSM_SD_NOTIFY_REQ_CB: {
1235                 struct msm_sd_req_vb2_q *req_sd = arg;
1236
1237                 rc = msm_vb2_request_cb(req_sd);
1238                 if (rc < 0)
1239                         return;
1240         }
1241                 break;
1242
1243         default:
1244                 break;
1245         }
1246 }
1247
1248 static ssize_t write_logsync(struct file *file, const char __user *buf,
1249                 size_t count, loff_t *ppos)
1250 {
1251         char lbuf[LOGSYNC_PACKET_SIZE] = {0};
1252         uint64_t seq_num = 0;
1253
1254         if (copy_from_user(lbuf, buf, sizeof(lbuf)))
1255                 return -EFAULT;
1256
1257         if (kstrtoull(lbuf, 0, &seq_num) < 0)
1258                 pr_err("LOGSYNC (Kernel): Bad or malformed sequence number\n");
1259         else
1260                 pr_debug("LOGSYNC (Kernel): seq_num = %llu\n", seq_num);
1261
1262         return count;
1263 }
1264
1265
1266 static const struct file_operations logsync_fops = {
1267                 .write = write_logsync,
1268 };
1269
1270 static int msm_probe(struct platform_device *pdev)
1271 {
1272         struct msm_video_device *pvdev = NULL;
1273         static struct dentry *cam_debugfs_root;
1274         int rc = 0;
1275
1276         msm_v4l2_dev = kzalloc(sizeof(*msm_v4l2_dev),
1277                 GFP_KERNEL);
1278         if (!msm_v4l2_dev) {
1279                 rc = -ENOMEM;
1280                 goto probe_end;
1281         }
1282
1283         pvdev = kzalloc(sizeof(struct msm_video_device),
1284                 GFP_KERNEL);
1285         if (!pvdev) {
1286                 rc = -ENOMEM;
1287                 goto pvdev_fail;
1288         }
1289
1290         pvdev->vdev = video_device_alloc();
1291         if (!pvdev->vdev) {
1292                 rc = -ENOMEM;
1293                 goto video_fail;
1294         }
1295
1296 #if defined(CONFIG_MEDIA_CONTROLLER)
1297         msm_v4l2_dev->mdev = kzalloc(sizeof(struct media_device),
1298                 GFP_KERNEL);
1299         if (!msm_v4l2_dev->mdev) {
1300                 rc = -ENOMEM;
1301                 goto mdev_fail;
1302         }
1303         strlcpy(msm_v4l2_dev->mdev->model, MSM_CONFIGURATION_NAME,
1304                         sizeof(msm_v4l2_dev->mdev->model));
1305         msm_v4l2_dev->mdev->dev = &(pdev->dev);
1306
1307         rc = media_device_register(msm_v4l2_dev->mdev);
1308         if (WARN_ON(rc < 0))
1309                 goto media_fail;
1310
1311         if (WARN_ON((rc == media_entity_init(&pvdev->vdev->entity,
1312                         0, NULL, 0)) < 0))
1313                 goto entity_fail;
1314
1315         pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
1316         pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
1317 #endif
1318
1319         msm_v4l2_dev->notify = msm_sd_notify;
1320
1321         pvdev->vdev->v4l2_dev = msm_v4l2_dev;
1322
1323         rc = v4l2_device_register(&(pdev->dev), pvdev->vdev->v4l2_dev);
1324         if (WARN_ON(rc < 0))
1325                 goto register_fail;
1326
1327         strlcpy(pvdev->vdev->name, "msm-config", sizeof(pvdev->vdev->name));
1328         pvdev->vdev->release  = video_device_release;
1329         pvdev->vdev->fops     = &msm_fops;
1330         pvdev->vdev->ioctl_ops = &g_msm_ioctl_ops;
1331         pvdev->vdev->minor     = -1;
1332         pvdev->vdev->vfl_type  = VFL_TYPE_GRABBER;
1333         rc = video_register_device(pvdev->vdev,
1334                 VFL_TYPE_GRABBER, -1);
1335         if (WARN_ON(rc < 0))
1336                 goto v4l2_fail;
1337
1338 #if defined(CONFIG_MEDIA_CONTROLLER)
1339         /* FIXME: How to get rid of this messy? */
1340         pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev);
1341 #endif
1342
1343         atomic_set(&pvdev->opened, 0);
1344         video_set_drvdata(pvdev->vdev, pvdev);
1345
1346         msm_session_q = kzalloc(sizeof(*msm_session_q), GFP_KERNEL);
1347         if (!msm_session_q)
1348                 goto v4l2_fail;
1349
1350         msm_init_queue(msm_session_q);
1351         spin_lock_init(&msm_eventq_lock);
1352         spin_lock_init(&msm_pid_lock);
1353         INIT_LIST_HEAD(&ordered_sd_list);
1354
1355         cam_debugfs_root = debugfs_create_dir(MSM_CAM_LOGSYNC_FILE_BASEDIR,
1356                                                 NULL);
1357         if (!cam_debugfs_root) {
1358                 pr_warn("NON-FATAL: failed to create logsync base directory\n");
1359         } else {
1360                 if (!debugfs_create_file(MSM_CAM_LOGSYNC_FILE_NAME,
1361                                          0666,
1362                                          cam_debugfs_root,
1363                                          NULL,
1364                                          &logsync_fops))
1365                         pr_warn("NON-FATAL: failed to create logsync debugfs file\n");
1366         }
1367
1368         rc = cam_ahb_clk_init(pdev);
1369         if (rc < 0) {
1370                 pr_err("%s: failed to register ahb clocks\n", __func__);
1371                 goto v4l2_fail;
1372         }
1373
1374         goto probe_end;
1375
1376 v4l2_fail:
1377         v4l2_device_unregister(pvdev->vdev->v4l2_dev);
1378 register_fail:
1379 #if defined(CONFIG_MEDIA_CONTROLLER)
1380         media_entity_cleanup(&pvdev->vdev->entity);
1381 entity_fail:
1382         media_device_unregister(msm_v4l2_dev->mdev);
1383 media_fail:
1384         kzfree(msm_v4l2_dev->mdev);
1385 mdev_fail:
1386 #endif
1387         video_device_release(pvdev->vdev);
1388 video_fail:
1389         kzfree(pvdev);
1390 pvdev_fail:
1391         kzfree(msm_v4l2_dev);
1392 probe_end:
1393         return rc;
1394 }
1395
1396 static const struct of_device_id msm_dt_match[] = {
1397         {.compatible = "qcom,msm-cam"},
1398         {}
1399 };
1400 MODULE_DEVICE_TABLE(of, msm_dt_match);
1401
1402 static struct platform_driver msm_driver = {
1403         .probe = msm_probe,
1404         .driver = {
1405                 .name = "msm",
1406                 .owner = THIS_MODULE,
1407                 .of_match_table = msm_dt_match,
1408         },
1409 };
1410
1411 static int __init msm_init(void)
1412 {
1413         return platform_driver_register(&msm_driver);
1414 }
1415
1416 static void __exit msm_exit(void)
1417 {
1418         platform_driver_unregister(&msm_driver);
1419 }
1420
1421
1422 module_init(msm_init);
1423 module_exit(msm_exit);
1424 MODULE_DESCRIPTION("MSM V4L2 Camera");
1425 MODULE_LICENSE("GPL v2");