linux/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c
<<
>>
Prefs
   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   VCHIQ_CONNECTED_CALLBACK_T g_deferred_callback[MAX_CALLBACKS];
  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/*
  26 * This function is used to defer initialization until the vchiq stack is
  27 * initialized. If the stack is already initialized, then the callback will
  28 * be made immediately, otherwise it will be deferred until
  29 * vchiq_call_connected_callbacks is called.
  30 */
  31void vchiq_add_connected_callback(VCHIQ_CONNECTED_CALLBACK_T callback)
  32{
  33        connected_init();
  34
  35        if (mutex_lock_killable(&g_connected_mutex))
  36                return;
  37
  38        if (g_connected)
  39                /* We're already connected. Call the callback immediately. */
  40
  41                callback();
  42        else {
  43                if (g_num_deferred_callbacks >= MAX_CALLBACKS)
  44                        vchiq_log_error(vchiq_core_log_level,
  45                                "There already %d callback registered - please increase MAX_CALLBACKS",
  46                                g_num_deferred_callbacks);
  47                else {
  48                        g_deferred_callback[g_num_deferred_callbacks] =
  49                                callback;
  50                        g_num_deferred_callbacks++;
  51                }
  52        }
  53        mutex_unlock(&g_connected_mutex);
  54}
  55EXPORT_SYMBOL(vchiq_add_connected_callback);
  56
  57/*
  58 * This function is called by the vchiq stack once it has been connected to
  59 * the videocore and clients can start to use the stack.
  60 */
  61void vchiq_call_connected_callbacks(void)
  62{
  63        int i;
  64
  65        connected_init();
  66
  67        if (mutex_lock_killable(&g_connected_mutex))
  68                return;
  69
  70        for (i = 0; i <  g_num_deferred_callbacks; i++)
  71                g_deferred_callback[i]();
  72
  73        g_num_deferred_callbacks = 0;
  74        g_connected = 1;
  75        mutex_unlock(&g_connected_mutex);
  76}
  77