// SPDX-License-Identifier: GPL-2.0
/*
 * ARM Message Handling Unit Version 3 (MHUv3) driver.
 *
 * Copyright (C) 2024 ARM Ltd.
 *
 * Based on ARM MHUv2 driver.
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/bits.h>
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/types.h>

/* ====== MHUv3 Registers ====== */

/* Maximum number of Doorbell channel windows */
#define MHUV3_DBCW_MAX			128
/* Number of DBCH combined interrupt status registers */
#define MHUV3_DBCH_CMB_INT_ST_REG_CNT	4

/* Number of FFCH combined interrupt status registers */
#define MHUV3_FFCH_CMB_INT_ST_REG_CNT	2

#define MHUV3_FLAG_BITS			32

/* Not a typo ... */
#define MHUV3_MAJOR_VERSION		2

enum {
	MHUV3_MBOX_CELL_TYPE,
	MHUV3_MBOX_CELL_CHWN,
	MHUV3_MBOX_CELL_PARAM,
	MHUV3_MBOX_CELLS
};

/* Padding bitfields/fields represents hole in the regs MMIO */

/* CTRL_Page */
struct blk_id {
#define id		GENMASK(3, 0)
	u32 val;
} __packed;

struct feat_spt0 {
#define	dbe_spt		GENMASK(3, 0)
#define	fe_spt		GENMASK(7, 4)
#define	fce_spt		GENMASK(11, 8)
	u32 val;
} __packed;

struct feat_spt1 {
#define	auto_op_spt	GENMASK(3, 0)
	u32 val;
} __packed;

struct dbch_cfg0 {
#define num_dbch	GENMASK(7, 0)
	u32 val;
} __packed;

struct ffch_cfg0 {
#define num_ffch	GENMASK(7, 0)
#define x8ba_spt	BIT(8)
#define x16ba_spt	BIT(9)
#define x32ba_spt	BIT(10)
#define x64ba_spt	BIT(11)
#define ffch_depth	GENMASK(25, 16)
	u32 val;
} __packed;

struct fch_cfg0 {
#define num_fch		GENMASK(9, 0)
#define fcgi_spt	BIT(10)		// MBX-only
#define num_fcg		GENMASK(15, 11)
#define num_fch_per_grp	GENMASK(20, 16)
#define fch_ws		GENMASK(28, 21)
	u32 val;
} __packed;

struct ctrl {
#define op_req		BIT(0)
#define	ch_op_mask	BIT(1)
	u32 val;
} __packed;

struct fch_ctrl {
#define _int_en		BIT(2)
	u32 val;
} __packed;

struct iidr {
#define implementer	GENMASK(11, 0)
#define revision	GENMASK(15, 12)
#define variant		GENMASK(19, 16)
#define product_id	GENMASK(31, 20)
	u32 val;
} __packed;

struct aidr {
#define arch_minor_rev	GENMASK(3, 0)
#define arch_major_rev	GENMASK(7, 4)
	u32 val;
} __packed;

struct ctrl_page {
	struct blk_id blk_id;
	u8 pad[12];
	struct feat_spt0 feat_spt0;
	struct feat_spt1 feat_spt1;
	u8 pad1[8];
	struct dbch_cfg0 dbch_cfg0;
	u8 pad2[12];
	struct ffch_cfg0 ffch_cfg0;
	u8 pad3[12];
	struct fch_cfg0 fch_cfg0;
	u8 pad4[188];
	struct ctrl x_ctrl;
	/*-- MBX-only registers --*/
	u8 pad5[60];
	struct fch_ctrl fch_ctrl;
	u32 fcg_int_en;
	u8 pad6[696];
	/*-- End of MBX-only ---- */
	u32 dbch_int_st[MHUV3_DBCH_CMB_INT_ST_REG_CNT];
	u32 ffch_int_st[MHUV3_FFCH_CMB_INT_ST_REG_CNT];
	/*-- MBX-only registers --*/
	u8 pad7[88];
	u32 fcg_int_st;
	u8 pad8[12];
	u32 fcg_grp_int_st[32];
	u8 pad9[2760];
	/*-- End of MBX-only ---- */
	struct iidr iidr;
	struct aidr aidr;
	u32 imp_def_id[12];
} __packed;

/* DBCW_Page */

struct xbcw_ctrl {
#define comb_en		BIT(0)
	u32 val;
} __packed;

struct pdbcw_int {
#define tfr_ack		BIT(0)
	u32 val;
} __packed;

struct pdbcw_page {
	u32 st;
	u8 pad[8];
	u32 set;
	struct pdbcw_int int_st;
	struct pdbcw_int int_clr;
	struct pdbcw_int int_en;
	struct xbcw_ctrl ctrl;
} __packed;

struct mdbcw_page {
	u32 st;
	u32 st_msk;
	u32 clr;
	u8 pad[4];
	u32 msk_st;
	u32 msk_set;
	u32 msk_clr;
	struct xbcw_ctrl ctrl;
} __packed;

struct dummy_page {
	u8 pad[SZ_4K];
} __packed;

struct mhu3_pbx_frame_reg {
	struct ctrl_page ctrl;
	struct pdbcw_page dbcw[MHUV3_DBCW_MAX];
	struct dummy_page ffcw;
	struct dummy_page fcw;
	u8 pad[SZ_4K * 11];
	struct dummy_page impdef;
} __packed;

struct mhu3_mbx_frame_reg {
	struct ctrl_page ctrl;
	struct mdbcw_page dbcw[MHUV3_DBCW_MAX];
	struct dummy_page ffcw;
	struct dummy_page fcw;
	u8 pad[SZ_4K * 11];
	struct dummy_page impdef;
} __packed;

/* Macro for reading a bitmask within a physically mapped packed struct */
#define readl_relaxed_bitmask(_regptr, _bitmask)			\
	({								\
		unsigned long _rval;					\
		_rval = readl_relaxed(_regptr);				\
		FIELD_GET(_bitmask, _rval);				\
	})

/* Macro for writing a bitmask within a physically mapped packed struct */
#define writel_relaxed_bitmask(_value, _regptr, _bitmask)		\
	({								\
		unsigned long _rval;					\
		typeof(_regptr) _rptr = _regptr;			\
		typeof(_bitmask) _bmask = _bitmask;			\
		_rval = readl_relaxed(_rptr);				\
		_rval &= ~(_bmask);					\
		_rval |= FIELD_PREP((unsigned long long)_bmask, _value);\
		writel_relaxed(_rval, _rptr);				\
	})

/* ====== MHUv3 data structures ====== */

enum mhuv3_frame {
	PBX_FRAME,
	MBX_FRAME,
};

static char *mhuv3_str[] = {
	"PBX",
	"MBX"
};

enum mhuv3_extension_type {
	DBE_EXT,
	FCE_EXT,
	FE_EXT,
	NUM_EXT
};

static char *mhuv3_ext_str[] = {
	"DBE",
	"FCE",
	"FE"
};

struct mhuv3;

/**
 * struct mhuv3_protocol_ops - MHUv3 operations
 *
 * @rx_startup: Receiver startup callback.
 * @rx_shutdown: Receiver shutdown callback.
 * @read_data: Read available Sender in-band LE data (if any).
 * @rx_complete: Acknowledge data reception to the Sender. Any out-of-band data
 *		 has to have been already retrieved before calling this.
 * @tx_startup: Sender startup callback.
 * @tx_shutdown: Sender shutdown callback.
 * @last_tx_done: Report back to the Sender if the last transfer has completed.
 * @send_data: Send data to the receiver.
 *
 * Each supported transport protocol provides its own implementation of
 * these operations.
 */
struct mhuv3_protocol_ops {
	int (*rx_startup)(struct mhuv3 *mhu, struct mbox_chan *chan);
	void (*rx_shutdown)(struct mhuv3 *mhu, struct mbox_chan *chan);
	void *(*read_data)(struct mhuv3 *mhu, struct mbox_chan *chan);
	void (*rx_complete)(struct mhuv3 *mhu, struct mbox_chan *chan);
	void (*tx_startup)(struct mhuv3 *mhu, struct mbox_chan *chan);
	void (*tx_shutdown)(struct mhuv3 *mhu, struct mbox_chan *chan);
	int (*last_tx_done)(struct mhuv3 *mhu, struct mbox_chan *chan);
	int (*send_data)(struct mhuv3 *mhu, struct mbox_chan *chan, void *arg);
};

/**
 * struct mhuv3_mbox_chan_priv - MHUv3 channel private information
 *
 * @ch_idx: Channel window index associated to this mailbox channel.
 * @doorbell: Doorbell bit number within the @ch_idx window.
 *	      Only relevant to Doorbell transport.
 * @ops: Transport protocol specific operations for this channel.
 *
 * Transport specific data attached to mmailbox channel priv data.
 */
struct mhuv3_mbox_chan_priv {
	u32 ch_idx;
	u32 doorbell;
	const struct mhuv3_protocol_ops *ops;
};

/**
 * struct mhuv3_extension - MHUv3 extension descriptor
 *
 * @type: Type of extension
 * @num_chans: Max number of channels found for this extension.
 * @base_ch_idx: First channel number assigned to this extension, picked from
 *		 the set of all mailbox channels descriptors created.
 * @mbox_of_xlate: Extension specific helper to parse DT and lookup associated
 *		   channel from the related 'mboxes' property.
 * @combined_irq_setup: Extension specific helper to setup the combined irq.
 * @channels_init: Extension specific helper to initialize channels.
 * @chan_from_comb_irq_get: Extension specific helper to lookup which channel
 *			    triggered the combined irq.
 * @pending_db: Array of per-channel pending doorbells.
 * @pending_lock: Protect access to pending_db.
 */
struct mhuv3_extension {
	enum mhuv3_extension_type type;
	unsigned int num_chans;
	unsigned int base_ch_idx;
	struct mbox_chan *(*mbox_of_xlate)(struct mhuv3 *mhu,
					   unsigned int channel,
					   unsigned int param);
	void (*combined_irq_setup)(struct mhuv3 *mhu);
	int (*channels_init)(struct mhuv3 *mhu);
	struct mbox_chan *(*chan_from_comb_irq_get)(struct mhuv3 *mhu);
	u32 pending_db[MHUV3_DBCW_MAX];
	/* Protect access to pending_db */
	spinlock_t pending_lock;
};

/**
 * struct mhuv3 - MHUv3 mailbox controller data
 *
 * @frame:	Frame type: MBX_FRAME or PBX_FRAME.
 * @auto_op_full: Flag to indicate if the MHU supports AutoOp full mode.
 * @major: MHUv3 controller architectural major version.
 * @minor: MHUv3 controller architectural minor version.
 * @implem: MHUv3 controller IIDR implementer.
 * @rev: MHUv3 controller IIDR revision.
 * @var: MHUv3 controller IIDR variant.
 * @prod_id: MHUv3 controller IIDR product_id.
 * @num_chans: The total number of channels discovered across all extensions.
 * @cmb_irq: Combined IRQ number if any found defined.
 * @ctrl: A reference to the MHUv3 control page for this block.
 * @pbx: Base address of the PBX register mapping region.
 * @mbx: Base address of the MBX register mapping region.
 * @ext: Array holding descriptors for any found implemented extension.
 * @mbox: Mailbox controller belonging to the MHU frame.
 */
struct mhuv3 {
	enum mhuv3_frame frame;
	bool auto_op_full;
	unsigned int major;
	unsigned int minor;
	unsigned int implem;
	unsigned int rev;
	unsigned int var;
	unsigned int prod_id;
	unsigned int num_chans;
	int cmb_irq;
	struct ctrl_page __iomem *ctrl;
	union {
		struct mhu3_pbx_frame_reg __iomem *pbx;
		struct mhu3_mbx_frame_reg __iomem *mbx;
	};
	struct mhuv3_extension *ext[NUM_EXT];
	struct mbox_controller mbox;
};

#define mhu_from_mbox(_mbox) container_of(_mbox, struct mhuv3, mbox)

typedef int (*mhuv3_extension_initializer)(struct mhuv3 *mhu);

/* =================== Doorbell transport protocol operations =============== */

static void mhuv3_doorbell_tx_startup(struct mhuv3 *mhu, struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;

	/* Enable Transfer Acknowledgment events */
	writel_relaxed_bitmask(0x1, &mhu->pbx->dbcw[priv->ch_idx].int_en, tfr_ack);
}

static void mhuv3_doorbell_tx_shutdown(struct mhuv3 *mhu, struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
	unsigned long flags;

	/* Disable Channel Transfer Ack events */
	writel_relaxed_bitmask(0x0, &mhu->pbx->dbcw[priv->ch_idx].int_en, tfr_ack);

	/* Clear Channel Transfer Ack and pending doorbells */
	writel_relaxed_bitmask(0x1, &mhu->pbx->dbcw[priv->ch_idx].int_clr, tfr_ack);
	spin_lock_irqsave(&e->pending_lock, flags);
	e->pending_db[priv->ch_idx] = 0;
	spin_unlock_irqrestore(&e->pending_lock, flags);
}

static int mhuv3_doorbell_rx_startup(struct mhuv3 *mhu, struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;

	/* Unmask Channel Transfer events */
	writel_relaxed(BIT(priv->doorbell), &mhu->mbx->dbcw[priv->ch_idx].msk_clr);

	return 0;
}

static void mhuv3_doorbell_rx_shutdown(struct mhuv3 *mhu,
				       struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;

	/* Mask Channel Transfer events */
	writel_relaxed(BIT(priv->doorbell), &mhu->mbx->dbcw[priv->ch_idx].msk_set);
}

static void mhuv3_doorbell_rx_complete(struct mhuv3 *mhu, struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;

	/* Clearing the pending transfer generates the Channel Transfer Ack */
	writel_relaxed(BIT(priv->doorbell), &mhu->mbx->dbcw[priv->ch_idx].clr);
}

static int mhuv3_doorbell_last_tx_done(struct mhuv3 *mhu,
				       struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
	int done;

	done = !(readl_relaxed(&mhu->pbx->dbcw[priv->ch_idx].st) &
		 BIT(priv->doorbell));
	if (done) {
		struct mhuv3_extension *e = mhu->ext[DBE_EXT];
		unsigned long flags;

		/* Take care to clear the pending doorbell also when polling */
		spin_lock_irqsave(&e->pending_lock, flags);
		e->pending_db[priv->ch_idx] &= ~BIT(priv->doorbell);
		spin_unlock_irqrestore(&e->pending_lock, flags);
	}

	return done;
}

static int mhuv3_doorbell_send_data(struct mhuv3 *mhu, struct mbox_chan *chan,
				    void *arg)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
	struct mhuv3_extension *e = mhu->ext[DBE_EXT];

	scoped_guard(spinlock_irqsave, &e->pending_lock) {
		/* Only one in-flight Transfer is allowed per-doorbell */
		if (e->pending_db[priv->ch_idx] & BIT(priv->doorbell))
			return -EBUSY;

		e->pending_db[priv->ch_idx] |= BIT(priv->doorbell);
	}

	writel_relaxed(BIT(priv->doorbell), &mhu->pbx->dbcw[priv->ch_idx].set);

	return 0;
}

static const struct mhuv3_protocol_ops mhuv3_doorbell_ops = {
	.tx_startup = mhuv3_doorbell_tx_startup,
	.tx_shutdown = mhuv3_doorbell_tx_shutdown,
	.rx_startup = mhuv3_doorbell_rx_startup,
	.rx_shutdown = mhuv3_doorbell_rx_shutdown,
	.rx_complete = mhuv3_doorbell_rx_complete,
	.last_tx_done = mhuv3_doorbell_last_tx_done,
	.send_data = mhuv3_doorbell_send_data,
};

/* Sender and receiver mailbox ops */
static bool mhuv3_sender_last_tx_done(struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);

	return priv->ops->last_tx_done(mhu, chan);
}

static int mhuv3_sender_send_data(struct mbox_chan *chan, void *data)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);

	if (!priv->ops->last_tx_done(mhu, chan))
		return -EBUSY;

	return priv->ops->send_data(mhu, chan, data);
}

static int mhuv3_sender_startup(struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);

	if (priv->ops->tx_startup)
		priv->ops->tx_startup(mhu, chan);

	return 0;
}

static void mhuv3_sender_shutdown(struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);

	if (priv->ops->tx_shutdown)
		priv->ops->tx_shutdown(mhu, chan);
}

static const struct mbox_chan_ops mhuv3_sender_ops = {
	.send_data = mhuv3_sender_send_data,
	.startup = mhuv3_sender_startup,
	.shutdown = mhuv3_sender_shutdown,
	.last_tx_done = mhuv3_sender_last_tx_done,
};

static int mhuv3_receiver_startup(struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);

	return priv->ops->rx_startup(mhu, chan);
}

static void mhuv3_receiver_shutdown(struct mbox_chan *chan)
{
	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);

	priv->ops->rx_shutdown(mhu, chan);
}

static int mhuv3_receiver_send_data(struct mbox_chan *chan, void *data)
{
	dev_err(chan->mbox->dev,
		"Trying to transmit on a MBX MHUv3 frame\n");
	return -EIO;
}

static bool mhuv3_receiver_last_tx_done(struct mbox_chan *chan)
{
	dev_err(chan->mbox->dev, "Trying to Tx poll on a MBX MHUv3 frame\n");
	return true;
}

static const struct mbox_chan_ops mhuv3_receiver_ops = {
	.send_data = mhuv3_receiver_send_data,
	.startup = mhuv3_receiver_startup,
	.shutdown = mhuv3_receiver_shutdown,
	.last_tx_done = mhuv3_receiver_last_tx_done,
};

static struct mbox_chan *mhuv3_dbe_mbox_of_xlate(struct mhuv3 *mhu,
						 unsigned int channel,
						 unsigned int doorbell)
{
	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
	struct mbox_controller *mbox = &mhu->mbox;
	struct mbox_chan *chans = mbox->chans;

	if (channel >= e->num_chans || doorbell >= MHUV3_FLAG_BITS) {
		dev_err(mbox->dev, "Couldn't xlate to a valid channel (%d: %d)\n",
			channel, doorbell);
		return ERR_PTR(-ENODEV);
	}

	return &chans[e->base_ch_idx + channel * MHUV3_FLAG_BITS + doorbell];
}

static void mhuv3_dbe_combined_irq_setup(struct mhuv3 *mhu)
{
	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
	int i;

	if (mhu->frame == PBX_FRAME) {
		struct pdbcw_page __iomem *dbcw = mhu->pbx->dbcw;

		for (i = 0; i < e->num_chans; i++) {
			writel_relaxed_bitmask(0x1, &dbcw[i].int_clr, tfr_ack);
			writel_relaxed_bitmask(0x0, &dbcw[i].int_en, tfr_ack);
			writel_relaxed_bitmask(0x1, &dbcw[i].ctrl, comb_en);
		}
	} else {
		struct mdbcw_page __iomem *dbcw = mhu->mbx->dbcw;

		for (i = 0; i < e->num_chans; i++) {
			writel_relaxed(0xFFFFFFFF, &dbcw[i].clr);
			writel_relaxed(0xFFFFFFFF, &dbcw[i].msk_set);
			writel_relaxed_bitmask(0x1, &dbcw[i].ctrl, comb_en);
		}
	}
}

static int mhuv3_dbe_channels_init(struct mhuv3 *mhu)
{
	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
	struct mbox_controller *mbox = &mhu->mbox;
	struct mbox_chan *chans;
	int i;

	chans = mbox->chans + mbox->num_chans;
	e->base_ch_idx = mbox->num_chans;
	for (i = 0; i < e->num_chans; i++) {
		struct mhuv3_mbox_chan_priv *priv;
		int k;

		for (k = 0; k < MHUV3_FLAG_BITS; k++) {
			priv = devm_kmalloc(mbox->dev, sizeof(*priv), GFP_KERNEL);
			if (!priv)
				return -ENOMEM;

			priv->ch_idx = i;
			priv->ops = &mhuv3_doorbell_ops;
			priv->doorbell = k;
			chans++->con_priv = priv;
			mbox->num_chans++;
		}
	}

	spin_lock_init(&e->pending_lock);

	return 0;
}

static bool mhuv3_dbe_doorbell_lookup(struct mhuv3 *mhu, unsigned int channel,
				      unsigned int *db)
{
	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
	struct device *dev = mhu->mbox.dev;
	u32 st;

	if (mhu->frame == PBX_FRAME) {
		u32 active_dbs, fired_dbs;

		st = readl_relaxed_bitmask(&mhu->pbx->dbcw[channel].int_st,
					   tfr_ack);
		if (!st)
			goto err_spurious;

		active_dbs = readl_relaxed(&mhu->pbx->dbcw[channel].st);
		scoped_guard(spinlock_irqsave, &e->pending_lock) {
			fired_dbs = e->pending_db[channel] & ~active_dbs;
			if (!fired_dbs)
				goto err_spurious;

			*db = __ffs(fired_dbs);
			e->pending_db[channel] &= ~BIT(*db);
		}
		fired_dbs &= ~BIT(*db);
		/* Clear TFR Ack if no more doorbells pending */
		if (!fired_dbs)
			writel_relaxed_bitmask(0x1,
					       &mhu->pbx->dbcw[channel].int_clr,
					       tfr_ack);
	} else {
		st = readl_relaxed(&mhu->mbx->dbcw[channel].st_msk);
		if (!st)
			goto err_spurious;

		*db = __ffs(st);
	}

	return true;

err_spurious:
	dev_warn(dev, "Spurious IRQ on %s channel:%d\n",
		 mhuv3_str[mhu->frame], channel);

	return false;
}

static struct mbox_chan *mhuv3_dbe_chan_from_comb_irq_get(struct mhuv3 *mhu)
{
	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
	struct device *dev = mhu->mbox.dev;
	int i;

	for (i = 0; i < MHUV3_DBCH_CMB_INT_ST_REG_CNT; i++) {
		unsigned int channel, db;
		u32 cmb_st;

		cmb_st = readl_relaxed(&mhu->ctrl->dbch_int_st[i]);
		if (!cmb_st)
			continue;

		channel = i * MHUV3_FLAG_BITS + __ffs(cmb_st);
		if (channel >= e->num_chans) {
			dev_err(dev, "Invalid %s channel:%d\n",
				mhuv3_str[mhu->frame], channel);
			return ERR_PTR(-EIO);
		}

		if (!mhuv3_dbe_doorbell_lookup(mhu, channel, &db))
			continue;

		dev_dbg(dev, "Found %s ch[%d]/db[%d]\n",
			mhuv3_str[mhu->frame], channel, db);

		return &mhu->mbox.chans[channel * MHUV3_FLAG_BITS + db];
	}

	return ERR_PTR(-EIO);
}

static int mhuv3_dbe_init(struct mhuv3 *mhu)
{
	struct device *dev = mhu->mbox.dev;
	struct mhuv3_extension *e;

	if (!readl_relaxed_bitmask(&mhu->ctrl->feat_spt0, dbe_spt))
		return 0;

	dev_dbg(dev, "%s: Initializing DBE Extension.\n", mhuv3_str[mhu->frame]);

	e = devm_kzalloc(dev, sizeof(*e), GFP_KERNEL);
	if (!e)
		return -ENOMEM;

	e->type = DBE_EXT;
	/* Note that, by the spec, the number of channels is (num_dbch + 1) */
	e->num_chans =
		readl_relaxed_bitmask(&mhu->ctrl->dbch_cfg0, num_dbch) + 1;
	e->mbox_of_xlate = mhuv3_dbe_mbox_of_xlate;
	e->combined_irq_setup = mhuv3_dbe_combined_irq_setup;
	e->channels_init = mhuv3_dbe_channels_init;
	e->chan_from_comb_irq_get = mhuv3_dbe_chan_from_comb_irq_get;

	mhu->num_chans += e->num_chans * MHUV3_FLAG_BITS;
	mhu->ext[DBE_EXT] = e;

	dev_dbg(dev, "%s: found %d DBE channels.\n",
		mhuv3_str[mhu->frame], e->num_chans);

	return 0;
}

static int mhuv3_fce_init(struct mhuv3 *mhu)
{
	struct device *dev = mhu->mbox.dev;

	if (!readl_relaxed_bitmask(&mhu->ctrl->feat_spt0, fce_spt))
		return 0;

	dev_dbg(dev, "%s: FCE Extension not supported by driver.\n",
		mhuv3_str[mhu->frame]);

	return 0;
}

static int mhuv3_fe_init(struct mhuv3 *mhu)
{
	struct device *dev = mhu->mbox.dev;

	if (!readl_relaxed_bitmask(&mhu->ctrl->feat_spt0, fe_spt))
		return 0;

	dev_dbg(dev, "%s: FE Extension not supported by driver.\n",
		mhuv3_str[mhu->frame]);

	return 0;
}

static mhuv3_extension_initializer mhuv3_extension_init[NUM_EXT] = {
	mhuv3_dbe_init,
	mhuv3_fce_init,
	mhuv3_fe_init,
};

static int mhuv3_initialize_channels(struct device *dev, struct mhuv3 *mhu)
{
	struct mbox_controller *mbox = &mhu->mbox;
	int i, ret = 0;

	mbox->chans = devm_kcalloc(dev, mhu->num_chans,
				   sizeof(*mbox->chans), GFP_KERNEL);
	if (!mbox->chans)
		return dev_err_probe(dev, -ENOMEM,
				     "Failed to initialize channels\n");

	for (i = 0; i < NUM_EXT && !ret; i++)
		if (mhu->ext[i])
			ret = mhu->ext[i]->channels_init(mhu);

	return ret;
}

static struct mbox_chan *mhuv3_mbox_of_xlate(struct mbox_controller *mbox,
					     const struct of_phandle_args *pa)
{
	struct mhuv3 *mhu = mhu_from_mbox(mbox);
	unsigned int type, channel, param;

	if (pa->args_count != MHUV3_MBOX_CELLS)
		return ERR_PTR(-EINVAL);

	type = pa->args[MHUV3_MBOX_CELL_TYPE];
	if (type >= NUM_EXT)
		return ERR_PTR(-EINVAL);

	channel = pa->args[MHUV3_MBOX_CELL_CHWN];
	param = pa->args[MHUV3_MBOX_CELL_PARAM];

	return mhu->ext[type]->mbox_of_xlate(mhu, channel, param);
}

static void mhu_frame_cleanup_actions(void *data)
{
	struct mhuv3 *mhu = data;

	writel_relaxed_bitmask(0x0, &mhu->ctrl->x_ctrl, op_req);
}

static int mhuv3_frame_init(struct mhuv3 *mhu, void __iomem *regs)
{
	struct device *dev = mhu->mbox.dev;
	int i;

	mhu->ctrl = regs;
	mhu->frame = readl_relaxed_bitmask(&mhu->ctrl->blk_id, id);
	if (mhu->frame > MBX_FRAME)
		return dev_err_probe(dev, -EINVAL,
				     "Invalid Frame type- %d\n", mhu->frame);

	mhu->major = readl_relaxed_bitmask(&mhu->ctrl->aidr, arch_major_rev);
	mhu->minor = readl_relaxed_bitmask(&mhu->ctrl->aidr, arch_minor_rev);
	mhu->implem = readl_relaxed_bitmask(&mhu->ctrl->iidr, implementer);
	mhu->rev = readl_relaxed_bitmask(&mhu->ctrl->iidr, revision);
	mhu->var = readl_relaxed_bitmask(&mhu->ctrl->iidr, variant);
	mhu->prod_id = readl_relaxed_bitmask(&mhu->ctrl->iidr, product_id);
	if (mhu->major != MHUV3_MAJOR_VERSION)
		return dev_err_probe(dev, -EINVAL,
				     "Unsupported MHU %s block - major:%d  minor:%d\n",
				     mhuv3_str[mhu->frame], mhu->major,
				     mhu->minor);

	mhu->auto_op_full =
		!!readl_relaxed_bitmask(&mhu->ctrl->feat_spt1, auto_op_spt);
	/* Request the PBX/MBX to remain operational */
	if (mhu->auto_op_full) {
		writel_relaxed_bitmask(0x1, &mhu->ctrl->x_ctrl, op_req);
		devm_add_action_or_reset(dev, mhu_frame_cleanup_actions, mhu);
	}

	dev_dbg(dev,
		"Found MHU %s block - major:%d  minor:%d\n  implem:0x%X  rev:0x%X  var:0x%X  prod_id:0x%X",
		mhuv3_str[mhu->frame], mhu->major, mhu->minor,
		mhu->implem, mhu->rev, mhu->var, mhu->prod_id);

	if (mhu->frame == PBX_FRAME)
		mhu->pbx = regs;
	else
		mhu->mbx = regs;

	for (i = 0; i < NUM_EXT; i++) {
		int ret;

		/*
		 * Note that extensions initialization fails only when such
		 * extension initialization routine fails and the extensions
		 * was found to be supported in hardware and in software.
		 */
		ret = mhuv3_extension_init[i](mhu);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to initialize %s %s\n",
					     mhuv3_str[mhu->frame],
					     mhuv3_ext_str[i]);
	}

	return 0;
}

static irqreturn_t mhuv3_pbx_comb_interrupt(int irq, void *arg)
{
	unsigned int i, found = 0;
	struct mhuv3 *mhu = arg;
	struct mbox_chan *chan;
	struct device *dev;
	int ret = IRQ_NONE;

	dev = mhu->mbox.dev;
	for (i = 0; i < NUM_EXT; i++) {
		struct mhuv3_mbox_chan_priv *priv;

		/* FCE does not participate to the PBX combined */
		if (i == FCE_EXT || !mhu->ext[i])
			continue;

		chan = mhu->ext[i]->chan_from_comb_irq_get(mhu);
		if (IS_ERR(chan))
			continue;

		found++;
		priv = chan->con_priv;
		if (!chan->cl) {
			dev_warn(dev, "TX Ack on UNBOUND channel (%u)\n",
				 priv->ch_idx);
			continue;
		}

		mbox_chan_txdone(chan, 0);
		ret = IRQ_HANDLED;
	}

	if (found == 0)
		dev_warn_once(dev, "Failed to find channel for the TX interrupt\n");

	return ret;
}

static irqreturn_t mhuv3_mbx_comb_interrupt(int irq, void *arg)
{
	unsigned int i, found = 0;
	struct mhuv3 *mhu = arg;
	struct mbox_chan *chan;
	struct device *dev;
	int ret = IRQ_NONE;

	dev = mhu->mbox.dev;
	for (i = 0; i < NUM_EXT; i++) {
		struct mhuv3_mbox_chan_priv *priv;
		void *data __free(kfree) = NULL;

		if (!mhu->ext[i])
			continue;

		/* Process any extension which could be source of the IRQ */
		chan = mhu->ext[i]->chan_from_comb_irq_get(mhu);
		if (IS_ERR(chan))
			continue;

		found++;
		/* From here on we need to call rx_complete even on error */
		priv = chan->con_priv;
		if (!chan->cl) {
			dev_warn(dev, "RX Data on UNBOUND channel (%u)\n",
				 priv->ch_idx);
			goto rx_ack;
		}

		/* Read optional in-band LE data first. */
		if (priv->ops->read_data) {
			data = priv->ops->read_data(mhu, chan);
			if (IS_ERR(data)) {
				dev_err(dev,
					"Failed to read in-band data. err:%ld\n",
					PTR_ERR(data));
				goto rx_ack;
			}
		}

		mbox_chan_received_data(chan, data);
		ret = IRQ_HANDLED;

		/*
		 * Acknowledge transfer after any possible optional
		 * out-of-band data has also been retrieved via
		 * mbox_chan_received_data().
		 */
rx_ack:
		if (priv->ops->rx_complete)
			priv->ops->rx_complete(mhu, chan);
	}

	if (found == 0)
		dev_warn_once(dev, "Failed to find channel for the RX interrupt\n");

	return ret;
}

static int mhuv3_setup_pbx(struct mhuv3 *mhu)
{
	struct device *dev = mhu->mbox.dev;

	mhu->mbox.ops = &mhuv3_sender_ops;

	if (mhu->cmb_irq > 0) {
		int ret, i;

		ret = devm_request_threaded_irq(dev, mhu->cmb_irq, NULL,
						mhuv3_pbx_comb_interrupt,
						IRQF_ONESHOT, "mhuv3-pbx", mhu);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to request PBX IRQ\n");

		mhu->mbox.txdone_irq = true;
		mhu->mbox.txdone_poll = false;

		for (i = 0; i < NUM_EXT; i++)
			if (mhu->ext[i])
				mhu->ext[i]->combined_irq_setup(mhu);

		dev_dbg(dev, "MHUv3 PBX IRQs initialized.\n");

		return 0;
	}

	dev_info(dev, "Using PBX in Tx polling mode.\n");
	mhu->mbox.txdone_irq = false;
	mhu->mbox.txdone_poll = true;
	mhu->mbox.txpoll_period = 1;

	return 0;
}

static int mhuv3_setup_mbx(struct mhuv3 *mhu)
{
	struct device *dev = mhu->mbox.dev;
	int ret, i;

	mhu->mbox.ops = &mhuv3_receiver_ops;

	if (mhu->cmb_irq <= 0)
		return dev_err_probe(dev, -EINVAL,
				     "MBX combined IRQ is missing !\n");

	ret = devm_request_threaded_irq(dev, mhu->cmb_irq, NULL,
					mhuv3_mbx_comb_interrupt, IRQF_ONESHOT,
					"mhuv3-mbx", mhu);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to request MBX IRQ\n");

	for (i = 0; i < NUM_EXT; i++)
		if (mhu->ext[i])
			mhu->ext[i]->combined_irq_setup(mhu);

	dev_dbg(dev, "MHUv3 MBX IRQs initialized.\n");

	return ret;
}

static int mhuv3_irqs_init(struct mhuv3 *mhu, struct platform_device *pdev)
{
	dev_dbg(mhu->mbox.dev, "Initializing %s block.\n",
		mhuv3_str[mhu->frame]);

	if (mhu->frame == PBX_FRAME) {
		mhu->cmb_irq =
			platform_get_irq_byname_optional(pdev, "combined");
		return mhuv3_setup_pbx(mhu);
	}

	mhu->cmb_irq = platform_get_irq_byname(pdev, "combined");
	return mhuv3_setup_mbx(mhu);
}

static int mhuv3_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	void __iomem *regs;
	struct mhuv3 *mhu;
	int ret;

	mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
	if (!mhu)
		return -ENOMEM;

	regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	mhu->mbox.dev = dev;
	ret = mhuv3_frame_init(mhu, regs);
	if (ret)
		return ret;

	ret = mhuv3_irqs_init(mhu, pdev);
	if (ret)
		return ret;

	mhu->mbox.of_xlate = mhuv3_mbox_of_xlate;
	ret = mhuv3_initialize_channels(dev, mhu);
	if (ret)
		return ret;

	ret = devm_mbox_controller_register(dev, &mhu->mbox);
	if (ret)
		return dev_err_probe(dev, ret,
				     "Failed to register ARM MHUv3 driver\n");

	return ret;
}

static const struct of_device_id mhuv3_of_match[] = {
	{ .compatible = "arm,mhuv3", .data = NULL },
	{}
};
MODULE_DEVICE_TABLE(of, mhuv3_of_match);

static struct platform_driver mhuv3_driver = {
	.driver = {
		.name = "arm-mhuv3-mailbox",
		.of_match_table = mhuv3_of_match,
	},
	.probe = mhuv3_probe,
};
module_platform_driver(mhuv3_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ARM MHUv3 Driver");
MODULE_AUTHOR("Cristian Marussi <cristian.marussi@arm.com>");
