diff mbox series

[2/3] staging: vchiq_arm: get rid of global device structure

Message ID 20220502183045.206519-3-athierry@redhat.com (mailing list archive)
State New, archived
Headers show
Series staging: vchiq_arm: remove some unnecessary global | expand

Commit Message

Adrien Thierry May 2, 2022, 6:30 p.m. UTC
Get rid of the global g_dev structure.

This is part of an effort to address TODO item "Get rid of all non
essential global structures and create a proper per device structure"

Signed-off-by: Adrien Thierry <athierry@redhat.com>
---
 .../bcm2835-audio/bcm2835-vchiq.c             |  7 ++-
 .../include/linux/raspberrypi/vchiq.h         | 12 ++--
 .../interface/vchiq_arm/vchiq_arm.c           | 63 +++++++++----------
 .../interface/vchiq_arm/vchiq_core.c          | 14 ++---
 .../interface/vchiq_arm/vchiq_core.h          | 10 +--
 .../interface/vchiq_arm/vchiq_dev.c           |  2 +-
 .../vc04_services/vchiq-mmal/mmal-vchiq.c     |  2 +-
 7 files changed, 53 insertions(+), 57 deletions(-)

Comments

Stefan Wahren May 4, 2022, 3:05 p.m. UTC | #1
Hi Adrien,

Am 02.05.22 um 20:30 schrieb Adrien Thierry:
> Get rid of the global g_dev structure.

i understand the motivation, but could you please explain more in detail 
why you decided to add vchiq_instance instead of device reference? I 
think vchiq_instance is a more internal structure which should be 
avoided in kernel consumers like bcm2835-audio or mmal.

Best regards

>
> This is part of an effort to address TODO item "Get rid of all non
> essential global structures and create a proper per device structure"
>
> Signed-off-by: Adrien Thierry <athierry@redhat.com>
> ---
>   .../bcm2835-audio/bcm2835-vchiq.c             |  7 ++-
>   .../include/linux/raspberrypi/vchiq.h         | 12 ++--
>   .../interface/vchiq_arm/vchiq_arm.c           | 63 +++++++++----------
>   .../interface/vchiq_arm/vchiq_core.c          | 14 ++---
>   .../interface/vchiq_arm/vchiq_core.h          | 10 +--
>   .../interface/vchiq_arm/vchiq_dev.c           |  2 +-
>   .../vc04_services/vchiq-mmal/mmal-vchiq.c     |  2 +-
>   7 files changed, 53 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
> index e429b33b4d39..701abe430877 100644
> --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
> +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
> @@ -322,6 +322,8 @@ int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
>   			unsigned int size, void *src)
>   {
>   	struct bcm2835_audio_instance *instance = alsa_stream->instance;
> +	struct bcm2835_vchi_ctx *vchi_ctx = alsa_stream->chip->vchi_ctx;
> +	struct vchiq_instance *vchiq_instance = vchi_ctx->instance;
>   	struct vc_audio_msg m = {
>   		.type = VC_AUDIO_MSG_TYPE_WRITE,
>   		.write.count = size,
> @@ -343,9 +345,8 @@ int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
>   	count = size;
>   	if (!instance->max_packet) {
>   		/* Send the message to the videocore */
> -		status = vchiq_bulk_transmit(instance->service_handle, src,
> -					     count, NULL,
> -					     VCHIQ_BULK_MODE_BLOCKING);
> +		status = vchiq_bulk_transmit(vchiq_instance, instance->service_handle, src, count,
> +					     NULL, VCHIQ_BULK_MODE_BLOCKING);
>   	} else {
>   		while (count > 0) {
>   			int bytes = min(instance->max_packet, count);
> diff --git a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
> index c93f2f3e87bb..715f02e7f1e1 100644
> --- a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
> +++ b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
> @@ -96,12 +96,12 @@ extern void           vchiq_release_message(unsigned int service,
>   	struct vchiq_header *header);
>   extern int vchiq_queue_kernel_message(unsigned int handle, void *data,
>   				      unsigned int size);
> -extern enum vchiq_status vchiq_bulk_transmit(unsigned int service,
> -	const void *data, unsigned int size, void *userdata,
> -	enum vchiq_bulk_mode mode);
> -extern enum vchiq_status vchiq_bulk_receive(unsigned int service,
> -	void *data, unsigned int size, void *userdata,
> -	enum vchiq_bulk_mode mode);
> +extern enum vchiq_status vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int service,
> +					     const void *data, unsigned int size, void *userdata,
> +					     enum vchiq_bulk_mode mode);
> +extern enum vchiq_status vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int service,
> +					    void *data, unsigned int size, void *userdata,
> +					    enum vchiq_bulk_mode mode);
>   extern void *vchiq_get_service_userdata(unsigned int service);
>   extern enum vchiq_status vchiq_get_peer_version(unsigned int handle,
>   	short *peer_version);
> diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
> index e6e0737c85fc..3b447c635c3f 100644
> --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
> +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
> @@ -148,12 +148,11 @@ static unsigned int g_fragments_size;
>   static char *g_fragments_base;
>   static char *g_free_fragments;
>   static struct semaphore g_free_fragments_sema;
> -static struct device *g_dev;
>   
>   static DEFINE_SEMAPHORE(g_free_fragments_mutex);
>   
>   static enum vchiq_status
> -vchiq_blocking_bulk_transfer(unsigned int handle, void *data,
> +vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *data,
>   			     unsigned int size, enum vchiq_bulk_dir dir);
>   
>   static irqreturn_t
> @@ -175,17 +174,17 @@ vchiq_doorbell_irq(int irq, void *dev_id)
>   }
>   
>   static void
> -cleanup_pagelistinfo(struct vchiq_pagelist_info *pagelistinfo)
> +cleanup_pagelistinfo(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo)
>   {
>   	if (pagelistinfo->scatterlist_mapped) {
> -		dma_unmap_sg(g_dev, pagelistinfo->scatterlist,
> +		dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist,
>   			     pagelistinfo->num_pages, pagelistinfo->dma_dir);
>   	}
>   
>   	if (pagelistinfo->pages_need_release)
>   		unpin_user_pages(pagelistinfo->pages, pagelistinfo->num_pages);
>   
> -	dma_free_coherent(g_dev, pagelistinfo->pagelist_buffer_size,
> +	dma_free_coherent(instance->state->dev, pagelistinfo->pagelist_buffer_size,
>   			  pagelistinfo->pagelist, pagelistinfo->dma_addr);
>   }
>   
> @@ -212,7 +211,7 @@ is_adjacent_block(u32 *addrs, u32 addr, unsigned int k)
>    */
>   
>   static struct vchiq_pagelist_info *
> -create_pagelist(char *buf, char __user *ubuf,
> +create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf,
>   		size_t count, unsigned short type)
>   {
>   	struct pagelist *pagelist;
> @@ -250,7 +249,7 @@ create_pagelist(char *buf, char __user *ubuf,
>   	/* Allocate enough storage to hold the page pointers and the page
>   	 * list
>   	 */
> -	pagelist = dma_alloc_coherent(g_dev, pagelist_size, &dma_addr,
> +	pagelist = dma_alloc_coherent(instance->state->dev, pagelist_size, &dma_addr,
>   				      GFP_KERNEL);
>   
>   	vchiq_log_trace(vchiq_arm_log_level, "%s - %pK", __func__, pagelist);
> @@ -292,7 +291,7 @@ create_pagelist(char *buf, char __user *ubuf,
>   			size_t bytes = PAGE_SIZE - off;
>   
>   			if (!pg) {
> -				cleanup_pagelistinfo(pagelistinfo);
> +				cleanup_pagelistinfo(instance, pagelistinfo);
>   				return NULL;
>   			}
>   
> @@ -315,7 +314,7 @@ create_pagelist(char *buf, char __user *ubuf,
>   			/* This is probably due to the process being killed */
>   			if (actual_pages > 0)
>   				unpin_user_pages(pages, actual_pages);
> -			cleanup_pagelistinfo(pagelistinfo);
> +			cleanup_pagelistinfo(instance, pagelistinfo);
>   			return NULL;
>   		}
>   		 /* release user pages */
> @@ -338,13 +337,13 @@ create_pagelist(char *buf, char __user *ubuf,
>   		count -= len;
>   	}
>   
> -	dma_buffers = dma_map_sg(g_dev,
> +	dma_buffers = dma_map_sg(instance->state->dev,
>   				 scatterlist,
>   				 num_pages,
>   				 pagelistinfo->dma_dir);
>   
>   	if (dma_buffers == 0) {
> -		cleanup_pagelistinfo(pagelistinfo);
> +		cleanup_pagelistinfo(instance, pagelistinfo);
>   		return NULL;
>   	}
>   
> @@ -378,7 +377,7 @@ create_pagelist(char *buf, char __user *ubuf,
>   		char *fragments;
>   
>   		if (down_interruptible(&g_free_fragments_sema)) {
> -			cleanup_pagelistinfo(pagelistinfo);
> +			cleanup_pagelistinfo(instance, pagelistinfo);
>   			return NULL;
>   		}
>   
> @@ -397,7 +396,7 @@ create_pagelist(char *buf, char __user *ubuf,
>   }
>   
>   static void
> -free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
> +free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo,
>   	      int actual)
>   {
>   	struct pagelist *pagelist = pagelistinfo->pagelist;
> @@ -411,7 +410,7 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
>   	 * NOTE: dma_unmap_sg must be called before the
>   	 * cpu can touch any of the data/pages.
>   	 */
> -	dma_unmap_sg(g_dev, pagelistinfo->scatterlist,
> +	dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist,
>   		     pagelistinfo->num_pages, pagelistinfo->dma_dir);
>   	pagelistinfo->scatterlist_mapped = 0;
>   
> @@ -460,7 +459,7 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
>   			set_page_dirty(pages[i]);
>   	}
>   
> -	cleanup_pagelistinfo(pagelistinfo);
> +	cleanup_pagelistinfo(instance, pagelistinfo);
>   }
>   
>   int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
> @@ -547,7 +546,6 @@ int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
>   		return err ? : -ENXIO;
>   	}
>   
> -	g_dev = dev;
>   	vchiq_log_info(vchiq_arm_log_level, "vchiq_init - done (slots %pK, phys %pad)",
>   		       vchiq_slot_zero, &slot_phys);
>   
> @@ -615,12 +613,12 @@ remote_event_signal(struct remote_event *event)
>   }
>   
>   int
> -vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset,
> +vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk, void *offset,
>   			void __user *uoffset, int size, int dir)
>   {
>   	struct vchiq_pagelist_info *pagelistinfo;
>   
> -	pagelistinfo = create_pagelist(offset, uoffset, size,
> +	pagelistinfo = create_pagelist(instance, offset, uoffset, size,
>   				       (dir == VCHIQ_BULK_RECEIVE)
>   				       ? PAGELIST_READ
>   				       : PAGELIST_WRITE);
> @@ -640,10 +638,10 @@ vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset,
>   }
>   
>   void
> -vchiq_complete_bulk(struct vchiq_bulk *bulk)
> +vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk)
>   {
>   	if (bulk && bulk->remote_data && bulk->actual)
> -		free_pagelist((struct vchiq_pagelist_info *)bulk->remote_data,
> +		free_pagelist(instance, (struct vchiq_pagelist_info *)bulk->remote_data,
>   			      bulk->actual);
>   }
>   
> @@ -834,8 +832,8 @@ vchiq_open_service(struct vchiq_instance *instance,
>   EXPORT_SYMBOL(vchiq_open_service);
>   
>   enum vchiq_status
> -vchiq_bulk_transmit(unsigned int handle, const void *data, unsigned int size,
> -		    void *userdata, enum vchiq_bulk_mode mode)
> +vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int handle, const void *data,
> +		    unsigned int size, void *userdata, enum vchiq_bulk_mode mode)
>   {
>   	enum vchiq_status status;
>   
> @@ -843,13 +841,13 @@ vchiq_bulk_transmit(unsigned int handle, const void *data, unsigned int size,
>   		switch (mode) {
>   		case VCHIQ_BULK_MODE_NOCALLBACK:
>   		case VCHIQ_BULK_MODE_CALLBACK:
> -			status = vchiq_bulk_transfer(handle,
> +			status = vchiq_bulk_transfer(instance, handle,
>   						     (void *)data, NULL,
>   						     size, userdata, mode,
>   						     VCHIQ_BULK_TRANSMIT);
>   			break;
>   		case VCHIQ_BULK_MODE_BLOCKING:
> -			status = vchiq_blocking_bulk_transfer(handle, (void *)data, size,
> +			status = vchiq_blocking_bulk_transfer(instance, handle, (void *)data, size,
>   							      VCHIQ_BULK_TRANSMIT);
>   			break;
>   		default:
> @@ -871,8 +869,8 @@ vchiq_bulk_transmit(unsigned int handle, const void *data, unsigned int size,
>   }
>   EXPORT_SYMBOL(vchiq_bulk_transmit);
>   
> -enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data,
> -				     unsigned int size, void *userdata,
> +enum vchiq_status vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int handle,
> +				     void *data, unsigned int size, void *userdata,
>   				     enum vchiq_bulk_mode mode)
>   {
>   	enum vchiq_status status;
> @@ -881,12 +879,12 @@ enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data,
>   		switch (mode) {
>   		case VCHIQ_BULK_MODE_NOCALLBACK:
>   		case VCHIQ_BULK_MODE_CALLBACK:
> -			status = vchiq_bulk_transfer(handle, data, NULL,
> +			status = vchiq_bulk_transfer(instance, handle, data, NULL,
>   						     size, userdata,
>   						     mode, VCHIQ_BULK_RECEIVE);
>   			break;
>   		case VCHIQ_BULK_MODE_BLOCKING:
> -			status = vchiq_blocking_bulk_transfer(handle, (void *)data, size,
> +			status = vchiq_blocking_bulk_transfer(instance, handle, (void *)data, size,
>   							      VCHIQ_BULK_RECEIVE);
>   			break;
>   		default:
> @@ -909,10 +907,9 @@ enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data,
>   EXPORT_SYMBOL(vchiq_bulk_receive);
>   
>   static enum vchiq_status
> -vchiq_blocking_bulk_transfer(unsigned int handle, void *data, unsigned int size,
> -			     enum vchiq_bulk_dir dir)
> +vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *data,
> +			     unsigned int size, enum vchiq_bulk_dir dir)
>   {
> -	struct vchiq_instance *instance;
>   	struct vchiq_service *service;
>   	enum vchiq_status status;
>   	struct bulk_waiter_node *waiter = NULL, *iter;
> @@ -921,8 +918,6 @@ vchiq_blocking_bulk_transfer(unsigned int handle, void *data, unsigned int size,
>   	if (!service)
>   		return VCHIQ_ERROR;
>   
> -	instance = service->instance;
> -
>   	vchiq_service_put(service);
>   
>   	mutex_lock(&instance->bulk_waiter_list_mutex);
> @@ -959,7 +954,7 @@ vchiq_blocking_bulk_transfer(unsigned int handle, void *data, unsigned int size,
>   		}
>   	}
>   
> -	status = vchiq_bulk_transfer(handle, data, NULL, size,
> +	status = vchiq_bulk_transfer(instance, handle, data, NULL, size,
>   				     &waiter->bulk_waiter,
>   				     VCHIQ_BULK_MODE_BLOCKING, dir);
>   	if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) || !waiter->bulk_waiter.bulk) {
> diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
> index 0d5c39d7c6e2..04eec18835da 100644
> --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
> +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
> @@ -1441,7 +1441,7 @@ abort_outstanding_bulks(struct vchiq_service *service,
>   		}
>   
>   		if (queue->process != queue->local_insert) {
> -			vchiq_complete_bulk(bulk);
> +			vchiq_complete_bulk(service->instance, bulk);
>   
>   			vchiq_log_info(SRVTRACE_LEVEL(service),
>   				       "%s %c%c%c%c d:%d ABORTED - tx len:%d, rx len:%d",
> @@ -1769,7 +1769,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
>   
>   			DEBUG_TRACE(PARSE_LINE);
>   			WARN_ON(queue->process == queue->local_insert);
> -			vchiq_complete_bulk(bulk);
> +			vchiq_complete_bulk(service->instance, bulk);
>   			queue->process++;
>   			mutex_unlock(&service->bulk_mutex);
>   			DEBUG_TRACE(PARSE_LINE);
> @@ -2998,9 +2998,9 @@ vchiq_remove_service(unsigned int handle)
>    * When called in blocking mode, the userdata field points to a bulk_waiter
>    * structure.
>    */
> -enum vchiq_status vchiq_bulk_transfer(unsigned int handle, void *offset, void __user *uoffset,
> -				      int size, void *userdata, enum vchiq_bulk_mode mode,
> -				      enum vchiq_bulk_dir dir)
> +enum vchiq_status vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle,
> +				      void *offset, void __user *uoffset, int size, void *userdata,
> +				      enum vchiq_bulk_mode mode, enum vchiq_bulk_dir dir)
>   {
>   	struct vchiq_service *service = find_service_by_handle(handle);
>   	struct vchiq_bulk_queue *queue;
> @@ -3077,7 +3077,7 @@ enum vchiq_status vchiq_bulk_transfer(unsigned int handle, void *offset, void __
>   	bulk->size = size;
>   	bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
>   
> -	if (vchiq_prepare_bulk_data(bulk, offset, uoffset, size, dir))
> +	if (vchiq_prepare_bulk_data(instance, bulk, offset, uoffset, size, dir))
>   		goto unlock_error_exit;
>   
>   	wmb();
> @@ -3141,7 +3141,7 @@ enum vchiq_status vchiq_bulk_transfer(unsigned int handle, void *offset, void __
>   unlock_both_error_exit:
>   	mutex_unlock(&state->slot_mutex);
>   cancel_bulk_error_exit:
> -	vchiq_complete_bulk(bulk);
> +	vchiq_complete_bulk(service->instance, bulk);
>   unlock_error_exit:
>   	mutex_unlock(&service->bulk_mutex);
>   
> diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
> index 352017ff5309..2ce54ce9f02a 100644
> --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
> +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
> @@ -489,8 +489,8 @@ extern void
>   remote_event_pollall(struct vchiq_state *state);
>   
>   extern enum vchiq_status
> -vchiq_bulk_transfer(unsigned int handle, void *offset, void __user *uoffset,
> -		    int size, void *userdata, enum vchiq_bulk_mode mode,
> +vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *offset,
> +		    void __user *uoffset, int size, void *userdata, enum vchiq_bulk_mode mode,
>   		    enum vchiq_bulk_dir dir);
>   
>   extern int
> @@ -556,10 +556,10 @@ vchiq_queue_message(unsigned int handle,
>   		    void *context,
>   		    size_t size);
>   
> -int vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset, void __user *uoffset,
> -			    int size, int dir);
> +int vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk, void *offset,
> +			    void __user *uoffset, int size, int dir);
>   
> -void vchiq_complete_bulk(struct vchiq_bulk *bulk);
> +void vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk);
>   
>   void remote_event_signal(struct remote_event *event);
>   
> diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
> index 66bbfec332ba..077e3fcbd651 100644
> --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
> +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
> @@ -330,7 +330,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance,
>   		userdata = args->userdata;
>   	}
>   
> -	status = vchiq_bulk_transfer(args->handle, NULL, args->data, args->size,
> +	status = vchiq_bulk_transfer(instance, args->handle, NULL, args->data, args->size,
>   				     userdata, args->mode, dir);
>   
>   	if (!waiter) {
> diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
> index 249dd3e30c2f..88813af8de49 100644
> --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
> +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
> @@ -293,7 +293,7 @@ static void buffer_to_host_work_cb(struct work_struct *work)
>   		len = 8;
>   	/* queue the bulk submission */
>   	vchiq_use_service(instance->service_handle);
> -	ret = vchiq_bulk_receive(instance->service_handle,
> +	ret = vchiq_bulk_receive(instance->vchiq_instance, instance->service_handle,
>   				 msg_context->u.bulk.buffer->buffer,
>   				 /* Actual receive needs to be a multiple
>   				  * of 4 bytes
Adrien Thierry May 5, 2022, 6:11 p.m. UTC | #2
Hi Stefan,

Thanks for your feedback.

> i understand the motivation, but could you please explain more in detail
> why you decided to add vchiq_instance instead of device reference? I
> think vchiq_instance is a more internal structure which should be
> avoided in kernel consumers like bcm2835-audio or mmal.

I used the vchiq_instance instead of the device reference because in order
to get rid of the vchiq_states array (patch 3/3 [1]), I needed another way
to access the vchiq_state in the 'handle_to_service' function. So I passed
the vchiq_instance to it (I could also have passed the state directly
instead of the instance), and this propagated in the caller chain all the
way up to 'vchiq_bulk_transmit' and friends which are used in the
bcm2835-audio consumer.  Please let me know if you see a better way of
doing this :)

Thanks,

Adrien

[1] https://lore.kernel.org/all/20220502183045.206519-4-athierry@redhat.com/
Stefan Wahren May 9, 2022, 10:51 a.m. UTC | #3
Hi Adrien,

Am 05.05.22 um 20:11 schrieb Adrien Thierry:
> Hi Stefan,
>
> Thanks for your feedback.
>
>> i understand the motivation, but could you please explain more in detail
>> why you decided to add vchiq_instance instead of device reference? I
>> think vchiq_instance is a more internal structure which should be
>> avoided in kernel consumers like bcm2835-audio or mmal.
> I used the vchiq_instance instead of the device reference because in order
> to get rid of the vchiq_states array (patch 3/3 [1]), I needed another way
> to access the vchiq_state in the 'handle_to_service' function. So I passed
> the vchiq_instance to it (I could also have passed the state directly
> instead of the instance), and this propagated in the caller chain all the
> way up to 'vchiq_bulk_transmit' and friends which are used in the
> bcm2835-audio consumer.

Okay, in this case please add this explanation to the commit message.

Best regards

>    Please let me know if you see a better way of
> doing this :)
>
> Thanks,
>
> Adrien
>
> [1] https://lore.kernel.org/all/20220502183045.206519-4-athierry@redhat.com/
>
diff mbox series

Patch

diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
index e429b33b4d39..701abe430877 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
@@ -322,6 +322,8 @@  int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
 			unsigned int size, void *src)
 {
 	struct bcm2835_audio_instance *instance = alsa_stream->instance;
+	struct bcm2835_vchi_ctx *vchi_ctx = alsa_stream->chip->vchi_ctx;
+	struct vchiq_instance *vchiq_instance = vchi_ctx->instance;
 	struct vc_audio_msg m = {
 		.type = VC_AUDIO_MSG_TYPE_WRITE,
 		.write.count = size,
@@ -343,9 +345,8 @@  int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
 	count = size;
 	if (!instance->max_packet) {
 		/* Send the message to the videocore */
-		status = vchiq_bulk_transmit(instance->service_handle, src,
-					     count, NULL,
-					     VCHIQ_BULK_MODE_BLOCKING);
+		status = vchiq_bulk_transmit(vchiq_instance, instance->service_handle, src, count,
+					     NULL, VCHIQ_BULK_MODE_BLOCKING);
 	} else {
 		while (count > 0) {
 			int bytes = min(instance->max_packet, count);
diff --git a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
index c93f2f3e87bb..715f02e7f1e1 100644
--- a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
+++ b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
@@ -96,12 +96,12 @@  extern void           vchiq_release_message(unsigned int service,
 	struct vchiq_header *header);
 extern int vchiq_queue_kernel_message(unsigned int handle, void *data,
 				      unsigned int size);
-extern enum vchiq_status vchiq_bulk_transmit(unsigned int service,
-	const void *data, unsigned int size, void *userdata,
-	enum vchiq_bulk_mode mode);
-extern enum vchiq_status vchiq_bulk_receive(unsigned int service,
-	void *data, unsigned int size, void *userdata,
-	enum vchiq_bulk_mode mode);
+extern enum vchiq_status vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int service,
+					     const void *data, unsigned int size, void *userdata,
+					     enum vchiq_bulk_mode mode);
+extern enum vchiq_status vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int service,
+					    void *data, unsigned int size, void *userdata,
+					    enum vchiq_bulk_mode mode);
 extern void *vchiq_get_service_userdata(unsigned int service);
 extern enum vchiq_status vchiq_get_peer_version(unsigned int handle,
 	short *peer_version);
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index e6e0737c85fc..3b447c635c3f 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -148,12 +148,11 @@  static unsigned int g_fragments_size;
 static char *g_fragments_base;
 static char *g_free_fragments;
 static struct semaphore g_free_fragments_sema;
-static struct device *g_dev;
 
 static DEFINE_SEMAPHORE(g_free_fragments_mutex);
 
 static enum vchiq_status
-vchiq_blocking_bulk_transfer(unsigned int handle, void *data,
+vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *data,
 			     unsigned int size, enum vchiq_bulk_dir dir);
 
 static irqreturn_t
@@ -175,17 +174,17 @@  vchiq_doorbell_irq(int irq, void *dev_id)
 }
 
 static void
-cleanup_pagelistinfo(struct vchiq_pagelist_info *pagelistinfo)
+cleanup_pagelistinfo(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo)
 {
 	if (pagelistinfo->scatterlist_mapped) {
-		dma_unmap_sg(g_dev, pagelistinfo->scatterlist,
+		dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist,
 			     pagelistinfo->num_pages, pagelistinfo->dma_dir);
 	}
 
 	if (pagelistinfo->pages_need_release)
 		unpin_user_pages(pagelistinfo->pages, pagelistinfo->num_pages);
 
-	dma_free_coherent(g_dev, pagelistinfo->pagelist_buffer_size,
+	dma_free_coherent(instance->state->dev, pagelistinfo->pagelist_buffer_size,
 			  pagelistinfo->pagelist, pagelistinfo->dma_addr);
 }
 
@@ -212,7 +211,7 @@  is_adjacent_block(u32 *addrs, u32 addr, unsigned int k)
  */
 
 static struct vchiq_pagelist_info *
-create_pagelist(char *buf, char __user *ubuf,
+create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf,
 		size_t count, unsigned short type)
 {
 	struct pagelist *pagelist;
@@ -250,7 +249,7 @@  create_pagelist(char *buf, char __user *ubuf,
 	/* Allocate enough storage to hold the page pointers and the page
 	 * list
 	 */
-	pagelist = dma_alloc_coherent(g_dev, pagelist_size, &dma_addr,
+	pagelist = dma_alloc_coherent(instance->state->dev, pagelist_size, &dma_addr,
 				      GFP_KERNEL);
 
 	vchiq_log_trace(vchiq_arm_log_level, "%s - %pK", __func__, pagelist);
@@ -292,7 +291,7 @@  create_pagelist(char *buf, char __user *ubuf,
 			size_t bytes = PAGE_SIZE - off;
 
 			if (!pg) {
-				cleanup_pagelistinfo(pagelistinfo);
+				cleanup_pagelistinfo(instance, pagelistinfo);
 				return NULL;
 			}
 
@@ -315,7 +314,7 @@  create_pagelist(char *buf, char __user *ubuf,
 			/* This is probably due to the process being killed */
 			if (actual_pages > 0)
 				unpin_user_pages(pages, actual_pages);
-			cleanup_pagelistinfo(pagelistinfo);
+			cleanup_pagelistinfo(instance, pagelistinfo);
 			return NULL;
 		}
 		 /* release user pages */
@@ -338,13 +337,13 @@  create_pagelist(char *buf, char __user *ubuf,
 		count -= len;
 	}
 
-	dma_buffers = dma_map_sg(g_dev,
+	dma_buffers = dma_map_sg(instance->state->dev,
 				 scatterlist,
 				 num_pages,
 				 pagelistinfo->dma_dir);
 
 	if (dma_buffers == 0) {
-		cleanup_pagelistinfo(pagelistinfo);
+		cleanup_pagelistinfo(instance, pagelistinfo);
 		return NULL;
 	}
 
@@ -378,7 +377,7 @@  create_pagelist(char *buf, char __user *ubuf,
 		char *fragments;
 
 		if (down_interruptible(&g_free_fragments_sema)) {
-			cleanup_pagelistinfo(pagelistinfo);
+			cleanup_pagelistinfo(instance, pagelistinfo);
 			return NULL;
 		}
 
@@ -397,7 +396,7 @@  create_pagelist(char *buf, char __user *ubuf,
 }
 
 static void
-free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
+free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo,
 	      int actual)
 {
 	struct pagelist *pagelist = pagelistinfo->pagelist;
@@ -411,7 +410,7 @@  free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
 	 * NOTE: dma_unmap_sg must be called before the
 	 * cpu can touch any of the data/pages.
 	 */
-	dma_unmap_sg(g_dev, pagelistinfo->scatterlist,
+	dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist,
 		     pagelistinfo->num_pages, pagelistinfo->dma_dir);
 	pagelistinfo->scatterlist_mapped = 0;
 
@@ -460,7 +459,7 @@  free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
 			set_page_dirty(pages[i]);
 	}
 
-	cleanup_pagelistinfo(pagelistinfo);
+	cleanup_pagelistinfo(instance, pagelistinfo);
 }
 
 int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
@@ -547,7 +546,6 @@  int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
 		return err ? : -ENXIO;
 	}
 
-	g_dev = dev;
 	vchiq_log_info(vchiq_arm_log_level, "vchiq_init - done (slots %pK, phys %pad)",
 		       vchiq_slot_zero, &slot_phys);
 
@@ -615,12 +613,12 @@  remote_event_signal(struct remote_event *event)
 }
 
 int
-vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset,
+vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk, void *offset,
 			void __user *uoffset, int size, int dir)
 {
 	struct vchiq_pagelist_info *pagelistinfo;
 
-	pagelistinfo = create_pagelist(offset, uoffset, size,
+	pagelistinfo = create_pagelist(instance, offset, uoffset, size,
 				       (dir == VCHIQ_BULK_RECEIVE)
 				       ? PAGELIST_READ
 				       : PAGELIST_WRITE);
@@ -640,10 +638,10 @@  vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset,
 }
 
 void
-vchiq_complete_bulk(struct vchiq_bulk *bulk)
+vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk)
 {
 	if (bulk && bulk->remote_data && bulk->actual)
-		free_pagelist((struct vchiq_pagelist_info *)bulk->remote_data,
+		free_pagelist(instance, (struct vchiq_pagelist_info *)bulk->remote_data,
 			      bulk->actual);
 }
 
@@ -834,8 +832,8 @@  vchiq_open_service(struct vchiq_instance *instance,
 EXPORT_SYMBOL(vchiq_open_service);
 
 enum vchiq_status
-vchiq_bulk_transmit(unsigned int handle, const void *data, unsigned int size,
-		    void *userdata, enum vchiq_bulk_mode mode)
+vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int handle, const void *data,
+		    unsigned int size, void *userdata, enum vchiq_bulk_mode mode)
 {
 	enum vchiq_status status;
 
@@ -843,13 +841,13 @@  vchiq_bulk_transmit(unsigned int handle, const void *data, unsigned int size,
 		switch (mode) {
 		case VCHIQ_BULK_MODE_NOCALLBACK:
 		case VCHIQ_BULK_MODE_CALLBACK:
-			status = vchiq_bulk_transfer(handle,
+			status = vchiq_bulk_transfer(instance, handle,
 						     (void *)data, NULL,
 						     size, userdata, mode,
 						     VCHIQ_BULK_TRANSMIT);
 			break;
 		case VCHIQ_BULK_MODE_BLOCKING:
-			status = vchiq_blocking_bulk_transfer(handle, (void *)data, size,
+			status = vchiq_blocking_bulk_transfer(instance, handle, (void *)data, size,
 							      VCHIQ_BULK_TRANSMIT);
 			break;
 		default:
@@ -871,8 +869,8 @@  vchiq_bulk_transmit(unsigned int handle, const void *data, unsigned int size,
 }
 EXPORT_SYMBOL(vchiq_bulk_transmit);
 
-enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data,
-				     unsigned int size, void *userdata,
+enum vchiq_status vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int handle,
+				     void *data, unsigned int size, void *userdata,
 				     enum vchiq_bulk_mode mode)
 {
 	enum vchiq_status status;
@@ -881,12 +879,12 @@  enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data,
 		switch (mode) {
 		case VCHIQ_BULK_MODE_NOCALLBACK:
 		case VCHIQ_BULK_MODE_CALLBACK:
-			status = vchiq_bulk_transfer(handle, data, NULL,
+			status = vchiq_bulk_transfer(instance, handle, data, NULL,
 						     size, userdata,
 						     mode, VCHIQ_BULK_RECEIVE);
 			break;
 		case VCHIQ_BULK_MODE_BLOCKING:
-			status = vchiq_blocking_bulk_transfer(handle, (void *)data, size,
+			status = vchiq_blocking_bulk_transfer(instance, handle, (void *)data, size,
 							      VCHIQ_BULK_RECEIVE);
 			break;
 		default:
@@ -909,10 +907,9 @@  enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data,
 EXPORT_SYMBOL(vchiq_bulk_receive);
 
 static enum vchiq_status
-vchiq_blocking_bulk_transfer(unsigned int handle, void *data, unsigned int size,
-			     enum vchiq_bulk_dir dir)
+vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *data,
+			     unsigned int size, enum vchiq_bulk_dir dir)
 {
-	struct vchiq_instance *instance;
 	struct vchiq_service *service;
 	enum vchiq_status status;
 	struct bulk_waiter_node *waiter = NULL, *iter;
@@ -921,8 +918,6 @@  vchiq_blocking_bulk_transfer(unsigned int handle, void *data, unsigned int size,
 	if (!service)
 		return VCHIQ_ERROR;
 
-	instance = service->instance;
-
 	vchiq_service_put(service);
 
 	mutex_lock(&instance->bulk_waiter_list_mutex);
@@ -959,7 +954,7 @@  vchiq_blocking_bulk_transfer(unsigned int handle, void *data, unsigned int size,
 		}
 	}
 
-	status = vchiq_bulk_transfer(handle, data, NULL, size,
+	status = vchiq_bulk_transfer(instance, handle, data, NULL, size,
 				     &waiter->bulk_waiter,
 				     VCHIQ_BULK_MODE_BLOCKING, dir);
 	if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) || !waiter->bulk_waiter.bulk) {
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
index 0d5c39d7c6e2..04eec18835da 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -1441,7 +1441,7 @@  abort_outstanding_bulks(struct vchiq_service *service,
 		}
 
 		if (queue->process != queue->local_insert) {
-			vchiq_complete_bulk(bulk);
+			vchiq_complete_bulk(service->instance, bulk);
 
 			vchiq_log_info(SRVTRACE_LEVEL(service),
 				       "%s %c%c%c%c d:%d ABORTED - tx len:%d, rx len:%d",
@@ -1769,7 +1769,7 @@  parse_message(struct vchiq_state *state, struct vchiq_header *header)
 
 			DEBUG_TRACE(PARSE_LINE);
 			WARN_ON(queue->process == queue->local_insert);
-			vchiq_complete_bulk(bulk);
+			vchiq_complete_bulk(service->instance, bulk);
 			queue->process++;
 			mutex_unlock(&service->bulk_mutex);
 			DEBUG_TRACE(PARSE_LINE);
@@ -2998,9 +2998,9 @@  vchiq_remove_service(unsigned int handle)
  * When called in blocking mode, the userdata field points to a bulk_waiter
  * structure.
  */
-enum vchiq_status vchiq_bulk_transfer(unsigned int handle, void *offset, void __user *uoffset,
-				      int size, void *userdata, enum vchiq_bulk_mode mode,
-				      enum vchiq_bulk_dir dir)
+enum vchiq_status vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle,
+				      void *offset, void __user *uoffset, int size, void *userdata,
+				      enum vchiq_bulk_mode mode, enum vchiq_bulk_dir dir)
 {
 	struct vchiq_service *service = find_service_by_handle(handle);
 	struct vchiq_bulk_queue *queue;
@@ -3077,7 +3077,7 @@  enum vchiq_status vchiq_bulk_transfer(unsigned int handle, void *offset, void __
 	bulk->size = size;
 	bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
 
-	if (vchiq_prepare_bulk_data(bulk, offset, uoffset, size, dir))
+	if (vchiq_prepare_bulk_data(instance, bulk, offset, uoffset, size, dir))
 		goto unlock_error_exit;
 
 	wmb();
@@ -3141,7 +3141,7 @@  enum vchiq_status vchiq_bulk_transfer(unsigned int handle, void *offset, void __
 unlock_both_error_exit:
 	mutex_unlock(&state->slot_mutex);
 cancel_bulk_error_exit:
-	vchiq_complete_bulk(bulk);
+	vchiq_complete_bulk(service->instance, bulk);
 unlock_error_exit:
 	mutex_unlock(&service->bulk_mutex);
 
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
index 352017ff5309..2ce54ce9f02a 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
@@ -489,8 +489,8 @@  extern void
 remote_event_pollall(struct vchiq_state *state);
 
 extern enum vchiq_status
-vchiq_bulk_transfer(unsigned int handle, void *offset, void __user *uoffset,
-		    int size, void *userdata, enum vchiq_bulk_mode mode,
+vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *offset,
+		    void __user *uoffset, int size, void *userdata, enum vchiq_bulk_mode mode,
 		    enum vchiq_bulk_dir dir);
 
 extern int
@@ -556,10 +556,10 @@  vchiq_queue_message(unsigned int handle,
 		    void *context,
 		    size_t size);
 
-int vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset, void __user *uoffset,
-			    int size, int dir);
+int vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk, void *offset,
+			    void __user *uoffset, int size, int dir);
 
-void vchiq_complete_bulk(struct vchiq_bulk *bulk);
+void vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk);
 
 void remote_event_signal(struct remote_event *event);
 
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
index 66bbfec332ba..077e3fcbd651 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
@@ -330,7 +330,7 @@  static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance,
 		userdata = args->userdata;
 	}
 
-	status = vchiq_bulk_transfer(args->handle, NULL, args->data, args->size,
+	status = vchiq_bulk_transfer(instance, args->handle, NULL, args->data, args->size,
 				     userdata, args->mode, dir);
 
 	if (!waiter) {
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
index 249dd3e30c2f..88813af8de49 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
@@ -293,7 +293,7 @@  static void buffer_to_host_work_cb(struct work_struct *work)
 		len = 8;
 	/* queue the bulk submission */
 	vchiq_use_service(instance->service_handle);
-	ret = vchiq_bulk_receive(instance->service_handle,
+	ret = vchiq_bulk_receive(instance->vchiq_instance, instance->service_handle,
 				 msg_context->u.bulk.buffer->buffer,
 				 /* Actual receive needs to be a multiple
 				  * of 4 bytes