summaryrefslogtreecommitdiff
path: root/mhi
diff options
context:
space:
mode:
authorHsiu-Chang Chen <hsiuchangchen@google.com>2022-02-15 10:19:35 +0800
committerHsiu-Chang Chen <hsiuchangchen@google.com>2022-03-03 03:43:57 +0000
commit2af1153b42048ff3e1ad049dee7ddff26081acd2 (patch)
tree44c5c95488028d0bd883c83068b14f50a48589cf /mhi
parentef22de835ccf8c7c394dbd601c0ca1d7a4ab1681 (diff)
downloadcnss2-2af1153b42048ff3e1ad049dee7ddff26081acd2.tar.gz
wcn6740: Update cnss/mhi/qmi/qrtr drivers
Migrate wlan codes to Rel2(Post CS5) Bug: 218419889 Test: Basic functions Change-Id: Ifd845bfba4ca35d14f5606b5cf2dde12e397801b
Diffstat (limited to 'mhi')
-rw-r--r--mhi/core/main.c32
-rw-r--r--mhi/core/misc.c43
2 files changed, 59 insertions, 16 deletions
diff --git a/mhi/core/main.c b/mhi/core/main.c
index acca77d..febe2ac 100644
--- a/mhi/core/main.c
+++ b/mhi/core/main.c
@@ -242,6 +242,11 @@ void *mhi_to_virtual(struct mhi_ring *ring, dma_addr_t addr)
return (addr - ring->iommu_base) + ring->base;
}
+dma_addr_t mhi_to_physical(struct mhi_ring *ring, void *addr)
+{
+ return (addr - ring->base) + ring->iommu_base;
+}
+
static void mhi_add_ring_element(struct mhi_controller *mhi_cntrl,
struct mhi_ring *ring)
{
@@ -671,6 +676,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
mhi_del_ring_element(mhi_cntrl, tre_ring);
local_rp = tre_ring->rp;
+ read_unlock_bh(&mhi_chan->lock);
+
/* notify client */
mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
@@ -693,6 +700,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
kfree(buf_info->cb_buf);
}
}
+
+ read_lock_bh(&mhi_chan->lock);
}
break;
} /* CC_EOT */
@@ -799,6 +808,7 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl,
struct mhi_ring *mhi_ring = &cmd_ring->ring;
struct mhi_tre *cmd_pkt;
struct mhi_chan *mhi_chan;
+ struct mhi_tre *mhi_tre;
u32 chan;
if (!is_valid_ring_ptr(mhi_ring, ptr)) {
@@ -808,9 +818,11 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl,
cmd_pkt = mhi_to_virtual(mhi_ring, ptr);
- if (cmd_pkt != mhi_ring->rp)
- panic("Out of order cmd completion: 0x%p. Expected: 0x%p\n",
- cmd_pkt, mhi_ring->rp);
+ if (cmd_pkt != mhi_ring->rp) {
+ mhi_tre = mhi_ring->rp;
+ panic("Out of order cmd completion: 0x%llx. Expected: 0x%llx\n",
+ ptr, (u64)mhi_to_physical(mhi_ring, mhi_tre));
+ }
if (MHI_TRE_GET_CMD_TYPE(cmd_pkt) == MHI_CMD_SFR_CFG) {
mhi_misc_cmd_completion(mhi_cntrl, MHI_CMD_SFR_CFG,
@@ -1287,6 +1299,9 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
int eot, eob, chain, bei;
int ret;
+ /* Protect accesses for reading and incrementing WP */
+ write_lock_bh(&mhi_chan->lock);
+
buf_ring = &mhi_chan->buf_ring;
tre_ring = &mhi_chan->tre_ring;
@@ -1304,8 +1319,10 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
if (!info->pre_mapped) {
ret = mhi_cntrl->map_single(mhi_cntrl, buf_info);
- if (ret)
+ if (ret) {
+ write_unlock_bh(&mhi_chan->lock);
return ret;
+ }
}
eob = !!(flags & MHI_EOB);
@@ -1318,14 +1335,17 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
mhi_tre->dword[0] = MHI_TRE_DATA_DWORD0(info->len);
mhi_tre->dword[1] = MHI_TRE_DATA_DWORD1(bei, eot, eob, chain);
- MHI_VERB("Channel: %d WP: 0x%p TRE: 0x%llx 0x%08x 0x%08x\n",
- mhi_chan->chan, mhi_tre, mhi_tre->ptr, mhi_tre->dword[0],
+ MHI_VERB("Channel: %d WP: 0x%llx TRE: 0x%llx 0x%08x 0x%08x\n",
+ mhi_chan->chan, (u64)mhi_to_physical(tre_ring, mhi_tre),
+ mhi_tre->ptr, mhi_tre->dword[0],
mhi_tre->dword[1]);
/* increment WP */
mhi_add_ring_element(mhi_cntrl, tre_ring);
mhi_add_ring_element(mhi_cntrl, buf_ring);
+ write_unlock_bh(&mhi_chan->lock);
+
return 0;
}
diff --git a/mhi/core/misc.c b/mhi/core/misc.c
index f0c1f69..20f6333 100644
--- a/mhi/core/misc.c
+++ b/mhi/core/misc.c
@@ -180,6 +180,9 @@ int mhi_misc_register_controller(struct mhi_controller *mhi_cntrl)
mhi_priv->log_buf = ipc_log_context_create(MHI_IPC_LOG_PAGES,
mhi_dev->name, 0);
+ if (!mhi_priv->log_buf)
+ MHI_ERR("%s:Failed to create MHI IPC logs\n", __func__);
+
mhi_priv->log_lvl = MHI_MISC_DEBUG_LEVEL;
mhi_priv->mhi_cntrl = mhi_cntrl;
@@ -675,6 +678,7 @@ static void mhi_process_sfr(struct mhi_controller *mhi_cntrl,
crash_info_handler(sfr_buf);
}
#endif
+
/* force sfr string to log in kernel msg */
MHI_ERR("%s\n", sfr_buf);
err:
@@ -773,7 +777,17 @@ bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie)
struct device *dev = &mhi_cntrl->mhi_dev->dev;
int ret;
u32 val;
-
+ int i;
+ bool result = false;
+ struct {
+ char *name;
+ u32 offset;
+ } error_reg[] = {
+ { "ERROR_DBG1", BHI_ERRDBG1 },
+ { "ERROR_DBG2", BHI_ERRDBG2 },
+ { "ERROR_DBG3", BHI_ERRDBG3 },
+ { NULL },
+ };
if (!mhi_cntrl->rddm_image || !cookie)
return false;
@@ -782,15 +796,23 @@ bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie)
if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
return false;
- ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_ERRDBG2, &val);
- if (ret)
- return false;
+ /* look for an RDDM cookie match in any of the error debug registers */
+ for (i = 0; error_reg[i].name; i++) {
- MHI_VERB("BHI_ERRDBG2 value:0x%x\n", val);
- if (val == cookie)
- return true;
+ ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, error_reg[i].offset, &val);
- return false;
+ if (ret)
+ break;
+
+ MHI_VERB("reg: %s value:0x%x\n", error_reg[i].name, val);
+
+ if (!(val ^ cookie)) {
+ MHI_VERB("RDDM Cookie found in %s\n", error_reg[i].name);
+ return true;
+ }
+ }
+ MHI_VERB("RDDM Cookie not found\n");
+ return result;
}
EXPORT_SYMBOL(mhi_scan_rddm_cookie);
@@ -922,6 +944,9 @@ static int mhi_get_capability_offset(struct mhi_controller *mhi_cntrl,
if (ret)
return ret;
do {
+ if (*offset >= MHI_REG_SIZE)
+ return -ENXIO;
+
ret = mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, *offset,
CAP_CAPID_MASK, CAP_CAPID_SHIFT,
&cur_cap);
@@ -938,8 +963,6 @@ static int mhi_get_capability_offset(struct mhi_controller *mhi_cntrl,
return ret;
*offset = next_offset;
- if (*offset >= MHI_REG_SIZE)
- return -ENXIO;
} while (next_offset);
return -ENXIO;