diff options
author | Xie Xiaobo <xiaobo.xie@nxp.com> | 2017-12-12 08:23:55 (GMT) |
---|---|---|
committer | Xie Xiaobo <xiaobo.xie@nxp.com> | 2017-12-12 08:23:55 (GMT) |
commit | 708b8b8eb67124716c8579a9e259742b040d4dd3 (patch) | |
tree | afc209d3f63c3d79e91a98c8f3ba01465977b574 /drivers/usb | |
parent | c0246a9ec4d461ef4dd7647f94005380bb9e7f0b (diff) | |
parent | 5fe8cfe356d2dbf6f9d7e213614d6be9ad0ac592 (diff) | |
download | linux-708b8b8eb67124716c8579a9e259742b040d4dd3.tar.xz |
Merge branch 'linux-4.9-nxp' into linux-4.9 on Dec. 8, 2017
Signed-off-by: Xiaobo Xie <xiaobo.xie@nxp.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/dwc3/core.c | 2 | ||||
-rw-r--r-- | drivers/usb/dwc3/core.h | 2 | ||||
-rw-r--r-- | drivers/usb/dwc3/ep0.c | 4 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 100 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 4 |
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) |