Merge 5.2-rc3 into staging-next
[platform/kernel/linux-starfive.git] / drivers / staging / vc04_services / interface / vchiq_arm / vchiq_connected.c
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
3
4 #include "vchiq_connected.h"
5 #include "vchiq_core.h"
6 #include <linux/module.h>
7 #include <linux/mutex.h>
8
9 #define  MAX_CALLBACKS  10
10
11 static   int                        g_connected;
12 static   int                        g_num_deferred_callbacks;
13 static   VCHIQ_CONNECTED_CALLBACK_T g_deferred_callback[MAX_CALLBACKS];
14 static   int                        g_once_init;
15 static   struct mutex               g_connected_mutex;
16
17 /****************************************************************************
18 *
19 * Function to initialize our lock.
20 *
21 ***************************************************************************/
22
23 static void connected_init(void)
24 {
25         if (!g_once_init) {
26                 mutex_init(&g_connected_mutex);
27                 g_once_init = 1;
28         }
29 }
30
31 /****************************************************************************
32 *
33 * This function is used to defer initialization until the vchiq stack is
34 * initialized. If the stack is already initialized, then the callback will
35 * be made immediately, otherwise it will be deferred until
36 * vchiq_call_connected_callbacks is called.
37 *
38 ***************************************************************************/
39
40 void vchiq_add_connected_callback(VCHIQ_CONNECTED_CALLBACK_T callback)
41 {
42         connected_init();
43
44         if (mutex_lock_killable(&g_connected_mutex))
45                 return;
46
47         if (g_connected)
48                 /* We're already connected. Call the callback immediately. */
49
50                 callback();
51         else {
52                 if (g_num_deferred_callbacks >= MAX_CALLBACKS)
53                         vchiq_log_error(vchiq_core_log_level,
54                                 "There already %d callback registered - "
55                                 "please increase MAX_CALLBACKS",
56                                 g_num_deferred_callbacks);
57                 else {
58                         g_deferred_callback[g_num_deferred_callbacks] =
59                                 callback;
60                         g_num_deferred_callbacks++;
61                 }
62         }
63         mutex_unlock(&g_connected_mutex);
64 }
65
66 /****************************************************************************
67 *
68 * This function is called by the vchiq stack once it has been connected to
69 * the videocore and clients can start to use the stack.
70 *
71 ***************************************************************************/
72
73 void vchiq_call_connected_callbacks(void)
74 {
75         int i;
76
77         connected_init();
78
79         if (mutex_lock_killable(&g_connected_mutex))
80                 return;
81
82         for (i = 0; i <  g_num_deferred_callbacks; i++)
83                 g_deferred_callback[i]();
84
85         g_num_deferred_callbacks = 0;
86         g_connected = 1;
87         mutex_unlock(&g_connected_mutex);
88 }
89 EXPORT_SYMBOL(vchiq_add_connected_callback);