Commit 4c1f5c88 authored by Harrison Metzger's avatar Harrison Metzger Committed by Greg Kroah-Hartman

USB: fixed bug in usbsevseg using USB autosuspend incorrectly

This patch fixes a bug with the usbsevseg driver which assumed that USB
autosuspend will always be used.
Signed-off-by: default avatarHarrison Metzger <harrisonmetz@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent cdc04834
...@@ -49,6 +49,7 @@ struct usb_sevsegdev { ...@@ -49,6 +49,7 @@ struct usb_sevsegdev {
u16 textlength; u16 textlength;
u8 shadow_power; /* for PM */ u8 shadow_power; /* for PM */
u8 has_interface_pm;
}; };
/* sysfs_streq can't replace this completely /* sysfs_streq can't replace this completely
...@@ -68,12 +69,16 @@ static void update_display_powered(struct usb_sevsegdev *mydev) ...@@ -68,12 +69,16 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
{ {
int rc; int rc;
if (!mydev->shadow_power && mydev->powered) { if (mydev->powered && !mydev->has_interface_pm) {
rc = usb_autopm_get_interface(mydev->intf); rc = usb_autopm_get_interface(mydev->intf);
if (rc < 0) if (rc < 0)
return; return;
mydev->has_interface_pm = 1;
} }
if (mydev->shadow_power != 1)
return;
rc = usb_control_msg(mydev->udev, rc = usb_control_msg(mydev->udev,
usb_sndctrlpipe(mydev->udev, 0), usb_sndctrlpipe(mydev->udev, 0),
0x12, 0x12,
...@@ -86,8 +91,10 @@ static void update_display_powered(struct usb_sevsegdev *mydev) ...@@ -86,8 +91,10 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
if (rc < 0) if (rc < 0)
dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc); dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc);
if (mydev->shadow_power && !mydev->powered) if (!mydev->powered && mydev->has_interface_pm) {
usb_autopm_put_interface(mydev->intf); usb_autopm_put_interface(mydev->intf);
mydev->has_interface_pm = 0;
}
} }
static void update_display_mode(struct usb_sevsegdev *mydev) static void update_display_mode(struct usb_sevsegdev *mydev)
...@@ -351,6 +358,10 @@ static int sevseg_probe(struct usb_interface *interface, ...@@ -351,6 +358,10 @@ static int sevseg_probe(struct usb_interface *interface,
mydev->intf = interface; mydev->intf = interface;
usb_set_intfdata(interface, mydev); usb_set_intfdata(interface, mydev);
/* PM */
mydev->shadow_power = 1; /* currently active */
mydev->has_interface_pm = 0; /* have not issued autopm_get */
/*set defaults */ /*set defaults */
mydev->textmode = 0x02; /* ascii mode */ mydev->textmode = 0x02; /* ascii mode */
mydev->mode_msb = 0x06; /* 6 characters */ mydev->mode_msb = 0x06; /* 6 characters */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment