From a087146c72bad795bcab80e5987c5b80fa225000 Mon Sep 17 00:00:00 2001 From: Brian Russell Date: Thu, 19 Mar 2015 17:55:26 +0000 Subject: uio: Request/free irq separate from dev lifecycle Separate irq request/free from the device lifecycle. After device unregister the parent module can call pci_disable_msi. >From the PCI MSI how to: "Before calling this function, a device driver must always call free_irq() on any interrupt for which it previously called request_irq(). Failure to do so results in a BUG_ON(), leaving the device with MSI enabled and thus leaking its vector." So we need to separately free the irq at unregister to allow the device to be kept around in the case of it still having open FDs. Signed-off-by: Brian Russell Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/uio') diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 6276f13..65bf067 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -835,7 +835,15 @@ int __uio_register_device(struct module *owner, info->uio_dev = idev; if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) { - ret = devm_request_irq(idev->dev, info->irq, uio_interrupt, + /* + * Note that we deliberately don't use devm_request_irq + * here. The parent module can unregister the UIO device + * and call pci_disable_msi, which requires that this + * irq has been freed. However, the device may have open + * FDs at the time of unregister and therefore may not be + * freed until they are released. + */ + ret = request_irq(info->irq, uio_interrupt, info->irq_flags, info->name, idev); if (ret) goto err_request_irq; @@ -871,6 +879,8 @@ void uio_unregister_device(struct uio_info *info) uio_dev_del_attributes(idev); + free_irq(idev->info->irq, idev); + device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); return; -- cgit v1.1 From 4d8beff2ae07fad85d723b4cdf704b05f0ed4794 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 16 Mar 2015 20:54:38 +0100 Subject: uio: constify of_device_id array of_device_id is always used as const. (See driver.of_match_table and open firmware functions) Signed-off-by: Fabian Frederick Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_pdrv_genirq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/uio') diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index f598ecd..59c172a 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -252,7 +252,7 @@ static const struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = { }; #ifdef CONFIG_OF -static struct of_device_id uio_of_genirq_match[] = { +static const struct of_device_id uio_of_genirq_match[] = { { /* This is filled with module_parm */ }, { /* Sentinel */ }, }; -- cgit v1.1 From 16c9c8e1ae228e89b66cbc03ec6c753ee44d39bc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Apr 2015 16:04:21 +0200 Subject: Revert "uio: constify of_device_id array" This reverts commit 4d8beff2ae07fad85d723b4cdf704b05f0ed4794. It causes build warnings, and it's incorrect as we do write to this structure. Reported-by: Stephen Rothwell Cc: Fabian Frederick Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_pdrv_genirq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/uio') diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index 59c172a..f598ecd 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -252,7 +252,7 @@ static const struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = { }; #ifdef CONFIG_OF -static const struct of_device_id uio_of_genirq_match[] = { +static struct of_device_id uio_of_genirq_match[] = { { /* This is filled with module_parm */ }, { /* Sentinel */ }, }; -- cgit v1.1