msm: mdss: Add error check for cmds_tx and cmds_rx APIs
Currently in the MDSS DSI driver, there is no error checking
and return for add, dma_tx and dma_rx functions in cmds_tx
and cmds_rx APIs in case read or write operations fails.
So, added error checks and return messages. Also, enable
irq after dma_add in cmds_rx in correspondence with cmdx_tx api.
Change-Id: I0fc2310ae8476510b3f903382988fec25cc2efdb
Signed-off-by: Jayant Shekhar <jshekhar@codeaurora.org>
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 055f233..e48d0d2 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1157,11 +1157,21 @@
dchdr = &cm->dchdr;
mdss_dsi_buf_reserve(tp, len);
len = mdss_dsi_cmd_dma_add(tp, cm);
+ if (!len) {
+ pr_err("%s: failed to call cmd_dma_add\n", __func__);
+ return -EINVAL;
+ }
tot += len;
if (dchdr->last) {
tp->data = tp->start; /* begin of buf */
mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
- mdss_dsi_cmd_dma_tx(ctrl, tp);
+ len = mdss_dsi_cmd_dma_tx(ctrl, tp);
+ if (IS_ERR_VALUE(len)) {
+ mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM);
+ pr_err("%s: failed to call cmd_dma_tx for cmd = 0x%x\n",
+ __func__, cmds->payload[0]);
+ return -EINVAL;
+ }
if (dchdr->wait)
usleep(dchdr->wait * 1000);
@@ -1181,7 +1191,7 @@
struct dsi_cmd_desc *cmds, int cnt)
{
u32 dsi_ctrl, data;
- int video_mode;
+ int video_mode, ret = 0;
u32 left_dsi_ctrl = 0;
bool left_ctrl_restore = false;
@@ -1221,7 +1231,12 @@
MIPI_OUTP((ctrl->ctrl_base) + 0x0004, data);
}
- mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt);
+ ret = mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("%s: failed to call\n",
+ __func__);
+ cnt = -EINVAL;
+ }
if (left_ctrl_restore)
MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
@@ -1257,7 +1272,7 @@
int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl,
struct dsi_cmd_desc *cmds, int rlen, u32 rx_flags)
{
- int cnt, len, diff, pkt_size;
+ int cnt, len, diff, pkt_size, ret = 0;
struct dsi_buf *tp, *rp;
int no_max_pkt_size;
char cmd;
@@ -1334,19 +1349,44 @@
/* packet size need to be set at every read */
pkt_size = len;
max_pktsize[0] = pkt_size;
- mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
mdss_dsi_buf_init(tp);
- mdss_dsi_cmd_dma_add(tp, &pkt_size_cmd);
- mdss_dsi_cmd_dma_tx(ctrl, tp);
+ ret = mdss_dsi_cmd_dma_add(tp, &pkt_size_cmd);
+ if (!ret) {
+ pr_err("%s: failed to call\n",
+ __func__);
+ rp->len = 0;
+ goto end;
+ }
+ mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
+ ret = mdss_dsi_cmd_dma_tx(ctrl, tp);
+ if (IS_ERR_VALUE(ret)) {
+ mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM);
+ pr_err("%s: failed to call\n",
+ __func__);
+ rp->len = 0;
+ goto end;
+ }
pr_debug("%s: Max packet size sent\n", __func__);
}
+ mdss_dsi_buf_init(tp);
+ ret = mdss_dsi_cmd_dma_add(tp, cmds);
+ if (!ret) {
+ pr_err("%s: failed to call cmd_dma_add for cmd = 0x%x\n",
+ __func__, cmds->payload[0]);
+ rp->len = 0;
+ goto end;
+ }
mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
- mdss_dsi_buf_init(tp);
- mdss_dsi_cmd_dma_add(tp, cmds);
-
/* transmit read comamnd to client */
- mdss_dsi_cmd_dma_tx(ctrl, tp);
+ ret = mdss_dsi_cmd_dma_tx(ctrl, tp);
+ if (IS_ERR_VALUE(ret)) {
+ mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM);
+ pr_err("%s: failed to call\n",
+ __func__);
+ rp->len = 0;
+ goto end;
+ }
/*
* once cmd_dma_done interrupt received,
* return data from client is ready and stored
@@ -1378,7 +1418,7 @@
switch (cmd) {
case DTYPE_ACK_ERR_RESP:
pr_debug("%s: rx ACK_ERR_PACLAGE\n", __func__);
- break;
+ rp->len = 0;
case DTYPE_GEN_READ1_RESP:
case DTYPE_DCS_READ1_RESP:
mdss_dsi_short_read1_resp(rp);
@@ -1394,10 +1434,10 @@
rp->len -= diff; /* align bytes */
break;
default:
- pr_debug("%s: Unknown cmd received\n", __func__);
- break;
+ pr_warning("%s:Invalid response cmd\n", __func__);
+ rp->len = 0;
}
-
+end:
if (left_ctrl_restore)
MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
left_dsi_ctrl); /*restore */
@@ -1413,7 +1453,7 @@
static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
struct dsi_buf *tp)
{
- int len;
+ int len, ret = 0;
int domain = MDSS_IOMMU_DOMAIN_UNSECURE;
char *bp;
unsigned long size, addr;
@@ -1458,16 +1498,18 @@
MIPI_OUTP((ctrl->ctrl_base) + 0x090, 0x01); /* trigger */
wmb();
- if (!wait_for_completion_timeout(&ctrl->dma_comp,
- msecs_to_jiffies(DMA_TX_TIMEOUT))) {
- pr_err("%s: dma timeout error\n", __func__);
- }
+ ret = wait_for_completion_timeout(&ctrl->dma_comp,
+ msecs_to_jiffies(DMA_TX_TIMEOUT));
+ if (ret == 0)
+ ret = -ETIMEDOUT;
+ else
+ ret = tp->len;
if (is_mdss_iommu_attached())
msm_iommu_unmap_contig_buffer(addr,
mdss_get_iommu_domain(domain), 0, size);
- return tp->len;
+ return ret;
}
static int mdss_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl,