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

Commit d1c48038 authored by Andrew Duggan's avatar Andrew Duggan Committed by Jiri Kosina
Browse files

HID: i2c-hid: Only disable irq wake if it was successfully enabled during suspend



Enabling irq wake could potentially fail and calling disable_irq_wake
after a failed call to enable_irq_wake could result in an unbalanced irq
warning. This patch warns if enable_irq_wake fails and avoids other
potential issues caused by calling disable_irq_wake on resume after
enable_irq_wake failed during suspend.

Signed-off-by: default avatarAndrew Duggan <aduggan@synaptics.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent af4739c2
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -149,6 +149,8 @@ struct i2c_hid {
	int			irq;

	struct i2c_hid_platform_data pdata;

	bool			irq_wake_enabled;
};

static int __i2c_hid_command(struct i2c_client *client,
@@ -1091,13 +1093,20 @@ static int i2c_hid_suspend(struct device *dev)
	struct i2c_hid *ihid = i2c_get_clientdata(client);
	struct hid_device *hid = ihid->hid;
	int ret = 0;
	int wake_status;

	if (hid->driver && hid->driver->suspend)
		ret = hid->driver->suspend(hid, PMSG_SUSPEND);

	disable_irq(ihid->irq);
	if (device_may_wakeup(&client->dev))
		enable_irq_wake(ihid->irq);
	if (device_may_wakeup(&client->dev)) {
		wake_status = enable_irq_wake(ihid->irq);
		if (!wake_status)
			ihid->irq_wake_enabled = true;
		else
			hid_warn(hid, "Failed to enable irq wake: %d\n",
				wake_status);
	}

	/* Save some power */
	i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
@@ -1111,14 +1120,21 @@ static int i2c_hid_resume(struct device *dev)
	struct i2c_client *client = to_i2c_client(dev);
	struct i2c_hid *ihid = i2c_get_clientdata(client);
	struct hid_device *hid = ihid->hid;
	int wake_status;

	enable_irq(ihid->irq);
	ret = i2c_hid_hwreset(client);
	if (ret)
		return ret;

	if (device_may_wakeup(&client->dev))
		disable_irq_wake(ihid->irq);
	if (device_may_wakeup(&client->dev) && ihid->irq_wake_enabled) {
		wake_status = disable_irq_wake(ihid->irq);
		if (!wake_status)
			ihid->irq_wake_enabled = false;
		else
			hid_warn(hid, "Failed to disable irq wake: %d\n",
				wake_status);
	}

	if (hid->driver && hid->driver->reset_resume) {
		ret = hid->driver->reset_resume(hid);