1 /* SPDX-License-Identifier: GPL-2.0-only
2  *
3  * Copyright (C) 2020-21 Intel Corporation.
4  */
5 
6 #ifndef IOSM_IPC_TASK_QUEUE_H
7 #define IOSM_IPC_TASK_QUEUE_H
8 
9 /* Number of available element for the input message queue of the IPC
10  * ipc_task
11  */
12 #define IPC_THREAD_QUEUE_SIZE 256
13 
14 /**
15  * struct ipc_task_queue_args - Struct for Task queue elements
16  * @ipc_imem:   Pointer to struct iosm_imem
17  * @msg:        Message argument for tasklet function. (optional, can be NULL)
18  * @completion: OS object used to wait for the tasklet function to finish for
19  *              synchronous calls
20  * @func:       Function to be called in tasklet (tl) context
21  * @arg:        Generic integer argument for tasklet function (optional)
22  * @size:       Message size argument for tasklet function (optional)
23  * @response:   Return code of tasklet function for synchronous calls
24  * @is_copy:    Is true if msg contains a pointer to a copy of the original msg
25  *              for async. calls that needs to be freed once the tasklet returns
26  */
27 struct ipc_task_queue_args {
28 	struct iosm_imem *ipc_imem;
29 	void *msg;
30 	struct completion *completion;
31 	int (*func)(struct iosm_imem *ipc_imem, int arg, void *msg,
32 		    size_t size);
33 	int arg;
34 	size_t size;
35 	int response;
36 	u8 is_copy:1;
37 };
38 
39 /**
40  * struct ipc_task_queue - Struct for Task queue
41  * @q_lock:     Protect the message queue of the ipc ipc_task
42  * @args:       Message queue of the IPC ipc_task
43  * @q_rpos:     First queue element to process.
44  * @q_wpos:     First free element of the input queue.
45  */
46 struct ipc_task_queue {
47 	spinlock_t q_lock; /* for atomic operation on queue */
48 	struct ipc_task_queue_args args[IPC_THREAD_QUEUE_SIZE];
49 	unsigned int q_rpos;
50 	unsigned int q_wpos;
51 };
52 
53 /**
54  * struct ipc_task - Struct for Task
55  * @dev:	 Pointer to device structure
56  * @ipc_tasklet: Tasklet for serialized work offload
57  *		 from interrupts and OS callbacks
58  * @ipc_queue:	 Task for entry into ipc task queue
59  */
60 struct ipc_task {
61 	struct device *dev;
62 	struct tasklet_struct *ipc_tasklet;
63 	struct ipc_task_queue ipc_queue;
64 };
65 
66 /**
67  * ipc_task_init - Allocate a tasklet
68  * @ipc_task:	Pointer to ipc_task structure
69  * Returns: 0 on success and failure value on error.
70  */
71 int ipc_task_init(struct ipc_task *ipc_task);
72 
73 /**
74  * ipc_task_deinit - Free a tasklet, invalidating its pointer.
75  * @ipc_task:	Pointer to ipc_task structure
76  */
77 void ipc_task_deinit(struct ipc_task *ipc_task);
78 
79 /**
80  * ipc_task_queue_send_task - Synchronously/Asynchronously call a function in
81  *			      tasklet context.
82  * @imem:		Pointer to iosm_imem struct
83  * @func:		Function to be called in tasklet context
84  * @arg:		Integer argument for func
85  * @msg:		Message pointer argument for func
86  * @size:		Size argument for func
87  * @wait:		if true wait for result
88  *
89  * Returns: Result value returned by func or failure value if func could not
90  *	    be called.
91  */
92 int ipc_task_queue_send_task(struct iosm_imem *imem,
93 			     int (*func)(struct iosm_imem *ipc_imem, int arg,
94 					 void *msg, size_t size),
95 			     int arg, void *msg, size_t size, bool wait);
96 
97 #endif
98