diff options
Diffstat (limited to 'drivers/remoteproc/mtk_scp_ipi.c')
| -rw-r--r-- | drivers/remoteproc/mtk_scp_ipi.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/remoteproc/mtk_scp_ipi.c b/drivers/remoteproc/mtk_scp_ipi.c index 00f041ebcde6..c068227e251e 100644 --- a/drivers/remoteproc/mtk_scp_ipi.c +++ b/drivers/remoteproc/mtk_scp_ipi.c @@ -6,13 +6,17 @@ #include <linux/clk.h> #include <linux/err.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/time64.h> #include <linux/remoteproc/mtk_scp.h> #include "mtk_common.h" +#define SCP_TIMEOUT_US (2000 * USEC_PER_MSEC) + /** * scp_ipi_register() - register an ipi function * @@ -121,7 +125,7 @@ void scp_ipi_lock(struct mtk_scp *scp, u32 id) EXPORT_SYMBOL_GPL(scp_ipi_lock); /** - * scp_ipi_lock() - Unlock after operations of an IPI ID + * scp_ipi_unlock() - Unlock after operations of an IPI ID * * @scp: mtk_scp structure * @id: IPI ID @@ -156,33 +160,34 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, unsigned int wait) { struct mtk_share_obj __iomem *send_obj = scp->send_buf; - unsigned long timeout; + u32 val; int ret; + const struct mtk_scp_sizes_data *scp_sizes; + + scp_sizes = scp->data->scp_sizes; if (WARN_ON(id <= SCP_IPI_INIT) || WARN_ON(id >= SCP_IPI_MAX) || WARN_ON(id == SCP_IPI_NS_SERVICE) || - WARN_ON(len > sizeof(send_obj->share_buf)) || WARN_ON(!buf)) + WARN_ON(len > scp_sizes->ipi_share_buffer_size) || WARN_ON(!buf)) return -EINVAL; - mutex_lock(&scp->send_lock); - ret = clk_prepare_enable(scp->clk); if (ret) { dev_err(scp->dev, "failed to enable clock\n"); - goto unlock_mutex; + return ret; } + mutex_lock(&scp->send_lock); + /* Wait until SCP receives the last command */ - timeout = jiffies + msecs_to_jiffies(2000); - do { - if (time_after(jiffies, timeout)) { - dev_err(scp->dev, "%s: IPI timeout!\n", __func__); - ret = -ETIMEDOUT; - goto clock_disable; - } - } while (readl(scp->reg_base + scp->data->host_to_scp_reg)); + ret = readl_poll_timeout_atomic(scp->cluster->reg_base + scp->data->host_to_scp_reg, + val, !val, 0, SCP_TIMEOUT_US); + if (ret) { + dev_err(scp->dev, "%s: IPI timeout!\n", __func__); + goto unlock_mutex; + } - scp_memcpy_aligned(send_obj->share_buf, buf, len); + scp_memcpy_aligned(&send_obj->share_buf, buf, len); writel(len, &send_obj->len); writel(id, &send_obj->id); @@ -190,14 +195,13 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, scp->ipi_id_ack[id] = false; /* send the command to SCP */ writel(scp->data->host_to_scp_int_bit, - scp->reg_base + scp->data->host_to_scp_reg); + scp->cluster->reg_base + scp->data->host_to_scp_reg); if (wait) { /* wait for SCP's ACK */ - timeout = msecs_to_jiffies(wait); ret = wait_event_timeout(scp->ack_wq, scp->ipi_id_ack[id], - timeout); + msecs_to_jiffies(wait)); scp->ipi_id_ack[id] = false; if (WARN(!ret, "scp ipi %d ack time out !", id)) ret = -EIO; @@ -205,10 +209,9 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, ret = 0; } -clock_disable: - clk_disable_unprepare(scp->clk); unlock_mutex: mutex_unlock(&scp->send_lock); + clk_disable_unprepare(scp->clk); return ret; } |
