Commit e04a0a5a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-3.12-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are a number of small USB fixes for 3.12-rc2.

  One is a revert of a EHCI change that isn't quite ready for 3.12.
  Others are minor things, gadget fixes, Kconfig fixes, and some quirks
  and documentation updates.

  All have been in linux-next for a bit"

* tag 'usb-3.12-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: pl2303: distinguish between original and cloned HX chips
  USB: Faraday fotg210: fix email addresses
  USB: fix typo in usb serial simple driver Kconfig
  Revert "USB: EHCI: support running URB giveback in tasklet context"
  usb: s3c-hsotg: do not disconnect gadget when receiving ErlySusp intr
  usb: s3c-hsotg: fix unregistration function
  usb: gadget: f_mass_storage: reset endpoint driver data when disabled
  usb: host: fsl-mph-dr-of: Staticize local symbols
  usb: gadget: f_eem: Staticize eem_alloc
  usb: gadget: f_ecm: Staticize ecm_alloc
  usb: phy: omap-usb3: Fix return value
  usb: dwc3: gadget: avoid memory leak when failing to allocate all eps
  usb: dwc3: remove extcon dependency
  usb: gadget: add '__ref' for rndis_config_register() and cdc_config_register()
  usb: dwc3: pci: add support for BayTrail
  usb: gadget: cdc2: fix conversion to new interface of f_ecm
  usb: gadget: fix a bug and a WARN_ON in dummy-hcd
  usb: gadget: mv_u3d_core: fix violation of locking discipline in mv_u3d_ep_disable()
parents d8524ae9 42f4891c
config USB_DWC3 config USB_DWC3
tristate "DesignWare USB3 DRD Core Support" tristate "DesignWare USB3 DRD Core Support"
depends on (USB || USB_GADGET) && HAS_DMA depends on (USB || USB_GADGET) && HAS_DMA
depends on EXTCON
select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
help help
Say Y or M here if your system has a Dual Role SuperSpeed Say Y or M here if your system has a Dual Role SuperSpeed
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
/* FIXME define these in <linux/pci_ids.h> */ /* FIXME define these in <linux/pci_ids.h> */
#define PCI_VENDOR_ID_SYNOPSYS 0x16c3 #define PCI_VENDOR_ID_SYNOPSYS 0x16c3
#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd
#define PCI_DEVICE_ID_INTEL_BYT 0x0f37
struct dwc3_pci { struct dwc3_pci {
struct device *dev; struct device *dev;
...@@ -187,6 +188,7 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = { ...@@ -187,6 +188,7 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = {
PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
}, },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
{ } /* Terminating Entry */ { } /* Terminating Entry */
}; };
MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);
......
...@@ -2611,15 +2611,13 @@ int dwc3_gadget_init(struct dwc3 *dwc) ...@@ -2611,15 +2611,13 @@ int dwc3_gadget_init(struct dwc3 *dwc)
ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
if (ret) { if (ret) {
dev_err(dwc->dev, "failed to register udc\n"); dev_err(dwc->dev, "failed to register udc\n");
goto err5; goto err4;
} }
return 0; return 0;
err5:
dwc3_gadget_free_endpoints(dwc);
err4: err4:
dwc3_gadget_free_endpoints(dwc);
dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE, dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
dwc->ep0_bounce, dwc->ep0_bounce_addr); dwc->ep0_bounce, dwc->ep0_bounce_addr);
......
...@@ -113,12 +113,6 @@ static int __init cdc_do_config(struct usb_configuration *c) ...@@ -113,12 +113,6 @@ static int __init cdc_do_config(struct usb_configuration *c)
c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
} }
fi_ecm = usb_get_function_instance("ecm");
if (IS_ERR(fi_ecm)) {
status = PTR_ERR(fi_ecm);
goto err_func_ecm;
}
f_ecm = usb_get_function(fi_ecm); f_ecm = usb_get_function(fi_ecm);
if (IS_ERR(f_ecm)) { if (IS_ERR(f_ecm)) {
status = PTR_ERR(f_ecm); status = PTR_ERR(f_ecm);
...@@ -129,35 +123,24 @@ static int __init cdc_do_config(struct usb_configuration *c) ...@@ -129,35 +123,24 @@ static int __init cdc_do_config(struct usb_configuration *c)
if (status) if (status)
goto err_add_ecm; goto err_add_ecm;
fi_serial = usb_get_function_instance("acm");
if (IS_ERR(fi_serial)) {
status = PTR_ERR(fi_serial);
goto err_get_acm;
}
f_acm = usb_get_function(fi_serial); f_acm = usb_get_function(fi_serial);
if (IS_ERR(f_acm)) { if (IS_ERR(f_acm)) {
status = PTR_ERR(f_acm); status = PTR_ERR(f_acm);
goto err_func_acm; goto err_get_acm;
} }
status = usb_add_function(c, f_acm); status = usb_add_function(c, f_acm);
if (status) if (status)
goto err_add_acm; goto err_add_acm;
return 0; return 0;
err_add_acm: err_add_acm:
usb_put_function(f_acm); usb_put_function(f_acm);
err_func_acm:
usb_put_function_instance(fi_serial);
err_get_acm: err_get_acm:
usb_remove_function(c, f_ecm); usb_remove_function(c, f_ecm);
err_add_ecm: err_add_ecm:
usb_put_function(f_ecm); usb_put_function(f_ecm);
err_get_ecm: err_get_ecm:
usb_put_function_instance(fi_ecm);
err_func_ecm:
return status; return status;
} }
......
...@@ -923,8 +923,9 @@ static int dummy_udc_stop(struct usb_gadget *g, ...@@ -923,8 +923,9 @@ static int dummy_udc_stop(struct usb_gadget *g,
struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g);
struct dummy *dum = dum_hcd->dum; struct dummy *dum = dum_hcd->dum;
dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", if (driver)
driver->driver.name); dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n",
driver->driver.name);
dum->driver = NULL; dum->driver = NULL;
...@@ -1000,8 +1001,8 @@ static int dummy_udc_remove(struct platform_device *pdev) ...@@ -1000,8 +1001,8 @@ static int dummy_udc_remove(struct platform_device *pdev)
{ {
struct dummy *dum = platform_get_drvdata(pdev); struct dummy *dum = platform_get_drvdata(pdev);
usb_del_gadget_udc(&dum->gadget);
device_remove_file(&dum->gadget.dev, &dev_attr_function); device_remove_file(&dum->gadget.dev, &dev_attr_function);
usb_del_gadget_udc(&dum->gadget);
return 0; return 0;
} }
......
...@@ -995,7 +995,7 @@ static void ecm_unbind(struct usb_configuration *c, struct usb_function *f) ...@@ -995,7 +995,7 @@ static void ecm_unbind(struct usb_configuration *c, struct usb_function *f)
usb_ep_free_request(ecm->notify, ecm->notify_req); usb_ep_free_request(ecm->notify, ecm->notify_req);
} }
struct usb_function *ecm_alloc(struct usb_function_instance *fi) static struct usb_function *ecm_alloc(struct usb_function_instance *fi)
{ {
struct f_ecm *ecm; struct f_ecm *ecm;
struct f_ecm_opts *opts; struct f_ecm_opts *opts;
......
...@@ -624,7 +624,7 @@ static void eem_unbind(struct usb_configuration *c, struct usb_function *f) ...@@ -624,7 +624,7 @@ static void eem_unbind(struct usb_configuration *c, struct usb_function *f)
usb_free_all_descriptors(f); usb_free_all_descriptors(f);
} }
struct usb_function *eem_alloc(struct usb_function_instance *fi) static struct usb_function *eem_alloc(struct usb_function_instance *fi)
{ {
struct f_eem *eem; struct f_eem *eem;
struct f_eem_opts *opts; struct f_eem_opts *opts;
......
...@@ -2260,10 +2260,12 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) ...@@ -2260,10 +2260,12 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
/* Disable the endpoints */ /* Disable the endpoints */
if (fsg->bulk_in_enabled) { if (fsg->bulk_in_enabled) {
usb_ep_disable(fsg->bulk_in); usb_ep_disable(fsg->bulk_in);
fsg->bulk_in->driver_data = NULL;
fsg->bulk_in_enabled = 0; fsg->bulk_in_enabled = 0;
} }
if (fsg->bulk_out_enabled) { if (fsg->bulk_out_enabled) {
usb_ep_disable(fsg->bulk_out); usb_ep_disable(fsg->bulk_out);
fsg->bulk_out->driver_data = NULL;
fsg->bulk_out_enabled = 0; fsg->bulk_out_enabled = 0;
} }
......
...@@ -1214,6 +1214,6 @@ static struct platform_driver fotg210_driver = { ...@@ -1214,6 +1214,6 @@ static struct platform_driver fotg210_driver = {
module_platform_driver(fotg210_driver); module_platform_driver(fotg210_driver);
MODULE_AUTHOR("Yuan-Hsin Chen <yhchen@faraday-tech.com>"); MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(DRIVER_DESC); MODULE_DESCRIPTION(DRIVER_DESC);
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
MODULE_DESCRIPTION("FUSB300 USB gadget driver"); MODULE_DESCRIPTION("FUSB300 USB gadget driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yuan Hsin Chen <yhchen@faraday-tech.com>"); MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>");
MODULE_ALIAS("platform:fusb300_udc"); MODULE_ALIAS("platform:fusb300_udc");
#define DRIVER_VERSION "20 October 2010" #define DRIVER_VERSION "20 October 2010"
......
...@@ -179,7 +179,7 @@ static __init int rndis_do_config(struct usb_configuration *c) ...@@ -179,7 +179,7 @@ static __init int rndis_do_config(struct usb_configuration *c)
return ret; return ret;
} }
static int rndis_config_register(struct usb_composite_dev *cdev) static __ref int rndis_config_register(struct usb_composite_dev *cdev)
{ {
static struct usb_configuration config = { static struct usb_configuration config = {
.bConfigurationValue = MULTI_RNDIS_CONFIG_NUM, .bConfigurationValue = MULTI_RNDIS_CONFIG_NUM,
...@@ -194,7 +194,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev) ...@@ -194,7 +194,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev)
#else #else
static int rndis_config_register(struct usb_composite_dev *cdev) static __ref int rndis_config_register(struct usb_composite_dev *cdev)
{ {
return 0; return 0;
} }
...@@ -241,7 +241,7 @@ static __init int cdc_do_config(struct usb_configuration *c) ...@@ -241,7 +241,7 @@ static __init int cdc_do_config(struct usb_configuration *c)
return ret; return ret;
} }
static int cdc_config_register(struct usb_composite_dev *cdev) static __ref int cdc_config_register(struct usb_composite_dev *cdev)
{ {
static struct usb_configuration config = { static struct usb_configuration config = {
.bConfigurationValue = MULTI_CDC_CONFIG_NUM, .bConfigurationValue = MULTI_CDC_CONFIG_NUM,
...@@ -256,7 +256,7 @@ static int cdc_config_register(struct usb_composite_dev *cdev) ...@@ -256,7 +256,7 @@ static int cdc_config_register(struct usb_composite_dev *cdev)
#else #else
static int cdc_config_register(struct usb_composite_dev *cdev) static __ref int cdc_config_register(struct usb_composite_dev *cdev)
{ {
return 0; return 0;
} }
......
...@@ -645,6 +645,7 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep) ...@@ -645,6 +645,7 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep)
struct mv_u3d_ep *ep; struct mv_u3d_ep *ep;
struct mv_u3d_ep_context *ep_context; struct mv_u3d_ep_context *ep_context;
u32 epxcr, direction; u32 epxcr, direction;
unsigned long flags;
if (!_ep) if (!_ep)
return -EINVAL; return -EINVAL;
...@@ -661,7 +662,9 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep) ...@@ -661,7 +662,9 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep)
direction = mv_u3d_ep_dir(ep); direction = mv_u3d_ep_dir(ep);
/* nuke all pending requests (does flush) */ /* nuke all pending requests (does flush) */
spin_lock_irqsave(&u3d->lock, flags);
mv_u3d_nuke(ep, -ESHUTDOWN); mv_u3d_nuke(ep, -ESHUTDOWN);
spin_unlock_irqrestore(&u3d->lock, flags);
/* Disable the endpoint for Rx or Tx and reset the endpoint type */ /* Disable the endpoint for Rx or Tx and reset the endpoint type */
if (direction == MV_U3D_EP_DIR_OUT) { if (direction == MV_U3D_EP_DIR_OUT) {
......
...@@ -2475,8 +2475,6 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) ...@@ -2475,8 +2475,6 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
if (gintsts & GINTSTS_ErlySusp) { if (gintsts & GINTSTS_ErlySusp) {
dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n"); dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n");
writel(GINTSTS_ErlySusp, hsotg->regs + GINTSTS); writel(GINTSTS_ErlySusp, hsotg->regs + GINTSTS);
s3c_hsotg_disconnect(hsotg);
} }
/* /*
...@@ -2962,9 +2960,6 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, ...@@ -2962,9 +2960,6 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
if (!hsotg) if (!hsotg)
return -ENODEV; return -ENODEV;
if (!driver || driver != hsotg->driver || !driver->unbind)
return -EINVAL;
/* all endpoints should be shutdown */ /* all endpoints should be shutdown */
for (ep = 0; ep < hsotg->num_of_eps; ep++) for (ep = 0; ep < hsotg->num_of_eps; ep++)
s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); s3c_hsotg_ep_disable(&hsotg->eps[ep].ep);
...@@ -2972,15 +2967,15 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, ...@@ -2972,15 +2967,15 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
spin_lock_irqsave(&hsotg->lock, flags); spin_lock_irqsave(&hsotg->lock, flags);
s3c_hsotg_phy_disable(hsotg); s3c_hsotg_phy_disable(hsotg);
regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
hsotg->driver = NULL; if (!driver)
hsotg->driver = NULL;
hsotg->gadget.speed = USB_SPEED_UNKNOWN; hsotg->gadget.speed = USB_SPEED_UNKNOWN;
spin_unlock_irqrestore(&hsotg->lock, flags); spin_unlock_irqrestore(&hsotg->lock, flags);
dev_info(hsotg->dev, "unregistered gadget driver '%s'\n", regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
driver->driver.name);
return 0; return 0;
} }
......
...@@ -669,7 +669,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { ...@@ -669,7 +669,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_USB2 | HCD_MEMORY | HCD_BH, .flags = HCD_USB2 | HCD_MEMORY,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -43,7 +43,7 @@ static const struct hc_driver ehci_grlib_hc_driver = { ...@@ -43,7 +43,7 @@ static const struct hc_driver ehci_grlib_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -1158,7 +1158,7 @@ static const struct hc_driver ehci_hc_driver = { ...@@ -1158,7 +1158,7 @@ static const struct hc_driver ehci_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -96,7 +96,7 @@ static const struct hc_driver mv_ehci_hc_driver = { ...@@ -96,7 +96,7 @@ static const struct hc_driver mv_ehci_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -51,7 +51,7 @@ static const struct hc_driver ehci_octeon_hc_driver = { ...@@ -51,7 +51,7 @@ static const struct hc_driver ehci_octeon_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -286,7 +286,7 @@ static const struct hc_driver ehci_msp_hc_driver = { ...@@ -286,7 +286,7 @@ static const struct hc_driver ehci_msp_hc_driver = {
#else #else
.irq = ehci_irq, .irq = ehci_irq,
#endif #endif
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -28,7 +28,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { ...@@ -28,7 +28,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -71,7 +71,7 @@ static const struct hc_driver ps3_ehci_hc_driver = { ...@@ -71,7 +71,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
.product_desc = "PS3 EHCI Host Controller", .product_desc = "PS3 EHCI Host Controller",
.hcd_priv_size = sizeof(struct ehci_hcd), .hcd_priv_size = sizeof(struct ehci_hcd),
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
.reset = ps3_ehci_hc_reset, .reset = ps3_ehci_hc_reset,
.start = ehci_run, .start = ehci_run,
.stop = ehci_stop, .stop = ehci_stop,
......
...@@ -247,6 +247,8 @@ static int qtd_copy_status ( ...@@ -247,6 +247,8 @@ static int qtd_copy_status (
static void static void
ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status) ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status)
__releases(ehci->lock)
__acquires(ehci->lock)
{ {
if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
/* ... update hc-wide periodic stats */ /* ... update hc-wide periodic stats */
...@@ -272,8 +274,11 @@ ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status) ...@@ -272,8 +274,11 @@ ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status)
urb->actual_length, urb->transfer_buffer_length); urb->actual_length, urb->transfer_buffer_length);
#endif #endif
/* complete() can reenter this HCD */
usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
spin_unlock (&ehci->lock);
usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status); usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status);
spin_lock (&ehci->lock);
} }
static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh); static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
......
...@@ -55,7 +55,7 @@ const struct hc_driver ehci_sead3_hc_driver = { ...@@ -55,7 +55,7 @@ const struct hc_driver ehci_sead3_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -36,7 +36,7 @@ static const struct hc_driver ehci_sh_hc_driver = { ...@@ -36,7 +36,7 @@ static const struct hc_driver ehci_sh_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_USB2 | HCD_MEMORY | HCD_BH, .flags = HCD_USB2 | HCD_MEMORY,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -61,7 +61,7 @@ static const struct hc_driver ehci_tilegx_hc_driver = { ...@@ -61,7 +61,7 @@ static const struct hc_driver ehci_tilegx_hc_driver = {
* Generic hardware linkage. * Generic hardware linkage.
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
/* /*
* Basic lifecycle operations. * Basic lifecycle operations.
......
...@@ -108,7 +108,7 @@ static const struct hc_driver ehci_w90x900_hc_driver = { ...@@ -108,7 +108,7 @@ static const struct hc_driver ehci_w90x900_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_USB2|HCD_MEMORY|HCD_BH, .flags = HCD_USB2|HCD_MEMORY,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -79,7 +79,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = { ...@@ -79,7 +79,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = {
* generic hardware linkage * generic hardware linkage
*/ */
.irq = ehci_irq, .irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .flags = HCD_MEMORY | HCD_USB2,
/* /*
* basic lifecycle operations * basic lifecycle operations
......
...@@ -24,7 +24,7 @@ struct fsl_usb2_dev_data { ...@@ -24,7 +24,7 @@ struct fsl_usb2_dev_data {
enum fsl_usb2_operating_modes op_mode; /* operating mode */ enum fsl_usb2_operating_modes op_mode; /* operating mode */
}; };
struct fsl_usb2_dev_data dr_mode_data[] = { static struct fsl_usb2_dev_data dr_mode_data[] = {
{ {
.dr_mode = "host", .dr_mode = "host",
.drivers = { "fsl-ehci", NULL, NULL, }, .drivers = { "fsl-ehci", NULL, NULL, },
...@@ -42,7 +42,7 @@ struct fsl_usb2_dev_data dr_mode_data[] = { ...@@ -42,7 +42,7 @@ struct fsl_usb2_dev_data dr_mode_data[] = {
}, },
}; };
struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np) static struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np)
{ {
const unsigned char *prop; const unsigned char *prop;
int i; int i;
...@@ -75,7 +75,7 @@ static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) ...@@ -75,7 +75,7 @@ static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
return FSL_USB2_PHY_NONE; return FSL_USB2_PHY_NONE;
} }
struct platform_device *fsl_usb2_device_register( static struct platform_device *fsl_usb2_device_register(
struct platform_device *ofdev, struct platform_device *ofdev,
struct fsl_usb2_platform_data *pdata, struct fsl_usb2_platform_data *pdata,
const char *name, int id) const char *name, int id)
......
...@@ -79,7 +79,7 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate) ...@@ -79,7 +79,7 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
return &dpll_map[i].params; return &dpll_map[i].params;
} }
return 0; return NULL;
} }
static int omap_usb3_suspend(struct usb_phy *x, int suspend) static int omap_usb3_suspend(struct usb_phy *x, int suspend)
......
...@@ -60,7 +60,7 @@ config USB_SERIAL_SIMPLE ...@@ -60,7 +60,7 @@ config USB_SERIAL_SIMPLE
- Suunto ANT+ USB device. - Suunto ANT+ USB device.
- Fundamental Software dongle. - Fundamental Software dongle.
- HP4x calculators - HP4x calculators
- a number of Motoroloa phones - a number of Motorola phones
- Siemens USB/MPI adapter. - Siemens USB/MPI adapter.
- ViVOtech ViVOpay USB device. - ViVOtech ViVOpay USB device.
- Infineon Modem Flashloader USB interface - Infineon Modem Flashloader USB interface
......
...@@ -139,6 +139,7 @@ enum pl2303_type { ...@@ -139,6 +139,7 @@ enum pl2303_type {
HX_TA, /* HX(A) / X(A) / TA version */ /* TODO: improve */ HX_TA, /* HX(A) / X(A) / TA version */ /* TODO: improve */
HXD_EA_RA_SA, /* HXD / EA / RA / SA version */ /* TODO: improve */ HXD_EA_RA_SA, /* HXD / EA / RA / SA version */ /* TODO: improve */
TB, /* TB version */ TB, /* TB version */
HX_CLONE, /* Cheap and less functional clone of the HX chip */
}; };
/* /*
* NOTE: don't know the difference between type 0 and type 1, * NOTE: don't know the difference between type 0 and type 1,
...@@ -206,8 +207,23 @@ static int pl2303_startup(struct usb_serial *serial) ...@@ -206,8 +207,23 @@ static int pl2303_startup(struct usb_serial *serial)
* the device descriptors of the X/HX, HXD, EA, RA, SA, TA, TB * the device descriptors of the X/HX, HXD, EA, RA, SA, TA, TB
*/ */
if (le16_to_cpu(serial->dev->descriptor.bcdDevice) == 0x300) { if (le16_to_cpu(serial->dev->descriptor.bcdDevice) == 0x300) {
type = HX_TA; /* Check if the device is a clone */
type_str = "X/HX/TA"; pl2303_vendor_read(0x9494, 0, serial, buf);
/*
* NOTE: Not sure if this read is really needed.
* The HX returns 0x00, the clone 0x02, but the Windows
* driver seems to ignore the value and continues.
*/
pl2303_vendor_write(0x0606, 0xaa, serial);
pl2303_vendor_read(0x8686, 0, serial, buf);
if (buf[0] != 0xaa) {
type = HX_CLONE;
type_str = "X/HX clone (limited functionality)";
} else {
type = HX_TA;
type_str = "X/HX/TA";
}
pl2303_vendor_write(0x0606, 0x00, serial);
} else if (le16_to_cpu(serial->dev->descriptor.bcdDevice) } else if (le16_to_cpu(serial->dev->descriptor.bcdDevice)
== 0x400) { == 0x400) {
type = HXD_EA_RA_SA; type = HXD_EA_RA_SA;
...@@ -305,8 +321,9 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type, ...@@ -305,8 +321,9 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type,
{ {
/* /*
* NOTE: Only the values defined in baud_sup are supported ! * NOTE: Only the values defined in baud_sup are supported !
* => if unsupported values are set, the PL2303 seems to * => if unsupported values are set, the PL2303 uses 9600 baud instead
* use 9600 baud (at least my PL2303X always does) * => HX clones just don't work at unsupported baud rates < 115200 baud,
* for baud rates > 115200 they run at 115200 baud
*/ */
const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600, const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600,
4800, 7200, 9600, 14400, 19200, 28800, 38400, 4800, 7200, 9600, 14400, 19200, 28800, 38400,
...@@ -316,14 +333,14 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type, ...@@ -316,14 +333,14 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type,
* NOTE: With the exception of type_0/1 devices, the following * NOTE: With the exception of type_0/1 devices, the following
* additional baud rates are supported (tested with HX rev. 3A only): * additional baud rates are supported (tested with HX rev. 3A only):
* 110*, 56000*, 128000, 134400, 161280, 201600, 256000*, 268800, * 110*, 56000*, 128000, 134400, 161280, 201600, 256000*, 268800,
* 403200, 806400. (*: not HX) * 403200, 806400. (*: not HX and HX clones)
* *
* Maximum values: HXD, TB: 12000000; HX, TA: 6000000; * Maximum values: HXD, TB: 12000000; HX, TA: 6000000;
* type_0+1: 1228800; RA: 921600; SA: 115200 * type_0+1: 1228800; RA: 921600; HX clones, SA: 115200
* *
* As long as we are not using this encoding method for anything else * As long as we are not using this encoding method for anything else
* than the type_0+1 and HX chips, there is no point in complicating * than the type_0+1, HX and HX clone chips, there is no point in
* the code to support them. * complicating the code to support them.
*/ */
int i; int i;
...@@ -347,6 +364,8 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type, ...@@ -347,6 +364,8 @@ static int pl2303_baudrate_encode_direct(int baud, enum pl2303_type type,
baud = min_t(int, baud, 6000000); baud = min_t(int, baud, 6000000);
else if (type == type_0 || type == type_1) else if (type == type_0 || type == type_1)
baud = min_t(int, baud, 1228800); baud = min_t(int, baud, 1228800);
else if (type == HX_CLONE)
baud = min_t(int, baud, 115200);
/* Direct (standard) baud rate encoding method */ /* Direct (standard) baud rate encoding method */
put_unaligned_le32(baud, buf); put_unaligned_le32(baud, buf);
...@@ -359,7 +378,8 @@ static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type, ...@@ -359,7 +378,8 @@ static int pl2303_baudrate_encode_divisor(int baud, enum pl2303_type type,
/* /*
* Divisor based baud rate encoding method * Divisor based baud rate encoding method
* *
* NOTE: it's not clear if the type_0/1 chips support this method * NOTE: HX clones do NOT support this method.
* It's not clear if the type_0/1 chips support it.
* *
* divisor = 12MHz * 32 / baudrate = 2^A * B * divisor = 12MHz * 32 / baudrate = 2^A * B
* *
...@@ -452,7 +472,7 @@ static void pl2303_encode_baudrate(struct tty_struct *tty, ...@@ -452,7 +472,7 @@ static void pl2303_encode_baudrate(struct tty_struct *tty,
* 1) Direct method: encodes the baud rate value directly * 1) Direct method: encodes the baud rate value directly
* => supported by all chip types * => supported by all chip types
* 2) Divisor based method: encodes a divisor to a base value (12MHz*32) * 2) Divisor based method: encodes a divisor to a base value (12MHz*32)
* => supported by HX chips (and likely not by type_0/1 chips) * => not supported by HX clones (and likely type_0/1 chips)
* *
* NOTE: Although the divisor based baud rate encoding method is much * NOTE: Although the divisor based baud rate encoding method is much
* more flexible, some of the standard baud rate values can not be * more flexible, some of the standard baud rate values can not be
...@@ -460,7 +480,7 @@ static void pl2303_encode_baudrate(struct tty_struct *tty, ...@@ -460,7 +480,7 @@ static void pl2303_encode_baudrate(struct tty_struct *tty,
* the device likely uses the same baud rate generator for both methods * the device likely uses the same baud rate generator for both methods
* so that there is likley no difference. * so that there is likley no difference.
*/ */
if (type == type_0 || type == type_1) if (type == type_0 || type == type_1 || type == HX_CLONE)
baud = pl2303_baudrate_encode_direct(baud, type, buf); baud = pl2303_baudrate_encode_direct(baud, type, buf);
else else
baud = pl2303_baudrate_encode_divisor(baud, type, buf); baud = pl2303_baudrate_encode_divisor(baud, type, buf);
...@@ -813,6 +833,7 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state) ...@@ -813,6 +833,7 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
BREAK_REQUEST, BREAK_REQUEST_TYPE, state, BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
0, NULL, 0, 100); 0, NULL, 0, 100);
/* NOTE: HX clones don't support sending breaks, -EPIPE is returned */
if (result) if (result)
dev_err(&port->dev, "error sending break = %d\n", result); dev_err(&port->dev, "error sending break = %d\n", result);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment