cnss2: get msi_data again after request_irq is called

The reservation mode of interrupts in kernel assigns a dummy vector
when the interrupt is allocated and assigns a real vector when the
request_irq is called. The reservation mode helps to ease vector
pressure when devices with a large amount of queues/interrupts
are initialized, but only a minimal subset of those queues/interrupts
is actually used.
So on reservation mode, the msi_data may change after request_irq
is called, so reads msi_data again after mhi request_irq is called,
and then the correct msi_data is programmed into hardware components.
Without this change, spurious interrupt occurs in case of one MSI
vector.

Change-Id: I41070987798835f8fa95304fce3b964bbd77b31d
CRs-Fixed: 3313984
This commit is contained in:
Bing Sun
2022-10-17 11:59:13 +08:00
committed by Gerrit - the friendly Code Review server
parent 7418239f92
commit bb44300a42

View File

@@ -1870,6 +1870,23 @@ out:
return ret;
}
static int cnss_pci_config_msi_data(struct cnss_pci_data *pci_priv)
{
struct msi_desc *msi_desc;
struct pci_dev *pci_dev = pci_priv->pci_dev;
msi_desc = irq_get_msi_desc(pci_dev->irq);
if (!msi_desc) {
cnss_pr_err("msi_desc is NULL!\n");
return -EINVAL;
}
pci_priv->msi_ep_base_data = msi_desc->msg.data;
cnss_pr_dbg("MSI base data is %d\n", pci_priv->msi_ep_base_data);
return 0;
}
int cnss_pci_start_mhi(struct cnss_pci_data *pci_priv)
{
int ret = 0;
@@ -1920,6 +1937,14 @@ int cnss_pci_start_mhi(struct cnss_pci_data *pci_priv)
*/
set_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state);
ret = cnss_pci_handle_mhi_poweron_timeout(pci_priv);
} else if (!ret) {
/* kernel may allocate a dummy vector before request_irq and
* then allocate a real vector when request_irq is called.
* So get msi_data here again to avoid spurious interrupt
* as msi_data will configured to srngs.
*/
if (cnss_pci_is_one_msi(pci_priv))
ret = cnss_pci_config_msi_data(pci_priv);
}
return ret;
@@ -4424,7 +4449,6 @@ static int cnss_pci_enable_msi(struct cnss_pci_data *pci_priv)
struct pci_dev *pci_dev = pci_priv->pci_dev;
int num_vectors;
struct cnss_msi_config *msi_config;
struct msi_desc *msi_desc;
if (pci_priv->device_id == QCA6174_DEVICE_ID)
return 0;
@@ -4460,16 +4484,11 @@ static int cnss_pci_enable_msi(struct cnss_pci_data *pci_priv)
goto reset_msi_config;
}
msi_desc = irq_get_msi_desc(pci_dev->irq);
if (!msi_desc) {
cnss_pr_err("msi_desc is NULL!\n");
if (cnss_pci_config_msi_data(pci_priv)) {
ret = -EINVAL;
goto free_msi_vector;
}
pci_priv->msi_ep_base_data = msi_desc->msg.data;
cnss_pr_dbg("MSI base data is %d\n", pci_priv->msi_ep_base_data);
return 0;
free_msi_vector: