diff options
Diffstat (limited to 'drivers/usb/core/hcd-pci.c')
| -rw-r--r-- | drivers/usb/core/hcd-pci.c | 27 | 
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 88d9109b4b4..b992a886f05 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -367,6 +367,13 @@ static int check_root_hub_suspended(struct device *dev)  		dev_warn(dev, "Root hub is not suspended\n");  		return -EBUSY;  	} +	if (hcd->shared_hcd) { +		hcd = hcd->shared_hcd; +		if (HCD_RH_RUNNING(hcd)) { +			dev_warn(dev, "Secondary root hub is not suspended\n"); +			return -EBUSY; +		} +	}  	return 0;  } @@ -391,11 +398,16 @@ static int suspend_common(struct device *dev, bool do_wakeup)  		 */  		if (do_wakeup && HCD_WAKEUP_PENDING(hcd))  			return -EBUSY; +		if (do_wakeup && hcd->shared_hcd && +				HCD_WAKEUP_PENDING(hcd->shared_hcd)) +			return -EBUSY;  		retval = hcd->driver->pci_suspend(hcd, do_wakeup);  		suspend_report_result(hcd->driver->pci_suspend, retval);  		/* Check again in case wakeup raced with pci_suspend */ -		if (retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) { +		if ((retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) || +				(retval == 0 && do_wakeup && hcd->shared_hcd && +				 HCD_WAKEUP_PENDING(hcd->shared_hcd))) {  			if (hcd->driver->pci_resume)  				hcd->driver->pci_resume(hcd, false);  			retval = -EBUSY; @@ -426,7 +438,9 @@ static int resume_common(struct device *dev, int event)  	struct usb_hcd		*hcd = pci_get_drvdata(pci_dev);  	int			retval; -	if (HCD_RH_RUNNING(hcd)) { +	if (HCD_RH_RUNNING(hcd) || +			(hcd->shared_hcd && +			 HCD_RH_RUNNING(hcd->shared_hcd))) {  		dev_dbg(dev, "can't resume, not suspended!\n");  		return 0;  	} @@ -440,6 +454,8 @@ static int resume_common(struct device *dev, int event)  	pci_set_master(pci_dev);  	clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); +	if (hcd->shared_hcd) +		clear_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags);  	if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) {  		if (event != PM_EVENT_AUTO_RESUME) @@ -449,6 +465,8 @@ static int resume_common(struct device *dev, int event)  				event == PM_EVENT_RESTORE);  		if (retval) {  			dev_err(dev, "PCI post-resume error %d!\n", retval); +			if (hcd->shared_hcd) +				usb_hc_died(hcd->shared_hcd);  			usb_hc_died(hcd);  		}  	} @@ -474,8 +492,9 @@ static int hcd_pci_suspend_noirq(struct device *dev)  	pci_save_state(pci_dev); -	/* If the root hub is dead rather than suspended, -	 * disallow remote wakeup. +	/* If the root hub is dead rather than suspended, disallow remote +	 * wakeup.  usb_hc_died() should ensure that both hosts are marked as +	 * dying, so we only need to check the primary roothub.  	 */  	if (HCD_DEAD(hcd))  		device_set_wakeup_enable(dev, 0);  |