If the i2c-hid device was runtime suspended and then the system suspended itself we'd end up disabling interrupts twice (in i2c_hid_runtime_suspend and i2c_hid_suspend) and not reenabling them until later when the i2c-hid device was runtime resumed. Unfortunately the i2c_hid_resume() calls i2c_hid_hwreset() and that only works properly if interrupts are enabled. We can fix this by taking the advice from "runtime_pm.txt". Specifically we'll change i2c-hid to always resume to full power. This only works if our parents are also resumed to full power, but given the suggestion in "runtime_pm.txt" this seems a reasonable assumption. Signed-off-by: Doug Anderson <dianders@xxxxxxxxxxxx> --- Note that this was tested on a 3.14 kernel with backports. Any testing that folks can do on ToT is appreciated. Changes in v2: - Move pm_runtime_enable() higher in resume drivers/hid/i2c-hid/i2c-hid.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index ab4dd95..9e013f6 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -1090,15 +1090,18 @@ static int i2c_hid_suspend(struct device *dev) struct hid_device *hid = ihid->hid; int ret = 0; - disable_irq(ihid->irq); - if (device_may_wakeup(&client->dev)) - enable_irq_wake(ihid->irq); + if (!pm_runtime_suspended(dev)) { + /* Save some power */ + i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); + + disable_irq(ihid->irq); + } if (hid->driver && hid->driver->suspend) ret = hid->driver->suspend(hid, PMSG_SUSPEND); - /* Save some power */ - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); + if (device_may_wakeup(&client->dev)) + enable_irq_wake(ihid->irq); return ret; } @@ -1110,6 +1113,11 @@ static int i2c_hid_resume(struct device *dev) struct i2c_hid *ihid = i2c_get_clientdata(client); struct hid_device *hid = ihid->hid; + /* We'll resume to full power */ + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + enable_irq(ihid->irq); ret = i2c_hid_hwreset(client); if (ret) -- 2.2.0.rc0.207.ga3a616c -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html