189 lines
5.0 KiB
Diff
189 lines
5.0 KiB
Diff
--- a/drivers/usb/host/ohci-ssb.c
|
|
+++ b/drivers/usb/host/ohci-ssb.c
|
|
@@ -17,6 +17,8 @@
|
|
*/
|
|
#include <linux/ssb/ssb.h>
|
|
|
|
+extern int ssb_ehci_attach(struct ssb_device *dev, struct usb_hcd **hcd);
|
|
+extern void ssb_ehci_detach(struct ssb_device *dev, struct usb_hcd *hcd);
|
|
|
|
#define SSB_OHCI_TMSLOW_HOSTMODE (1 << 29)
|
|
|
|
@@ -24,6 +26,9 @@ struct ssb_ohci_device {
|
|
struct ohci_hcd ohci; /* _must_ be at the beginning. */
|
|
|
|
u32 enable_flags;
|
|
+#ifdef CONFIG_USB_EHCI_HCD_SSB
|
|
+ struct usb_hcd *ehci_hcd;
|
|
+#endif
|
|
};
|
|
|
|
static inline
|
|
@@ -92,6 +97,9 @@ static const struct hc_driver ssb_ohci_h
|
|
static void ssb_ohci_detach(struct ssb_device *dev)
|
|
{
|
|
struct usb_hcd *hcd = ssb_get_drvdata(dev);
|
|
+#ifdef CONFIG_USB_EHCI_HCD_SSB
|
|
+ struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
|
|
+#endif
|
|
|
|
if (hcd->driver->shutdown)
|
|
hcd->driver->shutdown(hcd);
|
|
@@ -99,6 +107,14 @@ static void ssb_ohci_detach(struct ssb_d
|
|
iounmap(hcd->regs);
|
|
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
|
usb_put_hcd(hcd);
|
|
+
|
|
+#ifdef CONFIG_USB_EHCI_HCD_SSB
|
|
+ /*
|
|
+ * Also detach ehci function
|
|
+ */
|
|
+ if (dev->id.coreid == SSB_DEV_USB20_HOST)
|
|
+ ssb_ehci_detach(dev, ohcidev->ehci_hcd);
|
|
+#endif
|
|
ssb_device_disable(dev, 0);
|
|
}
|
|
|
|
@@ -121,6 +137,9 @@ static int ssb_ohci_attach(struct ssb_de
|
|
/*
|
|
* USB 2.0 special considerations:
|
|
*
|
|
+ * Since the core supports both OHCI and EHCI functions,
|
|
+ * it must only be reset once.
|
|
+ *
|
|
* In addition to the standard SSB reset sequence, the Host
|
|
* Control Register must be programmed to bring the USB core
|
|
* and various phy components out of reset.
|
|
@@ -175,6 +194,14 @@ static int ssb_ohci_attach(struct ssb_de
|
|
|
|
ssb_set_drvdata(dev, hcd);
|
|
|
|
+#ifdef CONFIG_USB_EHCI_HCD_SSB
|
|
+ /*
|
|
+ * attach ehci function in this core
|
|
+ */
|
|
+ if (dev->id.coreid == SSB_DEV_USB20_HOST)
|
|
+ err = ssb_ehci_attach(dev, &(ohcidev->ehci_hcd));
|
|
+#endif
|
|
+
|
|
return err;
|
|
|
|
err_iounmap:
|
|
--- a/drivers/usb/host/ehci-ssb.c
|
|
+++ b/drivers/usb/host/ehci-ssb.c
|
|
@@ -106,10 +106,18 @@ static void ssb_ehci_detach(struct ssb_d
|
|
iounmap(hcd->regs);
|
|
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
|
usb_put_hcd(hcd);
|
|
+#ifndef CONFIG_USB_OHCI_HCD_SSB
|
|
+ ssb_device_disable(dev, 0);
|
|
+#endif
|
|
ssb_device_disable(dev, 0);
|
|
}
|
|
+EXPORT_SYMBOL_GPL(ssb_ehci_detach);
|
|
|
|
+#ifndef CONFIG_USB_OHCI_HCD_SSB
|
|
static int ssb_ehci_attach(struct ssb_device *dev)
|
|
+#else
|
|
+static int ssb_ehci_attach(struct ssb_device *dev, struct usb_hcd **ehci_hcd)
|
|
+#endif
|
|
{
|
|
struct ssb_ehci_device *ehcidev;
|
|
struct usb_hcd *hcd;
|
|
@@ -120,6 +128,7 @@ static int ssb_ehci_attach(struct ssb_de
|
|
dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
|
|
return -EOPNOTSUPP;
|
|
|
|
+#ifndef CONFIG_USB_OHCI_HCD_SSB
|
|
/*
|
|
* USB 2.0 special considerations:
|
|
*
|
|
@@ -155,6 +164,7 @@ static int ssb_ehci_attach(struct ssb_de
|
|
tmp |= 0x1;
|
|
ssb_write32(dev, 0x89c, tmp);
|
|
}
|
|
+#endif
|
|
|
|
hcd = usb_create_hcd(&ssb_ehci_hc_driver, dev->dev,
|
|
dev_name(dev->dev));
|
|
@@ -175,7 +185,11 @@ static int ssb_ehci_attach(struct ssb_de
|
|
if (err)
|
|
goto err_iounmap;
|
|
|
|
+#ifndef CONFIG_USB_OHCI_HCD_SSB
|
|
ssb_set_drvdata(dev, hcd);
|
|
+#else
|
|
+ *ehci_hcd = hcd;
|
|
+#endif
|
|
|
|
return err;
|
|
|
|
@@ -187,7 +201,9 @@ err_dev_disable:
|
|
ssb_device_disable(dev, 0);
|
|
return err;
|
|
}
|
|
+EXPORT_SYMBOL_GPL(ssb_ehci_attach);
|
|
|
|
+#ifndef CONFIG_USB_OHCI_HCD_SSB
|
|
static int ssb_ehci_probe(struct ssb_device *dev,
|
|
const struct ssb_device_id *id)
|
|
{
|
|
@@ -238,6 +254,7 @@ static int ssb_ehci_resume(struct ssb_de
|
|
#define ssb_ehci_suspend NULL
|
|
#define ssb_ehci_resume NULL
|
|
#endif /* CONFIG_PM */
|
|
+#endif /* !CONFIG_USB_OHCI_HCD_SSB */
|
|
|
|
static const struct ssb_device_id ssb_ehci_table[] = {
|
|
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
|
|
@@ -245,6 +262,8 @@ static const struct ssb_device_id ssb_eh
|
|
};
|
|
MODULE_DEVICE_TABLE(ssb, ssb_ehci_table);
|
|
|
|
+
|
|
+#ifndef CONFIG_USB_OHCI_HCD_SSB
|
|
static struct ssb_driver ssb_ehci_driver = {
|
|
.name = KBUILD_MODNAME,
|
|
.id_table = ssb_ehci_table,
|
|
@@ -253,3 +272,4 @@ static struct ssb_driver ssb_ehci_driver
|
|
.suspend = ssb_ehci_suspend,
|
|
.resume = ssb_ehci_resume,
|
|
};
|
|
+#endif
|
|
--- a/drivers/usb/host/ehci-hcd.c
|
|
+++ b/drivers/usb/host/ehci-hcd.c
|
|
@@ -1297,17 +1297,21 @@ static int __init ehci_hcd_init(void)
|
|
goto clean4;
|
|
#endif
|
|
|
|
+#ifndef CONFIG_USB_OHCI_HCD_SSB
|
|
#ifdef SSB_EHCI_DRIVER
|
|
retval = ssb_driver_register(&SSB_EHCI_DRIVER);
|
|
if (retval < 0)
|
|
goto clean5;
|
|
#endif
|
|
+#endif /* !CONFIG_USB_OHCI_HCD_SSB */
|
|
return retval;
|
|
|
|
+#ifndef CONFIG_USB_OHCI_HCD_SSB
|
|
#ifdef SSB_EHCI_DRIVER
|
|
/* ssb_driver_unregister(&SSB_EHCI_DRIVER); */
|
|
clean5:
|
|
#endif
|
|
+#endif /* !CONFIG_USB_OHCI_HCD_SSB */
|
|
#ifdef XILINX_OF_PLATFORM_DRIVER
|
|
of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER);
|
|
clean4:
|
|
@@ -1340,9 +1344,11 @@ module_init(ehci_hcd_init);
|
|
|
|
static void __exit ehci_hcd_cleanup(void)
|
|
{
|
|
+#ifndef CONFIG_USB_OHCI_HCD_SSB
|
|
#ifdef SSB_EHCI_DRIVER
|
|
ssb_driver_unregister(&SSB_EHCI_DRIVER);
|
|
#endif
|
|
+#endif /* !CONFIG_USB_OHCI_HCD_SSB */
|
|
#ifdef XILINX_OF_PLATFORM_DRIVER
|
|
of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER);
|
|
#endif
|