summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/core.c2
-rw-r--r--drivers/usb/dwc3/core.h2
-rw-r--r--drivers/usb/dwc3/ep0.c4
-rw-r--r--drivers/usb/dwc3/gadget.c7
-rw-r--r--drivers/usb/host/ehci-fsl.c100
-rw-r--r--drivers/usb/host/ehci-hub.c2
-rw-r--r--drivers/usb/host/ehci.h4
7 files changed, 64 insertions, 57 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index e34ef90..885d8e5 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1115,6 +1115,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
+ dwc->disable_devinit_u1u2_quirk = device_property_read_bool(dev,
+ "snps,disable_devinit_u1u2");
device_property_read_u8(dev, "snps,tx_de_emphasis",
&tx_de_emphasis);
device_property_read_string(dev, "snps,hsphy_interface",
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 9151eef..2549339 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -860,6 +860,7 @@ struct dwc3_scratchpad_array {
* 1 - -3.5dB de-emphasis
* 2 - No de-emphasis
* 3 - Reserved
+ * @disable_devinit_u1u2_quirk: disable device-initiated U1/U2 request.
*/
struct dwc3 {
struct usb_ctrlrequest *ctrl_req;
@@ -1016,6 +1017,7 @@ struct dwc3 {
unsigned tx_de_emphasis_quirk:1;
unsigned tx_de_emphasis:2;
+ unsigned disable_devinit_u1u2_quirk:1;
u16 imod_interval;
};
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 2331469..4e6c1bb 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -360,9 +360,9 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
if ((dwc->speed == DWC3_DSTS_SUPERSPEED) ||
(dwc->speed == DWC3_DSTS_SUPERSPEED_PLUS)) {
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- if (reg & DWC3_DCTL_INITU1ENA)
+ if ((reg & DWC3_DCTL_INITU1ENA) && !dwc->disable_devinit_u1u2_quirk)
usb_status |= 1 << USB_DEV_STAT_U1_ENABLED;
- if (reg & DWC3_DCTL_INITU2ENA)
+ if ((reg & DWC3_DCTL_INITU2ENA) && !dwc->disable_devinit_u1u2_quirk)
usb_status |= 1 << USB_DEV_STAT_U2_ENABLED;
}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index c61ddbf..51c86aa 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2930,6 +2930,7 @@ static irqreturn_t dwc3_interrupt(int irq, void *_evt)
int dwc3_gadget_init(struct dwc3 *dwc)
{
int ret, irq;
+ u32 reg;
struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
irq = platform_get_irq_byname(dwc3_pdev, "peripheral");
@@ -3044,6 +3045,12 @@ int dwc3_gadget_init(struct dwc3 *dwc)
goto err5;
}
+ if (dwc->disable_devinit_u1u2_quirk) {
+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg &= ~(DWC3_DCTL_INITU1ENA | DWC3_DCTL_INITU2ENA);
+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ }
+
return 0;
err5:
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index cd16860..d24b92d 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -36,6 +36,7 @@
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
#include <linux/of_platform.h>
+#include <linux/io.h>
#ifdef CONFIG_PPC
#include <asm/fsl_pm.h>
@@ -82,13 +83,23 @@ struct ccsr_usb_phy {
#define DRV_NAME "ehci-fsl"
static struct hc_driver __read_mostly fsl_ehci_hc_driver;
+
struct ehci_fsl {
- /* store current hcd state for otg;
- * have_hcd is true when host drv al already part of otg framework,
- * otherwise false;
- * hcd_add is true when otg framework wants to add host
- * drv as part of otg;flase when it wants to remove it
- */
+ struct ehci_hcd ehci;
+
+#ifdef CONFIG_PM
+struct ehci_regs saved_regs;
+struct ccsr_usb_phy saved_phy_regs;
+/* Saved USB PHY settings, need to restore after deep sleep. */
+u32 usb_ctrl;
+#endif
+ /*
+ * store current hcd state for otg;
+ * have_hcd is true when host drv al already part of otg framework,
+ * otherwise false;
+ * hcd_add is true when otg framework wants to add host
+ * drv as part of otg;flase when it wants to remove it
+ */
unsigned have_hcd:1;
unsigned hcd_add:1;
};
@@ -115,7 +126,7 @@ int retval;
/* host, gadget and otg share same int line */
retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
if (retval == 0)
- ehci_fsl->have_hcd = 1;
+ ehci_fsl->have_hcd = 1;
} else if (!ehci_fsl->hcd_add && ehci_fsl->have_hcd) {
usb_remove_hcd(hcd);
ehci_fsl->have_hcd = 0;
@@ -123,53 +134,26 @@ int retval;
}
#endif
-struct ehci_fsl {
- struct ehci_hcd ehci;
-
-#ifdef CONFIG_PM
-struct ehci_regs saved_regs;
-struct ccsr_usb_phy saved_phy_regs;
-/* Saved USB PHY settings, need to restore after deep sleep. */
-u32 usb_ctrl;
-#endif
- /*
- * store current hcd state for otg;
- * have_hcd is true when host drv al already part of otg framework,
- * otherwise false;
- * hcd_add is true when otg framework wants to add host
- * drv as part of otg;flase when it wants to remove it
- */
-unsigned have_hcd:1;
-unsigned hcd_add:1;
-};
-
-static strut ehci_fsl *hcd_to_ehci_fsl(struct usb_hcd *hcd)
-{
-struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-
-return container_of(ehci, struct ehci_fsl, ehci);
-}
-
#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE)
static void do_change_hcd(struct work_struct *work)
{
-struct ehci_hcd *ehci = container_of(work, struct ehci_hcd,
-change_hcd_work);
-struct usb_hcd *hcd = ehci_to_hcd(ehci);
-struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
-void __iomem *non_ehci = hcd->regs;
-int retval;
+ struct ehci_hcd *ehci = container_of(work, struct ehci_hcd,
+ change_hcd_work);
+ struct usb_hcd *hcd = ehci_to_hcd(ehci);
+ struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
+ void __iomem *non_ehci = hcd->regs;
+ int retval;
-if (ehci_fsl->hcd_add && !ehci_fsl->have_hcd) {
-writel(USBMODE_CM_HOST, non_ehci + FSL_SOC_USB_USBMODE);
-/* host, gadget and otg share same int line */
-retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
-if (retval == 0)
-ehci_fsl->have_hcd = 1;
-} else if (!ehci_fsl->hcd_add && ehci_fsl->have_hcd) {
- usb_remove_hcd(hcd);
-ehci_fsl->have_hcd = 0;
-}
+ if (ehci_fsl->hcd_add && !ehci_fsl->have_hcd) {
+ writel(USBMODE_CM_HOST, non_ehci + FSL_SOC_USB_USBMODE);
+ /* host, gadget and otg share same int line */
+ retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
+ if (retval == 0)
+ ehci_fsl->have_hcd = 1;
+ } else if (!ehci_fsl->hcd_add && ehci_fsl->have_hcd) {
+ usb_remove_hcd(hcd);
+ ehci_fsl->have_hcd = 0;
+ }
}
#endif
@@ -324,13 +308,12 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
return retval;
}
-static bool usb_phy_clk_valid(struct usb_hcd *hcd,
- enum fsl_usb2_phy_modes phy_mode)
+static bool usb_phy_clk_valid(struct usb_hcd *hcd)
{
void __iomem *non_ehci = hcd->regs;
bool ret = true;
- if (!(in_be32(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID))
+ if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID))
ret = false;
return ret;
@@ -456,6 +439,9 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci)
if (pdata->has_fsl_erratum_a005275 == 1)
ehci->has_fsl_hs_errata = 1;
+ if (pdata->has_fsl_erratum_a005697 == 1)
+ ehci->has_fsl_susp_errata = 1;
+
if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
(pdata->operating_mode == FSL_USB2_DR_OTG))
if (ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0))
@@ -752,7 +738,9 @@ static int ehci_fsl_drv_suspend(struct device *dev)
#ifdef CONFIG_PPC
suspend_state_t pm_state;
-pm_state = pm_suspend_state();
+/* FIXME:Need to port fsl_pm.h before enable below code. */
+/*pm_state = pm_suspend_state();*/
+pm_state = PM_SUSPEND_MEM;
if (pm_state == PM_SUSPEND_MEM)
ehci_fsl_save_context(hcd);
@@ -797,7 +785,9 @@ static int ehci_fsl_drv_resume(struct device *dev)
#ifdef CONFIG_PPC
suspend_state_t pm_state;
-pm_state = pm_suspend_state();
+/* FIXME:Need to port fsl_pm.h before enable below code.*/
+/* pm_state = pm_suspend_state(); */
+pm_state = PM_SUSPEND_MEM;
if (pm_state == PM_SUSPEND_MEM)
ehci_fsl_restore_context(hcd);
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index d4a8ec5..6d82575 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -278,6 +278,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) {
t2 |= PORT_SUSPEND;
set_bit(port, &ehci->bus_suspended);
+ if (ehci_has_fsl_susp_errata(ehci))
+ usleep_range(10000, 20000);
}
/* enable remote wakeup on all ports, if told to do so */
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index c4bd983..492efbb 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -222,6 +222,7 @@ struct ehci_hcd { /* one per controller */
unsigned no_selective_suspend:1;
unsigned has_fsl_port_bug:1; /* FreeScale */
unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */
+ unsigned has_fsl_susp_errata:1; /*Freescale SUSP quirk*/
unsigned big_endian_mmio:1;
unsigned big_endian_desc:1;
unsigned big_endian_capbase:1;
@@ -706,6 +707,9 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
#if defined(CONFIG_PPC_85xx)
/* Some Freescale processors have an erratum (USB A-005275) in which
* incoming packets get corrupted in HS mode
+ * Some Freescale processors have an erratum (USB A-005697) in which
+ * we need to wait for 10ms for bus to fo into suspend mode after
+ * setting SUSP bit
*/
#define ehci_has_fsl_hs_errata(e) ((e)->has_fsl_hs_errata)
#define ehci_has_fsl_susp_errata(e) ((e)->has_fsl_susp_errata)