4.20-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold johan@kernel.org
commit 82f844c22588bf47132c82faeda50b6db473162c upstream.
Make sure the receiver is powered (and booted) before enabling the wakeup interrupt to avoid spurious interrupts due to a floating input.
Similarly, disable the interrupt before powering off on probe errors and on unbind.
Fixes: d2efbbd18b1e ("gnss: add driver for sirfstar-based receivers") Cc: stable stable@vger.kernel.org # 4.19 Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/gnss/sirf.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
--- a/drivers/gnss/sirf.c +++ b/drivers/gnss/sirf.c @@ -310,30 +310,26 @@ static int sirf_probe(struct serdev_devi ret = -ENODEV; goto err_put_device; } + + ret = regulator_enable(data->vcc); + if (ret) + goto err_put_device; + + /* Wait for chip to boot into hibernate mode. */ + msleep(SIRF_BOOT_DELAY); }
if (data->wakeup) { ret = gpiod_to_irq(data->wakeup); if (ret < 0) - goto err_put_device; - + goto err_disable_vcc; data->irq = ret;
- ret = devm_request_threaded_irq(dev, data->irq, NULL, - sirf_wakeup_handler, + ret = request_threaded_irq(data->irq, NULL, sirf_wakeup_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "wakeup", data); if (ret) - goto err_put_device; - } - - if (data->on_off) { - ret = regulator_enable(data->vcc); - if (ret) - goto err_put_device; - - /* Wait for chip to boot into hibernate mode */ - msleep(SIRF_BOOT_DELAY); + goto err_disable_vcc; }
if (IS_ENABLED(CONFIG_PM)) { @@ -342,7 +338,7 @@ static int sirf_probe(struct serdev_devi } else { ret = sirf_runtime_resume(dev); if (ret < 0) - goto err_disable_vcc; + goto err_free_irq; }
ret = gnss_register_device(gdev); @@ -356,6 +352,9 @@ err_disable_rpm: pm_runtime_disable(dev); else sirf_runtime_suspend(dev); +err_free_irq: + if (data->wakeup) + free_irq(data->irq, data); err_disable_vcc: if (data->on_off) regulator_disable(data->vcc); @@ -376,6 +375,9 @@ static void sirf_remove(struct serdev_de else sirf_runtime_suspend(&serdev->dev);
+ if (data->wakeup) + free_irq(data->irq, data); + if (data->on_off) regulator_disable(data->vcc);