Merge "msm: mhi-dev: Flush ereqs from dev close to avoid OOS transfers"

This commit is contained in:
qctecmdr 2021-08-25 08:01:31 -07:00 • committed by Gerrit - the friendly Code Review server
commit fa98c03b65
3 changed files with 22 additions and 7 deletions

View file

@ -2603,6 +2603,7 @@ int32_t ep_pcie_irq_init(struct ep_pcie_dev_t *dev)
INIT_WORK(&dev->handle_d3cold_work, handle_d3cold_func);
if (dev->aggregated_irq) {
irq_set_status_flags(dev->irq[EP_PCIE_INT_GLOBAL].num, IRQ_NOAUTOEN);
ret = devm_request_irq(pdev,
dev->irq[EP_PCIE_INT_GLOBAL].num,
ep_pcie_handle_global_irq,
@ -3446,6 +3447,7 @@ static int ep_pcie_probe(struct platform_device *pdev)
qcom_edma_init(&pdev->dev);
enable_irq(ep_pcie_dev.irq[EP_PCIE_INT_GLOBAL].num);
return 0;
irq_deinit:

View file

@ -25,6 +25,7 @@
#include <linux/vmalloc.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/limits.h>
#include "mhi.h"
#include "mhi_hwio.h"
@ -65,7 +66,7 @@
#define MHI_DEV_CH_CLOSE_TIMEOUT_MIN 5000
#define MHI_DEV_CH_CLOSE_TIMEOUT_MAX 5100
#define MHI_DEV_CH_CLOSE_TIMEOUT_COUNT 30
#define MHI_DEV_CH_CLOSE_TIMEOUT_COUNT 200
uint32_t bhi_imgtxdb;
enum mhi_msg_level mhi_msg_lvl = MHI_MSG_ERROR;
@ -363,6 +364,12 @@ static void mhi_dev_event_msi_cb(void *req)
}
ch = ereq->context;
if (!ch) {
mhi_log(MHI_MSG_ERROR, "Invalid ereq context, return\n");
return;
}
if (ch->pend_flush_cnt++ >= U32_MAX)
ch->pend_flush_cnt = 0;
mhi = ch->ring->mhi_dev;
mhi_log(MHI_MSG_VERBOSE, "MSI completed for flush req %d\n",
@ -641,7 +648,8 @@ static int mhi_dev_flush_transfer_completion_events(struct mhi_dev *mhi,
list_del_init(&flush_ereq->list);
spin_unlock_irqrestore(&mhi->lock, flags);
ch->flush_req_cnt++;
if (ch->flush_req_cnt++ >= U32_MAX)
ch->flush_req_cnt = 0;
flush_ereq->flush_num = ch->flush_req_cnt;
mhi_log(MHI_MSG_DBG, "Flush num %d called for ch %d\n",
ch->flush_req_cnt, ch->ch_id);
@ -3214,24 +3222,28 @@ void mhi_dev_close_channel(struct mhi_dev_client *handle)
{
struct mhi_dev_channel *ch;
int count = 0;
int rc = 0;
if (!handle) {
mhi_log(MHI_MSG_ERROR, "Invalid channel access:%d\n", -ENODEV);
return;
}
ch = handle->channel;
mutex_lock(&ch->ch_lock);
rc = mhi_dev_flush_transfer_completion_events(mhi_ctx, ch);
if (rc) {
mhi_log(MHI_MSG_ERROR,
"Failed to flush read completions to host\n");
}
do {
if (ch->pend_wr_count &&
!list_empty(&ch->event_req_buffers)) {
if (ch->flush_req_cnt != ch->pend_flush_cnt) {
usleep_range(MHI_DEV_CH_CLOSE_TIMEOUT_MIN,
MHI_DEV_CH_CLOSE_TIMEOUT_MAX);
} else
break;
} while (++count < MHI_DEV_CH_CLOSE_TIMEOUT_COUNT);
mutex_lock(&ch->ch_lock);
if (ch->pend_wr_count)
mhi_log(MHI_MSG_ERROR, "%d writes pending for channel %d\n",
ch->pend_wr_count, ch->ch_id);

View file

@ -508,6 +508,7 @@ struct mhi_dev_channel {
uint32_t pend_wr_count;
uint32_t msi_cnt;
uint32_t flush_req_cnt;
uint32_t pend_flush_cnt;
bool skip_td;
bool db_pending;
bool reset_pending;