瀏覽代碼

Merge tag 'fixes-for-v3.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus

usb: fixes for v3.4-rc cycle

A few more fixes for v3.4-rc cycle.

It includes a couple of fixes to the ordering of the methods in udc-core.c.
Without these two patches, we will have issues when either unregistering a
gadget driver (triggered with dummy_hcd only) or issuing a device-initiated
disconnect through sysfs.

There's also a fix on dummy_hcd to not call ->pullup() from udc_stop() because
udc-core.c already handles that.

A fix to MUSB as promised, to kill the compile warnings regarding deprecated
interfaces. We are essentially dropping the __deprecated flag because it
doesn't look like we will ever be able to live without it when we consider the
amount of silicon issues we find on different MUSB instantiations.

A couple of other fixes are also available, one adding the missing transceiver
events to gpio_vbus and another adding a missing unregister call to MUSB's
davinci glue layer.
Greg Kroah-Hartman 13 年之前
父節點
當前提交
41c8a48aa8

+ 0 - 1
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;
 }
 

+ 1 - 1
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;

+ 1 - 1
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;
 		}

+ 2 - 2
drivers/usb/gadget/udc-core.c

@@ -263,8 +263,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
 
 	if (udc_is_newstyle(udc)) {
 		udc->driver->disconnect(udc->gadget);
-		udc->driver->unbind(udc->gadget);
 		usb_gadget_disconnect(udc->gadget);
+		udc->driver->unbind(udc->gadget);
 		usb_gadget_udc_stop(udc->gadget, udc->driver);
 	} else {
 		usb_gadget_stop(udc->gadget, udc->driver);
@@ -415,9 +415,9 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
 			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);
-		usb_gadget_disconnect(udc->gadget);
 	} else {
 		dev_err(dev, "unsupported command '%s'\n", buf);
 		return -EINVAL;

+ 2 - 1
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;
 }

+ 1 - 1
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;
 

+ 14 - 1
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");