Loading drivers/platform/msm/mhi_dev/mhi.c +55 −4 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,10 @@ #define TR_RING_ELEMENT_SZ sizeof(struct mhi_dev_transfer_ring_element) #define TR_RING_ELEMENT_SZ sizeof(struct mhi_dev_transfer_ring_element) #define RING_ELEMENT_TYPE_SZ sizeof(union mhi_dev_ring_element_type) #define RING_ELEMENT_TYPE_SZ sizeof(union mhi_dev_ring_element_type) #define MHI_DEV_CH_CLOSE_TIMEOUT_MIN 5000 #define MHI_DEV_CH_CLOSE_TIMEOUT_MAX 5100 #define MHI_DEV_CH_CLOSE_TIMEOUT_COUNT 30 uint32_t bhi_imgtxdb; uint32_t bhi_imgtxdb; enum mhi_msg_level mhi_msg_lvl = MHI_MSG_ERROR; enum mhi_msg_level mhi_msg_lvl = MHI_MSG_ERROR; enum mhi_msg_level mhi_ipc_msg_lvl = MHI_MSG_VERBOSE; enum mhi_msg_level mhi_ipc_msg_lvl = MHI_MSG_VERBOSE; Loading Loading @@ -1206,7 +1210,7 @@ static int mhi_dev_process_stop_cmd(struct mhi_dev_ring *ring, uint32_t ch_id, return 0; return 0; } else if (mhi->ch_ctx_cache[ch_id].ch_type == } else if (mhi->ch_ctx_cache[ch_id].ch_type == MHI_DEV_CH_TYPE_INBOUND_CHANNEL && MHI_DEV_CH_TYPE_INBOUND_CHANNEL && mhi->ch[ch_id].wr_request_active) { (mhi->ch[ch_id].pend_wr_count > 0)) { mhi_log(MHI_MSG_INFO, "Pending inbound transaction\n"); mhi_log(MHI_MSG_INFO, "Pending inbound transaction\n"); return 0; return 0; } } Loading Loading @@ -1758,9 +1762,23 @@ static void mhi_dev_transfer_completion_cb(void *mreq) rd_offset = req->rd_offset; rd_offset = req->rd_offset; ch->curr_ereq->context = ch; ch->curr_ereq->context = ch; if (mhi->ch_ctx_cache[ch->ch_id].ch_type == MHI_DEV_CH_TYPE_INBOUND_CHANNEL) ch->pend_wr_count--; dma_unmap_single(&mhi_ctx->pdev->dev, req->dma, dma_unmap_single(&mhi_ctx->pdev->dev, req->dma, req->len, DMA_FROM_DEVICE); req->len, DMA_FROM_DEVICE); /* * Channel got closed with transfers pending * Do not trigger callback or send cmpl to host */ if (ch->state == MHI_DEV_CH_CLOSED) { mhi_log(MHI_MSG_DBG, "Ch %d closed with %d writes pending\n", ch->ch_id, ch->pend_wr_count + 1); return; } /* Trigger client call back */ /* Trigger client call back */ req->client_cb(req); req->client_cb(req); Loading Loading @@ -2306,9 +2324,27 @@ int mhi_dev_channel_isempty(struct mhi_dev_client *handle) } } EXPORT_SYMBOL(mhi_dev_channel_isempty); EXPORT_SYMBOL(mhi_dev_channel_isempty); bool mhi_dev_channel_has_pending_write(struct mhi_dev_client *handle) { struct mhi_dev_channel *ch; if (!handle) { mhi_log(MHI_MSG_ERROR, "Invalid channel access\n"); return -EINVAL; } ch = handle->channel; if (!ch) return -EINVAL; return ch->pend_wr_count ? true : false; } EXPORT_SYMBOL(mhi_dev_channel_has_pending_write); void mhi_dev_close_channel(struct mhi_dev_client *handle) void mhi_dev_close_channel(struct mhi_dev_client *handle) { { struct mhi_dev_channel *ch; struct mhi_dev_channel *ch; int count = 0; if (!handle) { if (!handle) { mhi_log(MHI_MSG_ERROR, "Invalid channel access:%d\n", -ENODEV); mhi_log(MHI_MSG_ERROR, "Invalid channel access:%d\n", -ENODEV); Loading @@ -2316,8 +2352,20 @@ void mhi_dev_close_channel(struct mhi_dev_client *handle) } } ch = handle->channel; ch = handle->channel; do { if (ch->pend_wr_count) { 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); 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); if (ch->state != MHI_DEV_CH_PENDING_START) if (ch->state != MHI_DEV_CH_PENDING_START) if ((ch->ch_type == MHI_DEV_CH_TYPE_OUTBOUND_CHANNEL && if ((ch->ch_type == MHI_DEV_CH_TYPE_OUTBOUND_CHANNEL && !mhi_dev_channel_isempty(handle)) || ch->tre_loc) !mhi_dev_channel_isempty(handle)) || ch->tre_loc) Loading Loading @@ -2526,6 +2574,7 @@ int mhi_dev_write_channel(struct mhi_req *wreq) size_t bytes_to_write = 0; size_t bytes_to_write = 0; size_t bytes_written = 0; size_t bytes_written = 0; uint32_t tre_len = 0, suspend_wait_timeout = 0; uint32_t tre_len = 0, suspend_wait_timeout = 0; bool async_wr_sched = false; if (WARN_ON(!wreq || !wreq->client || !wreq->buf)) { if (WARN_ON(!wreq || !wreq->client || !wreq->buf)) { pr_err("%s: invalid parameters\n", __func__); pr_err("%s: invalid parameters\n", __func__); Loading Loading @@ -2569,12 +2618,12 @@ int mhi_dev_write_channel(struct mhi_req *wreq) handle_client = wreq->client; handle_client = wreq->client; ch = handle_client->channel; ch = handle_client->channel; ch->wr_request_active = true; ring = ch->ring; ring = ch->ring; mutex_lock(&ch->ch_lock); mutex_lock(&ch->ch_lock); ch->pend_wr_count++; if (ch->state == MHI_DEV_CH_STOPPED) { if (ch->state == MHI_DEV_CH_STOPPED) { mhi_log(MHI_MSG_ERROR, mhi_log(MHI_MSG_ERROR, "channel %d already stopped\n", wreq->chan); "channel %d already stopped\n", wreq->chan); Loading Loading @@ -2625,7 +2674,8 @@ int mhi_dev_write_channel(struct mhi_req *wreq) "Error while writing chan (%d) rc %d\n", "Error while writing chan (%d) rc %d\n", wreq->chan, rc); wreq->chan, rc); goto exit; goto exit; } } else if (wreq->mode == DMA_ASYNC) async_wr_sched = true; bytes_written += bytes_to_write; bytes_written += bytes_to_write; usr_buf_remaining -= bytes_to_write; usr_buf_remaining -= bytes_to_write; Loading Loading @@ -2665,7 +2715,8 @@ int mhi_dev_write_channel(struct mhi_req *wreq) } } } } exit: exit: ch->wr_request_active = false; if (wreq->mode == DMA_SYNC || !async_wr_sched) ch->pend_wr_count--; mutex_unlock(&ch->ch_lock); mutex_unlock(&ch->ch_lock); mutex_unlock(&mhi_ctx->mhi_write_test); mutex_unlock(&mhi_ctx->mhi_write_test); return bytes_written; return bytes_written; Loading drivers/platform/msm/mhi_dev/mhi.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -460,7 +460,7 @@ struct mhi_dev_channel { uint32_t tre_bytes_left; uint32_t tre_bytes_left; /* td size being read/written from/to so far */ /* td size being read/written from/to so far */ uint32_t td_size; uint32_t td_size; bool wr_request_active; uint32_t pend_wr_count; bool skip_td; bool skip_td; }; }; Loading drivers/platform/msm/mhi_dev/mhi_uci.c +45 −25 Original line number Original line Diff line number Diff line Loading @@ -46,6 +46,10 @@ #define MHI_UCI_AT_CTRL_READ_TIMEOUT msecs_to_jiffies(1000) #define MHI_UCI_AT_CTRL_READ_TIMEOUT msecs_to_jiffies(1000) #define MHI_UCI_WRITE_REQ_AVAIL_TIMEOUT msecs_to_jiffies(1000) #define MHI_UCI_WRITE_REQ_AVAIL_TIMEOUT msecs_to_jiffies(1000) #define MHI_UCI_RELEASE_TIMEOUT_MIN 5000 #define MHI_UCI_RELEASE_TIMEOUT_MAX 5100 #define MHI_UCI_RELEASE_TIMEOUT_COUNT 30 enum uci_dbg_level { enum uci_dbg_level { UCI_DBG_VERBOSE = 0x0, UCI_DBG_VERBOSE = 0x0, UCI_DBG_INFO = 0x1, UCI_DBG_INFO = 0x1, Loading Loading @@ -960,14 +964,35 @@ static int mhi_uci_client_release(struct inode *mhi_inode, struct file *file_handle) struct file *file_handle) { { struct uci_client *uci_handle = file_handle->private_data; struct uci_client *uci_handle = file_handle->private_data; int count = 0; if (!uci_handle) if (!uci_handle) return -EINVAL; return -EINVAL; if (atomic_sub_return(1, &uci_handle->ref_count) == 0) { if (atomic_sub_return(1, &uci_handle->ref_count)) { uci_log(UCI_DBG_DBG, "Client close chan %d, ref count 0x%x\n", iminor(mhi_inode), atomic_read(&uci_handle->ref_count)); return 0; } uci_log(UCI_DBG_DBG, uci_log(UCI_DBG_DBG, "Last client left, closing channel 0x%x\n", "Last client left, closing channel 0x%x\n", iminor(mhi_inode)); iminor(mhi_inode)); do { if (mhi_dev_channel_has_pending_write(uci_handle->out_handle)) usleep_range(MHI_UCI_RELEASE_TIMEOUT_MIN, MHI_UCI_RELEASE_TIMEOUT_MAX); else break; } while (++count < MHI_UCI_RELEASE_TIMEOUT_COUNT); if (count == MHI_UCI_RELEASE_TIMEOUT_COUNT) { uci_log(UCI_DBG_DBG, "Channel %d has pending writes\n", iminor(mhi_inode)); } if (atomic_read(&uci_handle->mhi_chans_open)) { if (atomic_read(&uci_handle->mhi_chans_open)) { atomic_set(&uci_handle->mhi_chans_open, 0); atomic_set(&uci_handle->mhi_chans_open, 0); Loading @@ -982,17 +1007,12 @@ static int mhi_uci_client_release(struct inode *mhi_inode, mhi_dev_close_channel(uci_handle->in_handle); mhi_dev_close_channel(uci_handle->in_handle); wake_up(&uci_handle->read_wq); wake_up(&uci_handle->read_wq); mutex_unlock(&uci_handle->in_chan_lock); mutex_unlock(&uci_handle->in_chan_lock); } } atomic_set(&uci_handle->read_data_ready, 0); atomic_set(&uci_handle->read_data_ready, 0); atomic_set(&uci_handle->write_data_ready, 0); atomic_set(&uci_handle->write_data_ready, 0); file_handle->private_data = NULL; file_handle->private_data = NULL; } else { uci_log(UCI_DBG_DBG, "Client close chan %d, ref count 0x%x\n", iminor(mhi_inode), atomic_read(&uci_handle->ref_count)); } return 0; return 0; } } Loading include/linux/msm_mhi_dev.h +13 −0 Original line number Original line Diff line number Diff line Loading @@ -194,6 +194,13 @@ int mhi_dev_write_channel(struct mhi_req *wreq); */ */ int mhi_dev_channel_isempty(struct mhi_dev_client *handle); int mhi_dev_channel_isempty(struct mhi_dev_client *handle); /** * mhi_dev_channel_has_pending_write() - Checks if there are any pending writes * to be completed on inbound channel * @handle_client: Client Handle issued during mhi_dev_open_channel */ bool mhi_dev_channel_has_pending_write(struct mhi_dev_client *handle); /** /** * mhi_ctrl_state_info() - Provide MHI state info * mhi_ctrl_state_info() - Provide MHI state info * @idx: Channel number idx. Look at channel_state_info and * @idx: Channel number idx. Look at channel_state_info and Loading Loading @@ -244,6 +251,12 @@ static inline int mhi_dev_channel_isempty(struct mhi_dev_client *handle) return -EINVAL; return -EINVAL; }; }; static inline bool mhi_dev_channel_has_pending_write (struct mhi_dev_client *handle) { return false; } static inline int mhi_ctrl_state_info(uint32_t idx, uint32_t *info) static inline int mhi_ctrl_state_info(uint32_t idx, uint32_t *info) { { return -EINVAL; return -EINVAL; Loading Loading
drivers/platform/msm/mhi_dev/mhi.c +55 −4 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,10 @@ #define TR_RING_ELEMENT_SZ sizeof(struct mhi_dev_transfer_ring_element) #define TR_RING_ELEMENT_SZ sizeof(struct mhi_dev_transfer_ring_element) #define RING_ELEMENT_TYPE_SZ sizeof(union mhi_dev_ring_element_type) #define RING_ELEMENT_TYPE_SZ sizeof(union mhi_dev_ring_element_type) #define MHI_DEV_CH_CLOSE_TIMEOUT_MIN 5000 #define MHI_DEV_CH_CLOSE_TIMEOUT_MAX 5100 #define MHI_DEV_CH_CLOSE_TIMEOUT_COUNT 30 uint32_t bhi_imgtxdb; uint32_t bhi_imgtxdb; enum mhi_msg_level mhi_msg_lvl = MHI_MSG_ERROR; enum mhi_msg_level mhi_msg_lvl = MHI_MSG_ERROR; enum mhi_msg_level mhi_ipc_msg_lvl = MHI_MSG_VERBOSE; enum mhi_msg_level mhi_ipc_msg_lvl = MHI_MSG_VERBOSE; Loading Loading @@ -1206,7 +1210,7 @@ static int mhi_dev_process_stop_cmd(struct mhi_dev_ring *ring, uint32_t ch_id, return 0; return 0; } else if (mhi->ch_ctx_cache[ch_id].ch_type == } else if (mhi->ch_ctx_cache[ch_id].ch_type == MHI_DEV_CH_TYPE_INBOUND_CHANNEL && MHI_DEV_CH_TYPE_INBOUND_CHANNEL && mhi->ch[ch_id].wr_request_active) { (mhi->ch[ch_id].pend_wr_count > 0)) { mhi_log(MHI_MSG_INFO, "Pending inbound transaction\n"); mhi_log(MHI_MSG_INFO, "Pending inbound transaction\n"); return 0; return 0; } } Loading Loading @@ -1758,9 +1762,23 @@ static void mhi_dev_transfer_completion_cb(void *mreq) rd_offset = req->rd_offset; rd_offset = req->rd_offset; ch->curr_ereq->context = ch; ch->curr_ereq->context = ch; if (mhi->ch_ctx_cache[ch->ch_id].ch_type == MHI_DEV_CH_TYPE_INBOUND_CHANNEL) ch->pend_wr_count--; dma_unmap_single(&mhi_ctx->pdev->dev, req->dma, dma_unmap_single(&mhi_ctx->pdev->dev, req->dma, req->len, DMA_FROM_DEVICE); req->len, DMA_FROM_DEVICE); /* * Channel got closed with transfers pending * Do not trigger callback or send cmpl to host */ if (ch->state == MHI_DEV_CH_CLOSED) { mhi_log(MHI_MSG_DBG, "Ch %d closed with %d writes pending\n", ch->ch_id, ch->pend_wr_count + 1); return; } /* Trigger client call back */ /* Trigger client call back */ req->client_cb(req); req->client_cb(req); Loading Loading @@ -2306,9 +2324,27 @@ int mhi_dev_channel_isempty(struct mhi_dev_client *handle) } } EXPORT_SYMBOL(mhi_dev_channel_isempty); EXPORT_SYMBOL(mhi_dev_channel_isempty); bool mhi_dev_channel_has_pending_write(struct mhi_dev_client *handle) { struct mhi_dev_channel *ch; if (!handle) { mhi_log(MHI_MSG_ERROR, "Invalid channel access\n"); return -EINVAL; } ch = handle->channel; if (!ch) return -EINVAL; return ch->pend_wr_count ? true : false; } EXPORT_SYMBOL(mhi_dev_channel_has_pending_write); void mhi_dev_close_channel(struct mhi_dev_client *handle) void mhi_dev_close_channel(struct mhi_dev_client *handle) { { struct mhi_dev_channel *ch; struct mhi_dev_channel *ch; int count = 0; if (!handle) { if (!handle) { mhi_log(MHI_MSG_ERROR, "Invalid channel access:%d\n", -ENODEV); mhi_log(MHI_MSG_ERROR, "Invalid channel access:%d\n", -ENODEV); Loading @@ -2316,8 +2352,20 @@ void mhi_dev_close_channel(struct mhi_dev_client *handle) } } ch = handle->channel; ch = handle->channel; do { if (ch->pend_wr_count) { 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); 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); if (ch->state != MHI_DEV_CH_PENDING_START) if (ch->state != MHI_DEV_CH_PENDING_START) if ((ch->ch_type == MHI_DEV_CH_TYPE_OUTBOUND_CHANNEL && if ((ch->ch_type == MHI_DEV_CH_TYPE_OUTBOUND_CHANNEL && !mhi_dev_channel_isempty(handle)) || ch->tre_loc) !mhi_dev_channel_isempty(handle)) || ch->tre_loc) Loading Loading @@ -2526,6 +2574,7 @@ int mhi_dev_write_channel(struct mhi_req *wreq) size_t bytes_to_write = 0; size_t bytes_to_write = 0; size_t bytes_written = 0; size_t bytes_written = 0; uint32_t tre_len = 0, suspend_wait_timeout = 0; uint32_t tre_len = 0, suspend_wait_timeout = 0; bool async_wr_sched = false; if (WARN_ON(!wreq || !wreq->client || !wreq->buf)) { if (WARN_ON(!wreq || !wreq->client || !wreq->buf)) { pr_err("%s: invalid parameters\n", __func__); pr_err("%s: invalid parameters\n", __func__); Loading Loading @@ -2569,12 +2618,12 @@ int mhi_dev_write_channel(struct mhi_req *wreq) handle_client = wreq->client; handle_client = wreq->client; ch = handle_client->channel; ch = handle_client->channel; ch->wr_request_active = true; ring = ch->ring; ring = ch->ring; mutex_lock(&ch->ch_lock); mutex_lock(&ch->ch_lock); ch->pend_wr_count++; if (ch->state == MHI_DEV_CH_STOPPED) { if (ch->state == MHI_DEV_CH_STOPPED) { mhi_log(MHI_MSG_ERROR, mhi_log(MHI_MSG_ERROR, "channel %d already stopped\n", wreq->chan); "channel %d already stopped\n", wreq->chan); Loading Loading @@ -2625,7 +2674,8 @@ int mhi_dev_write_channel(struct mhi_req *wreq) "Error while writing chan (%d) rc %d\n", "Error while writing chan (%d) rc %d\n", wreq->chan, rc); wreq->chan, rc); goto exit; goto exit; } } else if (wreq->mode == DMA_ASYNC) async_wr_sched = true; bytes_written += bytes_to_write; bytes_written += bytes_to_write; usr_buf_remaining -= bytes_to_write; usr_buf_remaining -= bytes_to_write; Loading Loading @@ -2665,7 +2715,8 @@ int mhi_dev_write_channel(struct mhi_req *wreq) } } } } exit: exit: ch->wr_request_active = false; if (wreq->mode == DMA_SYNC || !async_wr_sched) ch->pend_wr_count--; mutex_unlock(&ch->ch_lock); mutex_unlock(&ch->ch_lock); mutex_unlock(&mhi_ctx->mhi_write_test); mutex_unlock(&mhi_ctx->mhi_write_test); return bytes_written; return bytes_written; Loading
drivers/platform/msm/mhi_dev/mhi.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -460,7 +460,7 @@ struct mhi_dev_channel { uint32_t tre_bytes_left; uint32_t tre_bytes_left; /* td size being read/written from/to so far */ /* td size being read/written from/to so far */ uint32_t td_size; uint32_t td_size; bool wr_request_active; uint32_t pend_wr_count; bool skip_td; bool skip_td; }; }; Loading
drivers/platform/msm/mhi_dev/mhi_uci.c +45 −25 Original line number Original line Diff line number Diff line Loading @@ -46,6 +46,10 @@ #define MHI_UCI_AT_CTRL_READ_TIMEOUT msecs_to_jiffies(1000) #define MHI_UCI_AT_CTRL_READ_TIMEOUT msecs_to_jiffies(1000) #define MHI_UCI_WRITE_REQ_AVAIL_TIMEOUT msecs_to_jiffies(1000) #define MHI_UCI_WRITE_REQ_AVAIL_TIMEOUT msecs_to_jiffies(1000) #define MHI_UCI_RELEASE_TIMEOUT_MIN 5000 #define MHI_UCI_RELEASE_TIMEOUT_MAX 5100 #define MHI_UCI_RELEASE_TIMEOUT_COUNT 30 enum uci_dbg_level { enum uci_dbg_level { UCI_DBG_VERBOSE = 0x0, UCI_DBG_VERBOSE = 0x0, UCI_DBG_INFO = 0x1, UCI_DBG_INFO = 0x1, Loading Loading @@ -960,14 +964,35 @@ static int mhi_uci_client_release(struct inode *mhi_inode, struct file *file_handle) struct file *file_handle) { { struct uci_client *uci_handle = file_handle->private_data; struct uci_client *uci_handle = file_handle->private_data; int count = 0; if (!uci_handle) if (!uci_handle) return -EINVAL; return -EINVAL; if (atomic_sub_return(1, &uci_handle->ref_count) == 0) { if (atomic_sub_return(1, &uci_handle->ref_count)) { uci_log(UCI_DBG_DBG, "Client close chan %d, ref count 0x%x\n", iminor(mhi_inode), atomic_read(&uci_handle->ref_count)); return 0; } uci_log(UCI_DBG_DBG, uci_log(UCI_DBG_DBG, "Last client left, closing channel 0x%x\n", "Last client left, closing channel 0x%x\n", iminor(mhi_inode)); iminor(mhi_inode)); do { if (mhi_dev_channel_has_pending_write(uci_handle->out_handle)) usleep_range(MHI_UCI_RELEASE_TIMEOUT_MIN, MHI_UCI_RELEASE_TIMEOUT_MAX); else break; } while (++count < MHI_UCI_RELEASE_TIMEOUT_COUNT); if (count == MHI_UCI_RELEASE_TIMEOUT_COUNT) { uci_log(UCI_DBG_DBG, "Channel %d has pending writes\n", iminor(mhi_inode)); } if (atomic_read(&uci_handle->mhi_chans_open)) { if (atomic_read(&uci_handle->mhi_chans_open)) { atomic_set(&uci_handle->mhi_chans_open, 0); atomic_set(&uci_handle->mhi_chans_open, 0); Loading @@ -982,17 +1007,12 @@ static int mhi_uci_client_release(struct inode *mhi_inode, mhi_dev_close_channel(uci_handle->in_handle); mhi_dev_close_channel(uci_handle->in_handle); wake_up(&uci_handle->read_wq); wake_up(&uci_handle->read_wq); mutex_unlock(&uci_handle->in_chan_lock); mutex_unlock(&uci_handle->in_chan_lock); } } atomic_set(&uci_handle->read_data_ready, 0); atomic_set(&uci_handle->read_data_ready, 0); atomic_set(&uci_handle->write_data_ready, 0); atomic_set(&uci_handle->write_data_ready, 0); file_handle->private_data = NULL; file_handle->private_data = NULL; } else { uci_log(UCI_DBG_DBG, "Client close chan %d, ref count 0x%x\n", iminor(mhi_inode), atomic_read(&uci_handle->ref_count)); } return 0; return 0; } } Loading
include/linux/msm_mhi_dev.h +13 −0 Original line number Original line Diff line number Diff line Loading @@ -194,6 +194,13 @@ int mhi_dev_write_channel(struct mhi_req *wreq); */ */ int mhi_dev_channel_isempty(struct mhi_dev_client *handle); int mhi_dev_channel_isempty(struct mhi_dev_client *handle); /** * mhi_dev_channel_has_pending_write() - Checks if there are any pending writes * to be completed on inbound channel * @handle_client: Client Handle issued during mhi_dev_open_channel */ bool mhi_dev_channel_has_pending_write(struct mhi_dev_client *handle); /** /** * mhi_ctrl_state_info() - Provide MHI state info * mhi_ctrl_state_info() - Provide MHI state info * @idx: Channel number idx. Look at channel_state_info and * @idx: Channel number idx. Look at channel_state_info and Loading Loading @@ -244,6 +251,12 @@ static inline int mhi_dev_channel_isempty(struct mhi_dev_client *handle) return -EINVAL; return -EINVAL; }; }; static inline bool mhi_dev_channel_has_pending_write (struct mhi_dev_client *handle) { return false; } static inline int mhi_ctrl_state_info(uint32_t idx, uint32_t *info) static inline int mhi_ctrl_state_info(uint32_t idx, uint32_t *info) { { return -EINVAL; return -EINVAL; Loading