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 */
27struct 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 */
46struct 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 */
60struct 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 */
71int 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 */
77void 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 */
92int 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