diff mbox

[v2] input: tablet: pegasus_notetaker: USB PM fixes

Message ID 20160623171835.GE32561@dtor-ws (mailing list archive)
State New, archived
Headers show

Commit Message

Dmitry Torokhov June 23, 2016, 5:18 p.m. UTC
Hi Martin,

On Tue, Jun 14, 2016 at 01:20:15PM +0200, Martin Kepplinger wrote:
>  static int pegasus_reset_resume(struct usb_interface *intf)
>  {
> +	struct pegasus *pegasus = usb_get_intfdata(intf);
> +
> +	if (pegasus->dev->users)
> +		pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
> +
>  	return pegasus_resume(intf);

Hmm, we need to take input mutex when using pegasus->dev->users, how
about the version below instead?

Thanks.

Comments

Martin Kepplinger-Novakovic June 28, 2016, 4:17 p.m. UTC | #1
Am 2016-06-23 um 19:18 schrieb Dmitry Torokhov:
> Hi Martin,
> 
> On Tue, Jun 14, 2016 at 01:20:15PM +0200, Martin Kepplinger wrote:
>>  static int pegasus_reset_resume(struct usb_interface *intf)
>>  {
>> +	struct pegasus *pegasus = usb_get_intfdata(intf);
>> +
>> +	if (pegasus->dev->users)
>> +		pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
>> +
>>  	return pegasus_resume(intf);
> 
> Hmm, we need to take input mutex when using pegasus->dev->users, how
> about the version below instead?
> 
> Thanks.
> 

Sorry for the delay, give me a few more days to test and confirm this or
come up with a final patch.

thanks
                            martin
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Torokhov July 8, 2016, 9:08 p.m. UTC | #2
On Tue, Jun 28, 2016 at 06:17:13PM +0200, Martin Kepplinger wrote:
> Am 2016-06-23 um 19:18 schrieb Dmitry Torokhov:
> > Hi Martin,
> > 
> > On Tue, Jun 14, 2016 at 01:20:15PM +0200, Martin Kepplinger wrote:
> >>  static int pegasus_reset_resume(struct usb_interface *intf)
> >>  {
> >> +	struct pegasus *pegasus = usb_get_intfdata(intf);
> >> +
> >> +	if (pegasus->dev->users)
> >> +		pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
> >> +
> >>  	return pegasus_resume(intf);
> > 
> > Hmm, we need to take input mutex when using pegasus->dev->users, how
> > about the version below instead?
> > 
> > Thanks.
> > 
> 
> Sorry for the delay, give me a few more days to test and confirm this or
> come up with a final patch.

Martin, did you have time to try out this version of the patch?

Thanks!
Martin Kepplinger-Novakovic July 9, 2016, 12:07 p.m. UTC | #3
Am 2016-07-08 um 23:08 schrieb Dmitry Torokhov:
> On Tue, Jun 28, 2016 at 06:17:13PM +0200, Martin Kepplinger wrote:
>> Am 2016-06-23 um 19:18 schrieb Dmitry Torokhov:
>>> Hi Martin,
>>>
>>> On Tue, Jun 14, 2016 at 01:20:15PM +0200, Martin Kepplinger wrote:
>>>>  static int pegasus_reset_resume(struct usb_interface *intf)
>>>>  {
>>>> +	struct pegasus *pegasus = usb_get_intfdata(intf);
>>>> +
>>>> +	if (pegasus->dev->users)
>>>> +		pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
>>>> +
>>>>  	return pegasus_resume(intf);
>>>
>>> Hmm, we need to take input mutex when using pegasus->dev->users, how
>>> about the version below instead?
>>>
>>> Thanks.
>>>
>>
>> Sorry for the delay, give me a few more days to test and confirm this or
>> come up with a final patch.
> 
> Martin, did you have time to try out this version of the patch?
> 
> Thanks!
> 

This patch doesn't seem to work as is. Holidays get in the way, but you
can expect a working patch(set) next week.

                   martin

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c
index 805afe3..d20ea06 100644
--- a/drivers/input/tablet/pegasus_notetaker.c
+++ b/drivers/input/tablet/pegasus_notetaker.c
@@ -80,7 +80,7 @@  struct pegasus {
 	struct work_struct init;
 };
 
-static void pegasus_control_msg(struct pegasus *pegasus, u8 *data, int len)
+static int pegasus_control_msg(struct pegasus *pegasus, u8 *data, int len)
 {
 	const int sizeof_buf = len + 2;
 	int result;
@@ -88,7 +88,7 @@  static void pegasus_control_msg(struct pegasus *pegasus, u8 *data, int len)
 
 	cmd_buf = kmalloc(sizeof_buf, GFP_KERNEL);
 	if (!cmd_buf)
-		return;
+		return -ENOMEM;
 
 	cmd_buf[0] = NOTETAKER_REPORT_ID;
 	cmd_buf[1] = len;
@@ -101,17 +101,23 @@  static void pegasus_control_msg(struct pegasus *pegasus, u8 *data, int len)
 				 0, 0, cmd_buf, sizeof_buf,
 				 USB_CTRL_SET_TIMEOUT);
 
-	if (result != sizeof_buf)
-		dev_err(&pegasus->usbdev->dev, "control msg error\n");
+	if (result != sizeof_buf) {
+		if (result >= 0)
+			result = -EIO;
+		dev_err(&pegasus->usbdev->dev, "control msg error: %d\n",
+			result);
+	}
 
 	kfree(cmd_buf);
+
+	return result;
 }
 
-static void pegasus_set_mode(struct pegasus *pegasus, u8 mode, u8 led)
+static int pegasus_set_mode(struct pegasus *pegasus, u8 mode, u8 led)
 {
 	u8 cmd[] = { NOTETAKER_SET_CMD, NOTETAKER_SET_MODE, led, mode };
 
-	pegasus_control_msg(pegasus, cmd, sizeof(cmd));
+	return pegasus_control_msg(pegasus, cmd, sizeof(cmd));
 }
 
 static void pegasus_parse_packet(struct pegasus *pegasus)
@@ -205,27 +211,24 @@  static int pegasus_open(struct input_dev *dev)
 		return retval;
 
 	pegasus->irq->dev = pegasus->usbdev;
-	if (usb_submit_urb(pegasus->irq, GFP_KERNEL))
+	if (usb_submit_urb(pegasus->irq, GFP_KERNEL)) {
 		retval = -EIO;
+		goto out;
+	}
 
-	pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
+	retval = pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
 
+out:
 	usb_autopm_put_interface(pegasus->intf);
-
 	return retval;
 }
 
 static void pegasus_close(struct input_dev *dev)
 {
 	struct pegasus *pegasus = input_get_drvdata(dev);
-	int autopm_error;
 
-	autopm_error = usb_autopm_get_interface(pegasus->intf);
 	usb_kill_urb(pegasus->irq);
 	cancel_work_sync(&pegasus->init);
-
-	if (!autopm_error)
-		usb_autopm_put_interface(pegasus->intf);
 }
 
 static int pegasus_probe(struct usb_interface *intf,
@@ -373,6 +376,7 @@  static int pegasus_suspend(struct usb_interface *intf, pm_message_t message)
 
 	mutex_lock(&pegasus->dev->mutex);
 	usb_kill_urb(pegasus->irq);
+	cancel_work_sync(&pegasus->init);
 	mutex_unlock(&pegasus->dev->mutex);
 
 	return 0;
@@ -393,7 +397,19 @@  static int pegasus_resume(struct usb_interface *intf)
 
 static int pegasus_reset_resume(struct usb_interface *intf)
 {
-	return pegasus_resume(intf);
+	struct pegasus *pegasus = usb_get_intfdata(intf);
+	int retval = 0;
+
+	mutex_lock(&pegasus->dev->mutex);
+	if (pegasus->dev->users) {
+		retval = pegasus_set_mode(pegasus, PEN_MODE_XY,
+					  NOTETAKER_LED_MOUSE);
+		if (!retval && usb_submit_urb(pegasus->irq, GFP_NOIO) < 0)
+			retval = -EIO;
+	}
+	mutex_unlock(&pegasus->dev->mutex);
+
+	return retval;
 }
 
 static const struct usb_device_id pegasus_ids[] = {