ARRAY_SIZE(phba->msix_entries));
        if (rc) {
                lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                               "0420 Enable MSI-X failed (%d), continuing "
-                               "with MSI\n", rc);
+                               "0420 PCI enable MSI-X failed (%d)\n", rc);
                goto msi_fail_out;
        } else
                for (i = 0; i < LPFC_MSIX_VECTORS; i++)
        rc = request_irq(phba->msix_entries[0].vector, &lpfc_sp_intr_handler,
                         IRQF_SHARED, LPFC_SP_DRIVER_HANDLER_NAME, phba);
        if (rc) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+               lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
                                "0421 MSI-X slow-path request_irq failed "
-                               "(%d), continuing with MSI\n", rc);
+                               "(%d)\n", rc);
                goto msi_fail_out;
        }
 
                         IRQF_SHARED, LPFC_FP_DRIVER_HANDLER_NAME, phba);
 
        if (rc) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+               lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
                                "0429 MSI-X fast-path request_irq failed "
-                               "(%d), continuing with MSI\n", rc);
+                               "(%d)\n", rc);
                goto irq_fail_out;
        }
 
                goto mbx_fail_out;
        rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
        if (rc != MBX_SUCCESS) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+               lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
                                "0351 Config MSI mailbox command failed, "
                                "mbxCmd x%x, mbxStatus x%x\n",
                                pmb->mb.mbxCommand, pmb->mb.mbxStatus);
        pci_disable_msix(phba->pcidev);
 }
 
+/**
+ * lpfc_enable_msi: Enable MSI interrupt mode.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to enable the MSI interrupt mode. The kernel
+ * function pci_enable_msi() is called to enable the MSI vector. The
+ * device driver is responsible for calling the request_irq() to register
+ * MSI vector with a interrupt the handler, which is done in this function.
+ *
+ * Return codes
+ *     0 - sucessful
+ *     other values - error
+ */
+static int
+lpfc_enable_msi(struct lpfc_hba *phba)
+{
+       int rc;
+
+       rc = pci_enable_msi(phba->pcidev);
+       if (!rc)
+               lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+                               "0462 PCI enable MSI mode success.\n");
+       else {
+               lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+                               "0471 PCI enable MSI mode failed (%d)\n", rc);
+               return rc;
+       }
+
+       rc = request_irq(phba->pcidev->irq, lpfc_intr_handler,
+                        IRQF_SHARED, LPFC_DRIVER_NAME, phba);
+       if (rc) {
+               pci_disable_msi(phba->pcidev);
+               lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+                               "0478 MSI request_irq failed (%d)\n", rc);
+       }
+       return rc;
+}
+
+/**
+ * lpfc_disable_msi: Disable MSI interrupt mode.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to disable the MSI interrupt mode. The driver
+ * calls free_irq() on MSI vector it has done request_irq() on before
+ * calling pci_disable_msi(). Failure to do so results in a BUG_ON() and
+ * a device will be left with MSI enabled and leaks its vector.
+ */
+
+static void
+lpfc_disable_msi(struct lpfc_hba *phba)
+{
+       free_irq(phba->pcidev->irq, phba);
+       pci_disable_msi(phba->pcidev);
+       return;
+}
+
+/**
+ * lpfc_log_intr_mode: Log the active interrupt mode
+ * @phba: pointer to lpfc hba data structure.
+ * @intr_mode: active interrupt mode adopted.
+ *
+ * This routine it invoked to log the currently used active interrupt mode
+ * to the device.
+ */
+static void
+lpfc_log_intr_mode(struct lpfc_hba *phba, uint32_t intr_mode)
+{
+       switch (intr_mode) {
+       case 0:
+               lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+                               "0470 Enable INTx interrupt mode.\n");
+               break;
+       case 1:
+               lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+                               "0481 Enabled MSI interrupt mode.\n");
+               break;
+       case 2:
+               lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+                               "0480 Enabled MSI-X interrupt mode.\n");
+               break;
+       default:
+               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "0482 Illegal interrupt mode.\n");
+               break;
+       }
+       return;
+}
+
+static void
+lpfc_stop_port(struct lpfc_hba *phba)
+{
+       /* Clear all interrupt enable conditions */
+       writel(0, phba->HCregaddr);
+       readl(phba->HCregaddr); /* flush */
+       /* Clear all pending interrupts */
+       writel(0xffffffff, phba->HAregaddr);
+       readl(phba->HAregaddr); /* flush */
+
+       /* Reset some HBA SLI setup states */
+       lpfc_stop_phba_timers(phba);
+       phba->pport->work_port_events = 0;
+
+       return;
+}
+
+/**
+ * lpfc_enable_intr: Enable device interrupt.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to enable device interrupt and associate driver's
+ * interrupt handler(s) to interrupt vector(s). Depends on the interrupt
+ * mode configured to the driver, the driver will try to fallback from the
+ * configured interrupt mode to an interrupt mode which is supported by the
+ * platform, kernel, and device in the order of: MSI-X -> MSI -> IRQ.
+ *
+ * Return codes
+ *   0 - sucessful
+ *   other values - error
+ **/
+static uint32_t
+lpfc_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
+{
+       uint32_t intr_mode = LPFC_INTR_ERROR;
+       int retval;
+
+       if (cfg_mode == 2) {
+               /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
+               retval = lpfc_sli_config_port(phba, 3);
+               if (!retval) {
+                       /* Now, try to enable MSI-X interrupt mode */
+                       retval = lpfc_enable_msix(phba);
+                       if (!retval) {
+                               /* Indicate initialization to MSI-X mode */
+                               phba->intr_type = MSIX;
+                               intr_mode = 2;
+                       }
+               }
+       }
+
+       /* Fallback to MSI if MSI-X initialization failed */
+       if (cfg_mode >= 1 && phba->intr_type == NONE) {
+               retval = lpfc_enable_msi(phba);
+               if (!retval) {
+                       /* Indicate initialization to MSI mode */
+                       phba->intr_type = MSI;
+                       intr_mode = 1;
+               }
+       }
+
+       /* Fallback to INTx if both MSI-X/MSI initalization failed */
+       if (phba->intr_type == NONE) {
+               retval = request_irq(phba->pcidev->irq, lpfc_intr_handler,
+                                    IRQF_SHARED, LPFC_DRIVER_NAME, phba);
+               if (!retval) {
+                       /* Indicate initialization to INTx mode */
+                       phba->intr_type = INTx;
+                       intr_mode = 0;
+               }
+       }
+       return intr_mode;
+}
+
+/**
+ * lpfc_disable_intr: Disable device interrupt.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to disable device interrupt and disassociate the
+ * driver's interrupt handler(s) from interrupt vector(s). Depending on the
+ * interrupt mode, the driver will release the interrupt vector(s) for the
+ * message signaled interrupt.
+ **/
+static void
+lpfc_disable_intr(struct lpfc_hba *phba)
+{
+       /* Disable the currently initialized interrupt mode */
+       if (phba->intr_type == MSIX)
+               lpfc_disable_msix(phba);
+       else if (phba->intr_type == MSI)
+               lpfc_disable_msi(phba);
+       else if (phba->intr_type == INTx)
+               free_irq(phba->pcidev->irq, phba);
+
+       /* Reset interrupt management states */
+       phba->intr_type = NONE;
+       phba->sli.slistat.sli_intr = 0;
+
+       return;
+}
+
 /**
  * lpfc_pci_probe_one: lpfc PCI probe func to register device to PCI subsystem.
  * @pdev: pointer to PCI device
        int error = -ENODEV, retval;
        int  i, hbq_count;
        uint16_t iotag;
+       uint32_t cfg_mode, intr_mode;
        int bars = pci_select_bars(pdev, IORESOURCE_MEM);
        struct lpfc_adapter_event_header adapter_event;
 
        lpfc_debugfs_initialize(vport);
 
        pci_set_drvdata(pdev, shost);
-       phba->intr_type = NONE;
 
        phba->MBslimaddr = phba->slim_memmap_p;
        phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
        phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
        phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
 
-       /* Configure and enable interrupt */
-       if (phba->cfg_use_msi == 2) {
-               /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
-               error = lpfc_sli_config_port(phba, 3);
-               if (error)
-                       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                               "0427 Firmware not capable of SLI 3 mode.\n");
-               else {
-                       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                               "0426 Firmware capable of SLI 3 mode.\n");
-                       /* Now, try to enable MSI-X interrupt mode */
-                       error = lpfc_enable_msix(phba);
-                       if (!error) {
-                               phba->intr_type = MSIX;
-                               lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                                               "0430 enable MSI-X mode.\n");
-                       }
-               }
-       }
-
-       /* Fallback to MSI if MSI-X initialization failed */
-       if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) {
-               retval = pci_enable_msi(phba->pcidev);
-               if (!retval) {
-                       phba->intr_type = MSI;
-                       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                                       "0473 enable MSI mode.\n");
-               } else
-                       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                                       "0452 enable IRQ mode.\n");
-       }
-
-       /* MSI-X is the only case the doesn't need to call request_irq */
-       if (phba->intr_type != MSIX) {
-               retval = request_irq(phba->pcidev->irq, lpfc_intr_handler,
-                                    IRQF_SHARED, LPFC_DRIVER_NAME, phba);
-               if (retval) {
-                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0451 Enable "
-                                       "interrupt handler failed\n");
-                       error = retval;
-                       goto out_disable_msi;
-               } else if (phba->intr_type != MSI)
-                       phba->intr_type = INTx;
-       }
-
+       /* Configure sysfs attributes */
        if (lpfc_alloc_sysfs_attr(vport)) {
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                                "1476 Failed to allocate sysfs attr\n");
                error = -ENOMEM;
-               goto out_free_irq;
+               goto out_destroy_port;
        }
 
-       if (lpfc_sli_hba_setup(phba)) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "1477 Failed to set up hba\n");
-               error = -ENODEV;
-               goto out_remove_device;
+       cfg_mode = phba->cfg_use_msi;
+       while (true) {
+               /* Configure and enable interrupt */
+               intr_mode = lpfc_enable_intr(phba, cfg_mode);
+               if (intr_mode == LPFC_INTR_ERROR) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "0426 Failed to enable interrupt.\n");
+                       goto out_free_sysfs_attr;
+               }
+               /* HBA SLI setup */
+               if (lpfc_sli_hba_setup(phba)) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "1477 Failed to set up hba\n");
+                       error = -ENODEV;
+                       goto out_remove_device;
+               }
+
+               /* Wait 50ms for the interrupts of previous mailbox commands */
+               msleep(50);
+               /* Check active interrupts received */
+               if (phba->sli.slistat.sli_intr > LPFC_MSIX_VECTORS) {
+                       /* Log the current active interrupt mode */
+                       phba->intr_mode = intr_mode;
+                       lpfc_log_intr_mode(phba, intr_mode);
+                       break;
+               } else {
+                       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+                                       "0451 Configure interrupt mode (%d) "
+                                       "failed active interrupt test.\n",
+                                       intr_mode);
+                       if (intr_mode == 0) {
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                               "0479 Failed to enable "
+                                               "interrupt.\n");
+                               error = -ENODEV;
+                               goto out_remove_device;
+                       }
+                       /* Stop HBA SLI setups */
+                       lpfc_stop_port(phba);
+                       /* Disable the current interrupt mode */
+                       lpfc_disable_intr(phba);
+                       /* Try next level of interrupt mode */
+                       cfg_mode = --intr_mode;
+               }
        }
 
        /*
        return 0;
 
 out_remove_device:
-       lpfc_free_sysfs_attr(vport);
        spin_lock_irq(shost->host_lock);
        vport->load_flag |= FC_UNLOADING;
        spin_unlock_irq(shost->host_lock);
-out_free_irq:
        lpfc_stop_phba_timers(phba);
        phba->pport->work_port_events = 0;
-
-       if (phba->intr_type == MSIX)
-               lpfc_disable_msix(phba);
-       else
-               free_irq(phba->pcidev->irq, phba);
-
-out_disable_msi:
-       if (phba->intr_type == MSI)
-               pci_disable_msi(phba->pcidev);
+       lpfc_disable_intr(phba);
+out_free_sysfs_attr:
+       lpfc_free_sysfs_attr(vport);
+out_destroy_port:
        destroy_port(vport);
 out_kthread_stop:
        kthread_stop(phba->worker_thread);
 
        lpfc_debugfs_terminate(vport);
 
-       if (phba->intr_type == MSIX)
-               lpfc_disable_msix(phba);
-       else {
-               free_irq(phba->pcidev->irq, phba);
-               if (phba->intr_type == MSI)
-                       pci_disable_msi(phba->pcidev);
-       }
+       /* Disable interrupt */
+       lpfc_disable_intr(phba);
 
        pci_set_drvdata(pdev, NULL);
        scsi_host_put(shost);
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
+       uint32_t intr_mode;
        int error;
 
        lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
                return error;
        }
 
-       /* Enable interrupt from device */
-       error = lpfc_enable_intr(phba);
-       if (error) {
+       /* Configure and enable interrupt */
+       intr_mode = lpfc_enable_intr(phba, phba->intr_mode);
+       if (intr_mode == LPFC_INTR_ERROR) {
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "0430 PM resume Failed to enable interrupt: "
-                               "error=x%x.\n", error);
-               return error;
-       }
+                               "0430 PM resume Failed to enable interrupt\n");
+               return -EIO;
+       } else
+               phba->intr_mode = intr_mode;
 
        /* Restart HBA and bring it online */
        lpfc_sli_brdrestart(phba);
        lpfc_online(phba);
 
+       /* Log the current active interrupt mode */
+       lpfc_log_intr_mode(phba, phba->intr_mode);
+
        return 0;
 }
 
        pring = &psli->ring[psli->fcp_ring];
        lpfc_sli_abort_iocb_ring(phba, pring);
 
-       if (phba->intr_type == MSIX)
-               lpfc_disable_msix(phba);
-       else {
-               free_irq(phba->pcidev->irq, phba);
-               if (phba->intr_type == MSI)
-                       pci_disable_msi(phba->pcidev);
-       }
+       /* Disable interrupt */
+       lpfc_disable_intr(phba);
 
        /* Request a slot reset. */
        return PCI_ERS_RESULT_NEED_RESET;
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
        struct lpfc_sli *psli = &phba->sli;
-       int error, retval;
+       uint32_t intr_mode;
 
        dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
        if (pci_enable_device_mem(pdev)) {
        psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
        spin_unlock_irq(&phba->hbalock);
 
-       /* Enable configured interrupt method */
-       phba->intr_type = NONE;
-       if (phba->cfg_use_msi == 2) {
-               /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
-               error = lpfc_sli_config_port(phba, 3);
-               if (error)
-                       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                               "0478 Firmware not capable of SLI 3 mode.\n");
-               else {
-                       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                               "0479 Firmware capable of SLI 3 mode.\n");
-                       /* Now, try to enable MSI-X interrupt mode */
-                       error = lpfc_enable_msix(phba);
-                       if (!error) {
-                               phba->intr_type = MSIX;
-                               lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                                               "0480 enable MSI-X mode.\n");
-                       }
-               }
-       }
-
-       /* Fallback to MSI if MSI-X initialization failed */
-       if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) {
-               retval = pci_enable_msi(phba->pcidev);
-               if (!retval) {
-                       phba->intr_type = MSI;
-                       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                                       "0481 enable MSI mode.\n");
-               } else
-                       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                                       "0470 enable IRQ mode.\n");
-       }
-
-       /* MSI-X is the only case the doesn't need to call request_irq */
-       if (phba->intr_type != MSIX) {
-               retval = request_irq(phba->pcidev->irq, lpfc_intr_handler,
-                                    IRQF_SHARED, LPFC_DRIVER_NAME, phba);
-               if (retval) {
-                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                                       "0471 Enable interrupt handler "
-                                       "failed\n");
-               } else if (phba->intr_type != MSI)
-                       phba->intr_type = INTx;
-       }
+       /* Configure and enable interrupt */
+       intr_mode = lpfc_enable_intr(phba, phba->intr_mode);
+       if (intr_mode == LPFC_INTR_ERROR) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "0427 Cannot re-enable interrupt after "
+                               "slot reset.\n");
+               return PCI_ERS_RESULT_DISCONNECT;
+       } else
+               phba->intr_mode = intr_mode;
 
        /* Take device offline; this will perform cleanup */
        lpfc_offline(phba);
        lpfc_sli_brdrestart(phba);
 
+       /* Log the current active interrupt mode */
+       lpfc_log_intr_mode(phba, phba->intr_mode);
+
        return PCI_ERS_RESULT_RECOVERED;
 }
 
 
        uint32_t ha_copy;
        uint32_t work_ha_copy;
        unsigned long status;
+       unsigned long iflag;
        uint32_t control;
 
        MAILBOX_t *mbox, *pmbox;
                if (unlikely(phba->link_state < LPFC_LINK_DOWN))
                        return IRQ_NONE;
                /* Need to read HA REG for slow-path events */
-               spin_lock(&phba->hbalock);
+               spin_lock_irqsave(&phba->hbalock, iflag);
                ha_copy = readl(phba->HAregaddr);
                /* If somebody is waiting to handle an eratt don't process it
                 * here. The brdkill function will do this.
                writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)),
                        phba->HAregaddr);
                readl(phba->HAregaddr); /* flush */
-               spin_unlock(&phba->hbalock);
+               spin_unlock_irqrestore(&phba->hbalock, iflag);
        } else
                ha_copy = phba->ha_copy;
 
                                 * Turn off Link Attention interrupts
                                 * until CLEAR_LA done
                                 */
-                               spin_lock(&phba->hbalock);
+                               spin_lock_irqsave(&phba->hbalock, iflag);
                                phba->sli.sli_flag &= ~LPFC_PROCESS_LA;
                                control = readl(phba->HCregaddr);
                                control &= ~HC_LAINT_ENA;
                                writel(control, phba->HCregaddr);
                                readl(phba->HCregaddr); /* flush */
-                               spin_unlock(&phba->hbalock);
+                               spin_unlock_irqrestore(&phba->hbalock, iflag);
                        }
                        else
                                work_ha_copy &= ~HA_LATT;
                                (HA_RXMASK  << (4*LPFC_ELS_RING)));
                        status >>= (4*LPFC_ELS_RING);
                        if (status & HA_RXMASK) {
-                               spin_lock(&phba->hbalock);
+                               spin_lock_irqsave(&phba->hbalock, iflag);
                                control = readl(phba->HCregaddr);
 
                                lpfc_debugfs_slow_ring_trc(phba,
                                                (uint32_t)((unsigned long)
                                                &phba->work_waitq));
                                }
-                               spin_unlock(&phba->hbalock);
+                               spin_unlock_irqrestore(&phba->hbalock, iflag);
                        }
                }
-               spin_lock(&phba->hbalock);
+               spin_lock_irqsave(&phba->hbalock, iflag);
                if (work_ha_copy & HA_ERATT)
                        lpfc_sli_read_hs(phba);
                if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) {
                        /* First check out the status word */
                        lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t));
                        if (pmbox->mbxOwner != OWN_HOST) {
-                               spin_unlock(&phba->hbalock);
+                               spin_unlock_irqrestore(&phba->hbalock, iflag);
                                /*
                                 * Stray Mailbox Interrupt, mbxCommand <cmd>
                                 * mbxStatus <status>
                                work_ha_copy &= ~HA_MBATT;
                        } else {
                                phba->sli.mbox_active = NULL;
-                               spin_unlock(&phba->hbalock);
+                               spin_unlock_irqrestore(&phba->hbalock, iflag);
                                phba->last_completion_time = jiffies;
                                del_timer(&phba->sli.mbox_tmo);
                                if (pmb->mbox_cmpl) {
                                                goto send_current_mbox;
                                        }
                                }
-                               spin_lock(&phba->pport->work_port_lock);
+                               spin_lock_irqsave(
+                                               &phba->pport->work_port_lock,
+                                               iflag);
                                phba->pport->work_port_events &=
                                        ~WORKER_MBOX_TMO;
-                               spin_unlock(&phba->pport->work_port_lock);
+                               spin_unlock_irqrestore(
+                                               &phba->pport->work_port_lock,
+                                               iflag);
                                lpfc_mbox_cmpl_put(phba, pmb);
                        }
                } else
-                       spin_unlock(&phba->hbalock);
+                       spin_unlock_irqrestore(&phba->hbalock, iflag);
 
                if ((work_ha_copy & HA_MBATT) &&
                    (phba->sli.mbox_active == NULL)) {
                                                "MBX_SUCCESS");
                }
 
-               spin_lock(&phba->hbalock);
+               spin_lock_irqsave(&phba->hbalock, iflag);
                phba->work_ha |= work_ha_copy;
-               spin_unlock(&phba->hbalock);
+               spin_unlock_irqrestore(&phba->hbalock, iflag);
                lpfc_worker_wake_up(phba);
        }
        return IRQ_HANDLED;
        struct lpfc_hba  *phba;
        uint32_t ha_copy;
        unsigned long status;
+       unsigned long iflag;
 
        /* Get the driver's phba structure from the dev_id and
         * assume the HBA is not interrupting.
                /* Need to read HA REG for FCP ring and other ring events */
                ha_copy = readl(phba->HAregaddr);
                /* Clear up only attention source related to fast-path */
-               spin_lock(&phba->hbalock);
+               spin_lock_irqsave(&phba->hbalock, iflag);
                writel((ha_copy & (HA_R0_CLR_MSK | HA_R1_CLR_MSK)),
                        phba->HAregaddr);
                readl(phba->HAregaddr); /* flush */
-               spin_unlock(&phba->hbalock);
+               spin_unlock_irqrestore(&phba->hbalock, iflag);
        } else
                ha_copy = phba->ha_copy;