diff options
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.c | 74 |
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); +} |