Re: [PATCH 1/3] USB: host: ehci_atmel: Move global variables to private struct

2015-01-17 Thread Alan Stern
On Sat, 17 Jan 2015, Sylvain Rochet wrote:

 This patch move Atmel EHCI global variables (clocks ptr and clocked
 boolean) to private struct atmel_ehci, appended at the end of the parent
 struct usb_hcd.
 
 Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
 ---
  drivers/usb/host/ehci-atmel.c | 75 
 +++
  1 file changed, 48 insertions(+), 27 deletions(-)
 
 diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
 index 2e0043b..a47fe3f 100644
 --- a/drivers/usb/host/ehci-atmel.c
 +++ b/drivers/usb/host/ehci-atmel.c
 @@ -30,45 +30,62 @@ static const char hcd_name[] = ehci-atmel;
  static struct hc_driver __read_mostly ehci_atmel_hc_driver;
  
  /* interface and function clocks */
 -static struct clk *iclk, *fclk, *uclk;
 -static int clocked;
 +struct atmel_ehci {
 + struct ehci_hcd ehci;
 +
 + struct clk *iclk;
 + struct clk *fclk;
 + struct clk *uclk;
 + bool clocked;
 +};
  
  /*-*/
  
 -static void atmel_start_clock(void)
 +static inline struct atmel_ehci *hcd_to_atmel_ehci(struct usb_hcd *hcd)
 +{
 + return (struct atmel_ehci *) hcd-hcd_priv;
 +}

This is not the right way to do it.  For an example of the right way, 
see the ehci-platform.c file.  Your private structure is stored in 
ehci-priv, and its size is specified by the .extra_priv_size member of 
an ehci_driver_overrides structure passed to ehci_init_driver().

Nevertheless, I approve the idea of getting rid of global variables.

Alan Stern

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] USB: host: ehci_atmel: Move global variables to private struct

2015-01-17 Thread Boris Brezillon
Hi Sylvain,

On Sat, 17 Jan 2015 19:23:31 +0100
Sylvain Rochet sylvain.roc...@finsecur.com wrote:

 This patch move Atmel EHCI global variables (clocks ptr and clocked
 boolean) to private struct atmel_ehci, appended at the end of the parent
 struct usb_hcd.

Maybe you should add a cover letter to clearly state that this series
depends on another one: [1].

Anyway, thanks for removing these global variables.

 
 Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com

To the whole series:

Acked-by: Boris Brezillon boris.brezil...@free-electrons.com

[1]https://www.mail-archive.com/linux-usb@vger.kernel.org/msg54675.html


-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 3/5] USB: host: ehci_atmel: Move global variables to private struct

2015-01-17 Thread Sylvain Rochet
This patch move Atmel EHCI global variables (clocks ptr and clocked
boolean) to private struct atmel_ehci_priv, stored in ehci-priv.

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
---
 drivers/usb/host/ehci-atmel.c | 78 +++
 1 file changed, 49 insertions(+), 29 deletions(-)

diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 2e0043b..eb0924f 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -27,48 +27,65 @@
 #define DRIVER_DESC EHCI Atmel driver
 
 static const char hcd_name[] = ehci-atmel;
-static struct hc_driver __read_mostly ehci_atmel_hc_driver;
 
 /* interface and function clocks */
-static struct clk *iclk, *fclk, *uclk;
-static int clocked;
+#define hcd_to_atmel_ehci_priv(h) ((struct atmel_ehci_priv 
*)hcd_to_ehci(h)-priv)
+
+struct atmel_ehci_priv {
+   struct clk *iclk;
+   struct clk *fclk;
+   struct clk *uclk;
+   bool clocked;
+};
+
+static struct hc_driver __read_mostly ehci_atmel_hc_driver;
+
+static const struct ehci_driver_overrides ehci_atmel_drv_overrides __initconst 
= {
+   .extra_priv_size = sizeof(struct atmel_ehci_priv),
+};
 
 /*-*/
 
-static void atmel_start_clock(void)
+static void atmel_start_clock(struct atmel_ehci_priv *atmel_ehci)
 {
-   if (clocked)
+   if (atmel_ehci-clocked)
return;
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
-   clk_set_rate(uclk, 4800);
-   clk_prepare_enable(uclk);
+   clk_set_rate(atmel_ehci-uclk, 4800);
+   clk_prepare_enable(atmel_ehci-uclk);
}
-   clk_prepare_enable(iclk);
-   clk_prepare_enable(fclk);
-   clocked = 1;
+   clk_prepare_enable(atmel_ehci-iclk);
+   clk_prepare_enable(atmel_ehci-fclk);
+   atmel_ehci-clocked = true;
 }
 
-static void atmel_stop_clock(void)
+static void atmel_stop_clock(struct atmel_ehci_priv *atmel_ehci)
 {
-   if (!clocked)
+   if (!atmel_ehci-clocked)
return;
-   clk_disable_unprepare(fclk);
-   clk_disable_unprepare(iclk);
+   clk_disable_unprepare(atmel_ehci-fclk);
+   clk_disable_unprepare(atmel_ehci-iclk);
if (IS_ENABLED(CONFIG_COMMON_CLK))
-   clk_disable_unprepare(uclk);
-   clocked = 0;
+   clk_disable_unprepare(atmel_ehci-uclk);
+   atmel_ehci-clocked = false;
 }
 
 static void atmel_start_ehci(struct platform_device *pdev)
 {
+   struct usb_hcd *hcd = platform_get_drvdata(pdev);
+   struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd);
+
dev_dbg(pdev-dev, start\n);
-   atmel_start_clock();
+   atmel_start_clock(atmel_ehci);
 }
 
 static void atmel_stop_ehci(struct platform_device *pdev)
 {
+   struct usb_hcd *hcd = platform_get_drvdata(pdev);
+   struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd);
+
dev_dbg(pdev-dev, stop\n);
-   atmel_stop_clock();
+   atmel_stop_clock(atmel_ehci);
 }
 
 /*-*/
@@ -79,6 +96,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
const struct hc_driver *driver = ehci_atmel_hc_driver;
struct resource *res;
struct ehci_hcd *ehci;
+   struct atmel_ehci_priv *atmel_ehci;
int irq;
int retval;
 
@@ -109,6 +127,7 @@ static int ehci_atmel_drv_probe(struct platform_device 
*pdev)
retval = -ENOMEM;
goto fail_create_hcd;
}
+   atmel_ehci = hcd_to_atmel_ehci_priv(hcd);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd-regs = devm_ioremap_resource(pdev-dev, res);
@@ -120,23 +139,23 @@ static int ehci_atmel_drv_probe(struct platform_device 
*pdev)
hcd-rsrc_start = res-start;
hcd-rsrc_len = resource_size(res);
 
-   iclk = devm_clk_get(pdev-dev, ehci_clk);
-   if (IS_ERR(iclk)) {
+   atmel_ehci-iclk = devm_clk_get(pdev-dev, ehci_clk);
+   if (IS_ERR(atmel_ehci-iclk)) {
dev_err(pdev-dev, Error getting interface clock\n);
retval = -ENOENT;
goto fail_request_resource;
}
-   fclk = devm_clk_get(pdev-dev, uhpck);
-   if (IS_ERR(fclk)) {
+   atmel_ehci-fclk = devm_clk_get(pdev-dev, uhpck);
+   if (IS_ERR(atmel_ehci-fclk)) {
dev_err(pdev-dev, Error getting function clock\n);
retval = -ENOENT;
goto fail_request_resource;
}
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
-   uclk = devm_clk_get(pdev-dev, usb_clk);
-   if (IS_ERR(uclk)) {
+   atmel_ehci-uclk = devm_clk_get(pdev-dev, usb_clk);
+   if (IS_ERR(atmel_ehci-uclk)) {
dev_err(pdev-dev, failed to get uclk\n);
-   retval = PTR_ERR(uclk);
+  

[PATCHv3 0/5] USB: host: Atmel OHCI and EHCI drivers improvements

2015-01-17 Thread Sylvain Rochet
Sylvain Rochet (5):
  USB: host: ehci_atmel: Add suspend/resume support
  USB: host: ohci_at91: Stop/start USB PLL for all sleep modes
  USB: host: ehci_atmel: Move global variables to private struct
  USB: host: ohci_at91: Move global variables to private struct
  USB: host: ohci_at91: usb_hcd_at91_probe(), remove useless stack
initialisation

 drivers/usb/host/ehci-atmel.c | 102 +++--
 drivers/usb/host/ohci-at91.c  | 104 +-
 2 files changed, 138 insertions(+), 68 deletions(-)

-- 
2.1.4
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 5/5] USB: host: ohci_at91: usb_hcd_at91_probe(), remove useless stack initialisation

2015-01-17 Thread Sylvain Rochet
struct usb_hcd *hcd = NULL;
...
hcd = usb_create_hcd(driver, dev, at91);

This patch remove *hcd useless initialisation

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
---
 drivers/usb/host/ohci-at91.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index ab39b94..7e37657 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -145,7 +145,7 @@ static int usb_hcd_at91_probe(const struct hc_driver 
*driver,
struct at91_usbh_data *board;
struct ohci_hcd *ohci;
int retval;
-   struct usb_hcd *hcd = NULL;
+   struct usb_hcd *hcd;
struct ohci_at91_priv *ohci_at91;
struct device *dev = pdev-dev;
struct resource *res;
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 4/5] USB: host: ohci_at91: Move global variables to private struct

2015-01-17 Thread Sylvain Rochet
This patch move AT91 OHCI global variables (clocks ptr and clocked
boolean) to private struct ohci_at91_priv, stored in ohci-priv.

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
---
 drivers/usb/host/ohci-at91.c | 85 ++--
 1 file changed, 51 insertions(+), 34 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index f0da734..ab39b94 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -33,7 +33,15 @@
for ((index) = 0; (index)  AT91_MAX_USBH_PORTS; (index)++)
 
 /* interface, function and usb clocks; sometimes also an AHB clock */
-static struct clk *iclk, *fclk, *uclk, *hclk;
+#define hcd_to_ohci_at91_priv(h) ((struct ohci_at91_priv 
*)hcd_to_ohci(h)-priv)
+
+struct ohci_at91_priv {
+   struct clk *iclk;
+   struct clk *fclk;
+   struct clk *uclk;
+   struct clk *hclk;
+   bool clocked;
+};
 /* interface and function clocks; sometimes also an AHB clock */
 
 #define DRIVER_DESC OHCI Atmel driver
@@ -41,49 +49,53 @@ static struct clk *iclk, *fclk, *uclk, *hclk;
 static const char hcd_name[] = ohci-atmel;
 
 static struct hc_driver __read_mostly ohci_at91_hc_driver;
-static int clocked;
+
+static const struct ohci_driver_overrides ohci_at91_drv_overrides __initconst 
= {
+   .extra_priv_size = sizeof(struct ohci_at91_priv),
+};
 
 extern int usb_disabled(void);
 
 /*-*/
 
-static void at91_start_clock(void)
+static void at91_start_clock(struct ohci_at91_priv *ohci_at91)
 {
-   if (clocked)
+   if (ohci_at91-clocked)
return;
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
-   clk_set_rate(uclk, 4800);
-   clk_prepare_enable(uclk);
+   clk_set_rate(ohci_at91-uclk, 4800);
+   clk_prepare_enable(ohci_at91-uclk);
}
-   clk_prepare_enable(hclk);
-   clk_prepare_enable(iclk);
-   clk_prepare_enable(fclk);
-   clocked = 1;
+   clk_prepare_enable(ohci_at91-hclk);
+   clk_prepare_enable(ohci_at91-iclk);
+   clk_prepare_enable(ohci_at91-fclk);
+   ohci_at91-clocked = true;
 }
 
-static void at91_stop_clock(void)
+static void at91_stop_clock(struct ohci_at91_priv *ohci_at91)
 {
-   if (!clocked)
+   if (!ohci_at91-clocked)
return;
-   clk_disable_unprepare(fclk);
-   clk_disable_unprepare(iclk);
-   clk_disable_unprepare(hclk);
+   clk_disable_unprepare(ohci_at91-fclk);
+   clk_disable_unprepare(ohci_at91-iclk);
+   clk_disable_unprepare(ohci_at91-hclk);
if (IS_ENABLED(CONFIG_COMMON_CLK))
-   clk_disable_unprepare(uclk);
-   clocked = 0;
+   clk_disable_unprepare(ohci_at91-uclk);
+   ohci_at91-clocked = false;
 }
 
 static void at91_start_hc(struct platform_device *pdev)
 {
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd-regs;
+   struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd);
 
dev_dbg(pdev-dev, start\n);
 
/*
 * Start the USB clocks.
 */
-   at91_start_clock();
+   at91_start_clock(ohci_at91);
 
/*
 * The USB host controller must remain in reset.
@@ -95,6 +107,7 @@ static void at91_stop_hc(struct platform_device *pdev)
 {
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd-regs;
+   struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd);
 
dev_dbg(pdev-dev, stop\n);
 
@@ -106,7 +119,7 @@ static void at91_stop_hc(struct platform_device *pdev)
/*
 * Stop the USB clocks.
 */
-   at91_stop_clock();
+   at91_stop_clock(ohci_at91);
 }
 
 
@@ -133,6 +146,7 @@ static int usb_hcd_at91_probe(const struct hc_driver 
*driver,
struct ohci_hcd *ohci;
int retval;
struct usb_hcd *hcd = NULL;
+   struct ohci_at91_priv *ohci_at91;
struct device *dev = pdev-dev;
struct resource *res;
int irq;
@@ -146,6 +160,7 @@ static int usb_hcd_at91_probe(const struct hc_driver 
*driver,
hcd = usb_create_hcd(driver, dev, at91);
if (!hcd)
return -ENOMEM;
+   ohci_at91 = hcd_to_ohci_at91_priv(hcd);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd-regs = devm_ioremap_resource(dev, res);
@@ -156,29 +171,29 @@ static int usb_hcd_at91_probe(const struct hc_driver 
*driver,
hcd-rsrc_start = res-start;
hcd-rsrc_len = resource_size(res);
 
-   iclk = devm_clk_get(dev, ohci_clk);
-   if (IS_ERR(iclk)) {
+   ohci_at91-iclk = devm_clk_get(dev, ohci_clk);
+   if (IS_ERR(ohci_at91-iclk)) {
dev_err(dev, failed to get ohci_clk\n);
-   retval = PTR_ERR(iclk);
+   retval = PTR_ERR(ohci_at91-iclk);
goto err;
}

[PATCHv3 2/5] USB: host: ohci_at91: Stop/start USB PLL for all sleep modes

2015-01-17 Thread Sylvain Rochet
Disable/unprepare clocks without testing the sleep target_state, removed
the at91_suspend_entering_slow_clock() call (which is only a
target_state == PM_SUSPEND_MEM).

Other kind of suspend now benefit from the power save induced by this
PLL deactivation. The resume penalty is about 500 us, which is not
negligible but acceptable considering the amount of power we are saving.

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
Reported-by: Boris Brezillon boris.brezil...@free-electrons.com
---
 drivers/usb/host/ohci-at91.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index dc9e4e6..f0da734 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -49,6 +49,8 @@ extern int usb_disabled(void);
 
 static void at91_start_clock(void)
 {
+   if (clocked)
+   return;
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
clk_set_rate(uclk, 4800);
clk_prepare_enable(uclk);
@@ -61,6 +63,8 @@ static void at91_start_clock(void)
 
 static void at91_stop_clock(void)
 {
+   if (!clocked)
+   return;
clk_disable_unprepare(fclk);
clk_disable_unprepare(iclk);
clk_disable_unprepare(hclk);
@@ -615,16 +619,14 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, 
pm_message_t mesg)
 *
 * REVISIT: some boards will be able to turn VBUS off...
 */
-   if (at91_suspend_entering_slow_clock()) {
-   ohci-hc_control = ohci_readl(ohci, ohci-regs-control);
-   ohci-hc_control = OHCI_CTRL_RWC;
-   ohci_writel(ohci, ohci-hc_control, ohci-regs-control);
-   ohci-rh_state = OHCI_RH_HALTED;
-
-   /* flush the writes */
-   (void) ohci_readl (ohci, ohci-regs-control);
-   at91_stop_clock();
-   }
+   ohci-hc_control = ohci_readl(ohci, ohci-regs-control);
+   ohci-hc_control = OHCI_CTRL_RWC;
+   ohci_writel(ohci, ohci-hc_control, ohci-regs-control);
+   ohci-rh_state = OHCI_RH_HALTED;
+
+   /* flush the writes */
+   (void) ohci_readl (ohci, ohci-regs-control);
+   at91_stop_clock();
 
return ret;
 }
@@ -636,8 +638,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device 
*pdev)
if (device_may_wakeup(pdev-dev))
disable_irq_wake(hcd-irq);
 
-   if (!clocked)
-   at91_start_clock();
+   at91_start_clock();
 
ohci_resume(hcd, false);
return 0;
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 1/5] USB: host: ehci_atmel: Add suspend/resume support

2015-01-17 Thread Sylvain Rochet
This patch add suspend/resume support for Atmel EHCI, mostly
about disabling and unpreparing clocks so USB PLL is stopped
before entering sleep state.

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
---
 drivers/usb/host/ehci-atmel.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 56a8850..2e0043b 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -37,6 +37,8 @@ static int clocked;
 
 static void atmel_start_clock(void)
 {
+   if (clocked)
+   return;
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
clk_set_rate(uclk, 4800);
clk_prepare_enable(uclk);
@@ -48,6 +50,8 @@ static void atmel_start_clock(void)
 
 static void atmel_stop_clock(void)
 {
+   if (!clocked)
+   return;
clk_disable_unprepare(fclk);
clk_disable_unprepare(iclk);
if (IS_ENABLED(CONFIG_COMMON_CLK))
@@ -174,6 +178,32 @@ static int ehci_atmel_drv_remove(struct platform_device 
*pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
+static int ehci_atmel_drv_suspend(struct platform_device *pdev, pm_message_t 
mesg)
+{
+   struct usb_hcd *hcd = platform_get_drvdata(pdev);
+   int ret;
+
+   ret = ehci_suspend(hcd, false);
+   if (ret)
+   return ret;
+
+   atmel_stop_clock();
+   return 0;
+}
+
+static int ehci_atmel_drv_resume(struct platform_device *pdev)
+{
+   struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+   atmel_start_clock();
+   return ehci_resume(hcd, false);
+}
+#else
+#define ehci_atmel_drv_suspend NULL
+#define ehci_atmel_drv_resume  NULL
+#endif
+
 #ifdef CONFIG_OF
 static const struct of_device_id atmel_ehci_dt_ids[] = {
{ .compatible = atmel,at91sam9g45-ehci },
@@ -187,6 +217,8 @@ static struct platform_driver ehci_atmel_driver = {
.probe  = ehci_atmel_drv_probe,
.remove = ehci_atmel_drv_remove,
.shutdown   = usb_hcd_platform_shutdown,
+   .suspend= ehci_atmel_drv_suspend,
+   .resume = ehci_atmel_drv_resume,
.driver = {
.name   = atmel-ehci,
.of_match_table = of_match_ptr(atmel_ehci_dt_ids),
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: XHCI, brain-dead scanner, and microframe rounding

2015-01-17 Thread Hans-Peter Jansen
Mathias Nyman mathias.nyman@... writes:

 
 On 09/15/2014 10:50 PM, Alan Stern wrote:
  On Mon, 15 Sep 2014, Mathias Nyman wrote:
  
  I haven't had time to dig into the usbmon traces, but I just got
another report from Gunter K�ningsmann
 about similar scanner problem, and I just noticed
  that in both cases we round the interval for high speed bulk _IN_
endpoint, which should not have interval
 set at all.
  The interval value should be ignored by host, but maybe setting it
still could cause some issues. 
 
  I don't have high hopes for this patch, but it's worth a shot.
  Can you try this out and see if it makes any difference?
 
  -Mathias
 
  diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
  index 8936211..7f21b77 100644
  --- a/drivers/usb/host/xhci-mem.c
  +++ b/drivers/usb/host/xhci-mem.c
   at  at  -1291,7 +1291,8  at  at  static unsigned int
xhci_get_endpoint_interval(struct usb_device *udev,
  /* Max NAK rate */
  if (usb_endpoint_xfer_control(ep-desc) ||
  usb_endpoint_xfer_bulk(ep-desc)) {
  -   interval = xhci_parse_microframe_interval(udev,
ep);
  +   if (!usb_endpoint_dir_in(ep-desc))
  +   interval =
xhci_parse_microframe_interval(udev, ep);
  
  It's not a good idea to test the direction of control endpoints, since
  they are bi-directional.
 
 Thats right, thanks, I only wanted the bulk endpoints checked here, I need
to change that.
 
  
  Also, xhci_parse_microframe_interval assumes the value is stored with
  an exponential encoding, but the NAK rate value for control and
  bulk-OUT endpoints is stored in the endpoint descriptor directly as a
  number of microframes (not exponential).
  
  It's not fully clear how xHCI controllers use the Interval field in the
  Endpoint Context.  Table 65 notably fails to include a line for HS
  bulk-OUT/control endpoints, and the text isn't clear as to whether the
  field is interpreted using exponential coding for non-periodic
  endpoints.  As near as I can tell, it is -- which means you should call
  xhci_microframes_to_exponent() here, not
  xhci_parse_microframe_interval().
  
  Alan Stern
  
 
 I think this is correct now as it is, assuming xhci Interval field for HS
bulk-OUT/control endpoint context
 uses the same exponential coding as for all other endpoints.
 
 flow goes:
 if (HS bulk or control ep)//endpoints bInterval is
in number of microframes here, 
   xhci_parse_microframe_interval()
 xhci_microframes_to_exponent(bInterval, ...)
   interval = fls(bInterval) - 1;// interval is now in
exponent form

Any progress on this one?

Quite a bunch of people, that try to use a scanner on a xhci port gets
bitten by this issue. Given, that modern haswell mainboards tend to only
support xhci ports anymore, this is a real showstopper and kind of
regression from users POV.

https://bugzilla.novell.com/show_bug.cgi?id=856794
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1102797

Would be nice to cc me on answers in order to relay results to other
suffering people.

Thanks in advance,
Pete


Re: [PATCHv3 1/5] USB: host: ehci_atmel: Add suspend/resume support

2015-01-17 Thread Sergei Shtylyov

Hello.

On 01/18/2015 12:25 AM, Sylvain Rochet wrote:

   There's little inconsistency in your patch subjects: you're using '_' but 
the files you're modifying are named using '-'...



This patch add suspend/resume support for Atmel EHCI, mostly
about disabling and unpreparing clocks so USB PLL is stopped
before entering sleep state.



Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
---
  drivers/usb/host/ehci-atmel.c | 32 
  1 file changed, 32 insertions(+)



diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 56a8850..2e0043b 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c

[...]

@@ -187,6 +217,8 @@ static struct platform_driver ehci_atmel_driver = {
.probe  = ehci_atmel_drv_probe,
.remove = ehci_atmel_drv_remove,
.shutdown   = usb_hcd_platform_shutdown,
+   .suspend= ehci_atmel_drv_suspend,
+   .resume = ehci_atmel_drv_resume,


   I think you should use 'struct dev_pm_ops' now.

WBR, Sergei

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] USB: host: ohci_at91: Move global variables to private struct

2015-01-17 Thread Sylvain Rochet
This patch move Atmel OHCI global variables (clocks ptr and clocked
boolean) to private struct ohci_at91, appended at the end of the parent
struct usb_hcd.

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
---
 drivers/usb/host/ohci-at91.c | 85 +++-
 1 file changed, 52 insertions(+), 33 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index f0da734..ca53f8a 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -33,7 +33,15 @@
for ((index) = 0; (index)  AT91_MAX_USBH_PORTS; (index)++)
 
 /* interface, function and usb clocks; sometimes also an AHB clock */
-static struct clk *iclk, *fclk, *uclk, *hclk;
+struct ohci_at91 {
+   struct ohci_hcd ohci;
+
+   struct clk *iclk;
+   struct clk *fclk;
+   struct clk *uclk;
+   struct clk *hclk;
+   bool clocked;
+};
 /* interface and function clocks; sometimes also an AHB clock */
 
 #define DRIVER_DESC OHCI Atmel driver
@@ -41,49 +49,54 @@ static struct clk *iclk, *fclk, *uclk, *hclk;
 static const char hcd_name[] = ohci-atmel;
 
 static struct hc_driver __read_mostly ohci_at91_hc_driver;
-static int clocked;
 
 extern int usb_disabled(void);
 
 /*-*/
 
-static void at91_start_clock(void)
+static inline struct ohci_at91 *hcd_to_ohci_at91(struct usb_hcd *hcd)
+{
+   return (struct ohci_at91 *) hcd-hcd_priv;
+}
+
+static void at91_start_clock(struct ohci_at91 *ohci_at91)
 {
-   if (clocked)
+   if (ohci_at91-clocked)
return;
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
-   clk_set_rate(uclk, 4800);
-   clk_prepare_enable(uclk);
+   clk_set_rate(ohci_at91-uclk, 4800);
+   clk_prepare_enable(ohci_at91-uclk);
}
-   clk_prepare_enable(hclk);
-   clk_prepare_enable(iclk);
-   clk_prepare_enable(fclk);
-   clocked = 1;
+   clk_prepare_enable(ohci_at91-hclk);
+   clk_prepare_enable(ohci_at91-iclk);
+   clk_prepare_enable(ohci_at91-fclk);
+   ohci_at91-clocked = true;
 }
 
-static void at91_stop_clock(void)
+static void at91_stop_clock(struct ohci_at91 *ohci_at91)
 {
-   if (!clocked)
+   if (!ohci_at91-clocked)
return;
-   clk_disable_unprepare(fclk);
-   clk_disable_unprepare(iclk);
-   clk_disable_unprepare(hclk);
+   clk_disable_unprepare(ohci_at91-fclk);
+   clk_disable_unprepare(ohci_at91-iclk);
+   clk_disable_unprepare(ohci_at91-hclk);
if (IS_ENABLED(CONFIG_COMMON_CLK))
-   clk_disable_unprepare(uclk);
-   clocked = 0;
+   clk_disable_unprepare(ohci_at91-uclk);
+   ohci_at91-clocked = false;
 }
 
 static void at91_start_hc(struct platform_device *pdev)
 {
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd-regs;
+   struct ohci_at91 *ohci_at91 = hcd_to_ohci_at91(hcd);
 
dev_dbg(pdev-dev, start\n);
 
/*
 * Start the USB clocks.
 */
-   at91_start_clock();
+   at91_start_clock(ohci_at91);
 
/*
 * The USB host controller must remain in reset.
@@ -95,6 +108,7 @@ static void at91_stop_hc(struct platform_device *pdev)
 {
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd-regs;
+   struct ohci_at91 *ohci_at91 = hcd_to_ohci_at91(hcd);
 
dev_dbg(pdev-dev, stop\n);
 
@@ -106,7 +120,7 @@ static void at91_stop_hc(struct platform_device *pdev)
/*
 * Stop the USB clocks.
 */
-   at91_stop_clock();
+   at91_stop_clock(ohci_at91);
 }
 
 
@@ -133,6 +147,7 @@ static int usb_hcd_at91_probe(const struct hc_driver 
*driver,
struct ohci_hcd *ohci;
int retval;
struct usb_hcd *hcd = NULL;
+   struct ohci_at91 *ohci_at91;
struct device *dev = pdev-dev;
struct resource *res;
int irq;
@@ -146,6 +161,7 @@ static int usb_hcd_at91_probe(const struct hc_driver 
*driver,
hcd = usb_create_hcd(driver, dev, at91);
if (!hcd)
return -ENOMEM;
+   ohci_at91 = hcd_to_ohci_at91(hcd);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd-regs = devm_ioremap_resource(dev, res);
@@ -156,29 +172,29 @@ static int usb_hcd_at91_probe(const struct hc_driver 
*driver,
hcd-rsrc_start = res-start;
hcd-rsrc_len = resource_size(res);
 
-   iclk = devm_clk_get(dev, ohci_clk);
-   if (IS_ERR(iclk)) {
+   ohci_at91-iclk = devm_clk_get(dev, ohci_clk);
+   if (IS_ERR(ohci_at91-iclk)) {
dev_err(dev, failed to get ohci_clk\n);
-   retval = PTR_ERR(iclk);
+   retval = PTR_ERR(ohci_at91-iclk);
goto err;
}
-   fclk = devm_clk_get(dev, uhpck);
-   if (IS_ERR(fclk)) {
+   

[PATCH 3/3] USB: host: ohci_at91: usb_hcd_at91_probe(), remove useless stack initialisation

2015-01-17 Thread Sylvain Rochet
struct usb_hcd *hcd = NULL;
...
hcd = usb_create_hcd(driver, dev, at91);

This patch remove *hcd useless initialisation to NULL;

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
---
 drivers/usb/host/ohci-at91.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index ca53f8a..10c9d76 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -146,7 +146,7 @@ static int usb_hcd_at91_probe(const struct hc_driver 
*driver,
struct at91_usbh_data *board;
struct ohci_hcd *ohci;
int retval;
-   struct usb_hcd *hcd = NULL;
+   struct usb_hcd *hcd;
struct ohci_at91 *ohci_at91;
struct device *dev = pdev-dev;
struct resource *res;
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] USB: host: ehci_atmel: Move global variables to private struct

2015-01-17 Thread Sylvain Rochet
This patch move Atmel EHCI global variables (clocks ptr and clocked
boolean) to private struct atmel_ehci, appended at the end of the parent
struct usb_hcd.

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
---
 drivers/usb/host/ehci-atmel.c | 75 +++
 1 file changed, 48 insertions(+), 27 deletions(-)

diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 2e0043b..a47fe3f 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -30,45 +30,62 @@ static const char hcd_name[] = ehci-atmel;
 static struct hc_driver __read_mostly ehci_atmel_hc_driver;
 
 /* interface and function clocks */
-static struct clk *iclk, *fclk, *uclk;
-static int clocked;
+struct atmel_ehci {
+   struct ehci_hcd ehci;
+
+   struct clk *iclk;
+   struct clk *fclk;
+   struct clk *uclk;
+   bool clocked;
+};
 
 /*-*/
 
-static void atmel_start_clock(void)
+static inline struct atmel_ehci *hcd_to_atmel_ehci(struct usb_hcd *hcd)
+{
+   return (struct atmel_ehci *) hcd-hcd_priv;
+}
+
+static void atmel_start_clock(struct atmel_ehci *atmel_ehci)
 {
-   if (clocked)
+   if (atmel_ehci-clocked)
return;
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
-   clk_set_rate(uclk, 4800);
-   clk_prepare_enable(uclk);
+   clk_set_rate(atmel_ehci-uclk, 4800);
+   clk_prepare_enable(atmel_ehci-uclk);
}
-   clk_prepare_enable(iclk);
-   clk_prepare_enable(fclk);
-   clocked = 1;
+   clk_prepare_enable(atmel_ehci-iclk);
+   clk_prepare_enable(atmel_ehci-fclk);
+   atmel_ehci-clocked = true;
 }
 
-static void atmel_stop_clock(void)
+static void atmel_stop_clock(struct atmel_ehci *atmel_ehci)
 {
-   if (!clocked)
+   if (!atmel_ehci-clocked)
return;
-   clk_disable_unprepare(fclk);
-   clk_disable_unprepare(iclk);
+   clk_disable_unprepare(atmel_ehci-fclk);
+   clk_disable_unprepare(atmel_ehci-iclk);
if (IS_ENABLED(CONFIG_COMMON_CLK))
-   clk_disable_unprepare(uclk);
-   clocked = 0;
+   clk_disable_unprepare(atmel_ehci-uclk);
+   atmel_ehci-clocked = false;
 }
 
 static void atmel_start_ehci(struct platform_device *pdev)
 {
+   struct usb_hcd *hcd = platform_get_drvdata(pdev);
+   struct atmel_ehci *atmel_ehci = hcd_to_atmel_ehci(hcd);
+
dev_dbg(pdev-dev, start\n);
-   atmel_start_clock();
+   atmel_start_clock(atmel_ehci);
 }
 
 static void atmel_stop_ehci(struct platform_device *pdev)
 {
+   struct usb_hcd *hcd = platform_get_drvdata(pdev);
+   struct atmel_ehci *atmel_ehci = hcd_to_atmel_ehci(hcd);
+
dev_dbg(pdev-dev, stop\n);
-   atmel_stop_clock();
+   atmel_stop_clock(atmel_ehci);
 }
 
 /*-*/
@@ -79,6 +96,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
const struct hc_driver *driver = ehci_atmel_hc_driver;
struct resource *res;
struct ehci_hcd *ehci;
+   struct atmel_ehci *atmel_ehci;
int irq;
int retval;
 
@@ -109,6 +127,7 @@ static int ehci_atmel_drv_probe(struct platform_device 
*pdev)
retval = -ENOMEM;
goto fail_create_hcd;
}
+   atmel_ehci = hcd_to_atmel_ehci(hcd);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd-regs = devm_ioremap_resource(pdev-dev, res);
@@ -120,23 +139,23 @@ static int ehci_atmel_drv_probe(struct platform_device 
*pdev)
hcd-rsrc_start = res-start;
hcd-rsrc_len = resource_size(res);
 
-   iclk = devm_clk_get(pdev-dev, ehci_clk);
-   if (IS_ERR(iclk)) {
+   atmel_ehci-iclk = devm_clk_get(pdev-dev, ehci_clk);
+   if (IS_ERR(atmel_ehci-iclk)) {
dev_err(pdev-dev, Error getting interface clock\n);
retval = -ENOENT;
goto fail_request_resource;
}
-   fclk = devm_clk_get(pdev-dev, uhpck);
-   if (IS_ERR(fclk)) {
+   atmel_ehci-fclk = devm_clk_get(pdev-dev, uhpck);
+   if (IS_ERR(atmel_ehci-fclk)) {
dev_err(pdev-dev, Error getting function clock\n);
retval = -ENOENT;
goto fail_request_resource;
}
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
-   uclk = devm_clk_get(pdev-dev, usb_clk);
-   if (IS_ERR(uclk)) {
+   atmel_ehci-uclk = devm_clk_get(pdev-dev, usb_clk);
+   if (IS_ERR(atmel_ehci-uclk)) {
dev_err(pdev-dev, failed to get uclk\n);
-   retval = PTR_ERR(uclk);
+   retval = PTR_ERR(atmel_ehci-uclk);
goto fail_request_resource;
}
}
@@ -173,7 +192,6 @@ static int ehci_atmel_drv_remove(struct 

Re: [PATCH 1/3] USB: host: ehci_atmel: Move global variables to private struct

2015-01-17 Thread Sylvain Rochet
Hello Alan,

On Sat, Jan 17, 2015 at 03:30:45PM -0500, Alan Stern wrote:
 
 This is not the right way to do it.  For an example of the right way, 
 see the ehci-platform.c file.  Your private structure is stored in 
 ehci-priv, and its size is specified by the .extra_priv_size member of 
 an ehci_driver_overrides structure passed to ehci_init_driver().

Dammit… reworked this way, thanks for the heads-up !

Sylvain
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


3.18 regression: Error while assigning device slot ID, USB3 devices not detected

2015-01-17 Thread Robert Hancock
I've got an Intel Haswell-based system with a Gigabyte Z87X-D3H 
motherboard under Fedora 21. After updating to the 3.18.2-200 Fedora 
kernel, I noticed some errors in dmesg and at least some of my USB3 
ports don't recognize any USB3 devices plugged into them:


[0.560838] xhci_hcd :00:14.0: Error while assigning device slot ID
[0.560912] xhci_hcd :00:14.0: Max number of devices this xHCI 
host supports is 32.

[0.560990] usb usb2-port2: couldn't allocate usb_device
[0.561098] xhci_hcd :00:14.0: Error while assigning device slot ID
[0.561163] xhci_hcd :00:14.0: Max number of devices this xHCI 
host supports is 32.

[0.561239] usb usb2-port5: couldn't allocate usb_device
[0.561344] xhci_hcd :00:14.0: Error while assigning device slot ID
[0.561409] xhci_hcd :00:14.0: Max number of devices this xHCI 
host supports is 32.

[0.561484] usb usb2-port6: couldn't allocate usb_device

This worked fine under 3.17. Is this a known problem?
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: 3.18 regression: Error while assigning device slot ID, USB3 devices not detected

2015-01-17 Thread Greg KH
On Sun, Jan 18, 2015 at 12:08:18AM -0600, Robert Hancock wrote:
 I've got an Intel Haswell-based system with a Gigabyte Z87X-D3H motherboard
 under Fedora 21. After updating to the 3.18.2-200 Fedora kernel, I noticed
 some errors in dmesg and at least some of my USB3 ports don't recognize any
 USB3 devices plugged into them:
 
 [0.560838] xhci_hcd :00:14.0: Error while assigning device slot ID
 [0.560912] xhci_hcd :00:14.0: Max number of devices this xHCI host
 supports is 32.
 [0.560990] usb usb2-port2: couldn't allocate usb_device
 [0.561098] xhci_hcd :00:14.0: Error while assigning device slot ID
 [0.561163] xhci_hcd :00:14.0: Max number of devices this xHCI host
 supports is 32.
 [0.561239] usb usb2-port5: couldn't allocate usb_device
 [0.561344] xhci_hcd :00:14.0: Error while assigning device slot ID
 [0.561409] xhci_hcd :00:14.0: Max number of devices this xHCI host
 supports is 32.
 [0.561484] usb usb2-port6: couldn't allocate usb_device
 
 This worked fine under 3.17. Is this a known problem?

Yes it is, should be fixed in Linus's tree now and will be backported to
the latest 3.18-stable tree in a week or so.

thanks,

greg k-h
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv3 1/5] USB: host: ehci_atmel: Add suspend/resume support

2015-01-17 Thread Sylvain Rochet
Hi Sergei,


On Sun, Jan 18, 2015 at 01:22:38AM +0300, Sergei Shtylyov wrote:
 
There's little inconsistency in your patch subjects: you're using
 '_' but the files you're modifying are named using '-'...

Indeed.


 @@ -187,6 +217,8 @@ static struct platform_driver ehci_atmel_driver = {
  .probe  = ehci_atmel_drv_probe,
  .remove = ehci_atmel_drv_remove,
  .shutdown   = usb_hcd_platform_shutdown,
 +.suspend= ehci_atmel_drv_suspend,
 +.resume = ehci_atmel_drv_resume,
 
I think you should use 'struct dev_pm_ops' now.

This way ?

static int ehci_atmel_drv_suspend(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
(...)


static SIMPLE_DEV_PM_OPS(ehci_atmel_pm_ops, ehci_atmel_drv_suspend, 
ehci_atmel_drv_resume);

(...)
.driver = {
.pm = ehci_atmel_pm_ops,
}
(...)


Should I send a v4 or can I send this change separately on top of the 
previous change ?


Sylvain
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mmc: vub300: remove unreachable return value handling

2015-01-17 Thread Nicholas Mc Guire
Signed-off-by: Nicholas Mc Guire der.h...@hofr.at
---

The return value of wait_for_completion_timeout is unsigned long, 
as it is used here for wait_for_completion_timeout only the type 
of commretval was changed to unsigned long.

As wait_for_completion_timeout does not return negative values
the commretval  0 case is not reachable and can be removed.

This was only compile-tested for x86_64_defconfig + CONFIG_MMC=m,
CONFIG_MMC_VUB300=m

Patch is against 3.19.0-rc4 -next-20150116

 drivers/mmc/host/vub300.c |4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index 4262296..fbabbb8 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -659,7 +659,7 @@ static void __vub300_irqpoll_response(struct 
vub300_mmc_host *vub300)
 static void __do_poll(struct vub300_mmc_host *vub300)
 {
/* cmd_mutex is held by vub300_pollwork_thread */
-   long commretval;
+   unsigned long commretval;
mod_timer(vub300-inactivity_timer, jiffies + HZ);
init_completion(vub300-irqpoll_complete);
send_irqpoll(vub300);
@@ -671,8 +671,6 @@ static void __do_poll(struct vub300_mmc_host *vub300)
vub300-usb_timed_out = 1;
usb_kill_urb(vub300-command_out_urb);
usb_kill_urb(vub300-command_res_urb);
-   } else if (commretval  0) {
-   vub300_queue_poll_work(vub300, 1);
} else { /* commretval  0 */
__vub300_irqpoll_response(vub300);
}
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: NETDEV WATCHDOG: internal(r8152): transmit queue 0 timed out

2015-01-17 Thread poma
On 17.01.2015 00:57, sean darcy wrote:
 On 01/16/2015 07:09 AM, poma wrote:
 On 16.01.2015 10:37, Hayes Wang wrote:
   poma [mailto:pomidorabelis...@gmail.com]
 Sent: Friday, January 16, 2015 4:25 PM
 [...]
 This looks like a USB problem. Is there a way to get usb (or
 NetworkManager) to reinitialize the driver when this happens?

 I would ask these people for advice, therefore.

 Our hw engineers need to analyse the behavior of the device.
 However, I don't think you have such instrument to provide
 the required information. If we don't know the reason, we
 couldn't give you the proper solution. Besides, your solution
 would work if and only if reloading the driver is helpful.

 The issue have to debug from the hardware, and I have no idea
 about what the software could do before analysing the hw. Maybe
 you could try the following driver first to check if it is useful.

 http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=2PNid=13PFid=56Level=5Conn=4DownTypeID=3GetDown=false

 Best Regards,
 Hayes


 Thanks for your response, Mr. Hayes.

 Mr. Sean, please download and check if timeout is still present with built 
 RTL8153 module from REALTEK site, as Mr. Hayes proposed.
 http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=2PNid=13PFid=56Level=5Conn=4DownTypeID=3GetDown=false#2
 r8152.53-2.03.0.tar.bz2

 Procedure - should be equal for both, Fedora 21  20:

 $ uname -r
 3.17.8-300.fc21.x86_64

 $ su -c 'yum install kernel-devel'

 $ tar xf r8152.53-2.03.0.tar.bz2
 $ cd r8152-2.03.0/
 $ make
 $ su

 # cp 50-usb-realtek-net.rules /etc/udev/rules.d/
 # udevadm trigger --action=add

 # modprobe -rv r8152
 # cp r8152.ko /lib/modules/$(uname -r)/updates/
 # depmod
 # modprobe -v r8152


 poma

 OK. Did all that. Now to see if I get the same problem over the next 
 couple of weeks.
 
 I'd never heard about the updates subfolder in modules. Very slick.
 
 But when I update the kernel, I get to do this again correct? How will I 

$ cd r8152-2.03.0/
$ make clean
$ make
$ su

# cp r8152.ko /lib/modules/$(uname -r)/updates/
# depmod
# modprobe -v r8152

is part of the procedure necessary for a new i.e. an upgraded kernel.


 know that this module has been incorporated in the running kernel. 
 modinfo doesn't give any version info.
 

$ modinfo r8152 -n

will show the module considered for loading.


 BTW, I'm not sure what modprobe --dump-modversions is supposed to do, 
 but it doesn't:
 
 #modprobe --dump-modversions r8152
 modprobe: FATAL: Module r8152 not found.
 # modprobe --dump-modversions r8152.ko
 modprobe: FATAL: Module r8152.ko not found.
 #lsmod | grep 8152
 r8152  49646  0
 

--dump-modversions will probably show the same error for any module.


 Thanks for all your help.
 
 sean
 

YW



--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv2 1/2] USB: host: ehci_atmel: Add suspend/resume support

2015-01-17 Thread Sylvain Rochet
This patch add suspend/resume support for Atmel EHCI, mostly
about disabling and unpreparing clocks so USB PLL is stopped
before entering sleep state.

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
---
 drivers/usb/host/ehci-atmel.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 56a8850..2e0043b 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -37,6 +37,8 @@ static int clocked;
 
 static void atmel_start_clock(void)
 {
+   if (clocked)
+   return;
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
clk_set_rate(uclk, 4800);
clk_prepare_enable(uclk);
@@ -48,6 +50,8 @@ static void atmel_start_clock(void)
 
 static void atmel_stop_clock(void)
 {
+   if (!clocked)
+   return;
clk_disable_unprepare(fclk);
clk_disable_unprepare(iclk);
if (IS_ENABLED(CONFIG_COMMON_CLK))
@@ -174,6 +178,32 @@ static int ehci_atmel_drv_remove(struct platform_device 
*pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
+static int ehci_atmel_drv_suspend(struct platform_device *pdev, pm_message_t 
mesg)
+{
+   struct usb_hcd *hcd = platform_get_drvdata(pdev);
+   int ret;
+
+   ret = ehci_suspend(hcd, false);
+   if (ret)
+   return ret;
+
+   atmel_stop_clock();
+   return 0;
+}
+
+static int ehci_atmel_drv_resume(struct platform_device *pdev)
+{
+   struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+   atmel_start_clock();
+   return ehci_resume(hcd, false);
+}
+#else
+#define ehci_atmel_drv_suspend NULL
+#define ehci_atmel_drv_resume  NULL
+#endif
+
 #ifdef CONFIG_OF
 static const struct of_device_id atmel_ehci_dt_ids[] = {
{ .compatible = atmel,at91sam9g45-ehci },
@@ -187,6 +217,8 @@ static struct platform_driver ehci_atmel_driver = {
.probe  = ehci_atmel_drv_probe,
.remove = ehci_atmel_drv_remove,
.shutdown   = usb_hcd_platform_shutdown,
+   .suspend= ehci_atmel_drv_suspend,
+   .resume = ehci_atmel_drv_resume,
.driver = {
.name   = atmel-ehci,
.of_match_table = of_match_ptr(atmel_ehci_dt_ids),
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv2 2/2] USB: host: ohci_at91: Stop/start USB PLL for all sleep modes

2015-01-17 Thread Sylvain Rochet
Disable/unprepare clocks without testing the sleep target_state, removed
the at91_suspend_entering_slow_clock() call (which is only a
target_state == PM_SUSPEND_MEM).

Other kind of suspend now benefit from the power save induced by this
PLL deactivation. The resume penalty is about 500 us, which is not
negligible but acceptable considering the amount of power we are saving.

Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
Reported-by: Boris Brezillon boris.brezil...@free-electrons.com
---
 drivers/usb/host/ohci-at91.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index dc9e4e6..f0da734 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -49,6 +49,8 @@ extern int usb_disabled(void);
 
 static void at91_start_clock(void)
 {
+   if (clocked)
+   return;
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
clk_set_rate(uclk, 4800);
clk_prepare_enable(uclk);
@@ -61,6 +63,8 @@ static void at91_start_clock(void)
 
 static void at91_stop_clock(void)
 {
+   if (!clocked)
+   return;
clk_disable_unprepare(fclk);
clk_disable_unprepare(iclk);
clk_disable_unprepare(hclk);
@@ -615,16 +619,14 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, 
pm_message_t mesg)
 *
 * REVISIT: some boards will be able to turn VBUS off...
 */
-   if (at91_suspend_entering_slow_clock()) {
-   ohci-hc_control = ohci_readl(ohci, ohci-regs-control);
-   ohci-hc_control = OHCI_CTRL_RWC;
-   ohci_writel(ohci, ohci-hc_control, ohci-regs-control);
-   ohci-rh_state = OHCI_RH_HALTED;
-
-   /* flush the writes */
-   (void) ohci_readl (ohci, ohci-regs-control);
-   at91_stop_clock();
-   }
+   ohci-hc_control = ohci_readl(ohci, ohci-regs-control);
+   ohci-hc_control = OHCI_CTRL_RWC;
+   ohci_writel(ohci, ohci-hc_control, ohci-regs-control);
+   ohci-rh_state = OHCI_RH_HALTED;
+
+   /* flush the writes */
+   (void) ohci_readl (ohci, ohci-regs-control);
+   at91_stop_clock();
 
return ret;
 }
@@ -636,8 +638,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device 
*pdev)
if (device_may_wakeup(pdev-dev))
disable_irq_wake(hcd-irq);
 
-   if (!clocked)
-   at91_start_clock();
+   at91_start_clock();
 
ohci_resume(hcd, false);
return 0;
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv2 1/2] USB: host: ehci_atmel: Add suspend/resume support

2015-01-17 Thread Boris Brezillon
On Sat, 17 Jan 2015 16:36:34 +0100
Sylvain Rochet sylvain.roc...@finsecur.com wrote:

 This patch add suspend/resume support for Atmel EHCI, mostly
 about disabling and unpreparing clocks so USB PLL is stopped
 before entering sleep state.
 
 Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com

Acked-by: Boris Brezillon boris.brezil...@free-electrons.com

 ---
  drivers/usb/host/ehci-atmel.c | 32 
  1 file changed, 32 insertions(+)
 
 diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
 index 56a8850..2e0043b 100644
 --- a/drivers/usb/host/ehci-atmel.c
 +++ b/drivers/usb/host/ehci-atmel.c
 @@ -37,6 +37,8 @@ static int clocked;
  
  static void atmel_start_clock(void)
  {
 + if (clocked)
 + return;
   if (IS_ENABLED(CONFIG_COMMON_CLK)) {
   clk_set_rate(uclk, 4800);
   clk_prepare_enable(uclk);
 @@ -48,6 +50,8 @@ static void atmel_start_clock(void)
  
  static void atmel_stop_clock(void)
  {
 + if (!clocked)
 + return;
   clk_disable_unprepare(fclk);
   clk_disable_unprepare(iclk);
   if (IS_ENABLED(CONFIG_COMMON_CLK))
 @@ -174,6 +178,32 @@ static int ehci_atmel_drv_remove(struct platform_device 
 *pdev)
   return 0;
  }
  
 +#ifdef CONFIG_PM
 +static int ehci_atmel_drv_suspend(struct platform_device *pdev, pm_message_t 
 mesg)
 +{
 + struct usb_hcd *hcd = platform_get_drvdata(pdev);
 + int ret;
 +
 + ret = ehci_suspend(hcd, false);
 + if (ret)
 + return ret;
 +
 + atmel_stop_clock();
 + return 0;
 +}
 +
 +static int ehci_atmel_drv_resume(struct platform_device *pdev)
 +{
 + struct usb_hcd *hcd = platform_get_drvdata(pdev);
 +
 + atmel_start_clock();
 + return ehci_resume(hcd, false);
 +}
 +#else
 +#define ehci_atmel_drv_suspend NULL
 +#define ehci_atmel_drv_resume  NULL
 +#endif
 +
  #ifdef CONFIG_OF
  static const struct of_device_id atmel_ehci_dt_ids[] = {
   { .compatible = atmel,at91sam9g45-ehci },
 @@ -187,6 +217,8 @@ static struct platform_driver ehci_atmel_driver = {
   .probe  = ehci_atmel_drv_probe,
   .remove = ehci_atmel_drv_remove,
   .shutdown   = usb_hcd_platform_shutdown,
 + .suspend= ehci_atmel_drv_suspend,
 + .resume = ehci_atmel_drv_resume,
   .driver = {
   .name   = atmel-ehci,
   .of_match_table = of_match_ptr(atmel_ehci_dt_ids),



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv2 2/2] USB: host: ohci_at91: Stop/start USB PLL for all sleep modes

2015-01-17 Thread Boris Brezillon
On Sat, 17 Jan 2015 16:36:35 +0100
Sylvain Rochet sylvain.roc...@finsecur.com wrote:

 Disable/unprepare clocks without testing the sleep target_state, removed
 the at91_suspend_entering_slow_clock() call (which is only a
 target_state == PM_SUSPEND_MEM).
 
 Other kind of suspend now benefit from the power save induced by this
 PLL deactivation. The resume penalty is about 500 us, which is not
 negligible but acceptable considering the amount of power we are saving.
 
 Signed-off-by: Sylvain Rochet sylvain.roc...@finsecur.com
 Reported-by: Boris Brezillon boris.brezil...@free-electrons.com

Acked-by: Boris Brezillon boris.brezil...@free-electrons.com

 ---
  drivers/usb/host/ohci-at91.c | 25 +
  1 file changed, 13 insertions(+), 12 deletions(-)
 
 diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
 index dc9e4e6..f0da734 100644
 --- a/drivers/usb/host/ohci-at91.c
 +++ b/drivers/usb/host/ohci-at91.c
 @@ -49,6 +49,8 @@ extern int usb_disabled(void);
  
  static void at91_start_clock(void)
  {
 + if (clocked)
 + return;
   if (IS_ENABLED(CONFIG_COMMON_CLK)) {
   clk_set_rate(uclk, 4800);
   clk_prepare_enable(uclk);
 @@ -61,6 +63,8 @@ static void at91_start_clock(void)
  
  static void at91_stop_clock(void)
  {
 + if (!clocked)
 + return;
   clk_disable_unprepare(fclk);
   clk_disable_unprepare(iclk);
   clk_disable_unprepare(hclk);
 @@ -615,16 +619,14 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, 
 pm_message_t mesg)
*
* REVISIT: some boards will be able to turn VBUS off...
*/
 - if (at91_suspend_entering_slow_clock()) {
 - ohci-hc_control = ohci_readl(ohci, ohci-regs-control);
 - ohci-hc_control = OHCI_CTRL_RWC;
 - ohci_writel(ohci, ohci-hc_control, ohci-regs-control);
 - ohci-rh_state = OHCI_RH_HALTED;
 -
 - /* flush the writes */
 - (void) ohci_readl (ohci, ohci-regs-control);
 - at91_stop_clock();
 - }
 + ohci-hc_control = ohci_readl(ohci, ohci-regs-control);
 + ohci-hc_control = OHCI_CTRL_RWC;
 + ohci_writel(ohci, ohci-hc_control, ohci-regs-control);
 + ohci-rh_state = OHCI_RH_HALTED;
 +
 + /* flush the writes */
 + (void) ohci_readl (ohci, ohci-regs-control);
 + at91_stop_clock();
  
   return ret;
  }
 @@ -636,8 +638,7 @@ static int ohci_hcd_at91_drv_resume(struct 
 platform_device *pdev)
   if (device_may_wakeup(pdev-dev))
   disable_irq_wake(hcd-irq);
  
 - if (!clocked)
 - at91_start_clock();
 + at91_start_clock();
  
   ohci_resume(hcd, false);
   return 0;



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html