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

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
......@@ -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);
return ERR_PTR(rc);
}
}
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,
};
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment