]> git.itanic.dy.fi Git - linux-stable/commitdiff
gnss: sirf: fix premature wakeup interrupt enable
authorJohan Hovold <johan@kernel.org>
Tue, 22 Jan 2019 17:22:53 +0000 (18:22 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 Mar 2019 06:17:21 +0000 (07:17 +0100)
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

index 2c22836d3ffd5f060ae2cde22dbd462ef977ee0b..4596fde16dfe622ca01324685512022b51800077 100644 (file)
@@ -310,30 +310,26 @@ static int sirf_probe(struct serdev_device *serdev)
                        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_device *serdev)
        } 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 @@ static int sirf_probe(struct serdev_device *serdev)
                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_device *serdev)
        else
                sirf_runtime_suspend(&serdev->dev);
 
+       if (data->wakeup)
+               free_irq(data->irq, data);
+
        if (data->on_off)
                regulator_disable(data->vcc);