qcacmn: Support one MSI vector dynamically

MSI vector number is defined in platform driver, so use platform
driver API to check whether it is in one MSI mode or not.

In case of one MSI vector, interrupt migration needs to be disabled.
This is because when interrupt migration happens, the MSI data may
change. However, MSI data is already programmed to rings during initial
phase and there is no way to know that MSI data is changed during run
time and reprogram again.

If it is in one MSI mode, disable interrupt migration by adding IRQ
flag IRQF_NOBALANCING.

Change-Id: I54579dfe1e658c1a2c395be93875d013d6e6affd
CRs-Fixed: 3290829
Цей коміт міститься в:
Bing Sun
2022-10-21 15:04:59 +08:00
зафіксовано Madan Koyyalamudi
джерело 9a6e6ec056
коміт 186e8421e0
2 змінених файлів з 27 додано та 17 видалено

Переглянути файл

@@ -3020,6 +3020,7 @@ int hif_ce_msi_configure_irq_by_ceid(struct hif_softc *scn, int ce_id)
struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn);
struct hif_pci_softc *pci_sc = HIF_GET_PCI_SOFTC(scn);
int pci_slot;
unsigned long irq_flags;
if (ce_id >= CE_COUNT_MAX)
return -EINVAL;
@@ -3041,8 +3042,12 @@ int hif_ce_msi_configure_irq_by_ceid(struct hif_softc *scn, int ce_id)
pci_slot = hif_get_pci_slot(scn);
msi_data = irq_id + msi_irq_start;
irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data);
hif_debug("%s: (ce_id %d, irq_id %d, msi_data %d, irq %d tasklet %pK)",
__func__, ce_id, irq_id, msi_data, irq,
if (pld_is_one_msi(scn->qdf_dev->dev))
irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
else
irq_flags = IRQF_SHARED;
hif_debug("%s: (ce_id %d, irq_id %d, msi_data %d, irq %d flag 0x%lx tasklet %pK)",
__func__, ce_id, irq_id, msi_data, irq, irq_flags,
&ce_sc->tasklets[ce_id]);
/* implies the ce is also initialized */
@@ -3056,7 +3061,7 @@ int hif_ce_msi_configure_irq_by_ceid(struct hif_softc *scn, int ce_id)
pci_slot, ce_id);
ret = pfrm_request_irq(scn->qdf_dev->dev,
irq, hif_ce_interrupt_handler, IRQF_SHARED,
irq, hif_ce_interrupt_handler, irq_flags,
ce_irqname[pci_slot][ce_id],
&ce_sc->tasklets[ce_id]);
if (ret)
@@ -3430,6 +3435,7 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn,
int irq = 0;
int j;
int pci_slot;
unsigned long irq_flags;
if (pld_get_enable_intx(scn->qdf_dev->dev))
return hif_grp_configure_legacyirq(scn, hif_ext_group);
@@ -3446,8 +3452,12 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn,
qdf_dev_set_irq_status_flags(irq,
QDF_IRQ_DISABLE_UNLAZY);
hif_debug("request_irq = %d for grp %d",
irq, hif_ext_group->grp_id);
if (pld_is_one_msi(scn->qdf_dev->dev))
irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
else
irq_flags = IRQF_SHARED | IRQF_NO_SUSPEND;
hif_debug("request_irq = %d for grp %d irq_flags 0x%lx",
irq, hif_ext_group->grp_id, irq_flags);
qdf_scnprintf(dp_irqname[pci_slot][hif_ext_group->grp_id],
DP_IRQ_NAME_LEN, "pci%u_wlan_grp_dp_%u",
@@ -3455,7 +3465,7 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn,
ret = pfrm_request_irq(
scn->qdf_dev->dev, irq,
hif_ext_group_interrupt_handler,
IRQF_SHARED | IRQF_NO_SUSPEND,
irq_flags,
dp_irqname[pci_slot][hif_ext_group->grp_id],
hif_ext_group);
if (ret) {