Re: [PATCH v2] Bluetooth: btintel_pcie: use managed IRQ teardown

From: Luiz Augusto von Dentz

Date: Tue Oct 06 2026 - 10:01:27 EST


Hi Runyu,

On Tue, Oct 6, 2026 at 5:56 AM Runyu Xiao <runyu.xiao@xxxxxxxxxx> wrote:
>
> The PCIe driver registers its MSI-X handlers with
> devm_request_threaded_irq(), but remove() uses free_irq() directly. The
> devres actions then retain registrations and attempt to release them again
> during device cleanup.
>
> Use devm_free_irq() for the remove path and for already registered vectors
> when a later setup request fails. This removes the managed resource at the
> same time as the IRQ is released and keeps MSI-X vector teardown ordered
> after IRQ ownership is gone.
>
> Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
> Cc: stable@xxxxxxxxxxxxxxx
> Tested-by: Ravindra <ravindra@xxxxxxxxx>
> Assisted-by: LLM
> Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
> ---
> Changes in v2:
> - Add Ravindra's Tested-by tag.

v1 has already been applied.

>
> drivers/bluetooth/btintel_pcie.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
> index 005c77a4f..f8901df7c 100644
> --- a/drivers/bluetooth/btintel_pcie.c
> +++ b/drivers/bluetooth/btintel_pcie.c
> @@ -1750,7 +1750,7 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
> static int btintel_pcie_setup_irq(struct btintel_pcie_data *data)
> {
> int err;
> - int num_irqs, i;
> + int num_irqs, i, j;
>
> for (i = 0; i < BTINTEL_PCIE_MSIX_VEC_MAX; i++)
> data->msix_entries[i].entry = i;
> @@ -1779,6 +1779,10 @@ static int btintel_pcie_setup_irq(struct btintel_pcie_data *data)
> KBUILD_MODNAME,
> msix_entry);
> if (err) {
> + for (j = 0; j < i; j++)
> + devm_free_irq(&data->pdev->dev,
> + data->msix_entries[j].vector,
> + &data->msix_entries[j]);
> pci_free_irq_vectors(data->pdev);
> data->alloc_vecs = 0;
> return err;
> @@ -3101,7 +3105,7 @@ static void btintel_pcie_remove(struct pci_dev *pdev)
> struct msix_entry *msix_entry;
>
> msix_entry = &data->msix_entries[i];
> - free_irq(msix_entry->vector, msix_entry);
> + devm_free_irq(&pdev->dev, msix_entry->vector, msix_entry);
> }
>
> pci_free_irq_vectors(pdev);
> --
> 2.34.1



--
Luiz Augusto von Dentz