mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 12:44:11 +08:00
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: Sudeep Holla <sudeep.holla@arm.com> Signed-off-by: Elliot Berman <quic_eberman@quicinc.com> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
This commit is contained in:
parent
f11ff34d88
commit
76d4adacd5
@ -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,
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user