aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Duggan <aduggan@synaptics.com>2014-07-11 19:34:18 -0400
committerJiri Kosina <jkosina@suse.cz>2014-07-29 05:11:31 -0400
commit109571cf3ec78a39477eedd6b11927f52cbcb1e8 (patch)
tree6948f723339e888757783ce421bc072ff4bae575
parent4c2f503aade27ebf12f5733a583d711f99dc5ec1 (diff)
HID: i2c-hid: call the hid driver's suspend and resume callbacks
Currently, the i2c-hid driver does not call the suspend, resume, and reset_resume callbacks in the hid_driver struct when those events occur. This means that HID drivers for i2c-hid devices will not be able to execute commands which may be needed during suspend or resume. One example is when a touchpad using the hid-multitouch driver gets reset by i2c-hid coming out of resume. Since the reset_resume callback never gets called the device is never put back into the correct input mode. This patch calls the suspend and resume callbacks and tries to duplicate the functionality of the usb-hid driver. Signed-off-by: Andrew Duggan <aduggan@synaptics.com> Signed-off-by: Vincent Huang <vincent.huang@tw.synaptics.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 21aafc8f48c8..747d54421e73 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -1054,21 +1054,29 @@ static int i2c_hid_remove(struct i2c_client *client)
1054static int i2c_hid_suspend(struct device *dev) 1054static int i2c_hid_suspend(struct device *dev)
1055{ 1055{
1056 struct i2c_client *client = to_i2c_client(dev); 1056 struct i2c_client *client = to_i2c_client(dev);
1057 struct i2c_hid *ihid = i2c_get_clientdata(client);
1058 struct hid_device *hid = ihid->hid;
1059 int ret = 0;
1057 1060
1058 disable_irq(client->irq); 1061 disable_irq(client->irq);
1059 if (device_may_wakeup(&client->dev)) 1062 if (device_may_wakeup(&client->dev))
1060 enable_irq_wake(client->irq); 1063 enable_irq_wake(client->irq);
1061 1064
1065 if (hid->driver && hid->driver->suspend)
1066 ret = hid->driver->suspend(hid, PMSG_SUSPEND);
1067
1062 /* Save some power */ 1068 /* Save some power */
1063 i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); 1069 i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
1064 1070
1065 return 0; 1071 return ret;
1066} 1072}
1067 1073
1068static int i2c_hid_resume(struct device *dev) 1074static int i2c_hid_resume(struct device *dev)
1069{ 1075{
1070 int ret; 1076 int ret;
1071 struct i2c_client *client = to_i2c_client(dev); 1077 struct i2c_client *client = to_i2c_client(dev);
1078 struct i2c_hid *ihid = i2c_get_clientdata(client);
1079 struct hid_device *hid = ihid->hid;
1072 1080
1073 enable_irq(client->irq); 1081 enable_irq(client->irq);
1074 ret = i2c_hid_hwreset(client); 1082 ret = i2c_hid_hwreset(client);
@@ -1078,6 +1086,11 @@ static int i2c_hid_resume(struct device *dev)
1078 if (device_may_wakeup(&client->dev)) 1086 if (device_may_wakeup(&client->dev))
1079 disable_irq_wake(client->irq); 1087 disable_irq_wake(client->irq);
1080 1088
1089 if (hid->driver && hid->driver->reset_resume) {
1090 ret = hid->driver->reset_resume(hid);
1091 return ret;
1092 }
1093
1081 return 0; 1094 return 0;
1082} 1095}
1083#endif 1096#endif