diff options
Diffstat (limited to 'gxp-mailbox-impl.h')
-rw-r--r-- | gxp-mailbox-impl.h | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/gxp-mailbox-impl.h b/gxp-mailbox-impl.h new file mode 100644 index 0000000..2f4b5d8 --- /dev/null +++ b/gxp-mailbox-impl.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Legacy implementation of the GXP mailbox interface. + * This file must be used only when the kernel driver has to compile the implementation of the + * mailbox by itself (i.e, when the target chip can't be compiled with GCIP). + * + * Copyright (C) 2022 Google LLC + */ + +#ifndef __GXP_MAILBOX_IMPL_H__ +#define __GXP_MAILBOX_IMPL_H__ + +#include <linux/spinlock_types.h> +#include <linux/types.h> +#include <linux/wait.h> +#include <linux/workqueue.h> + +#include "gxp-eventfd.h" +#include "gxp-pm.h" + +/* + * Basic Buffer descriptor struct for message payloads. + */ +struct buffer_descriptor { + /* Address in the device's virtual address space. */ + u64 address; + /* Size in bytes. */ + u32 size; + /* Flags can be used to indicate message type, etc. */ + u32 flags; +}; + +/* + * Format used for mailbox command queues. + */ +struct gxp_command { + /* Sequence number. Should match the corresponding response. */ + u64 seq; + /* + * Identifies the type of command. + * Should be a value from `gxp_mailbox_command_code` + */ + u16 code; + /* + * Priority level from 0 to 99, with 0 being the highest. Pending + * commands with higher priorities will be executed before lower + * priority ones. + */ + u8 priority; + /* + * Insert spaces to make padding explicit. This does not affect + * alignment. + */ + u8 reserved[5]; + /* Struct describing the buffer containing the message payload */ + struct buffer_descriptor buffer_descriptor; +}; + +/* + * Format used for mailbox response queues from kernel. + */ +struct gxp_response { + /* Sequence number. Should match the corresponding command. */ + u64 seq; + /* The status code. Either SUCCESS or an error. */ + u16 status; + /* Padding. */ + u16 reserved; + /* Return value, dependent on the command this responds to. */ + u32 retval; +}; + +/* + * Wrapper struct for responses consumed by a thread other than the one which + * sent the command. + */ +struct gxp_async_response { + struct list_head list_entry; + struct gxp_response resp; + struct delayed_work timeout_work; + /* + * If this response times out, this pointer to the owning mailbox is + * needed to delete this response from the list of pending responses. + */ + struct gxp_mailbox *mailbox; + /* Queue to add the response to once it is complete or timed out */ + struct list_head *dest_queue; + /* + * The lock that protects queue pointed to by `dest_queue`. + * The mailbox code also uses this lock to protect changes to the + * `dest_queue` pointer itself when processing this response. + */ + spinlock_t *dest_queue_lock; + /* Queue of clients to notify when this response is processed */ + wait_queue_head_t *dest_queue_waitq; + /* Specified power states vote during the command execution */ + struct gxp_power_states requested_states; + /* gxp_eventfd to signal when the response completes. May be NULL */ + struct gxp_eventfd *eventfd; +}; + +struct gxp_mailbox_wait_list { + struct list_head list; + struct gxp_response *resp; + bool is_async; +}; + +struct gxp_mailbox; +struct gxp_mailbox_args; +struct gxp_mailbox_manager; + +extern const struct gxp_mailbox_args gxp_mailbox_default_args; + +/* Initializes operators of @mgr to work with the legacy implementation of mailbox. */ +void gxp_mailbox_init(struct gxp_mailbox_manager *mgr); + +/* + * Following functions will be called by the `gxp-mailbox.c` according to its internal logic. + * You may not call these functions directly. + */ + +/* + * Initializes the mailbox to be able to wait and consume responses. + * This function will be called when the `gxp_mailbox_alloc` function is called. + */ +int gxp_mailbox_init_consume_responses(struct gxp_mailbox *mailbox); + +/* + * Flushes all pending responses in the mailbox. + * This function will be called when the `gxp_mailbox_release` function is called. + */ +void gxp_mailbox_release_consume_responses(struct gxp_mailbox *mailbox); + +/* + * Fetches and handles responses, then wakes up threads that are waiting for a response. + * This function will be called by a worker which is scheduled in the IRQ handler. (See the + * `gxp_mailbox_consume_responses_work` function) To prevent use-after-free or race-condition + * bugs, gxp_mailbox_release() must be called before free the mailbox. + */ +void gxp_mailbox_consume_responses(struct gxp_mailbox *mailbox); + +#endif /* __GXP_MAILBOX_IMPL_H__ */ |