mailbox: rockchip: amend txdone method to polling
Since there is no txdone irq in the Rockchip mailbox IP, invoking mbox_chan_txdone()/mbox_client_txdone() after mbox_send_message() to tick the TX would be free the active request which have not been sent out if the controller returned the EBUSY state before. So amend the txdone method to polling to fix it. The TX polling interval can specify in DT with "rockchip,txpoll-period-ms" property, if it is not set, the driver would hardcode to 5 milliseconds. Signed-off-by: Frank Wang <frank.wang@rock-chips.com> Change-Id: Ic26d3245dd8bd90ebad30fce9ece2f4452814f7f
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
#define MAILBOX_B2A_CMD(x) (0x30 + (x) * 8)
|
||||
#define MAILBOX_B2A_DAT(x) (0x34 + (x) * 8)
|
||||
|
||||
#define MAILBOX_POLLING_MS 5 /* default polling interval 5ms */
|
||||
|
||||
struct rockchip_mbox_data {
|
||||
int num_chans;
|
||||
};
|
||||
@@ -99,10 +101,21 @@ static void rockchip_mbox_shutdown(struct mbox_chan *chan)
|
||||
spin_unlock(&mb->cfg_lock);
|
||||
}
|
||||
|
||||
static bool rockchip_mbox_last_tx_done(struct mbox_chan *chan)
|
||||
{
|
||||
struct rockchip_mbox *mb = dev_get_drvdata(chan->mbox->dev);
|
||||
struct rockchip_mbox_chan *chans = chan->con_priv;
|
||||
u32 status;
|
||||
|
||||
status = readl_relaxed(mb->mbox_base + MAILBOX_A2B_STATUS);
|
||||
return !(status & (1U << chans->idx));
|
||||
}
|
||||
|
||||
static const struct mbox_chan_ops rockchip_mbox_chan_ops = {
|
||||
.send_data = rockchip_mbox_send_data,
|
||||
.startup = rockchip_mbox_startup,
|
||||
.shutdown = rockchip_mbox_shutdown,
|
||||
.last_tx_done = rockchip_mbox_last_tx_done,
|
||||
};
|
||||
|
||||
int rockchip_mbox_read_msg(struct mbox_chan *chan,
|
||||
@@ -172,6 +185,7 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
|
||||
const struct rockchip_mbox_data *drv_data;
|
||||
struct resource *res;
|
||||
int ret, irq, i;
|
||||
u32 txpoll_period;
|
||||
|
||||
if (!pdev->dev.of_node)
|
||||
return -ENODEV;
|
||||
@@ -203,9 +217,12 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
|
||||
mb->mbox.dev = &pdev->dev;
|
||||
mb->mbox.num_chans = drv_data->num_chans;
|
||||
mb->mbox.ops = &rockchip_mbox_chan_ops;
|
||||
mb->mbox.txdone_irq = true;
|
||||
spin_lock_init(&mb->cfg_lock);
|
||||
|
||||
mb->mbox.txdone_poll = true;
|
||||
ret = device_property_read_u32(&pdev->dev, "rockchip,txpoll-period-ms", &txpoll_period);
|
||||
mb->mbox.txpoll_period = !ret ? txpoll_period : MAILBOX_POLLING_MS;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
Reference in New Issue
Block a user