Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09675c2f authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

gnss: sirf: fix premature wakeup interrupt enable



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: d2efbbd1 ("gnss: add driver for sirfstar-based receivers")
Cc: stable <stable@vger.kernel.org>	# 4.19
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c426de69
Loading
Loading
Loading
Loading
+17 −15
Original line number Diff line number Diff line
@@ -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);