diff options
Diffstat (limited to 'drivers/usb')
62 files changed, 695 insertions, 471 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index cbd8f5f8059..76316a33061 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -2,14 +2,6 @@  # USB device configuration  # -menuconfig USB_SUPPORT -	bool "USB support" -	depends on HAS_IOMEM -	default y -	---help--- -	  This option adds core support for Universal Serial Bus (USB). -	  You will also need drivers from the following menu to make use of it. -  # many non-PCI SOC chips embed OHCI  config USB_ARCH_HAS_OHCI  	boolean @@ -63,6 +55,14 @@ config USB_ARCH_HAS_XHCI  	boolean  	default PCI +menuconfig USB_SUPPORT +	bool "USB support" +	depends on HAS_IOMEM +	default y +	---help--- +	  This option adds core support for Universal Serial Bus (USB). +	  You will also need drivers from the following menu to make use of it. +  if USB_SUPPORT  config USB_COMMON diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index c6f6560d436..0bb2b3248da 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -157,8 +157,9 @@ static void wdm_out_callback(struct urb *urb)  	spin_lock(&desc->iuspin);  	desc->werr = urb->status;  	spin_unlock(&desc->iuspin); -	clear_bit(WDM_IN_USE, &desc->flags);  	kfree(desc->outbuf); +	desc->outbuf = NULL; +	clear_bit(WDM_IN_USE, &desc->flags);  	wake_up(&desc->wait);  } @@ -338,7 +339,7 @@ static ssize_t wdm_write  	if (we < 0)  		return -EIO; -	desc->outbuf = buf = kmalloc(count, GFP_KERNEL); +	buf = kmalloc(count, GFP_KERNEL);  	if (!buf) {  		rv = -ENOMEM;  		goto outnl; @@ -406,10 +407,12 @@ static ssize_t wdm_write  	req->wIndex = desc->inum;  	req->wLength = cpu_to_le16(count);  	set_bit(WDM_IN_USE, &desc->flags); +	desc->outbuf = buf;  	rv = usb_submit_urb(desc->command, GFP_KERNEL);  	if (rv < 0) {  		kfree(buf); +		desc->outbuf = NULL;  		clear_bit(WDM_IN_USE, &desc->flags);  		dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);  	} else { diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f8e2d6d52e5..9a56635dc19 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1189,8 +1189,13 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)  	if (status == 0) {  		status = usb_suspend_device(udev, msg); -		/* Again, ignore errors during system sleep transitions */ -		if (!PMSG_IS_AUTO(msg)) +		/* +		 * Ignore errors from non-root-hub devices during +		 * system sleep transitions.  For the most part, +		 * these devices should go to low power anyway when +		 * the entire bus is suspended. +		 */ +		if (udev->parent && !PMSG_IS_AUTO(msg))  			status = 0;  	} diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 622b4a48e73..57ed9e400c0 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -493,6 +493,15 @@ static int hcd_pci_suspend_noirq(struct device *dev)  	pci_save_state(pci_dev); +	/* +	 * Some systems crash if an EHCI controller is in D3 during +	 * a sleep transition.  We have to leave such controllers in D0. +	 */ +	if (hcd->broken_pci_sleep) { +		dev_dbg(dev, "Staying in PCI D0\n"); +		return retval; +	} +  	/* 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. diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 9d7fc9a3993..140d3e11f21 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1978,6 +1978,18 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)  	if (status == 0) {  		usb_set_device_state(rhdev, USB_STATE_SUSPENDED);  		hcd->state = HC_STATE_SUSPENDED; + +		/* Did we race with a root-hub wakeup event? */ +		if (rhdev->do_remote_wakeup) { +			char	buffer[6]; + +			status = hcd->driver->hub_status_data(hcd, buffer); +			if (status != 0) { +				dev_dbg(&rhdev->dev, "suspend raced with wakeup event\n"); +				hcd_bus_resume(rhdev, PMSG_AUTO_RESUME); +				status = -EBUSY; +			} +		}  	} else {  		spin_lock_irq(&hcd_root_hub_lock);  		if (!HCD_DEAD(hcd)) { diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 28664eb7f55..ec6c97dadbe 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev)  {  	struct usb_device	*udev = *pdev;  	int			i; -	struct usb_hcd		*hcd = bus_to_hcd(udev->bus);  	/* mark the device as inactive, so any further urb submissions for  	 * this device (and any of its children) will fail immediately. @@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev)  	 * so that the hardware is now fully quiesced.  	 */  	dev_dbg (&udev->dev, "unregistering device\n"); -	mutex_lock(hcd->bandwidth_mutex);  	usb_disable_device(udev, 0); -	mutex_unlock(hcd->bandwidth_mutex);  	usb_hcd_synchronize_unlinks(udev);  	usb_remove_ep_devs(&udev->ep0); @@ -3163,6 +3160,22 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  	if (retval)  		goto fail; +	/* +	 * Some superspeed devices have finished the link training process +	 * and attached to a superspeed hub port, but the device descriptor +	 * got from those devices show they aren't superspeed devices. Warm +	 * reset the port attached by the devices can fix them. +	 */ +	if ((udev->speed == USB_SPEED_SUPER) && +			(le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { +		dev_err(&udev->dev, "got a wrong device descriptor, " +				"warm reset device\n"); +		hub_port_reset(hub, port1, udev, +				HUB_BH_RESET_TIME, true); +		retval = -EINVAL; +		goto fail; +	} +  	if (udev->descriptor.bMaxPacketSize0 == 0xff ||  			udev->speed == USB_SPEED_SUPER)  		i = 512; diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index cefa0c8b5b6..d2b9af59cba 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -428,18 +428,10 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)  	return retval;  } -static int default_open (struct inode *inode, struct file *file) -{ -	if (inode->i_private) -		file->private_data = inode->i_private; - -	return 0; -} -  static const struct file_operations default_file_operations = {  	.read =		default_read_file,  	.write =	default_write_file, -	.open =		default_open, +	.open =		simple_open,  	.llseek =	default_file_lseek,  }; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b3bdfede45e..ca717da3be9 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -308,7 +308,8 @@ static void sg_complete(struct urb *urb)  				retval = usb_unlink_urb(io->urbs [i]);  				if (retval != -EINPROGRESS &&  				    retval != -ENODEV && -				    retval != -EBUSY) +				    retval != -EBUSY && +				    retval != -EIDRM)  					dev_err(&io->dev->dev,  						"%s, unlink --> %d\n",  						__func__, retval); @@ -317,7 +318,6 @@ static void sg_complete(struct urb *urb)  		}  		spin_lock(&io->lock);  	} -	urb->dev = NULL;  	/* on the last completion, signal usb_sg_wait() */  	io->bytes += urb->actual_length; @@ -524,7 +524,6 @@ void usb_sg_wait(struct usb_sg_request *io)  		case -ENXIO:	/* hc didn't queue this one */  		case -EAGAIN:  		case -ENOMEM: -			io->urbs[i]->dev = NULL;  			retval = 0;  			yield();  			break; @@ -542,7 +541,6 @@ void usb_sg_wait(struct usb_sg_request *io)  			/* fail any uncompleted urbs */  		default: -			io->urbs[i]->dev = NULL;  			io->urbs[i]->status = retval;  			dev_dbg(&io->dev->dev, "%s, submit --> %d\n",  				__func__, retval); @@ -593,7 +591,10 @@ void usb_sg_cancel(struct usb_sg_request *io)  			if (!io->urbs [i]->dev)  				continue;  			retval = usb_unlink_urb(io->urbs [i]); -			if (retval != -EINPROGRESS && retval != -EBUSY) +			if (retval != -EINPROGRESS +					&& retval != -ENODEV +					&& retval != -EBUSY +					&& retval != -EIDRM)  				dev_warn(&io->dev->dev, "%s, unlink --> %d\n",  					__func__, retval);  		} @@ -1135,8 +1136,6 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,   * Deallocates hcd/hardware state for the endpoints (nuking all or most   * pending urbs) and usbcore state for the interfaces, so that usbcore   * must usb_set_configuration() before any interfaces could be used. - * - * Must be called with hcd->bandwidth_mutex held.   */  void usb_disable_device(struct usb_device *dev, int skip_ep0)  { @@ -1189,7 +1188,9 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)  			usb_disable_endpoint(dev, i + USB_DIR_IN, false);  		}  		/* Remove endpoints from the host controller internal state */ +		mutex_lock(hcd->bandwidth_mutex);  		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); +		mutex_unlock(hcd->bandwidth_mutex);  		/* Second pass: remove endpoint pointers */  	}  	for (i = skip_ep0; i < 16; ++i) { @@ -1749,7 +1750,6 @@ free_interfaces:  	/* if it's already configured, clear out old state first.  	 * getting rid of old interfaces means unbinding their drivers.  	 */ -	mutex_lock(hcd->bandwidth_mutex);  	if (dev->state != USB_STATE_ADDRESS)  		usb_disable_device(dev, 1);	/* Skip ep0 */ @@ -1762,6 +1762,7 @@ free_interfaces:  	 * host controller will not allow submissions to dropped endpoints.  If  	 * this call fails, the device state is unchanged.  	 */ +	mutex_lock(hcd->bandwidth_mutex);  	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);  	if (ret < 0) {  		mutex_unlock(hcd->bandwidth_mutex); diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 7239a73c1b8..cd9b3a2cd8a 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -539,6 +539,10 @@ EXPORT_SYMBOL_GPL(usb_submit_urb);   * never submitted, or it was unlinked before, or the hardware is already   * finished with it), even if the completion handler has not yet run.   * + * The URB must not be deallocated while this routine is running.  In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + *   * Unlinking and Endpoint Queues:   *   * [The behaviors and guarantees described below do not apply to virtual @@ -603,6 +607,10 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);   * with error -EPERM.  Thus even if the URB's completion handler always   * tries to resubmit, it will not succeed and the URB will become idle.   * + * The URB must not be deallocated while this routine is running.  In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + *   * This routine may not be used in an interrupt context (such as a bottom   * half or a completion handler), or when holding a spinlock, or in other   * situations where the caller can't schedule(). @@ -640,6 +648,10 @@ EXPORT_SYMBOL_GPL(usb_kill_urb);   * with error -EPERM.  Thus even if the URB's completion handler always   * tries to resubmit, it will not succeed and the URB will become idle.   * + * The URB must not be deallocated while this routine is running.  In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + *   * This routine may not be used in an interrupt context (such as a bottom   * half or a completion handler), or when holding a spinlock, or in other   * situations where the caller can't schedule(). diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 7bd815a507e..99b58d84553 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)  	for (i = 0; i < dwc->num_event_buffers; i++) {  		evt = dwc->ev_buffs[i]; -		if (evt) { +		if (evt)  			dwc3_free_one_event_buffer(dwc, evt); -			dwc->ev_buffs[i] = NULL; -		}  	} + +	kfree(dwc->ev_buffs);  }  /** diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 25910e251c0..3584a169886 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,  			dwc->test_mode_nr = wIndex >> 8;  			dwc->test_mode = true; +			break; +		default: +			return -EINVAL;  		}  		break; @@ -559,15 +562,20 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,  	length = trb->size & DWC3_TRB_SIZE_MASK;  	if (dwc->ep0_bounced) { +		unsigned transfer_size = ur->length; +		unsigned maxp = ep0->endpoint.maxpacket; + +		transfer_size += (maxp - (transfer_size % maxp));  		transferred = min_t(u32, ur->length, -				ep0->endpoint.maxpacket - length); +				transfer_size - length);  		memcpy(ur->buf, dwc->ep0_bounce, transferred);  		dwc->ep0_bounced = false;  	} else {  		transferred = ur->length - length; -		ur->actual += transferred;  	} +	ur->actual += transferred; +  	if ((epnum & 1) && ur->actual < ur->length) {  		/* for some reason we did not get everything out */ diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 0c935d7c65b..9d7bcd91007 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev)  			mod_timer(&udc->vbus_timer,  				  jiffies + VBUS_POLL_TIMEOUT);  		} else { -			if (request_irq(udc->board.vbus_pin, at91_vbus_irq, -					0, driver_name, udc)) { +			if (request_irq(gpio_to_irq(udc->board.vbus_pin), +					at91_vbus_irq, 0, driver_name, udc)) {  				DBG("request vbus irq %d failed\n",  				    udc->board.vbus_pin);  				retval = -EBUSY; @@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)  	return 0;  fail4:  	if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled) -		free_irq(udc->board.vbus_pin, udc); +		free_irq(gpio_to_irq(udc->board.vbus_pin), udc);  fail3:  	if (gpio_is_valid(udc->board.vbus_pin))  		gpio_free(udc->board.vbus_pin); @@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)  	device_init_wakeup(&pdev->dev, 0);  	remove_debug_file(udc);  	if (gpio_is_valid(udc->board.vbus_pin)) { -		free_irq(udc->board.vbus_pin, udc); +		free_irq(gpio_to_irq(udc->board.vbus_pin), udc);  		gpio_free(udc->board.vbus_pin);  	}  	free_irq(udc->udp_irq, udc); diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index a6dfd216416..170cbe89d9f 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -927,7 +927,6 @@ static int dummy_udc_stop(struct usb_gadget *g,  	dum->driver = NULL; -	dummy_pullup(&dum->gadget, 0);  	return 0;  } diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1cbba70836b..f52cb1ae45d 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)  	if (code == FUNCTIONFS_INTERFACE_REVMAP) {  		struct ffs_function *func = ffs->func;  		ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; -	} else if (gadget->ops->ioctl) { +	} else if (gadget && gadget->ops->ioctl) {  		ret = gadget->ops->ioctl(gadget, code, value);  	} else {  		ret = -ENOTTY; @@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs)  		ffs->ep0req = NULL;  		ffs->gadget = NULL;  		ffs_data_put(ffs); +		clear_bit(FFS_FL_BOUND, &ffs->flags);  	}  } diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index a371e966425..cb8c162cae5 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2189,7 +2189,7 @@ unknown_cmnd:  		common->data_size_from_cmnd = 0;  		sprintf(unknown, "Unknown x%02x", common->cmnd[0]);  		reply = check_command(common, common->cmnd_size, -				      DATA_DIR_UNKNOWN, 0xff, 0, unknown); +				      DATA_DIR_UNKNOWN, ~0, 0, unknown);  		if (reply == 0) {  			common->curlun->sense_data = SS_INVALID_COMMAND;  			reply = -EINVAL; diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 85a5cebe96b..965a6293206 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -345,7 +345,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)  		}  		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, -				skb->len <= 1, req->actual, req->actual); +				skb->len <= 1, req->actual, PAGE_SIZE);  		page = NULL;  		if (req->actual < req->length) { /* Last fragment */ diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 7b1cf18df5e..52343654f5d 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)  			if (buf) {  				memcpy(req->buf, buf, n);  				req->complete = rndis_response_complete; +				req->context = rndis;  				rndis_free_response(rndis->config, buf);  				value = n;  			} diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 4fac5692774..a896d73f7a9 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -2579,7 +2579,7 @@ static int do_scsi_command(struct fsg_dev *fsg)  		fsg->data_size_from_cmnd = 0;  		sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);  		if ((reply = check_command(fsg, fsg->cmnd_size, -				DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) { +				DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) {  			fsg->curlun->sense_data = SS_INVALID_COMMAND;  			reply = -EINVAL;  		} diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 5f94e79cd6b..55abfb6bd61 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)  		: (1 << (ep_index(ep)));  	/* check if the pipe is empty */ -	if (!(list_empty(&ep->queue))) { +	if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {  		/* Add td to the end */  		struct fsl_req *lastreq;  		lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); @@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)  		return -ENOMEM;  	} -	/* Update ep0 state */ -	if ((ep_index(ep) == 0)) -		udc->ep0_state = DATA_STATE_XMIT; -  	/* irq handler advances the queue */  	if (req != NULL)  		list_add_tail(&req->queue, &ep->queue); @@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)  		udc->ep0_dir = USB_DIR_OUT;  	ep = &udc->eps[0]; -	udc->ep0_state = WAIT_FOR_OUT_STATUS; +	if (udc->ep0_state != DATA_STATE_XMIT) +		udc->ep0_state = WAIT_FOR_OUT_STATUS;  	req->ep = ep;  	req->req.length = 0; @@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,  	list_add_tail(&req->queue, &ep->queue);  	udc->ep0_state = DATA_STATE_XMIT; +	if (ep0_prime_status(udc, EP_DIR_OUT)) +		ep0stall(udc); +  	return;  stall:  	ep0stall(udc); @@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc,  		spin_lock(&udc->lock);  		udc->ep0_state = (setup->bRequestType & USB_DIR_IN)  				?  DATA_STATE_XMIT : DATA_STATE_RECV; +		/* +		 * If the data stage is IN, send status prime immediately. +		 * See 2.0 Spec chapter 8.5.3.3 for detail. +		 */ +		if (udc->ep0_state == DATA_STATE_XMIT) +			if (ep0_prime_status(udc, EP_DIR_OUT)) +				ep0stall(udc); +  	} else {  		/* No data phase, IN status from gadget */  		udc->ep0_dir = USB_DIR_IN; @@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,  	switch (udc->ep0_state) {  	case DATA_STATE_XMIT: -		/* receive status phase */ -		if (ep0_prime_status(udc, EP_DIR_OUT)) -			ep0stall(udc); +		/* already primed at setup_received_irq */ +		udc->ep0_state = WAIT_FOR_OUT_STATUS;  		break;  	case DATA_STATE_RECV:  		/* send status phase */ diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 331cd6729d3..a85eaf40b94 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = {  static struct ffs_data *gfs_ffs_data;  static unsigned long gfs_registered; -static int  gfs_init(void) +static int __init gfs_init(void)  {  	ENTER(); @@ -169,7 +169,7 @@ static int  gfs_init(void)  }  module_init(gfs_init); -static void  gfs_exit(void) +static void __exit gfs_exit(void)  {  	ENTER(); diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 8793f32bab1..e58b1644297 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1574,7 +1574,6 @@ static void destroy_ep_files (struct dev_data *dev)  	DBG (dev, "%s %d\n", __func__, dev->state);  	/* dev->state must prevent interference */ -restart:  	spin_lock_irq (&dev->lock);  	while (!list_empty(&dev->epfiles)) {  		struct ep_data	*ep; diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 69295ba9d99..105b206cd84 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)  	/* currently we allocate TX FIFOs for all possible endpoints,  	 * and assume that they are all the same size. */ -	for (ep = 0; ep <= 15; ep++) { +	for (ep = 1; ep <= 15; ep++) {  		val = addr;  		val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;  		addr += size; @@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,  	/* write size / packets */  	writel(epsize, hsotg->regs + epsize_reg); -	if (using_dma(hsotg)) { +	if (using_dma(hsotg) && !continuing) {  		unsigned int dma_reg;  		/* write DMA address to control register, buffer already @@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,  	reg |= mpsval;  	writel(reg, regs + S3C_DIEPCTL(ep)); -	reg = readl(regs + S3C_DOEPCTL(ep)); -	reg &= ~S3C_DxEPCTL_MPS_MASK; -	reg |= mpsval; -	writel(reg, regs + S3C_DOEPCTL(ep)); +	if (ep) { +		reg = readl(regs + S3C_DOEPCTL(ep)); +		reg &= ~S3C_DxEPCTL_MPS_MASK; +		reg |= mpsval; +		writel(reg, regs + S3C_DOEPCTL(ep)); +	}  	return; @@ -1919,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,  		    ints & S3C_DIEPMSK_TxFIFOEmpty) {  			dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",  				__func__, idx); -			s3c_hsotg_trytx(hsotg, hs_ep); +			if (!using_dma(hsotg)) +				s3c_hsotg_trytx(hsotg, hs_ep);  		}  	}  } diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 56da49f31d6..e5e44f8cde9 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -263,9 +263,9 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)  	if (udc_is_newstyle(udc)) {  		udc->driver->disconnect(udc->gadget); +		usb_gadget_disconnect(udc->gadget);  		udc->driver->unbind(udc->gadget);  		usb_gadget_udc_stop(udc->gadget, udc->driver); -		usb_gadget_disconnect(udc->gadget);  	} else {  		usb_gadget_stop(udc->gadget, udc->driver);  	} @@ -411,9 +411,13 @@ static ssize_t usb_udc_softconn_store(struct device *dev,  	struct usb_udc		*udc = container_of(dev, struct usb_udc, dev);  	if (sysfs_streq(buf, "connect")) { +		if (udc_is_newstyle(udc)) +			usb_gadget_udc_start(udc->gadget, udc->driver);  		usb_gadget_connect(udc->gadget);  	} else if (sysfs_streq(buf, "disconnect")) {  		usb_gadget_disconnect(udc->gadget); +		if (udc_is_newstyle(udc)) +			usb_gadget_udc_stop(udc->gadget, udc->driver);  	} else {  		dev_err(dev, "unsupported command '%s'\n", buf);  		return -EINVAL; diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h index bc78c606c12..ca4e03a1c73 100644 --- a/drivers/usb/gadget/uvc.h +++ b/drivers/usb/gadget/uvc.h @@ -28,7 +28,7 @@  struct uvc_request_data  { -	unsigned int length; +	__s32 length;  	__u8 data[60];  }; diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c index d776adb2da6..0cdf89d32a1 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/uvc_queue.c @@ -543,11 +543,11 @@ done:  	return ret;  } +/* called with queue->irqlock held.. */  static struct uvc_buffer *  uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)  {  	struct uvc_buffer *nextbuf; -	unsigned long flags;  	if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&  	    buf->buf.length != buf->buf.bytesused) { @@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)  		return buf;  	} -	spin_lock_irqsave(&queue->irqlock, flags);  	list_del(&buf->queue);  	if (!list_empty(&queue->irqqueue))  		nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,  					   queue);  	else  		nextbuf = NULL; -	spin_unlock_irqrestore(&queue->irqlock, flags);  	buf->buf.sequence = queue->sequence++;  	do_gettimeofday(&buf->buf.timestamp); diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index f6e083b5019..54d7ca559cb 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c @@ -39,7 +39,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)  	if (data->length < 0)  		return usb_ep_set_halt(cdev->gadget->ep0); -	req->length = min(uvc->event_length, data->length); +	req->length = min_t(unsigned int, uvc->event_length, data->length);  	req->zero = data->length < uvc->event_length;  	req->dma = DMA_ADDR_INVALID; diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 19f318ababa..cf14c95a670 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -13,6 +13,7 @@  #include <linux/clk.h>  #include <linux/platform_device.h> +#include <linux/of.h>  #include <linux/of_platform.h>  /* interface and function clocks */ diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index fd9109d7eb0..680e1a31fb8 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -352,7 +352,6 @@ static int debug_async_open(struct inode *, struct file *);  static int debug_periodic_open(struct inode *, struct file *);  static int debug_registers_open(struct inode *, struct file *);  static int debug_async_open(struct inode *, struct file *); -static int debug_lpm_open(struct inode *, struct file *);  static ssize_t debug_lpm_read(struct file *file, char __user *user_buf,  				   size_t count, loff_t *ppos);  static ssize_t debug_lpm_write(struct file *file, const char __user *buffer, @@ -385,7 +384,7 @@ static const struct file_operations debug_registers_fops = {  };  static const struct file_operations debug_lpm_fops = {  	.owner		= THIS_MODULE, -	.open		= debug_lpm_open, +	.open		= simple_open,  	.read		= debug_lpm_read,  	.write		= debug_lpm_write,  	.release	= debug_lpm_close, @@ -970,12 +969,6 @@ static int debug_registers_open(struct inode *inode, struct file *file)  	return file->private_data ? 0 : -ENOMEM;  } -static int debug_lpm_open(struct inode *inode, struct file *file) -{ -	file->private_data = inode->i_private; -	return 0; -} -  static int debug_lpm_close(struct inode *inode, struct file *file)  {  	return 0; diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 3e7345172e0..d0a84bd3f3e 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,  	u32 portsc;  	struct usb_hcd *hcd = ehci_to_hcd(ehci);  	void __iomem *non_ehci = hcd->regs; +	struct fsl_usb2_platform_data *pdata; + +	pdata = hcd->self.controller->platform_data;  	portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);  	portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); @@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,  		/* fall through */  	case FSL_USB2_PHY_UTMI:  		/* enable UTMI PHY */ -		setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); +		if (pdata->have_sysif_regs) +			setbits32(non_ehci + FSL_SOC_USB_CTRL, +				  CTRL_UTMI_PHY_EN);  		portsc |= PORT_PTS_UTMI;  		break;  	case FSL_USB2_PHY_NONE: diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 057cdda7a48..4a3bc5b7a06 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -347,6 +347,8 @@ static int ehci_reset (struct ehci_hcd *ehci)  	if (ehci->debug)  		dbgp_external_startup(); +	ehci->port_c_suspend = ehci->suspended_ports = +			ehci->resuming_ports = 0;  	return retval;  } @@ -856,8 +858,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  		goto dead;  	} +	/* +	 * We don't use STS_FLR, but some controllers don't like it to +	 * remain on, so mask it out along with the other status bits. +	 */ +	masked_status = status & (INTR_MASK | STS_FLR); +  	/* Shared IRQ? */ -	masked_status = status & INTR_MASK;  	if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {  		spin_unlock(&ehci->lock);  		return IRQ_NONE; @@ -908,7 +915,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  		pcd_status = status;  		/* resume root hub? */ -		if (!(cmd & CMD_RUN)) +		if (ehci->rh_state == EHCI_RH_SUSPENDED)  			usb_hcd_resume_root_hub(hcd);  		/* get per-port change detect bits */ @@ -939,6 +946,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  			 * like usb_port_resume() does.  			 */  			ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); +			set_bit(i, &ehci->resuming_ports);  			ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);  			mod_timer(&hcd->rh_timer, ehci->reset_done[i]);  		} diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 256fbd42e48..38fe0762315 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -223,15 +223,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)  	 * remote wakeup, we must fail the suspend.  	 */  	if (hcd->self.root_hub->do_remote_wakeup) { -		port = HCS_N_PORTS(ehci->hcs_params); -		while (port--) { -			if (ehci->reset_done[port] != 0) { -				spin_unlock_irq(&ehci->lock); -				ehci_dbg(ehci, "suspend failed because " -						"port %d is resuming\n", -						port + 1); -				return -EBUSY; -			} +		if (ehci->resuming_ports) { +			spin_unlock_irq(&ehci->lock); +			ehci_dbg(ehci, "suspend failed because a port is resuming\n"); +			return -EBUSY;  		}  	} @@ -554,16 +549,12 @@ static int  ehci_hub_status_data (struct usb_hcd *hcd, char *buf)  {  	struct ehci_hcd	*ehci = hcd_to_ehci (hcd); -	u32		temp, status = 0; +	u32		temp, status;  	u32		mask;  	int		ports, i, retval = 1;  	unsigned long	flags;  	u32		ppcd = 0; -	/* if !USB_SUSPEND, root hub timers won't get shut down ... */ -	if (ehci->rh_state != EHCI_RH_RUNNING) -		return 0; -  	/* init status to no-changes */  	buf [0] = 0;  	ports = HCS_N_PORTS (ehci->hcs_params); @@ -572,6 +563,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)  		retval++;  	} +	/* Inform the core about resumes-in-progress by returning +	 * a non-zero value even if there are no status changes. +	 */ +	status = ehci->resuming_ports; +  	/* Some boards (mostly VIA?) report bogus overcurrent indications,  	 * causing massive log spam unless we completely ignore them.  It  	 * may be relevant that VIA VT8235 controllers, where PORT_POWER is @@ -846,6 +842,7 @@ static int ehci_hub_control (  				ehci_writel(ehci,  					temp & ~(PORT_RWC_BITS | PORT_RESUME),  					status_reg); +				clear_bit(wIndex, &ehci->resuming_ports);  				retval = handshake(ehci, status_reg,  					   PORT_RESUME, 0, 2000 /* 2msec */);  				if (retval != 0) { @@ -864,6 +861,7 @@ static int ehci_hub_control (  					ehci->reset_done[wIndex])) {  			status |= USB_PORT_STAT_C_RESET << 16;  			ehci->reset_done [wIndex] = 0; +			clear_bit(wIndex, &ehci->resuming_ports);  			/* force reset to complete */  			ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET), @@ -884,8 +882,10 @@ static int ehci_hub_control (  					ehci_readl(ehci, status_reg));  		} -		if (!(temp & (PORT_RESUME|PORT_RESET))) +		if (!(temp & (PORT_RESUME|PORT_RESET))) {  			ehci->reset_done[wIndex] = 0; +			clear_bit(wIndex, &ehci->resuming_ports); +		}  		/* transfer dedicated ports to the companion hc */  		if ((temp & PORT_CONNECT) && @@ -920,6 +920,7 @@ static int ehci_hub_control (  			status |= USB_PORT_STAT_SUSPEND;  		} else if (test_bit(wIndex, &ehci->suspended_ports)) {  			clear_bit(wIndex, &ehci->suspended_ports); +			clear_bit(wIndex, &ehci->resuming_ports);  			ehci->reset_done[wIndex] = 0;  			if (temp & PORT_PE)  				set_bit(wIndex, &ehci->port_c_suspend); diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index bba9850f32f..5c78f9e7146 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -42,6 +42,7 @@  #include <plat/usb.h>  #include <linux/regulator/consumer.h>  #include <linux/pm_runtime.h> +#include <linux/gpio.h>  /* EHCI Register Set */  #define EHCI_INSNREG04					(0xA0) @@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  		}  	} +	if (pdata->phy_reset) { +		if (gpio_is_valid(pdata->reset_gpio_port[0])) +			gpio_request_one(pdata->reset_gpio_port[0], +					 GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); + +		if (gpio_is_valid(pdata->reset_gpio_port[1])) +			gpio_request_one(pdata->reset_gpio_port[1], +					 GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); + +		/* Hold the PHY in RESET for enough time till DIR is high */ +		udelay(10); +	} +  	pm_runtime_enable(dev);  	pm_runtime_get_sync(dev); @@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  	/* root ports should always stay powered */  	ehci_port_power(omap_ehci, 1); +	if (pdata->phy_reset) { +		/* Hold the PHY in RESET for enough time till +		 * PHY is settled and ready +		 */ +		udelay(10); + +		if (gpio_is_valid(pdata->reset_gpio_port[0])) +			gpio_set_value(pdata->reset_gpio_port[0], 1); + +		if (gpio_is_valid(pdata->reset_gpio_port[1])) +			gpio_set_value(pdata->reset_gpio_port[1], 1); +	} +  	return 0;  err_add_hcd: @@ -259,8 +286,9 @@ err_io:   */  static int ehci_hcd_omap_remove(struct platform_device *pdev)  { -	struct device *dev	= &pdev->dev; -	struct usb_hcd *hcd	= dev_get_drvdata(dev); +	struct device *dev				= &pdev->dev; +	struct usb_hcd *hcd				= dev_get_drvdata(dev); +	struct ehci_hcd_omap_platform_data *pdata	= dev->platform_data;  	usb_remove_hcd(hcd);  	disable_put_regulator(dev->platform_data); @@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)  	pm_runtime_put_sync(dev);  	pm_runtime_disable(dev); +	if (pdata->phy_reset) { +		if (gpio_is_valid(pdata->reset_gpio_port[0])) +			gpio_free(pdata->reset_gpio_port[0]); + +		if (gpio_is_valid(pdata->reset_gpio_port[1])) +			gpio_free(pdata->reset_gpio_port[1]); +	}  	return 0;  } diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 01bb7241d6e..fe8dc069164 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -144,6 +144,14 @@ static int ehci_pci_setup(struct usb_hcd *hcd)  			hcd->has_tt = 1;  			tdi_reset(ehci);  		} +		if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) { +			/* EHCI #1 or #2 on 6 Series/C200 Series chipset */ +			if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) { +				ehci_info(ehci, "broken D3 during system sleep on ASUS\n"); +				hcd->broken_pci_sleep = 1; +				device_set_wakeup_capable(&pdev->dev, false); +			} +		}  		break;  	case PCI_VENDOR_ID_TDI:  		if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 3de48a2d795..f214a80cdee 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -24,6 +24,7 @@  #include <linux/gpio.h>  #include <linux/of.h>  #include <linux/of_gpio.h> +#include <linux/pm_runtime.h>  #include <mach/usb_phy.h>  #include <mach/iomap.h> @@ -37,9 +38,7 @@ struct tegra_ehci_hcd {  	struct clk *emc_clk;  	struct usb_phy *transceiver;  	int host_resumed; -	int bus_suspended;  	int port_resuming; -	int power_down_on_bus_suspend;  	enum tegra_usb_phy_port_speed port_speed;  }; @@ -224,6 +223,7 @@ static int tegra_ehci_hub_control(  		temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);  		/* start resume signalling */  		ehci_writel(ehci, temp | PORT_RESUME, status_reg); +		set_bit(wIndex-1, &ehci->resuming_ports);  		spin_unlock_irqrestore(&ehci->lock, flags);  		msleep(20); @@ -236,6 +236,7 @@ static int tegra_ehci_hub_control(  			pr_err("%s: timeout waiting for SUSPEND\n", __func__);  		ehci->reset_done[wIndex-1] = 0; +		clear_bit(wIndex-1, &ehci->resuming_ports);  		tegra->port_resuming = 1;  		goto done; @@ -271,120 +272,6 @@ static void tegra_ehci_restart(struct usb_hcd *hcd)  	up_write(&ehci_cf_port_reset_rwsem);  } -static int tegra_usb_suspend(struct usb_hcd *hcd) -{ -	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); -	struct ehci_regs __iomem *hw = tegra->ehci->regs; -	unsigned long flags; - -	spin_lock_irqsave(&tegra->ehci->lock, flags); - -	tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; -	ehci_halt(tegra->ehci); -	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - -	spin_unlock_irqrestore(&tegra->ehci->lock, flags); - -	tegra_ehci_power_down(hcd); -	return 0; -} - -static int tegra_usb_resume(struct usb_hcd *hcd) -{ -	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); -	struct ehci_hcd	*ehci = hcd_to_ehci(hcd); -	struct ehci_regs __iomem *hw = ehci->regs; -	unsigned long val; - -	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); -	tegra_ehci_power_up(hcd); - -	if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { -		/* Wait for the phy to detect new devices -		 * before we restart the controller */ -		msleep(10); -		goto restart; -	} - -	/* Force the phy to keep data lines in suspend state */ -	tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); - -	/* Enable host mode */ -	tdi_reset(ehci); - -	/* Enable Port Power */ -	val = readl(&hw->port_status[0]); -	val |= PORT_POWER; -	writel(val, &hw->port_status[0]); -	udelay(10); - -	/* Check if the phy resume from LP0. When the phy resume from LP0 -	 * USB register will be reset. */ -	if (!readl(&hw->async_next)) { -		/* Program the field PTC based on the saved speed mode */ -		val = readl(&hw->port_status[0]); -		val &= ~PORT_TEST(~0); -		if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) -			val |= PORT_TEST_FORCE; -		else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) -			val |= PORT_TEST(6); -		else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) -			val |= PORT_TEST(7); -		writel(val, &hw->port_status[0]); -		udelay(10); - -		/* Disable test mode by setting PTC field to NORMAL_OP */ -		val = readl(&hw->port_status[0]); -		val &= ~PORT_TEST(~0); -		writel(val, &hw->port_status[0]); -		udelay(10); -	} - -	/* Poll until CCS is enabled */ -	if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, -						 PORT_CONNECT, 2000)) { -		pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); -		goto restart; -	} - -	/* Poll until PE is enabled */ -	if (handshake(ehci, &hw->port_status[0], PORT_PE, -						 PORT_PE, 2000)) { -		pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); -		goto restart; -	} - -	/* Clear the PCI status, to avoid an interrupt taken upon resume */ -	val = readl(&hw->status); -	val |= STS_PCD; -	writel(val, &hw->status); - -	/* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ -	val = readl(&hw->port_status[0]); -	if ((val & PORT_POWER) && (val & PORT_PE)) { -		val |= PORT_SUSPEND; -		writel(val, &hw->port_status[0]); - -		/* Wait until port suspend completes */ -		if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, -							 PORT_SUSPEND, 1000)) { -			pr_err("%s: timeout waiting for PORT_SUSPEND\n", -								__func__); -			goto restart; -		} -	} - -	tegra_ehci_phy_restore_end(tegra->phy); -	return 0; - -restart: -	if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) -		tegra_ehci_phy_restore_end(tegra->phy); - -	tegra_ehci_restart(hcd); -	return 0; -} -  static void tegra_ehci_shutdown(struct usb_hcd *hcd)  {  	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); @@ -432,36 +319,6 @@ static int tegra_ehci_setup(struct usb_hcd *hcd)  	return retval;  } -#ifdef CONFIG_PM -static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) -{ -	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); -	int error_status = 0; - -	error_status = ehci_bus_suspend(hcd); -	if (!error_status && tegra->power_down_on_bus_suspend) { -		tegra_usb_suspend(hcd); -		tegra->bus_suspended = 1; -	} - -	return error_status; -} - -static int tegra_ehci_bus_resume(struct usb_hcd *hcd) -{ -	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); - -	if (tegra->bus_suspended && tegra->power_down_on_bus_suspend) { -		tegra_usb_resume(hcd); -		tegra->bus_suspended = 0; -	} - -	tegra_usb_phy_preresume(tegra->phy); -	tegra->port_resuming = 1; -	return ehci_bus_resume(hcd); -} -#endif -  struct temp_buffer {  	void *kmalloc_ptr;  	void *old_xfer_buffer; @@ -572,8 +429,8 @@ static const struct hc_driver tegra_ehci_hc_driver = {  	.hub_control		= tegra_ehci_hub_control,  	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,  #ifdef CONFIG_PM -	.bus_suspend		= tegra_ehci_bus_suspend, -	.bus_resume		= tegra_ehci_bus_resume, +	.bus_suspend		= ehci_bus_suspend, +	.bus_resume		= ehci_bus_resume,  #endif  	.relinquish_port	= ehci_relinquish_port,  	.port_handed_over	= ehci_port_handed_over, @@ -601,11 +458,187 @@ static int setup_vbus_gpio(struct platform_device *pdev)  		dev_err(&pdev->dev, "can't enable vbus\n");  		return err;  	} -	gpio_set_value(gpio, 1);  	return err;  } +#ifdef CONFIG_PM + +static int controller_suspend(struct device *dev) +{ +	struct tegra_ehci_hcd *tegra = +			platform_get_drvdata(to_platform_device(dev)); +	struct ehci_hcd	*ehci = tegra->ehci; +	struct usb_hcd *hcd = ehci_to_hcd(ehci); +	struct ehci_regs __iomem *hw = ehci->regs; +	unsigned long flags; + +	if (time_before(jiffies, ehci->next_statechange)) +		msleep(10); + +	spin_lock_irqsave(&ehci->lock, flags); + +	tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; +	ehci_halt(ehci); +	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + +	spin_unlock_irqrestore(&ehci->lock, flags); + +	tegra_ehci_power_down(hcd); +	return 0; +} + +static int controller_resume(struct device *dev) +{ +	struct tegra_ehci_hcd *tegra = +			platform_get_drvdata(to_platform_device(dev)); +	struct ehci_hcd	*ehci = tegra->ehci; +	struct usb_hcd *hcd = ehci_to_hcd(ehci); +	struct ehci_regs __iomem *hw = ehci->regs; +	unsigned long val; + +	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); +	tegra_ehci_power_up(hcd); + +	if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { +		/* Wait for the phy to detect new devices +		 * before we restart the controller */ +		msleep(10); +		goto restart; +	} + +	/* Force the phy to keep data lines in suspend state */ +	tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); + +	/* Enable host mode */ +	tdi_reset(ehci); + +	/* Enable Port Power */ +	val = readl(&hw->port_status[0]); +	val |= PORT_POWER; +	writel(val, &hw->port_status[0]); +	udelay(10); + +	/* Check if the phy resume from LP0. When the phy resume from LP0 +	 * USB register will be reset. */ +	if (!readl(&hw->async_next)) { +		/* Program the field PTC based on the saved speed mode */ +		val = readl(&hw->port_status[0]); +		val &= ~PORT_TEST(~0); +		if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) +			val |= PORT_TEST_FORCE; +		else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) +			val |= PORT_TEST(6); +		else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) +			val |= PORT_TEST(7); +		writel(val, &hw->port_status[0]); +		udelay(10); + +		/* Disable test mode by setting PTC field to NORMAL_OP */ +		val = readl(&hw->port_status[0]); +		val &= ~PORT_TEST(~0); +		writel(val, &hw->port_status[0]); +		udelay(10); +	} + +	/* Poll until CCS is enabled */ +	if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, +						 PORT_CONNECT, 2000)) { +		pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); +		goto restart; +	} + +	/* Poll until PE is enabled */ +	if (handshake(ehci, &hw->port_status[0], PORT_PE, +						 PORT_PE, 2000)) { +		pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); +		goto restart; +	} + +	/* Clear the PCI status, to avoid an interrupt taken upon resume */ +	val = readl(&hw->status); +	val |= STS_PCD; +	writel(val, &hw->status); + +	/* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ +	val = readl(&hw->port_status[0]); +	if ((val & PORT_POWER) && (val & PORT_PE)) { +		val |= PORT_SUSPEND; +		writel(val, &hw->port_status[0]); + +		/* Wait until port suspend completes */ +		if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, +							 PORT_SUSPEND, 1000)) { +			pr_err("%s: timeout waiting for PORT_SUSPEND\n", +								__func__); +			goto restart; +		} +	} + +	tegra_ehci_phy_restore_end(tegra->phy); +	goto done; + + restart: +	if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) +		tegra_ehci_phy_restore_end(tegra->phy); + +	tegra_ehci_restart(hcd); + + done: +	tegra_usb_phy_preresume(tegra->phy); +	tegra->port_resuming = 1; +	return 0; +} + +static int tegra_ehci_suspend(struct device *dev) +{ +	struct tegra_ehci_hcd *tegra = +			platform_get_drvdata(to_platform_device(dev)); +	struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); +	int rc = 0; + +	/* +	 * When system sleep is supported and USB controller wakeup is +	 * implemented: If the controller is runtime-suspended and the +	 * wakeup setting needs to be changed, call pm_runtime_resume(). +	 */ +	if (HCD_HW_ACCESSIBLE(hcd)) +		rc = controller_suspend(dev); +	return rc; +} + +static int tegra_ehci_resume(struct device *dev) +{ +	int rc; + +	rc = controller_resume(dev); +	if (rc == 0) { +		pm_runtime_disable(dev); +		pm_runtime_set_active(dev); +		pm_runtime_enable(dev); +	} +	return rc; +} + +static int tegra_ehci_runtime_suspend(struct device *dev) +{ +	return controller_suspend(dev); +} + +static int tegra_ehci_runtime_resume(struct device *dev) +{ +	return controller_resume(dev); +} + +static const struct dev_pm_ops tegra_ehci_pm_ops = { +	.suspend	= tegra_ehci_suspend, +	.resume		= tegra_ehci_resume, +	.runtime_suspend = tegra_ehci_runtime_suspend, +	.runtime_resume	= tegra_ehci_runtime_resume, +}; + +#endif +  static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);  static int tegra_ehci_probe(struct platform_device *pdev) @@ -720,7 +753,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)  	}  	tegra->host_resumed = 1; -	tegra->power_down_on_bus_suspend = pdata->power_down_on_bus_suspend;  	tegra->ehci = hcd_to_ehci(hcd);  	irq = platform_get_irq(pdev, 0); @@ -729,7 +761,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)  		err = -ENODEV;  		goto fail;  	} -	set_irq_flags(irq, IRQF_VALID);  #ifdef CONFIG_USB_OTG_UTILS  	if (pdata->operating_mode == TEGRA_USB_OTG) { @@ -745,6 +776,14 @@ static int tegra_ehci_probe(struct platform_device *pdev)  		goto fail;  	} +	pm_runtime_set_active(&pdev->dev); +	pm_runtime_get_noresume(&pdev->dev); + +	/* Don't skip the pm_runtime_forbid call if wakeup isn't working */ +	/* if (!pdata->power_down_on_bus_suspend) */ +		pm_runtime_forbid(&pdev->dev); +	pm_runtime_enable(&pdev->dev); +	pm_runtime_put_sync(&pdev->dev);  	return err;  fail: @@ -771,33 +810,6 @@ fail_hcd:  	return err;  } -#ifdef CONFIG_PM -static int tegra_ehci_resume(struct platform_device *pdev) -{ -	struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); -	struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - -	if (tegra->bus_suspended) -		return 0; - -	return tegra_usb_resume(hcd); -} - -static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state) -{ -	struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); -	struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - -	if (tegra->bus_suspended) -		return 0; - -	if (time_before(jiffies, tegra->ehci->next_statechange)) -		msleep(10); - -	return tegra_usb_suspend(hcd); -} -#endif -  static int tegra_ehci_remove(struct platform_device *pdev)  {  	struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); @@ -806,6 +818,10 @@ static int tegra_ehci_remove(struct platform_device *pdev)  	if (tegra == NULL || hcd == NULL)  		return -EINVAL; +	pm_runtime_get_sync(&pdev->dev); +	pm_runtime_disable(&pdev->dev); +	pm_runtime_put_noidle(&pdev->dev); +  #ifdef CONFIG_USB_OTG_UTILS  	if (tegra->transceiver) {  		otg_set_host(tegra->transceiver->otg, NULL); @@ -846,13 +862,12 @@ static struct of_device_id tegra_ehci_of_match[] __devinitdata = {  static struct platform_driver tegra_ehci_driver = {  	.probe		= tegra_ehci_probe,  	.remove		= tegra_ehci_remove, -#ifdef CONFIG_PM -	.suspend	= tegra_ehci_suspend, -	.resume		= tegra_ehci_resume, -#endif  	.shutdown	= tegra_ehci_hcd_shutdown,  	.driver		= {  		.name	= "tegra-ehci",  		.of_match_table = tegra_ehci_of_match, +#ifdef CONFIG_PM +		.pm	= &tegra_ehci_pm_ops, +#endif  	}  }; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 8f9acbc96fd..2694ed6558d 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -117,6 +117,8 @@ struct ehci_hcd {			/* one per controller */  			the change-suspend feature turned on */  	unsigned long		suspended_ports;	/* which ports are  			suspended */ +	unsigned long		resuming_ports;		/* which ports have +			started to resume */  	/* per-HC memory pools (could be per-bus, but ...) */  	struct dma_pool		*qh_pool;	/* qh per active urb */ diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index db8963f5fbc..13ebeca8e73 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -27,6 +27,10 @@  #error "CONFIG_ARCH_AT91 must be defined."  #endif +#define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS) +#define at91_for_each_port(index)	\ +		for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++) +  /* interface and function clocks; sometimes also an AHB clock */  static struct clk *iclk, *fclk, *hclk;  static int clocked; @@ -90,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev)  /*-------------------------------------------------------------------------*/ -static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); +static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);  /* configure so an HC device and id are always provided */  /* always called with process context; sleeping is OK */ @@ -104,7 +108,7 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);   * then invokes the start() method for the HCD associated with it   * through the hotplug entry's driver_data.   */ -static int usb_hcd_at91_probe(const struct hc_driver *driver, +static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,  			struct platform_device *pdev)  {  	int retval; @@ -199,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,   * context, "rmmod" or something similar.   *   */ -static void usb_hcd_at91_remove(struct usb_hcd *hcd, +static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,  				struct platform_device *pdev)  {  	usb_remove_hcd(hcd); @@ -240,26 +244,26 @@ ohci_at91_start (struct usb_hcd *hcd)  static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)  { -	if (port < 0 || port >= 2) +	if (!valid_port(port))  		return;  	if (!gpio_is_valid(pdata->vbus_pin[port]))  		return;  	gpio_set_value(pdata->vbus_pin[port], -		       !pdata->vbus_pin_active_low[port] ^ enable); +		       pdata->vbus_pin_active_low[port] ^ enable);  }  static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)  { -	if (port < 0 || port >= 2) +	if (!valid_port(port))  		return -EINVAL;  	if (!gpio_is_valid(pdata->vbus_pin[port]))  		return -EINVAL;  	return gpio_get_value(pdata->vbus_pin[port]) ^ -		!pdata->vbus_pin_active_low[port]; +		pdata->vbus_pin_active_low[port];  }  /* @@ -271,9 +275,9 @@ static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)  	int length = ohci_hub_status_data(hcd, buf);  	int port; -	for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) { +	at91_for_each_port(port) {  		if (pdata->overcurrent_changed[port]) { -			if (! length) +			if (!length)  				length = 1;  			buf[0] |= 1 << (port + 1);  		} @@ -297,11 +301,17 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		"ohci_at91_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n",  		hcd, typeReq, wValue, wIndex, buf, wLength); +	wIndex--; +  	switch (typeReq) {  	case SetPortFeature:  		if (wValue == USB_PORT_FEAT_POWER) {  			dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n"); -			ohci_at91_usb_set_power(pdata, wIndex - 1, 1); +			if (valid_port(wIndex)) { +				ohci_at91_usb_set_power(pdata, wIndex, 1); +				ret = 0; +			} +  			goto out;  		}  		break; @@ -312,9 +322,9 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			dev_dbg(hcd->self.controller,  				"ClearPortFeature: C_OVER_CURRENT\n"); -			if (wIndex == 1 || wIndex == 2) { -				pdata->overcurrent_changed[wIndex-1] = 0; -				pdata->overcurrent_status[wIndex-1] = 0; +			if (valid_port(wIndex)) { +				pdata->overcurrent_changed[wIndex] = 0; +				pdata->overcurrent_status[wIndex] = 0;  			}  			goto out; @@ -323,9 +333,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			dev_dbg(hcd->self.controller,  				"ClearPortFeature: OVER_CURRENT\n"); -			if (wIndex == 1 || wIndex == 2) { -				pdata->overcurrent_status[wIndex-1] = 0; -			} +			if (valid_port(wIndex)) +				pdata->overcurrent_status[wIndex] = 0;  			goto out; @@ -333,15 +342,15 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			dev_dbg(hcd->self.controller,  				"ClearPortFeature: POWER\n"); -			if (wIndex == 1 || wIndex == 2) { -				ohci_at91_usb_set_power(pdata, wIndex - 1, 0); +			if (valid_port(wIndex)) { +				ohci_at91_usb_set_power(pdata, wIndex, 0);  				return 0;  			}  		}  		break;  	} -	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); +	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);  	if (ret)  		goto out; @@ -377,18 +386,15 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex); -		if (wIndex == 1 || wIndex == 2) { -			if (! ohci_at91_usb_get_power(pdata, wIndex-1)) { +		if (valid_port(wIndex)) { +			if (!ohci_at91_usb_get_power(pdata, wIndex))  				*data &= ~cpu_to_le32(RH_PS_PPS); -			} -			if (pdata->overcurrent_changed[wIndex-1]) { +			if (pdata->overcurrent_changed[wIndex])  				*data |= cpu_to_le32(RH_PS_OCIC); -			} -			if (pdata->overcurrent_status[wIndex-1]) { +			if (pdata->overcurrent_status[wIndex])  				*data |= cpu_to_le32(RH_PS_POCI); -			}  		}  	} @@ -450,14 +456,14 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)  	/* From the GPIO notifying the over-current situation, find  	 * out the corresponding port */ -	for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) { +	at91_for_each_port(port) {  		if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {  			gpio = pdata->overcurrent_pin[port];  			break;  		}  	} -	if (port == ARRAY_SIZE(pdata->overcurrent_pin)) { +	if (port == AT91_MAX_USBH_PORTS) {  		dev_err(& pdev->dev, "overcurrent interrupt from unknown GPIO\n");  		return IRQ_HANDLED;  	} @@ -467,7 +473,7 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)  	/* When notified of an over-current situation, disable power  	   on the corresponding port, and mark this port in  	   over-current. */ -	if (! val) { +	if (!val) {  		ohci_at91_usb_set_power(pdata, port, 0);  		pdata->overcurrent_status[port]  = 1;  		pdata->overcurrent_changed[port] = 1; @@ -492,7 +498,7 @@ static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);  static int __devinit ohci_at91_of_init(struct platform_device *pdev)  {  	struct device_node *np = pdev->dev.of_node; -	int i, ret, gpio; +	int i, gpio;  	enum of_gpio_flags flags;  	struct at91_usbh_data	*pdata;  	u32 ports; @@ -514,48 +520,17 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)  	if (!of_property_read_u32(np, "num-ports", &ports))  		pdata->ports = ports; -	for (i = 0; i < 2; i++) { +	at91_for_each_port(i) {  		gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags);  		pdata->vbus_pin[i] = gpio;  		if (!gpio_is_valid(gpio))  			continue;  		pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW; -		ret = gpio_request(gpio, "ohci_vbus"); -		if (ret) { -			dev_warn(&pdev->dev, "can't request vbus gpio %d", gpio); -			continue; -		} -		ret = gpio_direction_output(gpio, !(flags & OF_GPIO_ACTIVE_LOW) ^ 1); -		if (ret) -			dev_warn(&pdev->dev, "can't put vbus gpio %d as output %d", -				 !(flags & OF_GPIO_ACTIVE_LOW) ^ 1, gpio);  	} -	for (i = 0; i < 2; i++) { -		gpio = of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags); -		pdata->overcurrent_pin[i] = gpio; -		if (!gpio_is_valid(gpio)) -			continue; -		ret = gpio_request(gpio, "ohci_overcurrent"); -		if (ret) { -			dev_err(&pdev->dev, "can't request overcurrent gpio %d", gpio); -			continue; -		} - -		ret = gpio_direction_input(gpio); -		if (ret) { -			dev_err(&pdev->dev, "can't configure overcurrent gpio %d as input", gpio); -			continue; -		} - -		ret = request_irq(gpio_to_irq(gpio), -				  ohci_hcd_at91_overcurrent_irq, -				  IRQF_SHARED, "ohci_overcurrent", pdev); -		if (ret) { -			gpio_free(gpio); -			dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n"); -		} -	} +	at91_for_each_port(i) +		pdata->overcurrent_pin[i] = +			of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);  	pdev->dev.platform_data = pdata; @@ -570,39 +545,73 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)  /*-------------------------------------------------------------------------*/ -static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) +static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)  {  	struct at91_usbh_data	*pdata;  	int			i; +	int			gpio; +	int			ret; -	i = ohci_at91_of_init(pdev); - -	if (i) -		return i; +	ret = ohci_at91_of_init(pdev); +	if (ret) +		return ret;  	pdata = pdev->dev.platform_data;  	if (pdata) { -		for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) { +		at91_for_each_port(i) {  			if (!gpio_is_valid(pdata->vbus_pin[i]))  				continue; -			gpio_request(pdata->vbus_pin[i], "ohci_vbus"); +			gpio = pdata->vbus_pin[i]; + +			ret = gpio_request(gpio, "ohci_vbus"); +			if (ret) { +				dev_err(&pdev->dev, +					"can't request vbus gpio %d\n", gpio); +				continue; +			} +			ret = gpio_direction_output(gpio, +						!pdata->vbus_pin_active_low[i]); +			if (ret) { +				dev_err(&pdev->dev, +					"can't put vbus gpio %d as output %d\n", +					gpio, !pdata->vbus_pin_active_low[i]); +				gpio_free(gpio); +				continue; +			} +  			ohci_at91_usb_set_power(pdata, i, 1);  		} -		for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) { -			int ret; - +		at91_for_each_port(i) {  			if (!gpio_is_valid(pdata->overcurrent_pin[i]))  				continue; -			gpio_request(pdata->overcurrent_pin[i], "ohci_overcurrent"); +			gpio = pdata->overcurrent_pin[i]; + +			ret = gpio_request(gpio, "ohci_overcurrent"); +			if (ret) { +				dev_err(&pdev->dev, +					"can't request overcurrent gpio %d\n", +					gpio); +				continue; +			} + +			ret = gpio_direction_input(gpio); +			if (ret) { +				dev_err(&pdev->dev, +					"can't configure overcurrent gpio %d as input\n", +					gpio); +				gpio_free(gpio); +				continue; +			} -			ret = request_irq(gpio_to_irq(pdata->overcurrent_pin[i]), +			ret = request_irq(gpio_to_irq(gpio),  					  ohci_hcd_at91_overcurrent_irq,  					  IRQF_SHARED, "ohci_overcurrent", pdev);  			if (ret) { -				gpio_free(pdata->overcurrent_pin[i]); -				dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n"); +				gpio_free(gpio); +				dev_err(&pdev->dev, +					"can't get gpio IRQ for overcurrent\n");  			}  		}  	} @@ -611,20 +620,20 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)  	return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);  } -static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) +static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)  {  	struct at91_usbh_data	*pdata = pdev->dev.platform_data;  	int			i;  	if (pdata) { -		for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) { +		at91_for_each_port(i) {  			if (!gpio_is_valid(pdata->vbus_pin[i]))  				continue;  			ohci_at91_usb_set_power(pdata, i, 0);  			gpio_free(pdata->vbus_pin[i]);  		} -		for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) { +		at91_for_each_port(i) {  			if (!gpio_is_valid(pdata->overcurrent_pin[i]))  				continue;  			free_irq(gpio_to_irq(pdata->overcurrent_pin[i]), pdev); @@ -687,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci");  static struct platform_driver ohci_hcd_at91_driver = {  	.probe		= ohci_hcd_at91_drv_probe, -	.remove		= ohci_hcd_at91_drv_remove, +	.remove		= __devexit_p(ohci_hcd_at91_drv_remove),  	.shutdown	= usb_hcd_platform_shutdown,  	.suspend	= ohci_hcd_at91_drv_suspend,  	.resume		= ohci_hcd_at91_drv_resume, diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 11de5f1be98..32dada8c8b4 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -825,9 +825,13 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)  		}  	} -	/* Disable any BIOS SMIs */ -	writel(XHCI_LEGACY_DISABLE_SMI, -			base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); +	val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); +	/* Mask off (turn off) any enabled SMIs */ +	val &= XHCI_LEGACY_DISABLE_SMI; +	/* Mask all SMI events bits, RW1C */ +	val |= XHCI_LEGACY_SMI_EVENTS; +	/* Disable any BIOS SMIs and clear all SMI events*/ +	writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);  	if (usb_is_intel_switchable_xhci(pdev))  		usb_enable_xhci_ports(pdev); diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 045cde4cbc3..768d54295a2 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -196,11 +196,12 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)  	status = get_hub_status_data(uhci, buf);  	switch (uhci->rh_state) { -	    case UHCI_RH_SUSPENDING:  	    case UHCI_RH_SUSPENDED:  		/* if port change, ask to be resumed */ -		if (status || uhci->resuming_ports) +		if (status || uhci->resuming_ports) { +			status = 1;  			usb_hcd_resume_root_hub(hcd); +		}  		break;  	    case UHCI_RH_AUTO_STOPPED: diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index e9b0f043455..4b436f5a417 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -119,7 +119,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci)  	xhci_dbg(xhci, "  Event Interrupts %s\n",  			(temp & CMD_EIE) ? "enabled " : "disabled");  	xhci_dbg(xhci, "  Host System Error Interrupts %s\n", -			(temp & CMD_EIE) ? "enabled " : "disabled"); +			(temp & CMD_HSEIE) ? "enabled " : "disabled");  	xhci_dbg(xhci, "  HC has %sfinished light reset\n",  			(temp & CMD_LRESET) ? "not " : "");  } diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index c7f33123d4c..377f4242dab 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -62,8 +62,9 @@  /* USB Legacy Support Control and Status Register  - section 7.1.2 */  /* Add this offset, plus the value of xECP in HCCPARAMS to the base address */  #define XHCI_LEGACY_CONTROL_OFFSET	(0x04) -/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ -#define	XHCI_LEGACY_DISABLE_SMI		((0x3 << 1) + (0xff << 5) + (0x7 << 17)) +/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ +#define	XHCI_LEGACY_DISABLE_SMI		((0x7 << 1) + (0xff << 5) + (0x7 << 17)) +#define XHCI_LEGACY_SMI_EVENTS		(0x7 << 29)  /* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */  #define XHCI_L1C               (1 << 16) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index cae4c6f2845..68eaa908ac8 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1796,11 +1796,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)  	int i;  	/* Free the Event Ring Segment Table and the actual Event Ring */ -	if (xhci->ir_set) { -		xhci_writel(xhci, 0, &xhci->ir_set->erst_size); -		xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); -		xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); -	}  	size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);  	if (xhci->erst.entries)  		dma_free_coherent(&pdev->dev, size, @@ -1812,7 +1807,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)  	xhci->event_ring = NULL;  	xhci_dbg(xhci, "Freed event ring\n"); -	xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);  	if (xhci->cmd_ring)  		xhci_ring_free(xhci, xhci->cmd_ring);  	xhci->cmd_ring = NULL; @@ -1841,7 +1835,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)  	xhci->medium_streams_pool = NULL;  	xhci_dbg(xhci, "Freed medium stream array pool\n"); -	xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr);  	if (xhci->dcbaa)  		dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa),  				xhci->dcbaa, xhci->dcbaa->dma); @@ -2459,6 +2452,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)  fail:  	xhci_warn(xhci, "Couldn't initialize memory\n"); +	xhci_halt(xhci); +	xhci_reset(xhci);  	xhci_mem_cleanup(xhci);  	return -ENOMEM;  } diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index ef98b38626f..7a856a767e7 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -95,6 +95,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)  		xhci->quirks |= XHCI_RESET_ON_RESUME;  		xhci_dbg(xhci, "QUIRK: Resetting on resume\n");  	} +	if (pdev->vendor == PCI_VENDOR_ID_VIA) +		xhci->quirks |= XHCI_RESET_ON_RESUME;  }  /* called during probe() after chip reset completes */ @@ -326,7 +328,7 @@ int __init xhci_register_pci(void)  	return pci_register_driver(&xhci_pci_driver);  } -void __exit xhci_unregister_pci(void) +void xhci_unregister_pci(void)  {  	pci_unregister_driver(&xhci_pci_driver);  } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6bd9d53062e..3d9422f16a2 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2417,7 +2417,7 @@ hw_died:  		u32 irq_pending;  		/* Acknowledge the PCI interrupt */  		irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); -		irq_pending |= 0x3; +		irq_pending |= IMAN_IP;  		xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending);  	} @@ -2734,7 +2734,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,  				urb->dev->speed == USB_SPEED_FULL)  			urb->interval /= 8;  	} -	return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); +	return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index);  }  /* @@ -3514,7 +3514,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,  	}  	ep_ring->num_trbs_free_temp = ep_ring->num_trbs_free; -	return xhci_queue_isoc_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); +	return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index);  }  /****		Command Ring Operations		****/ diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e1963d4a430..36641a7f237 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -106,6 +106,9 @@ int xhci_halt(struct xhci_hcd *xhci)  			STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);  	if (!ret)  		xhci->xhc_state |= XHCI_STATE_HALTED; +	else +		xhci_warn(xhci, "Host not halted after %u microseconds.\n", +				XHCI_MAX_HALT_USEC);  	return ret;  } @@ -664,11 +667,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci)  	xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification);  	xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);  	xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg); -	xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); -	xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);  	xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size);  	xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base);  	xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); +	xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); +	xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);  }  static void xhci_restore_registers(struct xhci_hcd *xhci) @@ -677,10 +680,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)  	xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification);  	xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr);  	xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg); -	xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); -	xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);  	xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size);  	xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); +	xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); +	xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); +	xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);  }  static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 91074fdab3e..3d69c4b2b54 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -205,6 +205,10 @@ struct xhci_op_regs {  #define CMD_PM_INDEX	(1 << 11)  /* bits 12:31 are reserved (and should be preserved on writes). */ +/* IMAN - Interrupt Management Register */ +#define IMAN_IP		(1 << 1) +#define IMAN_IE		(1 << 0) +  /* USBSTS - USB status - status bitmasks */  /* HC not running - set to 1 when run/stop bit is cleared. */  #define STS_HALT	XHCI_STS_HALT diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 959145baf3c..9dcb68f04f0 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary)  	unsigned		i;  	unsigned		size = max; -	sg = kmalloc(nents * sizeof *sg, GFP_KERNEL); +	sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);  	if (!sg)  		return NULL;  	sg_init_table(sg, nents); @@ -904,6 +904,9 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)  	struct ctrl_ctx		context;  	int			i; +	if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen) +		return -EOPNOTSUPP; +  	spin_lock_init(&context.lock);  	context.dev = dev;  	init_completion(&context.complete); @@ -1981,8 +1984,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)  	/* queued control messaging */  	case 10: -		if (param->sglen == 0) -			break;  		retval = 0;  		dev_info(&intf->dev,  				"TEST 10:  queue %d control calls, %d times\n", @@ -2276,6 +2277,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)  			if (status < 0) {  				WARNING(dev, "couldn't get endpoints, %d\n",  						status); +				kfree(dev->buf); +				kfree(dev);  				return status;  			}  			/* may find bulk or ISO pipes */ diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 897edda4227..70201462e19 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -99,9 +99,7 @@ static void yurex_delete(struct kref *kref)  	usb_put_dev(dev->udev);  	if (dev->cntl_urb) {  		usb_kill_urb(dev->cntl_urb); -		if (dev->cntl_req) -			usb_free_coherent(dev->udev, YUREX_BUF_SIZE, -				dev->cntl_req, dev->cntl_urb->setup_dma); +		kfree(dev->cntl_req);  		if (dev->cntl_buffer)  			usb_free_coherent(dev->udev, YUREX_BUF_SIZE,  				dev->cntl_buffer, dev->cntl_urb->transfer_dma); @@ -234,9 +232,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_  	}  	/* allocate buffer for control req */ -	dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, -					   GFP_KERNEL, -					   &dev->cntl_urb->setup_dma); +	dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);  	if (!dev->cntl_req) {  		err("Could not allocate cntl_req");  		goto error; @@ -286,7 +282,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_  			 usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),  			 dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,  			 dev, 1); -	dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; +	dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;  	if (usb_submit_urb(dev->urb, GFP_KERNEL)) {  		retval = -EIO;  		err("Could not submitting URB"); diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 97ab975fa44..768b4b55c81 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -386,7 +386,7 @@ static int davinci_musb_init(struct musb *musb)  	usb_nop_xceiv_register();  	musb->xceiv = usb_get_transceiver();  	if (!musb->xceiv) -		return -ENODEV; +		goto unregister;  	musb->mregs += DAVINCI_BASE_OFFSET; @@ -444,6 +444,7 @@ static int davinci_musb_init(struct musb *musb)  fail:  	usb_put_transceiver(musb->xceiv); +unregister:  	usb_nop_xceiv_unregister();  	return -ENODEV;  } diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0f8b82918a4..66aaccf0449 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)  	int	i = 0;  	u8	r;  	u8	power; +	int	ret; + +	pm_runtime_get_sync(phy->io_dev);  	/* Make sure the transceiver is not in low power mode */  	power = musb_readb(addr, MUSB_POWER); @@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)  	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)  				& MUSB_ULPI_REG_CMPLT)) {  		i++; -		if (i == 10000) -			return -ETIMEDOUT; +		if (i == 10000) { +			ret = -ETIMEDOUT; +			goto out; +		}  	}  	r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);  	r &= ~MUSB_ULPI_REG_CMPLT;  	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); -	return musb_readb(addr, MUSB_ULPI_REG_DATA); +	ret = musb_readb(addr, MUSB_ULPI_REG_DATA); + +out: +	pm_runtime_put(phy->io_dev); + +	return ret;  }  static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) @@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)  	int	i = 0;  	u8	r = 0;  	u8	power; +	int	ret = 0; + +	pm_runtime_get_sync(phy->io_dev);  	/* Make sure the transceiver is not in low power mode */  	power = musb_readb(addr, MUSB_POWER); @@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)  	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)  				& MUSB_ULPI_REG_CMPLT)) {  		i++; -		if (i == 10000) -			return -ETIMEDOUT; +		if (i == 10000) { +			ret = -ETIMEDOUT; +			goto out; +		}  	}  	r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);  	r &= ~MUSB_ULPI_REG_CMPLT;  	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); -	return 0; +out: +	pm_runtime_put(phy->io_dev); + +	return ret;  }  #else  #define musb_ulpi_read		NULL @@ -1904,14 +1922,17 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)  	if (!musb->isr) {  		status = -ENODEV; -		goto fail3; +		goto fail2;  	}  	if (!musb->xceiv->io_ops) { +		musb->xceiv->io_dev = musb->controller;  		musb->xceiv->io_priv = musb->mregs;  		musb->xceiv->io_ops = &musb_ulpi_access;  	} +	pm_runtime_get_sync(musb->controller); +  #ifndef CONFIG_MUSB_PIO_ONLY  	if (use_dma && dev->dma_mask) {  		struct dma_controller	*c; @@ -2023,6 +2044,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)  		goto fail5;  #endif +	pm_runtime_put(musb->controller); +  	dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",  			({char *s;  			 switch (musb->board_mode) { @@ -2047,6 +2070,9 @@ fail4:  		musb_gadget_cleanup(musb);  fail3: +	pm_runtime_put_sync(musb->controller); + +fail2:  	if (musb->irq_wake)  		device_init_wakeup(dev, 0);  	musb_platform_exit(musb); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 93de517a32a..f4a40f001c8 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -449,7 +449,7 @@ struct musb {  	 * We added this flag to forcefully disable double  	 * buffering until we get it working.  	 */ -	unsigned                double_buffer_not_ok:1 __deprecated; +	unsigned                double_buffer_not_ok:1;  	struct musb_hdrc_config	*config; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 79cb0af779f..ef8d744800a 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)  	}  	/* turn off DMA requests, discard state, stop polling ... */ -	if (is_in) { +	if (ep->epnum && is_in) {  		/* giveback saves bulk toggle */  		csr = musb_h_flush_rxfifo(ep, 0); diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2ae0bb30999..c7785e81254 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)  static int omap2430_musb_init(struct musb *musb)  { -	u32 l, status = 0; +	u32 l; +	int status = 0;  	struct device *dev = musb->controller;  	struct musb_hdrc_platform_data *plat = dev->platform_data;  	struct omap_musb_board_data *data = plat->board_data; @@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb)  	status = pm_runtime_get_sync(dev);  	if (status < 0) { -		dev_err(dev, "pm_runtime_get_sync FAILED"); +		dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);  		goto err1;  	} @@ -333,6 +334,7 @@ static int omap2430_musb_init(struct musb *musb)  	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); +	pm_runtime_put_noidle(musb->controller);  	return 0;  err1: @@ -452,14 +454,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev)  		goto err2;  	} +	pm_runtime_enable(&pdev->dev); +  	ret = platform_device_add(musb);  	if (ret) {  		dev_err(&pdev->dev, "failed to register musb device\n");  		goto err2;  	} -	pm_runtime_enable(&pdev->dev); -  	return 0;  err2: @@ -478,7 +480,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev)  	platform_device_del(glue->musb);  	platform_device_put(glue->musb); -	pm_runtime_put(&pdev->dev);  	kfree(glue);  	return 0; @@ -491,11 +492,13 @@ static int omap2430_runtime_suspend(struct device *dev)  	struct omap2430_glue		*glue = dev_get_drvdata(dev);  	struct musb			*musb = glue_to_musb(glue); -	musb->context.otg_interfsel = musb_readl(musb->mregs, -						OTG_INTERFSEL); +	if (musb) { +		musb->context.otg_interfsel = musb_readl(musb->mregs, +				OTG_INTERFSEL); -	omap2430_low_level_exit(musb); -	usb_phy_set_suspend(musb->xceiv, 1); +		omap2430_low_level_exit(musb); +		usb_phy_set_suspend(musb->xceiv, 1); +	}  	return 0;  } @@ -505,11 +508,13 @@ static int omap2430_runtime_resume(struct device *dev)  	struct omap2430_glue		*glue = dev_get_drvdata(dev);  	struct musb			*musb = glue_to_musb(glue); -	omap2430_low_level_init(musb); -	musb_writel(musb->mregs, OTG_INTERFSEL, -					musb->context.otg_interfsel); +	if (musb) { +		omap2430_low_level_init(musb); +		musb_writel(musb->mregs, OTG_INTERFSEL, +				musb->context.otg_interfsel); -	usb_phy_set_suspend(musb->xceiv, 0); +		usb_phy_set_suspend(musb->xceiv, 0); +	}  	return 0;  } diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 3ece43a2e4c..a0a2178974f 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c @@ -96,7 +96,7 @@ static void gpio_vbus_work(struct work_struct *work)  	struct gpio_vbus_data *gpio_vbus =  		container_of(work, struct gpio_vbus_data, work);  	struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; -	int gpio; +	int gpio, status;  	if (!gpio_vbus->phy.otg->gadget)  		return; @@ -108,7 +108,9 @@ static void gpio_vbus_work(struct work_struct *work)  	 */  	gpio = pdata->gpio_pullup;  	if (is_vbus_powered(pdata)) { +		status = USB_EVENT_VBUS;  		gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; +		gpio_vbus->phy.last_event = status;  		usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget);  		/* drawing a "unit load" is *always* OK, except for OTG */ @@ -117,6 +119,9 @@ static void gpio_vbus_work(struct work_struct *work)  		/* optionally enable D+ pullup */  		if (gpio_is_valid(gpio))  			gpio_set_value(gpio, !pdata->gpio_pullup_inverted); + +		atomic_notifier_call_chain(&gpio_vbus->phy.notifier, +					   status, gpio_vbus->phy.otg->gadget);  	} else {  		/* optionally disable D+ pullup */  		if (gpio_is_valid(gpio)) @@ -125,7 +130,12 @@ static void gpio_vbus_work(struct work_struct *work)  		set_vbus_draw(gpio_vbus, 0);  		usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); +		status = USB_EVENT_NONE;  		gpio_vbus->phy.state = OTG_STATE_B_IDLE; +		gpio_vbus->phy.last_event = status; + +		atomic_notifier_call_chain(&gpio_vbus->phy.notifier, +					   status, gpio_vbus->phy.otg->gadget);  	}  } @@ -287,6 +297,9 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)  			irq, err);  		goto err_irq;  	} + +	ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); +  	INIT_WORK(&gpio_vbus->work, gpio_vbus_work);  	gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 7f547dc3a59..ed8adb052ca 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -60,8 +60,6 @@ static int usb_serial_device_probe(struct device *dev)  		retval = -ENODEV;  		goto exit;  	} -	if (port->dev_state != PORT_REGISTERING) -		goto exit;  	driver = port->serial->type;  	if (driver->port_probe) { @@ -98,9 +96,6 @@ static int usb_serial_device_remove(struct device *dev)  	if (!port)  		return -ENODEV; -	if (port->dev_state != PORT_UNREGISTERING) -		return retval; -  	device_remove_file(&port->dev, &dev_attr_port_number);  	driver = port->serial->type; diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 0310e2df59f..ec30f95ef39 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -287,7 +287,8 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,  	/* Issue the request, attempting to read 'size' bytes */  	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),  				request, REQTYPE_DEVICE_TO_HOST, 0x0000, -				port_priv->bInterfaceNumber, buf, size, 300); +				port_priv->bInterfaceNumber, buf, size, +				USB_CTRL_GET_TIMEOUT);  	/* Convert data into an array of integers */  	for (i = 0; i < length; i++) @@ -340,12 +341,14 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,  		result = usb_control_msg(serial->dev,  				usb_sndctrlpipe(serial->dev, 0),  				request, REQTYPE_HOST_TO_DEVICE, 0x0000, -				port_priv->bInterfaceNumber, buf, size, 300); +				port_priv->bInterfaceNumber, buf, size, +				USB_CTRL_SET_TIMEOUT);  	} else {  		result = usb_control_msg(serial->dev,  				usb_sndctrlpipe(serial->dev, 0),  				request, REQTYPE_HOST_TO_DEVICE, data[0], -				port_priv->bInterfaceNumber, NULL, 0, 300); +				port_priv->bInterfaceNumber, NULL, 0, +				USB_CTRL_SET_TIMEOUT);  	}  	kfree(buf); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ff8605b4b4b..02e7f2d32d5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -75,7 +75,8 @@ struct ftdi_private {  	unsigned long last_dtr_rts;	/* saved modem control outputs */  	struct async_icount	icount;  	wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ -	char prev_status, diff_status;        /* Used for TIOCMIWAIT */ +	char prev_status;        /* Used for TIOCMIWAIT */ +	bool dev_gone;        /* Used to abort TIOCMIWAIT */  	char transmit_empty;	/* If transmitter is empty or not */  	struct usb_serial_port *port;  	__u16 interface;	/* FT2232C, FT2232H or FT4232H port interface @@ -1681,6 +1682,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)  	init_waitqueue_head(&priv->delta_msr_wait);  	priv->flags = ASYNC_LOW_LATENCY; +	priv->dev_gone = false;  	if (quirk && quirk->port_probe)  		quirk->port_probe(priv); @@ -1839,6 +1841,9 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)  	dbg("%s", __func__); +	priv->dev_gone = true; +	wake_up_interruptible_all(&priv->delta_msr_wait); +  	remove_sysfs_attrs(port);  	kref_put(&priv->kref, ftdi_sio_priv_release); @@ -1982,17 +1987,19 @@ static int ftdi_process_packet(struct tty_struct *tty,  	   N.B. packet may be processed more than once, but differences  	   are only processed once.  */  	status = packet[0] & FTDI_STATUS_B0_MASK; -	if (status & FTDI_RS0_CTS) -		priv->icount.cts++; -	if (status & FTDI_RS0_DSR) -		priv->icount.dsr++; -	if (status & FTDI_RS0_RI) -		priv->icount.rng++; -	if (status & FTDI_RS0_RLSD) -		priv->icount.dcd++;  	if (status != priv->prev_status) { -		priv->diff_status |= status ^ priv->prev_status; -		wake_up_interruptible(&priv->delta_msr_wait); +		char diff_status = status ^ priv->prev_status; + +		if (diff_status & FTDI_RS0_CTS) +			priv->icount.cts++; +		if (diff_status & FTDI_RS0_DSR) +			priv->icount.dsr++; +		if (diff_status & FTDI_RS0_RI) +			priv->icount.rng++; +		if (diff_status & FTDI_RS0_RLSD) +			priv->icount.dcd++; + +		wake_up_interruptible_all(&priv->delta_msr_wait);  		priv->prev_status = status;  	} @@ -2395,15 +2402,12 @@ static int ftdi_ioctl(struct tty_struct *tty,  	 */  	case TIOCMIWAIT:  		cprev = priv->icount; -		while (1) { +		while (!priv->dev_gone) {  			interruptible_sleep_on(&priv->delta_msr_wait);  			/* see if a signal did it */  			if (signal_pending(current))  				return -ERESTARTSYS;  			cnow = priv->icount; -			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && -			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) -				return -EIO; /* no change => error */  			if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||  			    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||  			    ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) || @@ -2412,7 +2416,7 @@ static int ftdi_ioctl(struct tty_struct *tty,  			}  			cprev = cnow;  		} -		/* not reached */ +		return -EIO;  		break;  	case TIOCSERGETLSR:  		return get_lsr_info(port, (struct serial_struct __user *)arg); diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 6e1622f2a29..08d16e8c002 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -27,8 +27,8 @@  /* Product information. */  #define FOCUS_VENDOR_ID			0x0C2E -#define FOCUS_PRODUCT_ID		0x0720 -#define FOCUS_PRODUCT_ID_UNI		0x0710 +#define FOCUS_PRODUCT_ID_BI		0x0720 +#define FOCUS_PRODUCT_ID_UNI		0x0700  #define METROUSB_SET_REQUEST_TYPE	0x40  #define METROUSB_SET_MODEM_CTRL_REQUEST	10 @@ -47,7 +47,7 @@ struct metrousb_private {  /* Device table list. */  static struct usb_device_id id_table[] = { -	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID) }, +	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) },  	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) },  	{ }, /* Terminating entry. */  }; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 836cfa9a515..f4465ccddc3 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -708,6 +708,7 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) },  	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) },  	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, +	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) },  	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) },  	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) },  	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) }, diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ff4a174fa5d..a1a9062954c 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -420,7 +420,7 @@ static void pl2303_set_termios(struct tty_struct *tty,  	control = priv->line_control;  	if ((cflag & CBAUD) == B0)  		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); -	else +	else if ((old_termios->c_cflag & CBAUD) == B0)  		priv->line_control |= (CONTROL_DTR | CONTROL_RTS);  	if (control != priv->line_control) {  		control = priv->line_control; diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index f14465a83dd..8c8bf806f6f 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = {  };  /* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; +static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };  static const struct sierra_iface_info direct_ip_interface_blacklist = {  	.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),  	.ifaceinfo = direct_ip_non_serial_ifaces, @@ -298,6 +298,9 @@ static const struct usb_device_id id_table[] = {  	/* Sierra Wireless HSPA Non-Composite Device */  	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},  	{ USB_DEVICE(0x1199, 0x6893) },	/* Sierra Wireless Device */ +	{ USB_DEVICE(0x1199, 0x68A2),   /* Sierra Wireless MC77xx in QMI mode */ +	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist +	},  	{ USB_DEVICE(0x1199, 0x68A3), 	/* Sierra Wireless Direct IP modems */  	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist  	}, diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 69230f01056..97355a15bbe 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1059,6 +1059,12 @@ int usb_serial_probe(struct usb_interface *interface,  		serial->attached = 1;  	} +	/* Avoid race with tty_open and serial_install by setting the +	 * disconnected flag and not clearing it until all ports have been +	 * registered. +	 */ +	serial->disconnected = 1; +  	if (get_free_serial(serial, num_ports, &minor) == NULL) {  		dev_err(&interface->dev, "No more free serial devices\n");  		goto probe_error; @@ -1070,19 +1076,16 @@ int usb_serial_probe(struct usb_interface *interface,  		port = serial->port[i];  		dev_set_name(&port->dev, "ttyUSB%d", port->number);  		dbg ("%s - registering %s", __func__, dev_name(&port->dev)); -		port->dev_state = PORT_REGISTERING;  		device_enable_async_suspend(&port->dev);  		retval = device_add(&port->dev); -		if (retval) { +		if (retval)  			dev_err(&port->dev, "Error registering port device, "  				"continuing\n"); -			port->dev_state = PORT_UNREGISTERED; -		} else { -			port->dev_state = PORT_REGISTERED; -		}  	} +	serial->disconnected = 0; +  	usb_serial_console_init(debug, minor);  exit: @@ -1124,22 +1127,8 @@ void usb_serial_disconnect(struct usb_interface *interface)  			}  			kill_traffic(port);  			cancel_work_sync(&port->work); -			if (port->dev_state == PORT_REGISTERED) { - -				/* Make sure the port is bound so that the -				 * driver's port_remove method is called. -				 */ -				if (!port->dev.driver) { -					int rc; - -					port->dev.driver = -							&serial->type->driver; -					rc = device_bind_driver(&port->dev); -				} -				port->dev_state = PORT_UNREGISTERING; +			if (device_is_registered(&port->dev))  				device_del(&port->dev); -				port->dev_state = PORT_UNREGISTERED; -			}  		}  	}  	serial->type->disconnect(serial); diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index c18538e4a6d..2653e73db62 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -132,6 +132,35 @@ static struct us_unusual_dev for_dynamic_ids =  #undef COMPLIANT_DEV  #undef USUAL_DEV +#ifdef CONFIG_LOCKDEP + +static struct lock_class_key us_interface_key[USB_MAXINTERFACES]; + +static void us_set_lock_class(struct mutex *mutex, +		struct usb_interface *intf) +{ +	struct usb_device *udev = interface_to_usbdev(intf); +	struct usb_host_config *config = udev->actconfig; +	int i; + +	for (i = 0; i < config->desc.bNumInterfaces; i++) { +		if (config->interface[i] == intf) +			break; +	} + +	BUG_ON(i == config->desc.bNumInterfaces); + +	lockdep_set_class(mutex, &us_interface_key[i]); +} + +#else + +static void us_set_lock_class(struct mutex *mutex, +		struct usb_interface *intf) +{ +} + +#endif  #ifdef CONFIG_PM	/* Minimal support for suspend and resume */ @@ -895,6 +924,7 @@ int usb_stor_probe1(struct us_data **pus,  	*pus = us = host_to_us(host);  	memset(us, 0, sizeof(struct us_data));  	mutex_init(&(us->dev_mutex)); +	us_set_lock_class(&us->dev_mutex, intf);  	init_completion(&us->cmnd_ready);  	init_completion(&(us->notify));  	init_waitqueue_head(&us->delay_wait);  |