Skip to content

Commit 9e35620

Browse files
committed
HID: add suspend/resume helpers
There is a lot of duplication of code in the HID low level drivers. Better have everything in one place so we can eventually extend it in a generic way. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: https://lore.kernel.org/r/20211202095334.14399-4-benjamin.tissoires@redhat.com
1 parent 740bebf commit 9e35620

5 files changed

Lines changed: 56 additions & 42 deletions

File tree

drivers/hid/hid-core.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,6 +2126,35 @@ void hid_hw_close(struct hid_device *hdev)
21262126
}
21272127
EXPORT_SYMBOL_GPL(hid_hw_close);
21282128

2129+
#ifdef CONFIG_PM
2130+
int hid_driver_suspend(struct hid_device *hdev, pm_message_t state)
2131+
{
2132+
if (hdev->driver && hdev->driver->suspend)
2133+
return hdev->driver->suspend(hdev, state);
2134+
2135+
return 0;
2136+
}
2137+
EXPORT_SYMBOL_GPL(hid_driver_suspend);
2138+
2139+
int hid_driver_reset_resume(struct hid_device *hdev)
2140+
{
2141+
if (hdev->driver && hdev->driver->reset_resume)
2142+
return hdev->driver->reset_resume(hdev);
2143+
2144+
return 0;
2145+
}
2146+
EXPORT_SYMBOL_GPL(hid_driver_reset_resume);
2147+
2148+
int hid_driver_resume(struct hid_device *hdev)
2149+
{
2150+
if (hdev->driver && hdev->driver->resume)
2151+
return hdev->driver->resume(hdev);
2152+
2153+
return 0;
2154+
}
2155+
EXPORT_SYMBOL_GPL(hid_driver_resume);
2156+
#endif /* CONFIG_PM */
2157+
21292158
struct hid_dynid {
21302159
struct list_head list;
21312160
struct hid_device_id id;

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

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,11 +1063,9 @@ static int i2c_hid_core_suspend(struct device *dev)
10631063
int ret;
10641064
int wake_status;
10651065

1066-
if (hid->driver && hid->driver->suspend) {
1067-
ret = hid->driver->suspend(hid, PMSG_SUSPEND);
1068-
if (ret < 0)
1069-
return ret;
1070-
}
1066+
ret = hid_driver_suspend(hid, PMSG_SUSPEND);
1067+
if (ret < 0)
1068+
return ret;
10711069

10721070
/* Save some power */
10731071
i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
@@ -1125,12 +1123,7 @@ static int i2c_hid_core_resume(struct device *dev)
11251123
if (ret)
11261124
return ret;
11271125

1128-
if (hid->driver && hid->driver->reset_resume) {
1129-
ret = hid->driver->reset_resume(hid);
1130-
return ret;
1131-
}
1132-
1133-
return 0;
1126+
return hid_driver_reset_resume(hid);
11341127
}
11351128
#endif
11361129

drivers/hid/surface-hid/surface_hid_core.c

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -204,50 +204,35 @@ static int surface_hid_suspend(struct device *dev)
204204
{
205205
struct surface_hid_device *d = dev_get_drvdata(dev);
206206

207-
if (d->hid->driver && d->hid->driver->suspend)
208-
return d->hid->driver->suspend(d->hid, PMSG_SUSPEND);
209-
210-
return 0;
207+
return hid_driver_suspend(d->hid, PMSG_SUSPEND);
211208
}
212209

213210
static int surface_hid_resume(struct device *dev)
214211
{
215212
struct surface_hid_device *d = dev_get_drvdata(dev);
216213

217-
if (d->hid->driver && d->hid->driver->resume)
218-
return d->hid->driver->resume(d->hid);
219-
220-
return 0;
214+
return hid_driver_resume(d->hid);
221215
}
222216

223217
static int surface_hid_freeze(struct device *dev)
224218
{
225219
struct surface_hid_device *d = dev_get_drvdata(dev);
226220

227-
if (d->hid->driver && d->hid->driver->suspend)
228-
return d->hid->driver->suspend(d->hid, PMSG_FREEZE);
229-
230-
return 0;
221+
return hid_driver_suspend(d->hid, PMSG_FREEZE);
231222
}
232223

233224
static int surface_hid_poweroff(struct device *dev)
234225
{
235226
struct surface_hid_device *d = dev_get_drvdata(dev);
236227

237-
if (d->hid->driver && d->hid->driver->suspend)
238-
return d->hid->driver->suspend(d->hid, PMSG_HIBERNATE);
239-
240-
return 0;
228+
return hid_driver_suspend(d->hid, PMSG_HIBERNATE);
241229
}
242230

243231
static int surface_hid_restore(struct device *dev)
244232
{
245233
struct surface_hid_device *d = dev_get_drvdata(dev);
246234

247-
if (d->hid->driver && d->hid->driver->reset_resume)
248-
return d->hid->driver->reset_resume(d->hid);
249-
250-
return 0;
235+
return hid_driver_reset_resume(d->hid);
251236
}
252237

253238
const struct dev_pm_ops surface_hid_pm_ops = {

drivers/hid/usbhid/hid-core.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,8 +1563,8 @@ static int hid_resume_common(struct hid_device *hid, bool driver_suspended)
15631563
int status = 0;
15641564

15651565
hid_restart_io(hid);
1566-
if (driver_suspended && hid->driver && hid->driver->resume)
1567-
status = hid->driver->resume(hid);
1566+
if (driver_suspended)
1567+
status = hid_driver_resume(hid);
15681568
return status;
15691569
}
15701570

@@ -1588,11 +1588,9 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
15881588
{
15891589
set_bit(HID_SUSPENDED, &usbhid->iofl);
15901590
spin_unlock_irq(&usbhid->lock);
1591-
if (hid->driver && hid->driver->suspend) {
1592-
status = hid->driver->suspend(hid, message);
1593-
if (status < 0)
1594-
goto failed;
1595-
}
1591+
status = hid_driver_suspend(hid, message);
1592+
if (status < 0)
1593+
goto failed;
15961594
driver_suspended = true;
15971595
} else {
15981596
usbhid_mark_busy(usbhid);
@@ -1602,8 +1600,7 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
16021600

16031601
} else {
16041602
/* TODO: resume() might need to handle suspend failure */
1605-
if (hid->driver && hid->driver->suspend)
1606-
status = hid->driver->suspend(hid, message);
1603+
status = hid_driver_suspend(hid, message);
16071604
driver_suspended = true;
16081605
spin_lock_irq(&usbhid->lock);
16091606
set_bit(HID_SUSPENDED, &usbhid->iofl);
@@ -1644,8 +1641,8 @@ static int hid_reset_resume(struct usb_interface *intf)
16441641
int status;
16451642

16461643
status = hid_post_reset(intf);
1647-
if (status >= 0 && hid->driver && hid->driver->reset_resume) {
1648-
int ret = hid->driver->reset_resume(hid);
1644+
if (status >= 0) {
1645+
int ret = hid_driver_reset_resume(hid);
16491646
if (ret < 0)
16501647
status = ret;
16511648
}

include/linux/hid.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,16 @@ s32 hid_snto32(__u32 value, unsigned n);
923923
__u32 hid_field_extract(const struct hid_device *hid, __u8 *report,
924924
unsigned offset, unsigned n);
925925

926+
#ifdef CONFIG_PM
927+
int hid_driver_suspend(struct hid_device *hdev, pm_message_t state);
928+
int hid_driver_reset_resume(struct hid_device *hdev);
929+
int hid_driver_resume(struct hid_device *hdev);
930+
#else
931+
static inline int hid_driver_suspend(struct hid_device *hdev, pm_message_t state) { return 0; }
932+
static inline int hid_driver_reset_resume(struct hid_device *hdev) { return 0; }
933+
static inline int hid_driver_resume(struct hid_device *hdev) { return 0; }
934+
#endif
935+
926936
/**
927937
* hid_device_io_start - enable HID input during probe, remove
928938
*

0 commit comments

Comments
 (0)