Commit 9ef449c6b31bb6a8e6dedc24de475a3b8c79be20 ("[media] rc: Postpone ISR registration") tried to fix an early ISR registration, but it didn't moved it far enough -- request_irq() has to be called only *after* device registration.
This patch should fix bug https://bugzilla.kernel.org/show_bug.cgi?id=46391. Cc: <sta...@vger.kernel.org> Signed-off-by: Luis Henriques <luis.henriq...@canonical.com> --- drivers/media/rc/ene_ir.c | 34 ++++++++++++++++++---------------- drivers/media/rc/fintek-cir.c | 11 ++++++----- drivers/media/rc/ite-cir.c | 11 ++++++----- drivers/media/rc/nuvoton-cir.c | 21 +++++++++++---------- drivers/media/rc/winbond-cir.c | 14 +++++++------- 5 files changed, 48 insertions(+), 43 deletions(-) diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 647dd95..3ff3bb6 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -1000,7 +1000,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); rdev = rc_allocate_device(); if (!dev || !rdev) - goto error1; + goto failure; /* validate resources */ error = -ENODEV; @@ -1011,10 +1011,10 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) if (!pnp_port_valid(pnp_dev, 0) || pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE) - goto error; + goto failure; if (!pnp_irq_valid(pnp_dev, 0)) - goto error; + goto failure; spin_lock_init(&dev->hw_lock); @@ -1030,7 +1030,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) /* detect hardware version and features */ error = ene_hw_detect(dev); if (error) - goto error; + goto failure; if (!dev->hw_learning_and_tx_capable && txsim) { dev->hw_learning_and_tx_capable = true; @@ -1077,30 +1077,32 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { dev->hw_io = -1; dev->irq = -1; - goto error; + goto failure; } + error = rc_register_device(rdev); + if (error) + goto failure2; + + error = -EBUSY; dev->irq = pnp_irq(pnp_dev, 0); if (request_irq(dev->irq, ene_isr, IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { dev->irq = -1; - goto error; + goto failure3; } - error = rc_register_device(rdev); - if (error < 0) - goto error; - pr_notice("driver has been successfully loaded\n"); return 0; -error: - if (dev && dev->irq >= 0) - free_irq(dev->irq, dev); - if (dev && dev->hw_io >= 0) - release_region(dev->hw_io, ENE_IO_SIZE); -error1: + +failure3: + rc_unregister_device(rdev); +failure2: + release_region(dev->hw_io, ENE_IO_SIZE); +failure: rc_free_device(rdev); kfree(dev); + return error; } diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index ab30c64..df8631e 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -558,12 +558,13 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id fintek->cir_port_len, FINTEK_DRIVER_NAME)) goto failure; - if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, - FINTEK_DRIVER_NAME, (void *)fintek)) - goto failure2; - ret = rc_register_device(rdev); if (ret) + goto failure2; + + ret = -EBUSY; + if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, + FINTEK_DRIVER_NAME, (void *)fintek)) goto failure3; device_init_wakeup(&pdev->dev, true); @@ -575,7 +576,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id return 0; failure3: - free_irq(fintek->cir_irq, fintek); + rc_unregister_device(rdev); failure2: release_region(fintek->cir_addr, fintek->cir_port_len); failure: diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 36fe5a3..530cc0b 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1596,12 +1596,13 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id dev_desc->io_region_size, ITE_DRIVER_NAME)) goto failure; - if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, - ITE_DRIVER_NAME, (void *)itdev)) - goto failure2; - ret = rc_register_device(rdev); if (ret) + goto failure2; + + ret = -EBUSY; + if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, + ITE_DRIVER_NAME, (void *)itdev)) goto failure3; itdev->rdev = rdev; @@ -1610,7 +1611,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id return 0; failure3: - free_irq(itdev->cir_irq, itdev); + rc_unregister_device(rdev); failure2: release_region(itdev->cir_addr, itdev->params.io_region_size); failure: diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 699eef3..a0e3cc7 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -1072,20 +1072,21 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) goto failure; - if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto failure2; - if (!request_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto failure2; + + ret = rc_register_device(rdev); + if (ret) goto failure3; - if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, + ret = -EBUSY; + if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, NVT_DRIVER_NAME, (void *)nvt)) goto failure4; - ret = rc_register_device(rdev); - if (ret) + if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) goto failure5; device_init_wakeup(&pdev->dev, true); @@ -1099,11 +1100,11 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) return 0; failure5: - free_irq(nvt->cir_wake_irq, nvt); + free_irq(nvt->cir_irq, nvt); failure4: - release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); + rc_unregister_device(rdev); failure3: - free_irq(nvt->cir_irq, nvt); + release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); failure2: release_region(nvt->cir_addr, CIR_IOREG_LENGTH); failure: diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 54ee348..a42ee93 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1056,26 +1056,26 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) goto exit_release_ebase; } + err = rc_register_device(data->dev); + if (err) + goto exit_release_sbase; + err = request_irq(data->irq, wbcir_irq_handler, IRQF_DISABLED, DRVNAME, device); if (err) { dev_err(dev, "Failed to claim IRQ %u\n", data->irq); err = -EBUSY; - goto exit_release_sbase; + goto exit_unregister_dev; } - err = rc_register_device(data->dev); - if (err) - goto exit_free_irq; - device_init_wakeup(&device->dev, 1); wbcir_init_hw(data); return 0; -exit_free_irq: - free_irq(data->irq, device); +exit_unregister_dev: + rc_unregister_device(data->dev); exit_release_sbase: release_region(data->sbase, SP_IOMEM_LEN); exit_release_ebase: -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/