blob: 9a78e65e0dbce71787fbcbd5b7746003277b7618 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* 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__ */