Loading drivers/platform/msm/gsi/gsi.c +27 −5 Original line number Original line Diff line number Diff line Loading @@ -537,7 +537,12 @@ static void gsi_process_chan(struct gsi_xfer_compl_evt *evt, ch_ctx->ring.rp_local = rp; ch_ctx->ring.rp_local = rp; } } /* * Increment RP local only in polling context to avoid * sys len mismatch. */ if (!(callback && ch_ctx->props.dir == GSI_CHAN_DIR_FROM_GSI)) /* the element at RP is also processed */ /* the element at RP is also processed */ gsi_incr_ring_rp(&ch_ctx->ring); gsi_incr_ring_rp(&ch_ctx->ring); Loading @@ -549,11 +554,20 @@ static void gsi_process_chan(struct gsi_xfer_compl_evt *evt, notify->veid = evt->veid; notify->veid = evt->veid; } } ch_ctx->stats.completed++; WARN_ON(!ch_ctx->user_data[rp_idx].valid); WARN_ON(!ch_ctx->user_data[rp_idx].valid); notify->xfer_user_data = ch_ctx->user_data[rp_idx].p; notify->xfer_user_data = ch_ctx->user_data[rp_idx].p; /* * In suspend just before stopping the channel possible to receive * the IEOB interrupt and xfer pointer will not be processed in this * mode and moving channel poll mode. In resume after starting the * channel will receive the IEOB interrupt and xfer pointer will be * overwritten. To avoid this process all data in polling context. */ if (!(callback && ch_ctx->props.dir == GSI_CHAN_DIR_FROM_GSI)) { ch_ctx->stats.completed++; ch_ctx->user_data[rp_idx].valid = false; ch_ctx->user_data[rp_idx].valid = false; } notify->chan_user_data = ch_ctx->props.chan_user_data; notify->chan_user_data = ch_ctx->props.chan_user_data; notify->evt_id = evt->code; notify->evt_id = evt->code; Loading @@ -572,10 +586,18 @@ static void gsi_process_evt_re(struct gsi_evt_ctx *ctx, struct gsi_chan_xfer_notify *notify, bool callback) struct gsi_chan_xfer_notify *notify, bool callback) { { struct gsi_xfer_compl_evt *evt; struct gsi_xfer_compl_evt *evt; struct gsi_chan_ctx *ch_ctx; evt = (struct gsi_xfer_compl_evt *)(ctx->ring.base_va + evt = (struct gsi_xfer_compl_evt *)(ctx->ring.base_va + ctx->ring.rp_local - ctx->ring.base); ctx->ring.rp_local - ctx->ring.base); gsi_process_chan(evt, notify, callback); gsi_process_chan(evt, notify, callback); /* * Increment RP local only in polling context to avoid * sys len mismatch. */ ch_ctx = &gsi_ctx->chan[evt->chid]; if (callback && ch_ctx->props.dir == GSI_CHAN_DIR_FROM_GSI) return; gsi_incr_ring_rp(&ctx->ring); gsi_incr_ring_rp(&ctx->ring); /* recycle this element */ /* recycle this element */ gsi_incr_ring_wp(&ctx->ring); gsi_incr_ring_wp(&ctx->ring); Loading drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +9 −3 Original line number Original line Diff line number Diff line Loading @@ -4594,8 +4594,14 @@ static void ipa_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) sys = (struct ipa3_sys_context *)notify->chan_user_data; sys = (struct ipa3_sys_context *)notify->chan_user_data; /* sys->ep->xfer_notify_valid = true; * In suspend just before stopping the channel possible to receive * the IEOB interrupt and xfer pointer will not be processed in this * mode and moving channel poll mode. In resume after starting the * channel will receive the IEOB interrupt and xfer pointer will be * overwritten. To avoid this process all data in polling context. */ sys->ep->xfer_notify_valid = false; sys->ep->xfer_notify = *notify; sys->ep->xfer_notify = *notify; switch (notify->evt_id) { switch (notify->evt_id) { Loading Loading @@ -4630,7 +4636,7 @@ static void ipa_dma_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) return; return; } } sys->ep->xfer_notify_valid = true; sys->ep->xfer_notify_valid = false; sys->ep->xfer_notify = *notify; sys->ep->xfer_notify = *notify; switch (notify->evt_id) { switch (notify->evt_id) { Loading Loading
drivers/platform/msm/gsi/gsi.c +27 −5 Original line number Original line Diff line number Diff line Loading @@ -537,7 +537,12 @@ static void gsi_process_chan(struct gsi_xfer_compl_evt *evt, ch_ctx->ring.rp_local = rp; ch_ctx->ring.rp_local = rp; } } /* * Increment RP local only in polling context to avoid * sys len mismatch. */ if (!(callback && ch_ctx->props.dir == GSI_CHAN_DIR_FROM_GSI)) /* the element at RP is also processed */ /* the element at RP is also processed */ gsi_incr_ring_rp(&ch_ctx->ring); gsi_incr_ring_rp(&ch_ctx->ring); Loading @@ -549,11 +554,20 @@ static void gsi_process_chan(struct gsi_xfer_compl_evt *evt, notify->veid = evt->veid; notify->veid = evt->veid; } } ch_ctx->stats.completed++; WARN_ON(!ch_ctx->user_data[rp_idx].valid); WARN_ON(!ch_ctx->user_data[rp_idx].valid); notify->xfer_user_data = ch_ctx->user_data[rp_idx].p; notify->xfer_user_data = ch_ctx->user_data[rp_idx].p; /* * In suspend just before stopping the channel possible to receive * the IEOB interrupt and xfer pointer will not be processed in this * mode and moving channel poll mode. In resume after starting the * channel will receive the IEOB interrupt and xfer pointer will be * overwritten. To avoid this process all data in polling context. */ if (!(callback && ch_ctx->props.dir == GSI_CHAN_DIR_FROM_GSI)) { ch_ctx->stats.completed++; ch_ctx->user_data[rp_idx].valid = false; ch_ctx->user_data[rp_idx].valid = false; } notify->chan_user_data = ch_ctx->props.chan_user_data; notify->chan_user_data = ch_ctx->props.chan_user_data; notify->evt_id = evt->code; notify->evt_id = evt->code; Loading @@ -572,10 +586,18 @@ static void gsi_process_evt_re(struct gsi_evt_ctx *ctx, struct gsi_chan_xfer_notify *notify, bool callback) struct gsi_chan_xfer_notify *notify, bool callback) { { struct gsi_xfer_compl_evt *evt; struct gsi_xfer_compl_evt *evt; struct gsi_chan_ctx *ch_ctx; evt = (struct gsi_xfer_compl_evt *)(ctx->ring.base_va + evt = (struct gsi_xfer_compl_evt *)(ctx->ring.base_va + ctx->ring.rp_local - ctx->ring.base); ctx->ring.rp_local - ctx->ring.base); gsi_process_chan(evt, notify, callback); gsi_process_chan(evt, notify, callback); /* * Increment RP local only in polling context to avoid * sys len mismatch. */ ch_ctx = &gsi_ctx->chan[evt->chid]; if (callback && ch_ctx->props.dir == GSI_CHAN_DIR_FROM_GSI) return; gsi_incr_ring_rp(&ctx->ring); gsi_incr_ring_rp(&ctx->ring); /* recycle this element */ /* recycle this element */ gsi_incr_ring_wp(&ctx->ring); gsi_incr_ring_wp(&ctx->ring); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +9 −3 Original line number Original line Diff line number Diff line Loading @@ -4594,8 +4594,14 @@ static void ipa_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) sys = (struct ipa3_sys_context *)notify->chan_user_data; sys = (struct ipa3_sys_context *)notify->chan_user_data; /* sys->ep->xfer_notify_valid = true; * In suspend just before stopping the channel possible to receive * the IEOB interrupt and xfer pointer will not be processed in this * mode and moving channel poll mode. In resume after starting the * channel will receive the IEOB interrupt and xfer pointer will be * overwritten. To avoid this process all data in polling context. */ sys->ep->xfer_notify_valid = false; sys->ep->xfer_notify = *notify; sys->ep->xfer_notify = *notify; switch (notify->evt_id) { switch (notify->evt_id) { Loading Loading @@ -4630,7 +4636,7 @@ static void ipa_dma_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) return; return; } } sys->ep->xfer_notify_valid = true; sys->ep->xfer_notify_valid = false; sys->ep->xfer_notify = *notify; sys->ep->xfer_notify = *notify; switch (notify->evt_id) { switch (notify->evt_id) { Loading