staging: vc04_services: Move global g_state to vchiq_state

The patch intended to drop the g_state pointer.
g_state is supposed to be a central place to track the state
via vchiq_state. This is now moved to be contained in the
struct vchiq_drv_mgmt. As a result vchiq_get_state() is also removed.

In order to have access to vchiq_drv_mgmt, vchiq_initialise()
and vchiq_mmal_init() are modified to receive a struct device pointer
as one of their function parameter

The vchiq_state pointer is now passed directly to
vchiq_dump_platform_instances() to get access to the state instead
getting it via vchiq_get_state().

For the char device, struct miscdevice is retrieved by struct file's
private data in vchiq_open and struct vchiq_drv_mgmt is retrieved
thereafter.

Removal of global variable members is now addressed hence, drop
the corresponding item from the TODO list.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Link: https://lore.kernel.org/r/20240412075743.60712-11-umang.jain@ideasonboard.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Umang Jain 2024-04-12 13:27:42 +05:30 committed by Greg Kroah-Hartman
parent 7f56c601ca
commit 42a2f6664e
12 changed files with 37 additions and 55 deletions

View File

@ -7,6 +7,8 @@
#include "bcm2835.h" #include "bcm2835.h"
#include "vc_vchi_audioserv_defs.h" #include "vc_vchi_audioserv_defs.h"
#include "../interface/vchiq_arm/vchiq_arm.h"
struct bcm2835_audio_instance { struct bcm2835_audio_instance {
struct device *dev; struct device *dev;
unsigned int service_handle; unsigned int service_handle;
@ -175,10 +177,11 @@ static void vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance)
int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx) int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx)
{ {
struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(dev->parent);
int ret; int ret;
/* Initialize and create a VCHI connection */ /* Initialize and create a VCHI connection */
ret = vchiq_initialise(&vchi_ctx->instance); ret = vchiq_initialise(&mgmt->state, &vchi_ctx->instance);
if (ret) { if (ret) {
dev_err(dev, "failed to initialise VCHI instance (ret=%d)\n", dev_err(dev, "failed to initialise VCHI instance (ret=%d)\n",
ret); ret);

View File

@ -1555,7 +1555,7 @@ static int mmal_init(struct bcm2835_mmal_dev *dev)
u32 param_size; u32 param_size;
struct vchiq_mmal_component *camera; struct vchiq_mmal_component *camera;
ret = vchiq_mmal_init(&dev->instance); ret = vchiq_mmal_init(dev->v4l2_dev.dev, &dev->instance);
if (ret < 0) { if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "%s: vchiq mmal init failed %d\n", v4l2_err(&dev->v4l2_dev, "%s: vchiq mmal init failed %d\n",
__func__, ret); __func__, ret);
@ -1854,7 +1854,7 @@ static int bcm2835_mmal_probe(struct vchiq_device *device)
return ret; return ret;
} }
ret = vchiq_mmal_init(&instance); ret = vchiq_mmal_init(&device->dev, &instance);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -48,6 +48,7 @@ struct vchiq_element {
}; };
struct vchiq_instance; struct vchiq_instance;
struct vchiq_state;
struct vchiq_service_base { struct vchiq_service_base {
int fourcc; int fourcc;
@ -78,7 +79,8 @@ struct vchiq_service_params_kernel {
short version_min; /* Update for incompatible changes */ short version_min; /* Update for incompatible changes */
}; };
extern int vchiq_initialise(struct vchiq_instance **pinstance); extern int vchiq_initialise(struct vchiq_state *state,
struct vchiq_instance **pinstance);
extern int vchiq_shutdown(struct vchiq_instance *instance); extern int vchiq_shutdown(struct vchiq_instance *instance);
extern int vchiq_connect(struct vchiq_instance *instance); extern int vchiq_connect(struct vchiq_instance *instance);
extern int vchiq_open_service(struct vchiq_instance *instance, extern int vchiq_open_service(struct vchiq_instance *instance,

View File

@ -41,14 +41,6 @@ The code follows the 80 characters limitation yet tends to go 3 or 4 levels of
indentation deep making it very unpleasant to read. This is specially relevant indentation deep making it very unpleasant to read. This is specially relevant
in the character driver ioctl code and in the core thread functions. in the character driver ioctl code and in the core thread functions.
* Get rid of all non essential global structures and create a proper per
device structure
The first thing one generally sees in a probe function is a memory allocation
for all the device specific data. This structure is then passed all over the
driver. This is good practice since it makes the driver work regardless of the
number of devices probed.
* Clean up Sparse warnings from __user annotations. See * Clean up Sparse warnings from __user annotations. See
vchiq_irq_queue_bulk_tx_rx(). Ensure that the address of "&waiter->bulk_waiter" vchiq_irq_queue_bulk_tx_rx(). Ensure that the address of "&waiter->bulk_waiter"
is never disclosed to userspace. is never disclosed to userspace.

View File

@ -59,8 +59,6 @@
#define KEEPALIVE_VER 1 #define KEEPALIVE_VER 1
#define KEEPALIVE_VER_MIN KEEPALIVE_VER #define KEEPALIVE_VER_MIN KEEPALIVE_VER
struct vchiq_state g_state;
/* /*
* The devices implemented in the VCHIQ firmware are not discoverable, * The devices implemented in the VCHIQ firmware are not discoverable,
* so we need to maintain a list of them in order to register them with * so we need to maintain a list of them in order to register them with
@ -698,9 +696,8 @@ void vchiq_dump_platform_state(struct seq_file *f)
} }
#define VCHIQ_INIT_RETRIES 10 #define VCHIQ_INIT_RETRIES 10
int vchiq_initialise(struct vchiq_instance **instance_out) int vchiq_initialise(struct vchiq_state *state, struct vchiq_instance **instance_out)
{ {
struct vchiq_state *state;
struct vchiq_instance *instance = NULL; struct vchiq_instance *instance = NULL;
int i, ret; int i, ret;
@ -710,7 +707,6 @@ int vchiq_initialise(struct vchiq_instance **instance_out)
* block forever. * block forever.
*/ */
for (i = 0; i < VCHIQ_INIT_RETRIES; i++) { for (i = 0; i < VCHIQ_INIT_RETRIES; i++) {
state = vchiq_get_state();
if (state) if (state)
break; break;
usleep_range(500, 600); usleep_range(500, 600);
@ -1026,9 +1022,10 @@ add_completion(struct vchiq_instance *instance, enum vchiq_reason reason,
void *bulk_userdata) void *bulk_userdata)
{ {
struct vchiq_completion_data_kernel *completion; struct vchiq_completion_data_kernel *completion;
struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(instance->state->dev);
int insert; int insert;
DEBUG_INITIALISE(g_state.local); DEBUG_INITIALISE(mgmt->state.local);
insert = instance->completion_insert; insert = instance->completion_insert;
while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) { while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) {
@ -1091,11 +1088,12 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason,
* containing the original callback and the user state structure, which * containing the original callback and the user state structure, which
* contains a circular buffer for completion records. * contains a circular buffer for completion records.
*/ */
struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(instance->state->dev);
struct user_service *user_service; struct user_service *user_service;
struct vchiq_service *service; struct vchiq_service *service;
bool skip_completion = false; bool skip_completion = false;
DEBUG_INITIALISE(g_state.local); DEBUG_INITIALISE(mgmt->state.local);
DEBUG_TRACE(SERVICE_CALLBACK_LINE); DEBUG_TRACE(SERVICE_CALLBACK_LINE);
@ -1200,9 +1198,8 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason,
bulk_userdata); bulk_userdata);
} }
void vchiq_dump_platform_instances(struct seq_file *f) void vchiq_dump_platform_instances(struct vchiq_state *state, struct seq_file *f)
{ {
struct vchiq_state *state = vchiq_get_state();
int i; int i;
if (!state) if (!state)
@ -1277,23 +1274,6 @@ void vchiq_dump_platform_service_state(struct seq_file *f,
seq_puts(f, "\n"); seq_puts(f, "\n");
} }
struct vchiq_state *
vchiq_get_state(void)
{
if (!g_state.remote) {
pr_err("%s: g_state.remote == NULL\n", __func__);
return NULL;
}
if (g_state.remote->initialised != 1) {
pr_notice("%s: g_state.remote->initialised != 1 (%d)\n",
__func__, g_state.remote->initialised);
return NULL;
}
return &g_state;
}
/* /*
* Autosuspend related functionality * Autosuspend related functionality
*/ */
@ -1327,7 +1307,7 @@ vchiq_keepalive_thread_func(void *v)
.version_min = KEEPALIVE_VER_MIN .version_min = KEEPALIVE_VER_MIN
}; };
ret = vchiq_initialise(&instance); ret = vchiq_initialise(state, &instance);
if (ret) { if (ret) {
dev_err(state->dev, "suspend: %s: vchiq_initialise failed %d\n", __func__, ret); dev_err(state->dev, "suspend: %s: vchiq_initialise failed %d\n", __func__, ret);
goto exit; goto exit;
@ -1775,7 +1755,7 @@ static int vchiq_probe(struct platform_device *pdev)
mgmt->info = info; mgmt->info = info;
platform_set_drvdata(pdev, mgmt); platform_set_drvdata(pdev, mgmt);
err = vchiq_platform_init(pdev, &g_state); err = vchiq_platform_init(pdev, &mgmt->state);
if (err) if (err)
goto failed_platform_init; goto failed_platform_init;

View File

@ -52,6 +52,8 @@ struct vchiq_drv_mgmt {
unsigned int fragments_size; unsigned int fragments_size;
void __iomem *regs; void __iomem *regs;
struct vchiq_state state;
}; };
struct user_service { struct user_service {
@ -98,11 +100,6 @@ struct vchiq_instance {
struct vchiq_debugfs_node debugfs_node; struct vchiq_debugfs_node debugfs_node;
}; };
extern struct vchiq_state g_state;
extern struct vchiq_state *
vchiq_get_state(void);
int int
vchiq_use_service(struct vchiq_instance *instance, unsigned int handle); vchiq_use_service(struct vchiq_instance *instance, unsigned int handle);

View File

@ -3505,7 +3505,7 @@ void vchiq_dump_state(struct seq_file *f, struct vchiq_state *state)
vchiq_dump_shared_state(f, state, state->remote, "Remote"); vchiq_dump_shared_state(f, state, state->remote, "Remote");
vchiq_dump_platform_instances(f); vchiq_dump_platform_instances(state, f);
for (i = 0; i < state->unused_service; i++) { for (i = 0; i < state->unused_service; i++) {
struct vchiq_service *service = find_service_by_port(state, i); struct vchiq_service *service = find_service_by_port(state, i);

View File

@ -527,7 +527,7 @@ void remote_event_signal(struct vchiq_state *state, struct remote_event *event);
void vchiq_dump_platform_state(struct seq_file *f); void vchiq_dump_platform_state(struct seq_file *f);
void vchiq_dump_platform_instances(struct seq_file *f); void vchiq_dump_platform_instances(struct vchiq_state *state, struct seq_file *f);
void vchiq_dump_platform_service_state(struct seq_file *f, struct vchiq_service *service); void vchiq_dump_platform_service_state(struct seq_file *f, struct vchiq_service *service);

View File

@ -42,7 +42,10 @@ static int debugfs_trace_show(struct seq_file *f, void *offset)
static int vchiq_dump_show(struct seq_file *f, void *offset) static int vchiq_dump_show(struct seq_file *f, void *offset)
{ {
vchiq_dump_state(f, &g_state); struct vchiq_instance *instance = f->private;
vchiq_dump_state(f, instance->state);
return 0; return 0;
} }
DEFINE_SHOW_ATTRIBUTE(vchiq_dump); DEFINE_SHOW_ATTRIBUTE(vchiq_dump);

View File

@ -208,7 +208,7 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance,
struct vchiq_header *header; struct vchiq_header *header;
int ret; int ret;
DEBUG_INITIALISE(g_state.local); DEBUG_INITIALISE(instance->state->local);
DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
service = find_service_for_instance(instance, args->handle); service = find_service_for_instance(instance, args->handle);
if (!service) if (!service)
@ -435,7 +435,7 @@ static int vchiq_ioc_await_completion(struct vchiq_instance *instance,
int remove; int remove;
int ret; int ret;
DEBUG_INITIALISE(g_state.local); DEBUG_INITIALISE(instance->state->local);
DEBUG_TRACE(AWAIT_COMPLETION_LINE); DEBUG_TRACE(AWAIT_COMPLETION_LINE);
if (!instance->connected) if (!instance->connected)
@ -1163,7 +1163,9 @@ vchiq_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static int vchiq_open(struct inode *inode, struct file *file) static int vchiq_open(struct inode *inode, struct file *file)
{ {
struct vchiq_state *state = vchiq_get_state(); struct miscdevice *vchiq_miscdev = file->private_data;
struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(vchiq_miscdev->parent);
struct vchiq_state *state = &mgmt->state;
struct vchiq_instance *instance; struct vchiq_instance *instance;
dev_dbg(state->dev, "arm: vchiq open\n"); dev_dbg(state->dev, "arm: vchiq open\n");
@ -1196,7 +1198,7 @@ static int vchiq_open(struct inode *inode, struct file *file)
static int vchiq_release(struct inode *inode, struct file *file) static int vchiq_release(struct inode *inode, struct file *file)
{ {
struct vchiq_instance *instance = file->private_data; struct vchiq_instance *instance = file->private_data;
struct vchiq_state *state = vchiq_get_state(); struct vchiq_state *state = instance->state;
struct vchiq_service *service; struct vchiq_service *service;
int ret = 0; int ret = 0;
int i; int i;

View File

@ -26,6 +26,7 @@
#include <media/videobuf2-vmalloc.h> #include <media/videobuf2-vmalloc.h>
#include "../include/linux/raspberrypi/vchiq.h" #include "../include/linux/raspberrypi/vchiq.h"
#include "../interface/vchiq_arm/vchiq_arm.h"
#include "mmal-common.h" #include "mmal-common.h"
#include "mmal-vchiq.h" #include "mmal-vchiq.h"
#include "mmal-msg.h" #include "mmal-msg.h"
@ -1852,7 +1853,7 @@ int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
} }
EXPORT_SYMBOL_GPL(vchiq_mmal_finalise); EXPORT_SYMBOL_GPL(vchiq_mmal_finalise);
int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) int vchiq_mmal_init(struct device *dev, struct vchiq_mmal_instance **out_instance)
{ {
int status; int status;
int err = -ENODEV; int err = -ENODEV;
@ -1865,6 +1866,7 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
.callback = mmal_service_callback, .callback = mmal_service_callback,
.userdata = NULL, .userdata = NULL,
}; };
struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(dev->parent);
/* compile time checks to ensure structure size as they are /* compile time checks to ensure structure size as they are
* directly (de)serialised from memory. * directly (de)serialised from memory.
@ -1880,7 +1882,7 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
BUILD_BUG_ON(sizeof(struct mmal_port) != 64); BUILD_BUG_ON(sizeof(struct mmal_port) != 64);
/* create a vchi instance */ /* create a vchi instance */
status = vchiq_initialise(&vchiq_instance); status = vchiq_initialise(&mgmt->state, &vchiq_instance);
if (status) { if (status) {
pr_err("Failed to initialise VCHI instance (status=%d)\n", pr_err("Failed to initialise VCHI instance (status=%d)\n",
status); status);

View File

@ -25,6 +25,7 @@
#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128 #define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128
struct vchiq_mmal_instance; struct vchiq_mmal_instance;
struct device;
enum vchiq_mmal_es_type { enum vchiq_mmal_es_type {
MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */ MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */
@ -94,7 +95,7 @@ struct vchiq_mmal_component {
u32 client_component; /* Used to ref back to client struct */ u32 client_component; /* Used to ref back to client struct */
}; };
int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); int vchiq_mmal_init(struct device *dev, struct vchiq_mmal_instance **out_instance);
int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance); int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance);
/* Initialise a mmal component and its ports /* Initialise a mmal component and its ports