aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlav Kongas <ok@artecdesign.ee>2005-10-28 08:04:45 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-04 16:48:29 -0500
commit535488fcf1e4b2331e1c4a1eb67ca09468c13507 (patch)
tree285a6e02054bb5a661605649d3527a73bbdba466
parent61a87adf2e7b410da8e41799c61c21a7b8c8b001 (diff)
[PATCH] USB: isp116x-hcd: support reiniting HC on resume
Until now the isp116x-hcd had no support to reinitialize the HC on resume, if the controller lost its state during suspend. This patch, generated against your Oct 26 git tree, adds that support. The patch is basically the same as the one tested by Ivan Kalatchev, who reported the problem, on 2.6.13. Please apply, Support reinitializing the isp116x host controller from scratch on resume, if the controller has lost its state. Signed-off-by: Olav Kongas <ok@artecdesign.ee> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-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;