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
11static int g_connected;
12static int g_num_deferred_callbacks;
13static void (*g_deferred_callback[MAX_CALLBACKS])(void);
14static int g_once_init;
15static DEFINE_MUTEX(g_connected_mutex);
16
17/* Function to initialize our lock */
18static void connected_init(void)
19{
20 if (!g_once_init)
21 g_once_init = 1;
22}
23
24/*
25 * This function is used to defer initialization until the vchiq stack is
26 * initialized. If the stack is already initialized, then the callback will
27 * be made immediately, otherwise it will be deferred until
28 * vchiq_call_connected_callbacks is called.
29 */
30void vchiq_add_connected_callback(struct vchiq_device *device, void (*callback)(void))
31{
32 connected_init();
33
34 if (mutex_lock_killable(&g_connected_mutex))
35 return;
36
37 if (g_connected) {
38 /* We're already connected. Call the callback immediately. */
39 callback();
40 } else {
41 if (g_num_deferred_callbacks >= MAX_CALLBACKS) {
42 dev_err(&device->dev,
43 "core: There already %d callback registered - please increase MAX_CALLBACKS\n",
44 g_num_deferred_callbacks);
45 } else {
46 g_deferred_callback[g_num_deferred_callbacks] =
47 callback;
48 g_num_deferred_callbacks++;
49 }
50 }
51 mutex_unlock(lock: &g_connected_mutex);
52}
53EXPORT_SYMBOL(vchiq_add_connected_callback);
54
55/*
56 * This function is called by the vchiq stack once it has been connected to
57 * the videocore and clients can start to use the stack.
58 */
59void vchiq_call_connected_callbacks(void)
60{
61 int i;
62
63 connected_init();
64
65 if (mutex_lock_killable(&g_connected_mutex))
66 return;
67
68 for (i = 0; i < g_num_deferred_callbacks; i++)
69 g_deferred_callback[i]();
70
71 g_num_deferred_callbacks = 0;
72 g_connected = 1;
73 mutex_unlock(lock: &g_connected_mutex);
74}
75

source code of linux/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c