aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/isp116x-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/isp116x-hcd.c')
-rw-r--r--drivers/usb/host/isp116x-hcd.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 82f64986bc22..5f56c4a42f52 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1201,11 +1201,14 @@ static int isp116x_bus_suspend(struct usb_hcd *hcd)
1201 return ret; 1201 return ret;
1202} 1202}
1203 1203
1204/* Get rid of these declarations later in cleanup */
1205static int isp116x_reset(struct usb_hcd *hcd);
1206static int isp116x_start(struct usb_hcd *hcd);
1207
1204static int isp116x_bus_resume(struct usb_hcd *hcd) 1208static int isp116x_bus_resume(struct usb_hcd *hcd)
1205{ 1209{
1206 struct isp116x *isp116x = hcd_to_isp116x(hcd); 1210 struct isp116x *isp116x = hcd_to_isp116x(hcd);
1207 u32 val; 1211 u32 val;
1208 int ret = -EINPROGRESS;
1209 1212
1210 msleep(5); 1213 msleep(5);
1211 spin_lock_irq(&isp116x->lock); 1214 spin_lock_irq(&isp116x->lock);
@@ -1219,20 +1222,27 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
1219 case HCCONTROL_USB_RESUME: 1222 case HCCONTROL_USB_RESUME:
1220 break; 1223 break;
1221 case HCCONTROL_USB_OPER: 1224 case HCCONTROL_USB_OPER:
1225 spin_unlock_irq(&isp116x->lock);
1222 /* Without setting power_state here the 1226 /* Without setting power_state here the
1223 SUSPENDED state won't be removed from 1227 SUSPENDED state won't be removed from
1224 sysfs/usbN/power.state as a response to remote 1228 sysfs/usbN/power.state as a response to remote
1225 wakeup. Maybe in the future. */ 1229 wakeup. Maybe in the future. */
1226 hcd->self.root_hub->dev.power.power_state = PMSG_ON; 1230 hcd->self.root_hub->dev.power.power_state = PMSG_ON;
1227 ret = 0; 1231 return 0;
1228 break;
1229 default: 1232 default:
1230 ret = -EBUSY; 1233 /* HCCONTROL_USB_RESET: this may happen, when during
1231 } 1234 suspension the HC lost power. Reinitialize completely */
1232
1233 if (ret != -EINPROGRESS) {
1234 spin_unlock_irq(&isp116x->lock); 1235 spin_unlock_irq(&isp116x->lock);
1235 return ret; 1236 DBG("Chip has been reset while suspended. Reinit from scratch.\n");
1237 isp116x_reset(hcd);
1238 isp116x_start(hcd);
1239 isp116x_hub_control(hcd, SetPortFeature,
1240 USB_PORT_FEAT_POWER, 1, NULL, 0);
1241 if ((isp116x->rhdesca & RH_A_NDP) == 2)
1242 isp116x_hub_control(hcd, SetPortFeature,
1243 USB_PORT_FEAT_POWER, 2, NULL, 0);
1244 hcd->self.root_hub->dev.power.power_state = PMSG_ON;
1245 return 0;
1236 } 1246 }
1237 1247
1238 val = isp116x->rhdesca & RH_A_NDP; 1248 val = isp116x->rhdesca & RH_A_NDP;