Skip to content

Commit 30eedf2

Browse files
krzklag-linaro
authored andcommitted
mfd: ezx-pcap: Avoid rescheduling after destroying workqueue
Driver allocates workqueue and then registers additional interrupt handler with devm interface. This means that device removal will not use a reversed order, but first destroy workqueue and then, via devm release handlers, free the interrupt. The interrupt handler registered with devm does not directly use/schedule work items on the workqueue and the remove() function correctly removes other IRQs handlers, however the code mixing devm and non-devm interfaces is difficult to analyze and read. Make the code flow much more obvious by using devm interface for allocating the workqueue, so it will be freed with the rest of devm resources. Change is not equivalent in the workqueue itself: use non-legacy API which does not set (__WQ_LEGACY | WQ_MEM_RECLAIM). The workqueue is used to update device registers, thus there is no point to run it for memory reclaim. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://patch.msgid.link/20260305-workqueue-devm-v2-9-66a38741c652@oss.qualcomm.com Signed-off-by: Lee Jones <lee@kernel.org>
1 parent ef5a54c commit 30eedf2

1 file changed

Lines changed: 2 additions & 6 deletions

File tree

drivers/mfd/ezx-pcap.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,6 @@ static void ezx_pcap_remove(struct spi_device *spi)
375375
/* cleanup irqchip */
376376
for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
377377
irq_set_chip_and_handler(i, NULL, NULL);
378-
379-
destroy_workqueue(pcap->workqueue);
380378
}
381379

382380
static int ezx_pcap_probe(struct spi_device *spi)
@@ -411,7 +409,7 @@ static int ezx_pcap_probe(struct spi_device *spi)
411409

412410
/* setup irq */
413411
pcap->irq_base = pdata->irq_base;
414-
pcap->workqueue = create_singlethread_workqueue("pcapd");
412+
pcap->workqueue = devm_alloc_ordered_workqueue(&spi->dev, "pcapd", 0);
415413
if (!pcap->workqueue)
416414
return -ENOMEM;
417415

@@ -463,9 +461,7 @@ static int ezx_pcap_probe(struct spi_device *spi)
463461
free_irqchip:
464462
for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
465463
irq_set_chip_and_handler(i, NULL, NULL);
466-
/* destroy_workqueue: */
467-
destroy_workqueue(pcap->workqueue);
468-
ret:
464+
469465
return ret;
470466
}
471467

0 commit comments

Comments
 (0)