Commit 76d4adac authored by Elliot Berman's avatar Elliot Berman Committed by Jassi Brar
Browse files

mailbox: pcc: Use mbox_bind_client



Use generic mbox_bind_client() to bind omap mailbox channel to a client.

mbox_bind_client is identical to the replaced lines, except that it:
 - Does the operation under con_mutex which prevents possible races in
   removal path
 - Sets TXDONE_BY_ACK if pcc uses TXDONE_BY_POLL and the client knows
   when tx is done. TXDONE_BY_ACK is already set if there's no interrupt,
   so this is not applicable.
 - Calls chan->mbox->ops->startup. This is usecase for requesting irq:
   move the devm_request_irq into the startup callback and unregister it
   in the shutdown path.

Tested-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Signed-off-by: default avatarElliot Berman <quic_eberman@quicinc.com>
Signed-off-by: default avatarJassi Brar <jaswinder.singh@linaro.org>
parent f11ff34d
Loading
Loading
Loading
Loading
+45 −39
Original line number Diff line number Diff line
@@ -282,8 +282,7 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
{
	struct pcc_chan_info *pchan;
	struct mbox_chan *chan;
	struct device *dev;
	unsigned long flags;
	int rc;

	if (subspace_id < 0 || subspace_id >= pcc_chan_count)
		return ERR_PTR(-ENOENT);
@@ -294,32 +293,10 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
		pr_err("Channel not found for idx: %d\n", subspace_id);
		return ERR_PTR(-EBUSY);
	}
	dev = chan->mbox->dev;

	spin_lock_irqsave(&chan->lock, flags);
	chan->msg_free = 0;
	chan->msg_count = 0;
	chan->active_req = NULL;
	chan->cl = cl;
	init_completion(&chan->tx_complete);

	if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
		chan->txdone_method = TXDONE_BY_ACK;

	spin_unlock_irqrestore(&chan->lock, flags);

	if (pchan->plat_irq > 0) {
		int rc;

		rc = devm_request_irq(dev, pchan->plat_irq, pcc_mbox_irq, 0,
				      MBOX_IRQ_NAME, chan);
		if (unlikely(rc)) {
			dev_err(dev, "failed to register PCC interrupt %d\n",
				pchan->plat_irq);
			pcc_mbox_free_channel(&pchan->chan);
	rc = mbox_bind_client(chan, cl);
	if (rc)
		return ERR_PTR(rc);
		}
	}

	return &pchan->chan;
}
@@ -333,23 +310,12 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
 */
void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan)
{
	struct pcc_chan_info *pchan_info = to_pcc_chan_info(pchan);
	struct mbox_chan *chan = pchan->mchan;
	unsigned long flags;

	if (!chan || !chan->cl)
		return;

	if (pchan_info->plat_irq > 0)
		devm_free_irq(chan->mbox->dev, pchan_info->plat_irq, chan);

	spin_lock_irqsave(&chan->lock, flags);
	chan->cl = NULL;
	chan->active_req = NULL;
	if (chan->txdone_method == TXDONE_BY_ACK)
		chan->txdone_method = TXDONE_BY_POLL;

	spin_unlock_irqrestore(&chan->lock, flags);
	mbox_free_channel(chan);
}
EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);

@@ -377,8 +343,48 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
	return pcc_chan_reg_read_modify_write(&pchan->db);
}

/**
 * pcc_startup - Called from Mailbox Controller code. Used here
 *		to request the interrupt.
 * @chan: Pointer to Mailbox channel to startup.
 *
 * Return: Err if something failed else 0 for success.
 */
static int pcc_startup(struct mbox_chan *chan)
{
	struct pcc_chan_info *pchan = chan->con_priv;
	int rc;

	if (pchan->plat_irq > 0) {
		rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 0,
				      MBOX_IRQ_NAME, chan);
		if (unlikely(rc)) {
			dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n",
				pchan->plat_irq);
			return rc;
		}
	}

	return 0;
}

/**
 * pcc_shutdown - Called from Mailbox Controller code. Used here
 *		to free the interrupt.
 * @chan: Pointer to Mailbox channel to shutdown.
 */
static void pcc_shutdown(struct mbox_chan *chan)
{
	struct pcc_chan_info *pchan = chan->con_priv;

	if (pchan->plat_irq > 0)
		devm_free_irq(chan->mbox->dev, pchan->plat_irq, chan);
}

static const struct mbox_chan_ops pcc_chan_ops = {
	.send_data = pcc_send_data,
	.startup = pcc_startup,
	.shutdown = pcc_shutdown,
};

/**