Skip to content

Commit 67b18df

Browse files
khfengbentiss
authored andcommitted
HID: i2c-hid: Remove runtime power management
Runtime power management in i2c-hid brings lots of issues, such as: - When transitioning from display manager to desktop session, i2c-hid was closed and opened, so the device was set to SLEEP and ON in a short period. Vendors confirmed that their devices can't handle fast ON/SLEEP command because Windows doesn't have this behavior. - When rebooting, i2c-hid was closed, and the driver core put the device back to full power before shutdown. This behavior also triggers a quick SLEEP and ON commands that some devices can't handle, renders an unusable touchpad after reboot. - Most importantly, my power meter reports little to none energy saving when i2c-hid is runtime suspended. So let's remove runtime power management since there is no actual benefit. Signed-off-by: Kai-Heng Feng <[email protected]> Acked-by: Hans de Goede <[email protected]> Signed-off-by: Benjamin Tissoires <[email protected]>
1 parent 16ff7bf commit 67b18df

File tree

1 file changed

+7
-111
lines changed

1 file changed

+7
-111
lines changed

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

Lines changed: 7 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include <linux/delay.h>
2727
#include <linux/slab.h>
2828
#include <linux/pm.h>
29-
#include <linux/pm_runtime.h>
3029
#include <linux/device.h>
3130
#include <linux/wait.h>
3231
#include <linux/err.h>
@@ -48,8 +47,6 @@
4847
/* quirks to control the device */
4948
#define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0)
5049
#define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1)
51-
#define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2)
52-
#define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3)
5350
#define I2C_HID_QUIRK_BOGUS_IRQ BIT(4)
5451

5552
/* flags */
@@ -172,14 +169,7 @@ static const struct i2c_hid_quirks {
172169
{ USB_VENDOR_ID_WEIDA, HID_ANY_ID,
173170
I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
174171
{ I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
175-
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET |
176-
I2C_HID_QUIRK_NO_RUNTIME_PM },
177-
{ I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33,
178-
I2C_HID_QUIRK_DELAY_AFTER_SLEEP },
179-
{ USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_8001,
180-
I2C_HID_QUIRK_NO_RUNTIME_PM },
181-
{ I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_01F0,
182-
I2C_HID_QUIRK_NO_RUNTIME_PM },
172+
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
183173
{ USB_VENDOR_ID_ELAN, HID_ANY_ID,
184174
I2C_HID_QUIRK_BOGUS_IRQ },
185175
{ 0, 0 }
@@ -397,7 +387,6 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state)
397387
{
398388
struct i2c_hid *ihid = i2c_get_clientdata(client);
399389
int ret;
400-
unsigned long now, delay;
401390

402391
i2c_hid_dbg(ihid, "%s\n", __func__);
403392

@@ -415,22 +404,9 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state)
415404
goto set_pwr_exit;
416405
}
417406

418-
if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP &&
419-
power_state == I2C_HID_PWR_ON) {
420-
now = jiffies;
421-
if (time_after(ihid->sleep_delay, now)) {
422-
delay = jiffies_to_usecs(ihid->sleep_delay - now);
423-
usleep_range(delay, delay + 1);
424-
}
425-
}
426-
427407
ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state,
428408
0, NULL, 0, NULL, 0);
429409

430-
if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP &&
431-
power_state == I2C_HID_PWR_SLEEP)
432-
ihid->sleep_delay = jiffies + msecs_to_jiffies(20);
433-
434410
if (ret)
435411
dev_err(&client->dev, "failed to change power setting.\n");
436412

@@ -791,11 +767,6 @@ static int i2c_hid_open(struct hid_device *hid)
791767
{
792768
struct i2c_client *client = hid->driver_data;
793769
struct i2c_hid *ihid = i2c_get_clientdata(client);
794-
int ret = 0;
795-
796-
ret = pm_runtime_get_sync(&client->dev);
797-
if (ret < 0)
798-
return ret;
799770

800771
set_bit(I2C_HID_STARTED, &ihid->flags);
801772
return 0;
@@ -807,27 +778,6 @@ static void i2c_hid_close(struct hid_device *hid)
807778
struct i2c_hid *ihid = i2c_get_clientdata(client);
808779

809780
clear_bit(I2C_HID_STARTED, &ihid->flags);
810-
811-
/* Save some power */
812-
pm_runtime_put(&client->dev);
813-
}
814-
815-
static int i2c_hid_power(struct hid_device *hid, int lvl)
816-
{
817-
struct i2c_client *client = hid->driver_data;
818-
struct i2c_hid *ihid = i2c_get_clientdata(client);
819-
820-
i2c_hid_dbg(ihid, "%s lvl:%d\n", __func__, lvl);
821-
822-
switch (lvl) {
823-
case PM_HINT_FULLON:
824-
pm_runtime_get_sync(&client->dev);
825-
break;
826-
case PM_HINT_NORMAL:
827-
pm_runtime_put(&client->dev);
828-
break;
829-
}
830-
return 0;
831781
}
832782

833783
struct hid_ll_driver i2c_hid_ll_driver = {
@@ -836,7 +786,6 @@ struct hid_ll_driver i2c_hid_ll_driver = {
836786
.stop = i2c_hid_stop,
837787
.open = i2c_hid_open,
838788
.close = i2c_hid_close,
839-
.power = i2c_hid_power,
840789
.output_report = i2c_hid_output_report,
841790
.raw_request = i2c_hid_raw_request,
842791
};
@@ -1104,26 +1053,23 @@ static int i2c_hid_probe(struct i2c_client *client,
11041053

11051054
i2c_hid_acpi_fix_up_power(&client->dev);
11061055

1107-
pm_runtime_get_noresume(&client->dev);
1108-
pm_runtime_set_active(&client->dev);
1109-
pm_runtime_enable(&client->dev);
11101056
device_enable_async_suspend(&client->dev);
11111057

11121058
/* Make sure there is something at this address */
11131059
ret = i2c_smbus_read_byte(client);
11141060
if (ret < 0) {
11151061
dev_dbg(&client->dev, "nothing at this address: %d\n", ret);
11161062
ret = -ENXIO;
1117-
goto err_pm;
1063+
goto err_regulator;
11181064
}
11191065

11201066
ret = i2c_hid_fetch_hid_descriptor(ihid);
11211067
if (ret < 0)
1122-
goto err_pm;
1068+
goto err_regulator;
11231069

11241070
ret = i2c_hid_init_irq(client);
11251071
if (ret < 0)
1126-
goto err_pm;
1072+
goto err_regulator;
11271073

11281074
hid = hid_allocate_device();
11291075
if (IS_ERR(hid)) {
@@ -1154,9 +1100,6 @@ static int i2c_hid_probe(struct i2c_client *client,
11541100
goto err_mem_free;
11551101
}
11561102

1157-
if (!(ihid->quirks & I2C_HID_QUIRK_NO_RUNTIME_PM))
1158-
pm_runtime_put(&client->dev);
1159-
11601103
return 0;
11611104

11621105
err_mem_free:
@@ -1165,10 +1108,6 @@ static int i2c_hid_probe(struct i2c_client *client,
11651108
err_irq:
11661109
free_irq(client->irq, ihid);
11671110

1168-
err_pm:
1169-
pm_runtime_put_noidle(&client->dev);
1170-
pm_runtime_disable(&client->dev);
1171-
11721111
err_regulator:
11731112
regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies),
11741113
ihid->pdata.supplies);
@@ -1181,12 +1120,6 @@ static int i2c_hid_remove(struct i2c_client *client)
11811120
struct i2c_hid *ihid = i2c_get_clientdata(client);
11821121
struct hid_device *hid;
11831122

1184-
if (!(ihid->quirks & I2C_HID_QUIRK_NO_RUNTIME_PM))
1185-
pm_runtime_get_sync(&client->dev);
1186-
pm_runtime_disable(&client->dev);
1187-
pm_runtime_set_suspended(&client->dev);
1188-
pm_runtime_put_noidle(&client->dev);
1189-
11901123
hid = ihid->hid;
11911124
hid_destroy_device(hid);
11921125

@@ -1219,25 +1152,15 @@ static int i2c_hid_suspend(struct device *dev)
12191152
int wake_status;
12201153

12211154
if (hid->driver && hid->driver->suspend) {
1222-
/*
1223-
* Wake up the device so that IO issues in
1224-
* HID driver's suspend code can succeed.
1225-
*/
1226-
ret = pm_runtime_resume(dev);
1227-
if (ret < 0)
1228-
return ret;
1229-
12301155
ret = hid->driver->suspend(hid, PMSG_SUSPEND);
12311156
if (ret < 0)
12321157
return ret;
12331158
}
12341159

1235-
if (!pm_runtime_suspended(dev)) {
1236-
/* Save some power */
1237-
i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
1160+
/* Save some power */
1161+
i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
12381162

1239-
disable_irq(client->irq);
1240-
}
1163+
disable_irq(client->irq);
12411164

12421165
if (device_may_wakeup(&client->dev)) {
12431166
wake_status = enable_irq_wake(client->irq);
@@ -1279,11 +1202,6 @@ static int i2c_hid_resume(struct device *dev)
12791202
wake_status);
12801203
}
12811204

1282-
/* We'll resume to full power */
1283-
pm_runtime_disable(dev);
1284-
pm_runtime_set_active(dev);
1285-
pm_runtime_enable(dev);
1286-
12871205
enable_irq(client->irq);
12881206

12891207
/* Instead of resetting device, simply powers the device on. This
@@ -1304,30 +1222,8 @@ static int i2c_hid_resume(struct device *dev)
13041222
}
13051223
#endif
13061224

1307-
#ifdef CONFIG_PM
1308-
static int i2c_hid_runtime_suspend(struct device *dev)
1309-
{
1310-
struct i2c_client *client = to_i2c_client(dev);
1311-
1312-
i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
1313-
disable_irq(client->irq);
1314-
return 0;
1315-
}
1316-
1317-
static int i2c_hid_runtime_resume(struct device *dev)
1318-
{
1319-
struct i2c_client *client = to_i2c_client(dev);
1320-
1321-
enable_irq(client->irq);
1322-
i2c_hid_set_power(client, I2C_HID_PWR_ON);
1323-
return 0;
1324-
}
1325-
#endif
1326-
13271225
static const struct dev_pm_ops i2c_hid_pm = {
13281226
SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_suspend, i2c_hid_resume)
1329-
SET_RUNTIME_PM_OPS(i2c_hid_runtime_suspend, i2c_hid_runtime_resume,
1330-
NULL)
13311227
};
13321228

13331229
static const struct i2c_device_id i2c_hid_id_table[] = {

0 commit comments

Comments
 (0)