Skip to content

Commit d1c4803

Browse files
aduggan-synaJiri Kosina
authored andcommitted
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: Andrew Duggan <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent af4739c commit d1c4803

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

drivers/hid/i2c-hid/i2c-hid.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ struct i2c_hid {
149149
int irq;
150150

151151
struct i2c_hid_platform_data pdata;
152+
153+
bool irq_wake_enabled;
152154
};
153155

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

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

10981101
disable_irq(ihid->irq);
1099-
if (device_may_wakeup(&client->dev))
1100-
enable_irq_wake(ihid->irq);
1102+
if (device_may_wakeup(&client->dev)) {
1103+
wake_status = enable_irq_wake(ihid->irq);
1104+
if (!wake_status)
1105+
ihid->irq_wake_enabled = true;
1106+
else
1107+
hid_warn(hid, "Failed to enable irq wake: %d\n",
1108+
wake_status);
1109+
}
11011110

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

11151125
enable_irq(ihid->irq);
11161126
ret = i2c_hid_hwreset(client);
11171127
if (ret)
11181128
return ret;
11191129

1120-
if (device_may_wakeup(&client->dev))
1121-
disable_irq_wake(ihid->irq);
1130+
if (device_may_wakeup(&client->dev) && ihid->irq_wake_enabled) {
1131+
wake_status = disable_irq_wake(ihid->irq);
1132+
if (!wake_status)
1133+
ihid->irq_wake_enabled = false;
1134+
else
1135+
hid_warn(hid, "Failed to disable irq wake: %d\n",
1136+
wake_status);
1137+
}
11221138

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

0 commit comments

Comments
 (0)