// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2018, NVIDIA CORPORATION.  All rights reserved.
 */

#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mailbox_controller.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>

#include <soc/tegra/fuse.h>

#include <dt-bindings/mailbox/tegra186-hsp.h>

#include "mailbox.h"

#define HSP_INT_IE(x)		(0x100 + ((x) * 4))
#define HSP_INT_IV		0x300
#define HSP_INT_IR		0x304

#define HSP_INT_EMPTY_SHIFT	0
#define HSP_INT_EMPTY_MASK	0xff
#define HSP_INT_FULL_SHIFT	8
#define HSP_INT_FULL_MASK	0xff

#define HSP_INT_DIMENSIONING	0x380
#define HSP_nSM_SHIFT		0
#define HSP_nSS_SHIFT		4
#define HSP_nAS_SHIFT		8
#define HSP_nDB_SHIFT		12
#define HSP_nSI_SHIFT		16
#define HSP_nINT_MASK		0xf

#define HSP_DB_TRIGGER	0x0
#define HSP_DB_ENABLE	0x4
#define HSP_DB_RAW	0x8
#define HSP_DB_PENDING	0xc

#define HSP_SM_SHRD_MBOX	0x0
#define HSP_SM_SHRD_MBOX_FULL	BIT(31)
#define HSP_SM_SHRD_MBOX_FULL_INT_IE	0x04
#define HSP_SM_SHRD_MBOX_EMPTY_INT_IE	0x08

#define HSP_DB_CCPLEX		1
#define HSP_DB_BPMP		3
#define HSP_DB_MAX		7

struct tegra_hsp_channel;
struct tegra_hsp;

struct tegra_hsp_channel {
	struct tegra_hsp *hsp;
	struct mbox_chan *chan;
	void __iomem *regs;
};

struct tegra_hsp_doorbell {
	struct tegra_hsp_channel channel;
	struct list_head list;
	const char *name;
	unsigned int master;
	unsigned int index;
};

struct tegra_hsp_mailbox {
	struct tegra_hsp_channel channel;
	unsigned int index;
	bool producer;
};

struct tegra_hsp_db_map {
	const char *name;
	unsigned int master;
	unsigned int index;
};

struct tegra_hsp_soc {
	const struct tegra_hsp_db_map *map;
	bool has_per_mb_ie;
};

struct tegra_hsp {
	struct device *dev;
	const struct tegra_hsp_soc *soc;
	struct mbox_controller mbox_db;
	struct mbox_controller mbox_sm;
	void __iomem *regs;
	unsigned int doorbell_irq;
	unsigned int *shared_irqs;
	unsigned int shared_irq;
	unsigned int num_sm;
	unsigned int num_as;
	unsigned int num_ss;
	unsigned int num_db;
	unsigned int num_si;

	spinlock_t lock;
	struct lock_class_key lock_key;

	struct list_head doorbells;
	struct tegra_hsp_mailbox *mailboxes;

	unsigned long mask;
};

static inline u32 tegra_hsp_readl(struct tegra_hsp *hsp, unsigned int offset)
{
	return readl(hsp->regs + offset);
}

static inline void tegra_hsp_writel(struct tegra_hsp *hsp, u32 value,
				    unsigned int offset)
{
	writel(value, hsp->regs + offset);
}

static inline u32 tegra_hsp_channel_readl(struct tegra_hsp_channel *channel,
					  unsigned int offset)
{
	return readl(channel->regs + offset);
}

static inline void tegra_hsp_channel_writel(struct tegra_hsp_channel *channel,
					    u32 value, unsigned int offset)
{
	writel(value, channel->regs + offset);
}

static bool tegra_hsp_doorbell_can_ring(struct tegra_hsp_doorbell *db)
{
	u32 value;

	value = tegra_hsp_channel_readl(&db->channel, HSP_DB_ENABLE);

	return (value & BIT(TEGRA_HSP_DB_MASTER_CCPLEX)) != 0;
}

static struct tegra_hsp_doorbell *
__tegra_hsp_doorbell_get(struct tegra_hsp *hsp, unsigned int master)
{
	struct tegra_hsp_doorbell *entry;

	list_for_each_entry(entry, &hsp->doorbells, list)
		if (entry->master == master)
			return entry;

	return NULL;
}

static struct tegra_hsp_doorbell *
tegra_hsp_doorbell_get(struct tegra_hsp *hsp, unsigned int master)
{
	struct tegra_hsp_doorbell *db;
	unsigned long flags;

	spin_lock_irqsave(&hsp->lock, flags);
	db = __tegra_hsp_doorbell_get(hsp, master);
	spin_unlock_irqrestore(&hsp->lock, flags);

	return db;
}

static irqreturn_t tegra_hsp_doorbell_irq(int irq, void *data)
{
	struct tegra_hsp *hsp = data;
	struct tegra_hsp_doorbell *db;
	unsigned long master, value;

	db = tegra_hsp_doorbell_get(hsp, TEGRA_HSP_DB_MASTER_CCPLEX);
	if (!db)
		return IRQ_NONE;

	value = tegra_hsp_channel_readl(&db->channel, HSP_DB_PENDING);
	tegra_hsp_channel_writel(&db->channel, value, HSP_DB_PENDING);

	spin_lock(&hsp->lock);

	for_each_set_bit(master, &value, hsp->mbox_db.num_chans) {
		struct tegra_hsp_doorbell *db;

		db = __tegra_hsp_doorbell_get(hsp, master);
		/*
		 * Depending on the bootloader chain, the CCPLEX doorbell will
		 * have some doorbells enabled, which means that requesting an
		 * interrupt will immediately fire.
		 *
		 * In that case, db->channel.chan will still be NULL here and
		 * cause a crash if not properly guarded.
		 *
		 * It remains to be seen if ignoring the doorbell in that case
		 * is the correct solution.
		 */
		if (db && db->channel.chan)
			mbox_chan_received_data(db->channel.chan, NULL);
	}

	spin_unlock(&hsp->lock);

	return IRQ_HANDLED;
}

static irqreturn_t tegra_hsp_shared_irq(int irq, void *data)
{
	struct tegra_hsp *hsp = data;
	unsigned long bit, mask;
	u32 status, value;
	void *msg;

	status = tegra_hsp_readl(hsp, HSP_INT_IR) & hsp->mask;

	/* process EMPTY interrupts first */
	mask = (status >> HSP_INT_EMPTY_SHIFT) & HSP_INT_EMPTY_MASK;

	for_each_set_bit(bit, &mask, hsp->num_sm) {
		struct tegra_hsp_mailbox *mb = &hsp->mailboxes[bit];

		if (mb->producer) {
			/*
			 * Disable EMPTY interrupts until data is sent with
			 * the next message. These interrupts are level-
			 * triggered, so if we kept them enabled they would
			 * constantly trigger until we next write data into
			 * the message.
			 */
			spin_lock(&hsp->lock);

			hsp->mask &= ~BIT(HSP_INT_EMPTY_SHIFT + mb->index);
			tegra_hsp_writel(hsp, hsp->mask,
					 HSP_INT_IE(hsp->shared_irq));

			spin_unlock(&hsp->lock);

			mbox_chan_txdone(mb->channel.chan, 0);
		}
	}

	/* process FULL interrupts */
	mask = (status >> HSP_INT_FULL_SHIFT) & HSP_INT_FULL_MASK;

	for_each_set_bit(bit, &mask, hsp->num_sm) {
		struct tegra_hsp_mailbox *mb = &hsp->mailboxes[bit];

		if (!mb->producer) {
			value = tegra_hsp_channel_readl(&mb->channel,
							HSP_SM_SHRD_MBOX);
			value &= ~HSP_SM_SHRD_MBOX_FULL;
			msg = (void *)(unsigned long)value;
			mbox_chan_received_data(mb->channel.chan, msg);

			/*
			 * Need to clear all bits here since some producers,
			 * such as TCU, depend on fields in the register
			 * getting cleared by the consumer.
			 *
			 * The mailbox API doesn't give the consumers a way
			 * of doing that explicitly, so we have to make sure
			 * we cover all possible cases.
			 */
			tegra_hsp_channel_writel(&mb->channel, 0x0,
						 HSP_SM_SHRD_MBOX);
		}
	}

	return IRQ_HANDLED;
}

static struct tegra_hsp_channel *
tegra_hsp_doorbell_create(struct tegra_hsp *hsp, const char *name,
			  unsigned int master, unsigned int index)
{
	struct tegra_hsp_doorbell *db;
	unsigned int offset;
	unsigned long flags;

	db = devm_kzalloc(hsp->dev, sizeof(*db), GFP_KERNEL);
	if (!db)
		return ERR_PTR(-ENOMEM);

	offset = (1 + (hsp->num_sm / 2) + hsp->num_ss + hsp->num_as) * SZ_64K;
	offset += index * 0x100;

	db->channel.regs = hsp->regs + offset;
	db->channel.hsp = hsp;

	db->name = devm_kstrdup_const(hsp->dev, name, GFP_KERNEL);
	db->master = master;
	db->index = index;

	spin_lock_irqsave(&hsp->lock, flags);
	list_add_tail(&db->list, &hsp->doorbells);
	spin_unlock_irqrestore(&hsp->lock, flags);

	return &db->channel;
}

static int tegra_hsp_doorbell_send_data(struct mbox_chan *chan, void *data)
{
	struct tegra_hsp_doorbell *db = chan->con_priv;

	tegra_hsp_channel_writel(&db->channel, 1, HSP_DB_TRIGGER);

	return 0;
}

static int tegra_hsp_doorbell_startup(struct mbox_chan *chan)
{
	struct tegra_hsp_doorbell *db = chan->con_priv;
	struct tegra_hsp *hsp = db->channel.hsp;
	struct tegra_hsp_doorbell *ccplex;
	unsigned long flags;
	u32 value;

	if (db->master >= chan->mbox->num_chans) {
		dev_err(chan->mbox->dev,
			"invalid master ID %u for HSP channel\n",
			db->master);
		return -EINVAL;
	}

	ccplex = tegra_hsp_doorbell_get(hsp, TEGRA_HSP_DB_MASTER_CCPLEX);
	if (!ccplex)
		return -ENODEV;

	/*
	 * On simulation platforms the BPMP hasn't had a chance yet to mark
	 * the doorbell as ringable by the CCPLEX, so we want to skip extra
	 * checks here.
	 */
	if (tegra_is_silicon() && !tegra_hsp_doorbell_can_ring(db))
		return -ENODEV;

	spin_lock_irqsave(&hsp->lock, flags);

	value = tegra_hsp_channel_readl(&ccplex->channel, HSP_DB_ENABLE);
	value |= BIT(db->master);
	tegra_hsp_channel_writel(&ccplex->channel, value, HSP_DB_ENABLE);

	spin_unlock_irqrestore(&hsp->lock, flags);

	return 0;
}

static void tegra_hsp_doorbell_shutdown(struct mbox_chan *chan)
{
	struct tegra_hsp_doorbell *db = chan->con_priv;
	struct tegra_hsp *hsp = db->channel.hsp;
	struct tegra_hsp_doorbell *ccplex;
	unsigned long flags;
	u32 value;

	ccplex = tegra_hsp_doorbell_get(hsp, TEGRA_HSP_DB_MASTER_CCPLEX);
	if (!ccplex)
		return;

	spin_lock_irqsave(&hsp->lock, flags);

	value = tegra_hsp_channel_readl(&ccplex->channel, HSP_DB_ENABLE);
	value &= ~BIT(db->master);
	tegra_hsp_channel_writel(&ccplex->channel, value, HSP_DB_ENABLE);

	spin_unlock_irqrestore(&hsp->lock, flags);
}

static const struct mbox_chan_ops tegra_hsp_db_ops = {
	.send_data = tegra_hsp_doorbell_send_data,
	.startup = tegra_hsp_doorbell_startup,
	.shutdown = tegra_hsp_doorbell_shutdown,
};

static int tegra_hsp_mailbox_send_data(struct mbox_chan *chan, void *data)
{
	struct tegra_hsp_mailbox *mb = chan->con_priv;
	struct tegra_hsp *hsp = mb->channel.hsp;
	unsigned long flags;
	u32 value;

	if (WARN_ON(!mb->producer))
		return -EPERM;

	/* copy data and mark mailbox full */
	value = (u32)(unsigned long)data;
	value |= HSP_SM_SHRD_MBOX_FULL;

	tegra_hsp_channel_writel(&mb->channel, value, HSP_SM_SHRD_MBOX);

	/* enable EMPTY interrupt for the shared mailbox */
	spin_lock_irqsave(&hsp->lock, flags);

	hsp->mask |= BIT(HSP_INT_EMPTY_SHIFT + mb->index);
	tegra_hsp_writel(hsp, hsp->mask, HSP_INT_IE(hsp->shared_irq));

	spin_unlock_irqrestore(&hsp->lock, flags);

	return 0;
}

static int tegra_hsp_mailbox_flush(struct mbox_chan *chan,
				   unsigned long timeout)
{
	struct tegra_hsp_mailbox *mb = chan->con_priv;
	struct tegra_hsp_channel *ch = &mb->channel;
	u32 value;

	timeout = jiffies + msecs_to_jiffies(timeout);

	while (time_before(jiffies, timeout)) {
		value = tegra_hsp_channel_readl(ch, HSP_SM_SHRD_MBOX);
		if ((value & HSP_SM_SHRD_MBOX_FULL) == 0) {
			mbox_chan_txdone(chan, 0);

			/* Wait until channel is empty */
			if (chan->active_req != NULL)
				continue;

			return 0;
		}

		udelay(1);
	}

	return -ETIME;
}

static int tegra_hsp_mailbox_startup(struct mbox_chan *chan)
{
	struct tegra_hsp_mailbox *mb = chan->con_priv;
	struct tegra_hsp_channel *ch = &mb->channel;
	struct tegra_hsp *hsp = mb->channel.hsp;
	unsigned long flags;

	chan->txdone_method = TXDONE_BY_IRQ;

	/*
	 * Shared mailboxes start out as consumers by default. FULL and EMPTY
	 * interrupts are coalesced at the same shared interrupt.
	 *
	 * Keep EMPTY interrupts disabled at startup and only enable them when
	 * the mailbox is actually full. This is required because the FULL and
	 * EMPTY interrupts are level-triggered, so keeping EMPTY interrupts
	 * enabled all the time would cause an interrupt storm while mailboxes
	 * are idle.
	 */

	spin_lock_irqsave(&hsp->lock, flags);

	if (mb->producer)
		hsp->mask &= ~BIT(HSP_INT_EMPTY_SHIFT + mb->index);
	else
		hsp->mask |= BIT(HSP_INT_FULL_SHIFT + mb->index);

	tegra_hsp_writel(hsp, hsp->mask, HSP_INT_IE(hsp->shared_irq));

	spin_unlock_irqrestore(&hsp->lock, flags);

	if (hsp->soc->has_per_mb_ie) {
		if (mb->producer)
			tegra_hsp_channel_writel(ch, 0x0,
						 HSP_SM_SHRD_MBOX_EMPTY_INT_IE);
		else
			tegra_hsp_channel_writel(ch, 0x1,
						 HSP_SM_SHRD_MBOX_FULL_INT_IE);
	}

	return 0;
}

static void tegra_hsp_mailbox_shutdown(struct mbox_chan *chan)
{
	struct tegra_hsp_mailbox *mb = chan->con_priv;
	struct tegra_hsp_channel *ch = &mb->channel;
	struct tegra_hsp *hsp = mb->channel.hsp;
	unsigned long flags;

	if (hsp->soc->has_per_mb_ie) {
		if (mb->producer)
			tegra_hsp_channel_writel(ch, 0x0,
						 HSP_SM_SHRD_MBOX_EMPTY_INT_IE);
		else
			tegra_hsp_channel_writel(ch, 0x0,
						 HSP_SM_SHRD_MBOX_FULL_INT_IE);
	}

	spin_lock_irqsave(&hsp->lock, flags);

	if (mb->producer)
		hsp->mask &= ~BIT(HSP_INT_EMPTY_SHIFT + mb->index);
	else
		hsp->mask &= ~BIT(HSP_INT_FULL_SHIFT + mb->index);

	tegra_hsp_writel(hsp, hsp->mask, HSP_INT_IE(hsp->shared_irq));

	spin_unlock_irqrestore(&hsp->lock, flags);
}

static const struct mbox_chan_ops tegra_hsp_sm_ops = {
	.send_data = tegra_hsp_mailbox_send_data,
	.flush = tegra_hsp_mailbox_flush,
	.startup = tegra_hsp_mailbox_startup,
	.shutdown = tegra_hsp_mailbox_shutdown,
};

static struct mbox_chan *tegra_hsp_db_xlate(struct mbox_controller *mbox,
					    const struct of_phandle_args *args)
{
	struct tegra_hsp *hsp = container_of(mbox, struct tegra_hsp, mbox_db);
	unsigned int type = args->args[0], master = args->args[1];
	struct tegra_hsp_channel *channel = ERR_PTR(-ENODEV);
	struct tegra_hsp_doorbell *db;
	struct mbox_chan *chan;
	unsigned long flags;
	unsigned int i;

	if (type != TEGRA_HSP_MBOX_TYPE_DB || !hsp->doorbell_irq)
		return ERR_PTR(-ENODEV);

	db = tegra_hsp_doorbell_get(hsp, master);
	if (db)
		channel = &db->channel;

	if (IS_ERR(channel))
		return ERR_CAST(channel);

	spin_lock_irqsave(&hsp->lock, flags);

	for (i = 0; i < mbox->num_chans; i++) {
		chan = &mbox->chans[i];
		if (!chan->con_priv) {
			channel->chan = chan;
			chan->con_priv = db;
			break;
		}

		chan = NULL;
	}

	spin_unlock_irqrestore(&hsp->lock, flags);

	return chan ?: ERR_PTR(-EBUSY);
}

static struct mbox_chan *tegra_hsp_sm_xlate(struct mbox_controller *mbox,
					    const struct of_phandle_args *args)
{
	struct tegra_hsp *hsp = container_of(mbox, struct tegra_hsp, mbox_sm);
	unsigned int type = args->args[0], index;
	struct tegra_hsp_mailbox *mb;

	index = args->args[1] & TEGRA_HSP_SM_MASK;

	if (type != TEGRA_HSP_MBOX_TYPE_SM || !hsp->shared_irqs ||
	    index >= hsp->num_sm)
		return ERR_PTR(-ENODEV);

	mb = &hsp->mailboxes[index];

	if ((args->args[1] & TEGRA_HSP_SM_FLAG_TX) == 0)
		mb->producer = false;
	else
		mb->producer = true;

	return mb->channel.chan;
}

static int tegra_hsp_add_doorbells(struct tegra_hsp *hsp)
{
	const struct tegra_hsp_db_map *map = hsp->soc->map;
	struct tegra_hsp_channel *channel;

	while (map->name) {
		channel = tegra_hsp_doorbell_create(hsp, map->name,
						    map->master, map->index);
		if (IS_ERR(channel))
			return PTR_ERR(channel);

		map++;
	}

	return 0;
}

static int tegra_hsp_add_mailboxes(struct tegra_hsp *hsp, struct device *dev)
{
	int i;

	hsp->mailboxes = devm_kcalloc(dev, hsp->num_sm, sizeof(*hsp->mailboxes),
				      GFP_KERNEL);
	if (!hsp->mailboxes)
		return -ENOMEM;

	for (i = 0; i < hsp->num_sm; i++) {
		struct tegra_hsp_mailbox *mb = &hsp->mailboxes[i];

		mb->index = i;

		mb->channel.hsp = hsp;
		mb->channel.regs = hsp->regs + SZ_64K + i * SZ_32K;
		mb->channel.chan = &hsp->mbox_sm.chans[i];
		mb->channel.chan->con_priv = mb;
	}

	return 0;
}

static int tegra_hsp_request_shared_irq(struct tegra_hsp *hsp)
{
	unsigned int i, irq = 0;
	int err;

	for (i = 0; i < hsp->num_si; i++) {
		irq = hsp->shared_irqs[i];
		if (irq <= 0)
			continue;

		err = devm_request_irq(hsp->dev, irq, tegra_hsp_shared_irq, 0,
				       dev_name(hsp->dev), hsp);
		if (err < 0) {
			dev_err(hsp->dev, "failed to request interrupt: %d\n",
				err);
			continue;
		}

		hsp->shared_irq = i;

		/* disable all interrupts */
		tegra_hsp_writel(hsp, 0, HSP_INT_IE(hsp->shared_irq));

		dev_dbg(hsp->dev, "interrupt requested: %u\n", irq);

		break;
	}

	if (i == hsp->num_si) {
		dev_err(hsp->dev, "failed to find available interrupt\n");
		return -ENOENT;
	}

	return 0;
}

static int tegra_hsp_probe(struct platform_device *pdev)
{
	struct tegra_hsp *hsp;
	struct resource *res;
	unsigned int i;
	u32 value;
	int err;

	hsp = devm_kzalloc(&pdev->dev, sizeof(*hsp), GFP_KERNEL);
	if (!hsp)
		return -ENOMEM;

	hsp->dev = &pdev->dev;
	hsp->soc = of_device_get_match_data(&pdev->dev);
	INIT_LIST_HEAD(&hsp->doorbells);
	spin_lock_init(&hsp->lock);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hsp->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(hsp->regs))
		return PTR_ERR(hsp->regs);

	value = tegra_hsp_readl(hsp, HSP_INT_DIMENSIONING);
	hsp->num_sm = (value >> HSP_nSM_SHIFT) & HSP_nINT_MASK;
	hsp->num_ss = (value >> HSP_nSS_SHIFT) & HSP_nINT_MASK;
	hsp->num_as = (value >> HSP_nAS_SHIFT) & HSP_nINT_MASK;
	hsp->num_db = (value >> HSP_nDB_SHIFT) & HSP_nINT_MASK;
	hsp->num_si = (value >> HSP_nSI_SHIFT) & HSP_nINT_MASK;

	err = platform_get_irq_byname_optional(pdev, "doorbell");
	if (err >= 0)
		hsp->doorbell_irq = err;

	if (hsp->num_si > 0) {
		unsigned int count = 0;

		hsp->shared_irqs = devm_kcalloc(&pdev->dev, hsp->num_si,
						sizeof(*hsp->shared_irqs),
						GFP_KERNEL);
		if (!hsp->shared_irqs)
			return -ENOMEM;

		for (i = 0; i < hsp->num_si; i++) {
			char *name;

			name = kasprintf(GFP_KERNEL, "shared%u", i);
			if (!name)
				return -ENOMEM;

			err = platform_get_irq_byname_optional(pdev, name);
			if (err >= 0) {
				hsp->shared_irqs[i] = err;
				count++;
			}

			kfree(name);
		}

		if (count == 0) {
			devm_kfree(&pdev->dev, hsp->shared_irqs);
			hsp->shared_irqs = NULL;
		}
	}

	/* setup the doorbell controller */
	hsp->mbox_db.of_xlate = tegra_hsp_db_xlate;
	hsp->mbox_db.num_chans = 32;
	hsp->mbox_db.dev = &pdev->dev;
	hsp->mbox_db.ops = &tegra_hsp_db_ops;

	hsp->mbox_db.chans = devm_kcalloc(&pdev->dev, hsp->mbox_db.num_chans,
					  sizeof(*hsp->mbox_db.chans),
					  GFP_KERNEL);
	if (!hsp->mbox_db.chans)
		return -ENOMEM;

	if (hsp->doorbell_irq) {
		err = tegra_hsp_add_doorbells(hsp);
		if (err < 0) {
			dev_err(&pdev->dev, "failed to add doorbells: %d\n",
			        err);
			return err;
		}
	}

	err = devm_mbox_controller_register(&pdev->dev, &hsp->mbox_db);
	if (err < 0) {
		dev_err(&pdev->dev, "failed to register doorbell mailbox: %d\n",
			err);
		return err;
	}

	/* setup the shared mailbox controller */
	hsp->mbox_sm.of_xlate = tegra_hsp_sm_xlate;
	hsp->mbox_sm.num_chans = hsp->num_sm;
	hsp->mbox_sm.dev = &pdev->dev;
	hsp->mbox_sm.ops = &tegra_hsp_sm_ops;

	hsp->mbox_sm.chans = devm_kcalloc(&pdev->dev, hsp->mbox_sm.num_chans,
					  sizeof(*hsp->mbox_sm.chans),
					  GFP_KERNEL);
	if (!hsp->mbox_sm.chans)
		return -ENOMEM;

	if (hsp->shared_irqs) {
		err = tegra_hsp_add_mailboxes(hsp, &pdev->dev);
		if (err < 0) {
			dev_err(&pdev->dev, "failed to add mailboxes: %d\n",
			        err);
			return err;
		}
	}

	err = devm_mbox_controller_register(&pdev->dev, &hsp->mbox_sm);
	if (err < 0) {
		dev_err(&pdev->dev, "failed to register shared mailbox: %d\n",
			err);
		return err;
	}

	platform_set_drvdata(pdev, hsp);

	if (hsp->doorbell_irq) {
		err = devm_request_irq(&pdev->dev, hsp->doorbell_irq,
				       tegra_hsp_doorbell_irq, IRQF_NO_SUSPEND,
				       dev_name(&pdev->dev), hsp);
		if (err < 0) {
			dev_err(&pdev->dev,
			        "failed to request doorbell IRQ#%u: %d\n",
				hsp->doorbell_irq, err);
			return err;
		}
	}

	if (hsp->shared_irqs) {
		err = tegra_hsp_request_shared_irq(hsp);
		if (err < 0)
			return err;
	}

	lockdep_register_key(&hsp->lock_key);
	lockdep_set_class(&hsp->lock, &hsp->lock_key);

	return 0;
}

static int tegra_hsp_remove(struct platform_device *pdev)
{
	struct tegra_hsp *hsp = platform_get_drvdata(pdev);

	lockdep_unregister_key(&hsp->lock_key);

	return 0;
}

static int __maybe_unused tegra_hsp_resume(struct device *dev)
{
	struct tegra_hsp *hsp = dev_get_drvdata(dev);
	unsigned int i;
	struct tegra_hsp_doorbell *db;

	list_for_each_entry(db, &hsp->doorbells, list) {
		if (db && db->channel.chan)
			tegra_hsp_doorbell_startup(db->channel.chan);
	}

	if (hsp->mailboxes) {
		for (i = 0; i < hsp->num_sm; i++) {
			struct tegra_hsp_mailbox *mb = &hsp->mailboxes[i];

			if (mb->channel.chan->cl)
				tegra_hsp_mailbox_startup(mb->channel.chan);
		}
	}

	return 0;
}

static const struct dev_pm_ops tegra_hsp_pm_ops = {
	.resume_noirq = tegra_hsp_resume,
};

static const struct tegra_hsp_db_map tegra186_hsp_db_map[] = {
	{ "ccplex", TEGRA_HSP_DB_MASTER_CCPLEX, HSP_DB_CCPLEX, },
	{ "bpmp",   TEGRA_HSP_DB_MASTER_BPMP,   HSP_DB_BPMP,   },
	{ /* sentinel */ }
};

static const struct tegra_hsp_soc tegra186_hsp_soc = {
	.map = tegra186_hsp_db_map,
	.has_per_mb_ie = false,
};

static const struct tegra_hsp_soc tegra194_hsp_soc = {
	.map = tegra186_hsp_db_map,
	.has_per_mb_ie = true,
};

static const struct of_device_id tegra_hsp_match[] = {
	{ .compatible = "nvidia,tegra186-hsp", .data = &tegra186_hsp_soc },
	{ .compatible = "nvidia,tegra194-hsp", .data = &tegra194_hsp_soc },
	{ }
};

static struct platform_driver tegra_hsp_driver = {
	.driver = {
		.name = "tegra-hsp",
		.of_match_table = tegra_hsp_match,
		.pm = &tegra_hsp_pm_ops,
	},
	.probe = tegra_hsp_probe,
	.remove = tegra_hsp_remove,
};

static int __init tegra_hsp_init(void)
{
	return platform_driver_register(&tegra_hsp_driver);
}
core_initcall(tegra_hsp_init);
