Skip to content

Commit f6cd378

Browse files
committed
Input: wacom - fix runtime PM related deadlock
When runtime PM is enabled by default for input devices, X hangs in wacom open: [<ffffffff814a00ea>] mutex_lock+0x1a/0x40 [<ffffffffa02bc94b>] wacom_resume+0x3b/0x90 [wacom] [<ffffffff81327a32>] usb_resume_interface+0xd2/0x190 [<ffffffff81327b5d>] usb_resume_both+0x6d/0x110 [<ffffffff81327c24>] usb_runtime_resume+0x24/0x40 [<ffffffff8130a2cf>] __pm_runtime_resume+0x26f/0x450 [<ffffffff8130a23a>] __pm_runtime_resume+0x1da/0x450 [<ffffffff8130a53a>] pm_runtime_resume+0x2a/0x50 [<ffffffff81328176>] usb_autopm_get_interface+0x26/0x60 [<ffffffffa02bc626>] wacom_open+0x36/0x90 [wacom] wacom_open() takes wacom->lock and calls usb_autopm_get_interface(), which in turn calls wacom_resume() which tries to acquire the lock again. The fix is to call usb_autopm_get_interface() first, before we take the lock. Since we do not do usb_autopm_put_interface() until wacom_close() is called runtime PM is effectively disabled for the driver, however changing it now would risk regressions so the complete fix will have to wait till the next merge window. Reported-by: Jiri Slaby <[email protected]> Acked-by: Oliver Neukum <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent d2520a4 commit f6cd378

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

drivers/input/tablet/wacom_sys.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,27 +103,26 @@ static void wacom_sys_irq(struct urb *urb)
103103
static int wacom_open(struct input_dev *dev)
104104
{
105105
struct wacom *wacom = input_get_drvdata(dev);
106+
int retval = 0;
106107

107-
mutex_lock(&wacom->lock);
108-
109-
wacom->irq->dev = wacom->usbdev;
110-
111-
if (usb_autopm_get_interface(wacom->intf) < 0) {
112-
mutex_unlock(&wacom->lock);
108+
if (usb_autopm_get_interface(wacom->intf) < 0)
113109
return -EIO;
114-
}
110+
111+
mutex_lock(&wacom->lock);
115112

116113
if (usb_submit_urb(wacom->irq, GFP_KERNEL)) {
117-
usb_autopm_put_interface(wacom->intf);
118-
mutex_unlock(&wacom->lock);
119-
return -EIO;
114+
retval = -EIO;
115+
goto out;
120116
}
121117

122118
wacom->open = true;
123119
wacom->intf->needs_remote_wakeup = 1;
124120

121+
out:
125122
mutex_unlock(&wacom->lock);
126-
return 0;
123+
if (retval)
124+
usb_autopm_put_interface(wacom->intf);
125+
return retval;
127126
}
128127

129128
static void wacom_close(struct input_dev *dev)
@@ -135,6 +134,8 @@ static void wacom_close(struct input_dev *dev)
135134
wacom->open = false;
136135
wacom->intf->needs_remote_wakeup = 0;
137136
mutex_unlock(&wacom->lock);
137+
138+
usb_autopm_put_interface(wacom->intf);
138139
}
139140

140141
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,

0 commit comments

Comments
 (0)