diff --git a/hif/src/ipcie/if_ipci.c b/hif/src/ipcie/if_ipci.c index e0c774964e24..2e2646951fc8 100644 --- a/hif/src/ipcie/if_ipci.c +++ b/hif/src/ipcie/if_ipci.c @@ -82,10 +82,25 @@ QDF_STATUS hif_ipci_open(struct hif_softc *hif_ctx, enum qdf_bus_type bus_type) return hif_ce_open(hif_ctx); } +/** + * hif_ce_msi_map_ce_to_irq() - map CE to IRQ + * @scn: hif context + * @ce_id: CE Id + * + * Return: IRQ number + */ +static int hif_ce_msi_map_ce_to_irq(struct hif_softc *scn, int ce_id) +{ + struct hif_ipci_softc *ipci_scn = HIF_GET_IPCI_SOFTC(scn); + + return ipci_scn->ce_msi_irq_num[ce_id]; +} + int hif_ipci_bus_configure(struct hif_softc *hif_sc) { int status = 0; struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_sc); + uint8_t wake_ce_id; hif_ce_prepare_config(hif_sc); @@ -108,10 +123,19 @@ int hif_ipci_bus_configure(struct hif_softc *hif_sc) if (status) goto disable_wlan; + status = hif_get_wake_ce_id(hif_sc, &wake_ce_id); + if (status) + goto unconfig_ce; + status = hif_configure_irq(hif_sc); if (status < 0) goto unconfig_ce; + hif_sc->wake_irq = hif_ce_msi_map_ce_to_irq(hif_sc, wake_ce_id); + + HIF_INFO("expecting wake from ce %d, irq %d", + wake_ce_id, hif_sc->wake_irq); + A_TARGET_ACCESS_UNLIKELY(hif_sc); return status; @@ -340,20 +364,6 @@ static irqreturn_t hif_ce_interrupt_handler(int irq, void *context) extern const char *ce_name[]; -/** - * hif_ce_msi_map_ce_to_irq() - map CE to IRQ - * @scn: hif context - * @ce_id: CE Id - * - * Return: IRQ number - */ -static int hif_ce_msi_map_ce_to_irq(struct hif_softc *scn, int ce_id) -{ - struct hif_ipci_softc *ipci_scn = HIF_GET_IPCI_SOFTC(scn); - - return ipci_scn->ce_msi_irq_num[ce_id]; -} - /* hif_ce_srng_msi_irq_disable() - disable the irq for msi * @hif_sc: hif context * @ce_id: which ce to disable copy complete interrupts for @@ -394,6 +404,11 @@ static int hif_ce_msi_configure_irq(struct hif_softc *scn) uint32_t msi_irq_start; struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn); struct hif_ipci_softc *ipci_sc = HIF_GET_IPCI_SOFTC(scn); + uint8_t wake_ce_id; + + ret = hif_get_wake_ce_id(scn, &wake_ce_id); + if (ret) + return ret; /* do ce irq assignments */ ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "CE", @@ -410,6 +425,7 @@ static int hif_ce_msi_configure_irq(struct hif_softc *scn) * used in the srng parameter configuration */ for (ce_id = 0; ce_id < scn->ce_count; ce_id++) { + unsigned long irqflags = IRQF_SHARED; unsigned int msi_data = (ce_id % msi_data_count) + msi_irq_start; irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data); @@ -421,10 +437,13 @@ static int hif_ce_msi_configure_irq(struct hif_softc *scn) if (!ce_sc->tasklets[ce_id].inited) continue; + if (ce_id == wake_ce_id) + irqflags |= IRQF_NO_SUSPEND; + ipci_sc->ce_msi_irq_num[ce_id] = irq; ret = pfrm_request_irq(scn->qdf_dev->dev, irq, hif_ce_interrupt_handler, - IRQF_SHARED, + irqflags, ce_name[ce_id], &ce_sc->tasklets[ce_id]); if (ret)