summaryrefslogtreecommitdiffstats
path: root/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c')
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c
new file mode 100644
index 000000000..bdb0ab617
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
+
+#include "vchiq_connected.h"
+#include "vchiq_core.h"
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+#define MAX_CALLBACKS 10
+
+static int g_connected;
+static int g_num_deferred_callbacks;
+static void (*g_deferred_callback[MAX_CALLBACKS])(void);
+static int g_once_init;
+static DEFINE_MUTEX(g_connected_mutex);
+
+/* Function to initialize our lock */
+static void connected_init(void)
+{
+ if (!g_once_init)
+ g_once_init = 1;
+}
+
+/*
+ * This function is used to defer initialization until the vchiq stack is
+ * initialized. If the stack is already initialized, then the callback will
+ * be made immediately, otherwise it will be deferred until
+ * vchiq_call_connected_callbacks is called.
+ */
+void vchiq_add_connected_callback(void (*callback)(void))
+{
+ connected_init();
+
+ if (mutex_lock_killable(&g_connected_mutex))
+ return;
+
+ if (g_connected) {
+ /* We're already connected. Call the callback immediately. */
+ callback();
+ } else {
+ if (g_num_deferred_callbacks >= MAX_CALLBACKS) {
+ vchiq_log_error(vchiq_core_log_level,
+ "There already %d callback registered - please increase MAX_CALLBACKS",
+ g_num_deferred_callbacks);
+ } else {
+ g_deferred_callback[g_num_deferred_callbacks] =
+ callback;
+ g_num_deferred_callbacks++;
+ }
+ }
+ mutex_unlock(&g_connected_mutex);
+}
+EXPORT_SYMBOL(vchiq_add_connected_callback);
+
+/*
+ * This function is called by the vchiq stack once it has been connected to
+ * the videocore and clients can start to use the stack.
+ */
+void vchiq_call_connected_callbacks(void)
+{
+ int i;
+
+ connected_init();
+
+ if (mutex_lock_killable(&g_connected_mutex))
+ return;
+
+ for (i = 0; i < g_num_deferred_callbacks; i++)
+ g_deferred_callback[i]();
+
+ g_num_deferred_callbacks = 0;
+ g_connected = 1;
+ mutex_unlock(&g_connected_mutex);
+}