@@ -25,6 +25,26 @@ static DEFINE_IDA(mhi_ep_cntrl_ida);
static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
static int mhi_ep_destroy_device(struct device *dev, void *data);
+static int mhi_ep_wake_host(struct mhi_ep_cntrl *mhi_cntrl)
+{
+ enum mhi_state state;
+ bool mhi_reset;
+ u32 count = 0;
+
+ mhi_cntrl->wakeup_host(mhi_cntrl);
+
+ /* Wait for Host to set the M0 state */
+ while (count++ < M0_WAIT_COUNT) {
+ msleep(M0_WAIT_DELAY_MS);
+
+ mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset);
+ if (state == MHI_STATE_M0)
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx,
struct mhi_ring_element *el, bool bei)
{
@@ -466,6 +486,14 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
mutex_lock(&mhi_chan->lock);
+ if (mhi_cntrl->mhi_state == MHI_STATE_M3) {
+ ret = mhi_ep_wake_host(mhi_cntrl);
+ if (ret) {
+ dev_err(dev, "Failed to wakeup host\n");
+ goto err_exit;
+ }
+ }
+
do {
/* Don't process the transfer ring if the channel is not in RUNNING state */
if (mhi_chan->state != MHI_CH_STATE_RUNNING) {
If the MHI state is in M3 then most probably the host kept the device in D3 hot or D3 cold, due to that endpoint transactions will not be read by the host, endpoint needs to wakes up the host to bring the host to D0 which eventually bring back the MHI state to M0. Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com> --- drivers/bus/mhi/ep/main.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)