diff options
author | Wojciech Ziemba <wojciech.ziemba@intel.com> | 2021-09-01 19:36:08 +0200 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2021-09-17 05:05:12 +0200 |
commit | 70fead3adb4eea70cf6f9dba681394653b1387e3 (patch) | |
tree | edbfedfc15d96ad87ac1c5f1d93e66aa383916a7 /drivers/crypto | |
parent | crypto: qat - free irqs only if allocated (diff) | |
download | linux-70fead3adb4eea70cf6f9dba681394653b1387e3.tar.xz linux-70fead3adb4eea70cf6f9dba681394653b1387e3.zip |
crypto: qat - free irq in case of failure
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>
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_isr.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/drivers/crypto/qat/qat_common/adf_isr.c b/drivers/crypto/qat/qat_common/adf_isr.c index 861a9368b9db..c55a9f14b0d2 100644 --- a/drivers/crypto/qat/qat_common/adf_isr.c +++ b/drivers/crypto/qat/qat_common/adf_isr.c @@ -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) |