/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef __MAILBOX_CONTROLLER_H
#define __MAILBOX_CONTROLLER_H

#include <linux/of.h>
#include <linux/types.h>
#include <linux/hrtimer.h>
#include <linux/device.h>
#include <linux/completion.h>

struct mbox_chan;

/**
 * struct mbox_chan_ops - methods to control mailbox channels
 * @send_data:	The API asks the MBOX controller driver, in atomic
 *		context try to transmit a message on the bus. Returns 0 if
 *		data is accepted for transmission, -EBUSY while rejecting
 *		if the remote hasn't yet read the last data sent. Actual
 *		transmission of data is reported by the controller via
 *		mbox_chan_txdone (if it has some TX ACK irq). It must not
 *		sleep.
 * @write_controller_data:
 *		Write data for the controller driver. This could be data to
 *		configure the controller or data that may be cached in the
 *		controller and not transmitted immediately. There is no ACK
 *		for this request and the request is not buffered in the
 *		controller. Must not sleep.
 * @startup:	Called when a client requests the chan. The controller
 *		could ask clients for additional parameters of communication
 *		to be provided via client's chan_data. This call may
 *		block. After this call the Controller must forward any
 *		data received on the chan by calling mbox_chan_received_data.
 *		The controller may do stuff that need to sleep.
 * @shutdown:	Called when a client relinquishes control of a chan.
 *		This call may block too. The controller must not forward
 *		any received data anymore.
 *		The controller may do stuff that need to sleep.
 * @last_tx_done: If the controller sets 'txdone_poll', the API calls
 *		  this to poll status of last TX. The controller must
 *		  give priority to IRQ method over polling and never
 *		  set both txdone_poll and txdone_irq. Only in polling
 *		  mode 'send_data' is expected to return -EBUSY.
 *		  The controller may do stuff that need to sleep/block.
 *		  Used only if txdone_poll:=true && txdone_irq:=false
 * @peek_data: Atomic check for any received data. Return true if controller
 *		  has some data to push to the client. False otherwise.
 * @debug:	Allow chan to be debugged when the client detects a channel is
 * 		locked up.
 */
struct mbox_chan_ops {
	int (*send_data)(struct mbox_chan *chan, void *data);
	int (*write_controller_data)(struct mbox_chan *chan, void *data);
	int (*startup)(struct mbox_chan *chan);
	void (*shutdown)(struct mbox_chan *chan);
	bool (*last_tx_done)(struct mbox_chan *chan);
	bool (*peek_data)(struct mbox_chan *chan);
};

/**
 * struct mbox_controller - Controller of a class of communication channels
 * @dev:		Device backing this controller
 * @ops:		Operators that work on each communication chan
 * @chans:		Array of channels
 * @num_chans:		Number of channels in the 'chans' array.
 * @txdone_irq:		Indicates if the controller can report to API when
 *			the last transmitted data was read by the remote.
 *			Eg, if it has some TX ACK irq.
 * @txdone_poll:	If the controller can read but not report the TX
 *			done. Ex, some register shows the TX status but
 *			no interrupt rises. Ignored if 'txdone_irq' is set.
 * @txpoll_period:	If 'txdone_poll' is in effect, the API polls for
 *			last TX's status after these many millisecs
 * @of_xlate:		Controller driver specific mapping of channel via DT
 * @is_idle:		Return if the controller is idle.
 * @poll_hrt:		API private. hrtimer used to poll for TXDONE on all
 *			channels.
 * @node:		API private. To hook into list of controllers.
 */
struct mbox_controller {
	struct device *dev;
	const struct mbox_chan_ops *ops;
	struct mbox_chan *chans;
	int num_chans;
	bool txdone_irq;
	bool txdone_poll;
	unsigned txpoll_period;
	struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
				      const struct of_phandle_args *sp);
	bool (*is_idle)(struct mbox_controller *mbox);
	void (*debug)(struct mbox_chan *chan);
	/* Internal to API */
	struct hrtimer poll_hrt;
	struct list_head node;
};

/*
 * The length of circular buffer for queuing messages from a client.
 * 'msg_count' tracks the number of buffered messages while 'msg_free'
 * is the index where the next message would be buffered.
 * We shouldn't need it too big because every transfer is interrupt
 * triggered and if we have lots of data to transfer, the interrupt
 * latencies are going to be the bottleneck, not the buffer length.
 * Besides, mbox_send_message could be called from atomic context and
 * the client could also queue another message from the notifier 'tx_done'
 * of the last transfer done.
 * REVISIT: If too many platforms see the "Try increasing MBOX_TX_QUEUE_LEN"
 * print, it needs to be taken from config option or somesuch.
 */
#define MBOX_TX_QUEUE_LEN	20

/**
 * struct mbox_chan - s/w representation of a communication chan
 * @mbox:		Pointer to the parent/provider of this channel
 * @txdone_method:	Way to detect TXDone chosen by the API
 * @cl:			Pointer to the current owner of this channel
 * @tx_complete:	Transmission completion
 * @active_req:		Currently active request hook
 * @msg_count:		No. of mssg currently queued
 * @msg_free:		Index of next available mssg slot
 * @msg_data:		Hook for data packet
 * @lock:		Serialise access to the channel
 * @con_priv:		Hook for controller driver to attach private data
 */
struct mbox_chan {
	struct mbox_controller *mbox;
	unsigned txdone_method;
	struct mbox_client *cl;
	struct completion tx_complete;
	void *active_req;
	unsigned msg_count, msg_free;
	void *msg_data[MBOX_TX_QUEUE_LEN];
	spinlock_t lock; /* Serialise access to the channel */
	void *con_priv;
};

int mbox_controller_register(struct mbox_controller *mbox); /* can sleep */
void mbox_controller_unregister(struct mbox_controller *mbox); /* can sleep */
void mbox_chan_received_data(struct mbox_chan *chan, void *data); /* atomic */
void mbox_chan_txdone(struct mbox_chan *chan, int r); /* atomic */

#endif /* __MAILBOX_CONTROLLER_H */
