crypto: qat - free irq in case of failure
authorWojciech Ziemba <wojciech.ziemba@intel.com>
Wed, 1 Sep 2021 17:36:08 +0000 (18:36 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 17 Sep 2021 03:05:12 +0000 (11:05 +0800)
If devm_request_irq() fails inside adf_request_irqs(), unwind properly by
freeing the allocated irqs.

Signed-off-by: Wojciech Ziemba <wojciech.ziemba@intel.com>
Co-developed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/qat/qat_common/adf_isr.c

index 861a936..c55a9f1 100644 (file)
@@ -126,6 +126,31 @@ static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
        return IRQ_NONE;
 }
 
+static void adf_free_irqs(struct adf_accel_dev *accel_dev)
+{
+       struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
+       struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+       struct adf_irq *irqs = pci_dev_info->msix_entries.irqs;
+       struct adf_etr_data *etr_data = accel_dev->transport;
+       int clust_irq = hw_data->num_banks;
+       int irq, i = 0;
+
+       if (pci_dev_info->msix_entries.num_entries > 1) {
+               for (i = 0; i < hw_data->num_banks; i++) {
+                       if (irqs[i].enabled) {
+                               irq = pci_irq_vector(pci_dev_info->pci_dev, i);
+                               irq_set_affinity_hint(irq, NULL);
+                               free_irq(irq, &etr_data->banks[i]);
+                       }
+               }
+       }
+
+       if (irqs[i].enabled) {
+               irq = pci_irq_vector(pci_dev_info->pci_dev, clust_irq);
+               free_irq(irq, accel_dev);
+       }
+}
+
 static int adf_request_irqs(struct adf_accel_dev *accel_dev)
 {
        struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
@@ -150,7 +175,8 @@ static int adf_request_irqs(struct adf_accel_dev *accel_dev)
                                dev_err(&GET_DEV(accel_dev),
                                        "Failed to get IRQ number of device vector %d - %s\n",
                                        i, name);
-                               return irq;
+                               ret = irq;
+                               goto err;
                        }
                        ret = request_irq(irq, adf_msix_isr_bundle, 0,
                                          &name[0], bank);
@@ -158,7 +184,7 @@ static int adf_request_irqs(struct adf_accel_dev *accel_dev)
                                dev_err(&GET_DEV(accel_dev),
                                        "Failed to allocate IRQ %d for %s\n",
                                        irq, name);
-                               return ret;
+                               goto err;
                        }
 
                        cpu = ((accel_dev->accel_id * hw_data->num_banks) +
@@ -177,41 +203,20 @@ static int adf_request_irqs(struct adf_accel_dev *accel_dev)
                dev_err(&GET_DEV(accel_dev),
                        "Failed to get IRQ number of device vector %d - %s\n",
                        i, name);
-               return irq;
+               ret = irq;
+               goto err;
        }
        ret = request_irq(irq, adf_msix_isr_ae, 0, &name[0], accel_dev);
        if (ret) {
                dev_err(&GET_DEV(accel_dev),
                        "Failed to allocate IRQ %d for %s\n", irq, name);
-               return ret;
+               goto err;
        }
        irqs[i].enabled = true;
        return ret;
-}
-
-static void adf_free_irqs(struct adf_accel_dev *accel_dev)
-{
-       struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
-       struct adf_hw_device_data *hw_data = accel_dev->hw_device;
-       struct adf_irq *irqs = pci_dev_info->msix_entries.irqs;
-       struct adf_etr_data *etr_data = accel_dev->transport;
-       int clust_irq = hw_data->num_banks;
-       int irq, i = 0;
-
-       if (pci_dev_info->msix_entries.num_entries > 1) {
-               for (i = 0; i < hw_data->num_banks; i++) {
-                       if (irqs[i].enabled) {
-                               irq = pci_irq_vector(pci_dev_info->pci_dev, i);
-                               irq_set_affinity_hint(irq, NULL);
-                               free_irq(irq, &etr_data->banks[i]);
-                       }
-               }
-       }
-
-       if (irqs[i].enabled) {
-               irq = pci_irq_vector(pci_dev_info->pci_dev, clust_irq);
-               free_irq(irq, accel_dev);
-       }
+err:
+       adf_free_irqs(accel_dev);
+       return ret;
 }
 
 static int adf_isr_alloc_msix_vectors_data(struct adf_accel_dev *accel_dev)