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:

committed by
Gerrit - the friendly Code Review server

parent
7418239f92
commit
bb44300a42
33
cnss2/pci.c
33
cnss2/pci.c
@@ -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:
|
||||
|
Reference in New Issue
Block a user