[PATCH] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen Acked-by: John Youn Tested-by: Stefan Wahren --- Hi Felipe, Can you please take this patch through your USB tree? This patch was dependent on "168d7c4e8bb2 reset: Return -ENOTSUPP when not configured" and is now in v3.8-rc1. The discussion is highlight here: https://lkml.org/lkml/2016/7/7/291 Thanks, Dinh --- v7: Use devm_reset_control_get_optional() v6: fix 80 line checkpatch warning in dev_err print v5: updated error conditions for not finding the reset property v4: use dev_dbg() if not a -EPROBE_DEFER v3: fix compile error v2: move to lowlevel_hw_init() --- drivers/usb/dwc2/core.h |1 + drivers/usb/dwc2/platform.c | 22 ++ 2 files changed, 23 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 9fae029..d645512 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -868,6 +868,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index fc6f525..530959a 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + ret = PTR_ERR(hsotg->reset); + switch (ret) { + case -ENOENT: + case -ENOTSUPP: + hsotg->reset = NULL; + break; + default: + dev_err(hsotg->dev, "error getting reset control %d\n", + ret); + return ret; + } + } + + if (hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +453,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } -- 1.7.9.5 -- 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
[RESEND PATCH] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen Acked-by: John Youn Tested-by: Stefan Wahren --- v7: Use devm_reset_control_get_optional() v6: fix 80 line checkpatch warning in dev_err print v5: updated error conditions for not finding the reset property v4: use dev_dbg() if not a -EPROBE_DEFER v3: fix compile error v2: move to lowlevel_hw_init() --- drivers/usb/dwc2/core.h |1 + drivers/usb/dwc2/platform.c | 22 ++ 2 files changed, 23 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..d34f169 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + ret = PTR_ERR(hsotg->reset); + switch (ret) { + case -ENOENT: + case -ENOTSUPP: + hsotg->reset = NULL; + break; + default: + dev_err(hsotg->dev, "error getting reset control %d\n", + ret); + return ret; + } + } + + if (hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +453,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } -- 1.7.9.5 -- 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
[RESEND PATCH] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen Acked-by: John Youn Tested-by: Stefan Wahren --- v7: Use devm_reset_control_get_optional() v6: fix 80 line checkpatch warning in dev_err print v5: updated error conditions for not finding the reset property v4: use dev_dbg() if not a -EPROBE_DEFER v3: fix compile error v2: move to lowlevel_hw_init() --- drivers/usb/dwc2/core.h |1 + drivers/usb/dwc2/platform.c | 22 ++ 2 files changed, 23 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..d34f169 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + ret = PTR_ERR(hsotg->reset); + switch (ret) { + case -ENOENT: + case -ENOTSUPP: + hsotg->reset = NULL; + break; + default: + dev_err(hsotg->dev, "error getting reset control %d\n", + ret); + return ret; + } + } + + if (hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +453,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } -- 1.7.9.5 -- 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
[PATCHv7] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen --- v7: Use devm_reset_control_get_optional() v6: fix 80 line checkpatch warning in dev_err print v5: updated error conditions for not finding the reset property v4: use dev_dbg() if not a -EPROBE_DEFER v3: fix compile error v2: move to lowlevel_hw_init() --- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/platform.c | 22 ++ 2 files changed, 23 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..d34f169 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + ret = PTR_ERR(hsotg->reset); + switch (ret) { + case -ENOENT: + case -ENOTSUPP: + hsotg->reset = NULL; + break; + default: + dev_err(hsotg->dev, "error getting reset control %d\n", + ret); + return ret; + } + } + + if (hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +453,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } -- 2.6.2 -- 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
[PATCHv6 2/2] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen --- v6: fix 80 line checkpatch warning in dev_err print v5: updated error conditions for not finding the reset property v4: use dev_dbg() if not a -EPROBE_DEFER v3: fix compile error v2: move to lowlevel_hw_init() --- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/platform.c | 21 + 2 files changed, 22 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..fa2c097 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,23 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + hsotg->reset = devm_reset_control_get(hsotg->dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + ret = PTR_ERR(hsotg->reset); + switch (ret) { + case -ENOENT: + hsotg->reset = NULL; + break; + default: + dev_err(hsotg->dev, "error getting reset control %d\n", + ret); + return ret; + } + } + + if (hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +452,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } -- 2.6.2 -- 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/2] Documentation: dt-bindings: dwc2: add the resets and reset-names property
From: Dinh NguyenDocument the optional 'resets' and 'reset-names' property for the DWC2 usb core. Signed-off-by: Dinh Nguyen Acked-by: Rob Herring --- Documentation/devicetree/bindings/usb/dwc2.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 20a68bf..c9ccea6 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -27,6 +27,9 @@ Refer to phy/phy-bindings.txt for generic phy consumer properties - g-rx-fifo-size: size of rx fifo size in gadget mode. - g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode. - g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) in gadget mode. +- resets: list of phandle and reset specifier pairs. The should be one entry for + softreset line of the USB IP. +- reset-names: Should be "dwc2". Example: -- 2.6.2 -- 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
[PATCHv5] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen --- v5: updated error conditions for not finding the reset property v4: use dev_dbg() if not a -EPROBE_DEFER v3: fix compile error v2: move to lowlevel_hw_init() --- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/platform.c | 20 2 files changed, 21 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..2861c89 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,22 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + hsotg->reset = devm_reset_control_get(hsotg->dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + ret = PTR_ERR(hsotg->reset); + switch (ret) { + case -ENOENT: + hsotg->reset = NULL; + break; + default: + dev_err(hsotg->dev, "error getting reset control %d\n", ret); + return ret; + } + } + + if (hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +451,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } -- 2.6.2 -- 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/2] Documentation: dt-bindings: dwc2: add the resets and reset-names property
From: Dinh NguyenDocument the optional 'resets' and 'reset-names' property for the DWC2 usb core. Signed-off-by: Dinh Nguyen --- Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala --- Documentation/devicetree/bindings/usb/dwc2.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 20a68bf..c9ccea6 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -27,6 +27,9 @@ Refer to phy/phy-bindings.txt for generic phy consumer properties - g-rx-fifo-size: size of rx fifo size in gadget mode. - g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode. - g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) in gadget mode. +- resets: list of phandle and reset specifier pairs. The should be one entry for + softreset line of the USB IP. +- reset-names: Should be "dwc2". Example: -- 2.6.2 -- 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 2/2] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen --- v4: use dev_dbg() if not a -EPROBE_DEFER v3: fix compile error v2: move to lowlevel_hw_init() --- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/platform.c | 15 +++ 2 files changed, 16 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..5e89af1 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,17 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + hsotg->reset = devm_reset_control_get(hsotg->dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + if (PTR_ERR(hsotg->reset) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_dbg(hsotg->dev, "Could not get reset control.\n"); + hsotg->reset = NULL; + } + + if(hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +446,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } -- 2.6.2 -- 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] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen --- v3: fix compile error v2: move to lowlevel_hw_init() --- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/platform.c | 15 +++ 2 files changed, 16 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..6987ef3 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,17 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + hsotg->reset = devm_reset_control_get(hsotg->dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + dev_info(hsotg->dev, "Could not get reset control!\n"); + if (PTR_ERR(hsotg->reset) == -EPROBE_DEFER) + return -EPROBE_DEFER; + hsotg->reset = NULL; + } + + if(hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +446,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } -- 2.8.1 -- 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] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen --- v2: move to lowlevel_hw_init() --- drivers/usb/dwc2/core.h |1 + drivers/usb/dwc2/platform.c | 15 +++ 2 files changed, 16 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..be6b18a 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,17 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + hsotg->reset = devm_reset_control_get(>dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + dev_info(>dev, "Could not get reset control!\n"); + if (PTR_ERR(hsotg->reset) == -EPROBE_DEFER) + return -EPROBE_DEFER; + hsotg->reset = NULL; + } + + if(hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +446,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } -- 1.7.9.5 -- 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 RESEND 2/2] ARM: socfpga: dts: add reset control for USB
From: Dinh NguyenAdd the resets property for the 2 USB controllers. Signed-off-by: Dinh Nguyen Cc: John Youn Cc: Felipe Balbi --- arch/arm/boot/dts/socfpga.dtsi |4 arch/arm/boot/dts/socfpga_arria10.dtsi |4 2 files changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index b89cbde3b..9f48141 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi @@ -831,6 +831,8 @@ interrupts = <0 125 4>; clocks = <_mp_clk>; clock-names = "otg"; + resets = < USB0_RESET>; + reset-names = "dwc2"; phys = <>; phy-names = "usb2-phy"; status = "disabled"; @@ -842,6 +844,8 @@ interrupts = <0 128 4>; clocks = <_mp_clk>; clock-names = "otg"; + resets = < USB1_RESET>; + reset-names = "dwc2"; phys = <>; phy-names = "usb2-phy"; status = "disabled"; diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi index 1c5e139..b065651 100644 --- a/arch/arm/boot/dts/socfpga_arria10.dtsi +++ b/arch/arm/boot/dts/socfpga_arria10.dtsi @@ -689,6 +689,8 @@ interrupts = <0 95 IRQ_TYPE_LEVEL_HIGH>; clocks = <_clk>; clock-names = "otg"; + resets = < USB0_RESET>; + reset-names = "dwc2"; phys = <>; phy-names = "usb2-phy"; status = "disabled"; @@ -700,6 +702,8 @@ interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>; clocks = <_clk>; clock-names = "otg"; + resets = < USB1_RESET>; + reset-names = "dwc2"; phys = <>; phy-names = "usb2-phy"; status = "disabled"; -- 1.7.9.5 -- 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 RESEND 1/2] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen Cc: John Youn Cc: Felipe Balbi --- Resend with Cc to Felipe. --- drivers/usb/dwc2/core.h |1 + drivers/usb/dwc2/platform.c | 15 +++ 2 files changed, 16 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..b1fa9dd 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,9 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + if(hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +438,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } @@ -529,6 +536,14 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(>dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); + hsotg->reset = devm_reset_control_get(>dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + dev_info(>dev, "Could not get reset control!\n"); + if (PTR_ERR(hsotg->reset) == -EPROBE_DEFER) + return -EPROBE_DEFER; + hsotg->reset = NULL; + } + retval = dwc2_lowlevel_hw_init(hsotg); if (retval) return retval; -- 1.7.9.5 -- 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/2] usb: dwc2: Add reset control to dwc2
From: Dinh NguyenAllow for platforms that have a reset controller driver in place to bring the USB IP out of reset. Signed-off-by: Dinh Nguyen Cc: John Youn --- drivers/usb/dwc2/core.h |1 + drivers/usb/dwc2/platform.c | 15 +++ 2 files changed, 16 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3c58d63..f748132 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -837,6 +837,7 @@ struct dwc2_hsotg { void *priv; int irq; struct clk *clk; + struct reset_control *reset; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629be..b1fa9dd 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -337,6 +338,9 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; + if(hsotg->reset) + reset_control_deassert(hsotg->reset); + /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -434,6 +438,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->reset) + reset_control_assert(hsotg->reset); + return 0; } @@ -529,6 +536,14 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(>dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); + hsotg->reset = devm_reset_control_get(>dev, "dwc2"); + if (IS_ERR(hsotg->reset)) { + dev_info(>dev, "Could not get reset control!\n"); + if (PTR_ERR(hsotg->reset) == -EPROBE_DEFER) + return -EPROBE_DEFER; + hsotg->reset = NULL; + } + retval = dwc2_lowlevel_hw_init(hsotg); if (retval) return retval; -- 1.7.9.5 -- 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/2] ARM: socfpga: dts: add reset control for USB
From: Dinh NguyenAdd the resets property for the 2 USB controllers. Signed-off-by: Dinh Nguyen --- arch/arm/boot/dts/socfpga.dtsi |4 arch/arm/boot/dts/socfpga_arria10.dtsi |4 2 files changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index b89cbde3b..9f48141 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi @@ -831,6 +831,8 @@ interrupts = <0 125 4>; clocks = <_mp_clk>; clock-names = "otg"; + resets = < USB0_RESET>; + reset-names = "dwc2"; phys = <>; phy-names = "usb2-phy"; status = "disabled"; @@ -842,6 +844,8 @@ interrupts = <0 128 4>; clocks = <_mp_clk>; clock-names = "otg"; + resets = < USB1_RESET>; + reset-names = "dwc2"; phys = <>; phy-names = "usb2-phy"; status = "disabled"; diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi index 1c5e139..b065651 100644 --- a/arch/arm/boot/dts/socfpga_arria10.dtsi +++ b/arch/arm/boot/dts/socfpga_arria10.dtsi @@ -689,6 +689,8 @@ interrupts = <0 95 IRQ_TYPE_LEVEL_HIGH>; clocks = <_clk>; clock-names = "otg"; + resets = < USB0_RESET>; + reset-names = "dwc2"; phys = <>; phy-names = "usb2-phy"; status = "disabled"; @@ -700,6 +702,8 @@ interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>; clocks = <_clk>; clock-names = "otg"; + resets = < USB1_RESET>; + reset-names = "dwc2"; phys = <>; phy-names = "usb2-phy"; status = "disabled"; -- 1.7.9.5 -- 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] usb: dwc2: fix unnecessary USB overcurrent condition
From: Dinh Nguyen dingu...@opensource.altera.com For platforms that use a ULPI phy, we should enable the external VbusValid signal instead. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Cc: Gregory Herrero gregory.herr...@intel.com Cc: Mian Yousaf Kaukab yousaf.kau...@intel.com Cc: Felipe Balbi ba...@ti.com --- drivers/usb/dwc2/core.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index e5b546f..08ffdc6 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -807,6 +807,11 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) if (hsotg-core_params-ts_dline 0) usbcfg |= GUSBCFG_TERMSELDLPULSE; + /* Set external VBUS indicator as needed. */ + if (hsotg-core_params-phy_type == DWC2_PHY_TYPE_PARAM_ULPI) + usbcfg |= (GUSBCFG_ULPI_INT_VBUS_IND | + GUSBCFG_INDICATORPASSTHROUGH); + writel(usbcfg, hsotg-regs + GUSBCFG); /* Reset the Controller */ -- 2.2.1 -- 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] usb: dwc2: remove early return on clock query
From: Dinh Nguyen dingu...@opensource.altera.com Since we have assigned clk=NULL, which is a valid clk, we should not be returning when a clock node is not provide. Instead, we should return only when we cannot enable the clock. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/gadget.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 05b0522..407f55c 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3451,8 +3451,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) hsotg-clk = devm_clk_get(dev, otg); if (IS_ERR(hsotg-clk)) { hsotg-clk = NULL; - dev_err(dev, cannot get otg clock\n); - return PTR_ERR(hsotg-clk); + dev_dbg(dev, cannot get otg clock\n); } hsotg-gadget.max_speed = USB_SPEED_HIGH; @@ -3461,7 +3460,12 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) /* reset the system */ - clk_prepare_enable(hsotg-clk); + ret = clk_prepare_enable(hsotg-clk); + if (ret) { + dev_err(dev, failed to enable otg clk\n); + goto err_clk; + } + /* regulators */ -- 2.0.3 -- 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
[PATCHv7 0/8] usb: dwc2: Add support for dual-role
From: Dinh Nguyen dingu...@opensource.altera.com Hello, This is version 7 of the patch series that combines the dwc2 gadget and host driver into a single dual role driver. Here are the main differences from V6: - patch 1/8: Addressed Felipe's comment on which variables should not be just limited to gadget(phy, uphy, regulator_bulk_data_supplies, irq, clk, debug_root, debug_file, and debug_fifo). - patch 2/8: Move conversion to use dev_pm_ops API to separate patch. - patch 3/8: Convert to use dev_pm_ops API - patch 4/8: Rebased to s3c_hsotg_core_init is now s3c_hsotg_core_init_disconnected(), followed by s3c_hsotg_core_connect(). - patch 5/8: Use IRQF_SHARED to have s3c_hsotg_irq handle gadget interrupts. Had to remove paulz's Acked-by for this patch, as it is not quite the same patch when his ack was given. - patch 6/8: Assign clk=NULL if a clock is not provided. - patch 7/8: Moved ahead of Kconfig/Makefile patch to avoid a build error when patch 8 is applied to dual-role. - patch 8/8: none For v7, the series is rebased on top of Felipe Balbi's tree on -next branch. I thought this might be appropriate as there are dwc2 patches already on this branch. As usual, tested on SOCFPGA(host, gadget, and dual-role) and on Rpi-B (host mode only). I have pushed this series to a git repo to make it more convenient for people to test/review. git://git.rocketboards.org/linux-socfpga-next.git dwc2_dual_role_v7 Thanks, Dinh Nguyen (8): usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure usb: dwc2: Move gadget probe function into platform code usb: dwc2: convert to use dev_pm_ops API usb: dwc2: Initialize the USB core for peripheral mode usb: dwc2: Update common interrupt handler to call gadget interrupt handler usb: dwc2: gadget: Do not fail probe if there isn't a clock node usb: dwc2: move usb_disabled() call to host driver only usb: dwc2: Update Kconfig to support dual-role drivers/usb/dwc2/Kconfig | 66 ++- drivers/usb/dwc2/Makefile| 32 ++--- drivers/usb/dwc2/core.c | 10 -- drivers/usb/dwc2/core.h | 192 ++ drivers/usb/dwc2/core_intr.c | 8 +- drivers/usb/dwc2/gadget.c| 274 ++- drivers/usb/dwc2/hcd.c | 6 +- drivers/usb/dwc2/hcd.h | 10 -- drivers/usb/dwc2/pci.c | 7 ++ drivers/usb/dwc2/platform.c | 42 ++- 10 files changed, 317 insertions(+), 330 deletions(-) -- 2.0.3 -- 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
[PATCHv7 8/8] usb: dwc2: Update Kconfig to support dual-role
From: Dinh Nguyen dingu...@opensource.altera.com Update DWC2 kconfig and makefile to support dual-role mode. The platform file will always get compiled for the case where the controller is directly connected to the CPU. So for loadable modules, dwc2.ko is built for host, peripheral, and dual-role mode. The PCI bus interface will be called dwc2_pci.ko and the platform interface module will be called dwc2_platform.ko. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v7: None v6: Correct notes for USB_DWC2_DUAL_ROLE and USB_DWC2_PERIPHERAL Remove extra default for USB_DWC2_PLATFORM and make it a condition for building dwc2_platform.ko. In addition USB_DWC2_PLATFORM and USB_DWC2_PCI are now tristate. v5: dwc2.ko for all modes along with dwc2_platform.ko and dwc2_pci.ko will get built for kernel modules. v3: Add USB_GADGET=y and USB_GADGET=USB_DWC2 for peripheral and dual-role config options. v2: Remove reference to dwc2_gadget --- drivers/usb/dwc2/Kconfig | 66 --- drivers/usb/dwc2/Makefile | 32 +++ 2 files changed, 55 insertions(+), 43 deletions(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index 4d02718..b323c4c 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,5 +1,5 @@ config USB_DWC2 - bool DesignWare USB2 DRD Core Support + tristate DesignWare USB2 DRD Core Support depends on USB || USB_GADGET help Say Y here if your system has a Dual Role Hi-Speed USB @@ -10,49 +10,61 @@ config USB_DWC2 bus interface module (if you have a PCI bus system) will be called dwc2_pci.ko, and the platform interface module (for controllers directly connected to the CPU) will be called - dwc2_platform.ko. For gadget mode, there will be a single - module called dwc2_gadget.ko. - - NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. The - host and gadget drivers are still currently separate drivers. - There are plans to merge the dwc2_gadget driver with the dwc2 - host driver in the near future to create a dual-role driver. + dwc2_platform.ko. For all modes(host, gadget and dual-role), there + will be an additional module named dwc2.ko. if USB_DWC2 +choice + bool DWC2 Mode Selection + default USB_DWC2_DUAL_ROLE if (USB USB_GADGET) + default USB_DWC2_HOST if (USB !USB_GADGET) + default USB_DWC2_PERIPHERAL if (!USB USB_GADGET) + config USB_DWC2_HOST - tristate Host only mode + bool Host only mode depends on USB help The Designware USB2.0 high-speed host controller - integrated into many SoCs. + integrated into many SoCs. Select this option if you want the + driver to operate in Host-only mode. -config USB_DWC2_PLATFORM - bool DWC2 Platform - depends on USB_DWC2_HOST - default USB_DWC2_HOST +comment Gadget/Dual-role mode requires USB Gadget support to be enabled + +config USB_DWC2_PERIPHERAL + bool Gadget only mode + depends on USB_GADGET=y || USB_GADGET=USB_DWC2 + help + The Designware USB2.0 high-speed gadget controller + integrated into many SoCs. Select this option if you want the + driver to operate in Peripheral-only mode. This option requires + USB_GADGET to be enabled. + +config USB_DWC2_DUAL_ROLE + bool Dual Role mode + depends on (USB=y || USB=USB_DWC2) (USB_GADGET=y || USB_GADGET=USB_DWC2) help - The Designware USB2.0 platform interface module for - controllers directly connected to the CPU. This is only - used for host mode. + Select this option if you want the driver to work in a dual-role + mode. In this mode both host and gadget features are enabled, and + the role will be determined by the cable that gets plugged-in. This + option requires USB_GADGET to be enabled. +endchoice + +config USB_DWC2_PLATFORM + tristate DWC2 Platform + default USB_DWC2_HOST || USB_DWC2_PERIPHERAL +help + The Designware USB2.0 platform interface module for + controllers directly connected to the CPU. config USB_DWC2_PCI - bool DWC2 PCI + tristate DWC2 PCI depends on USB_DWC2_HOST PCI default USB_DWC2_HOST help The Designware USB2.0 PCI interface module for controllers connected to a PCI bus. This is only used for host mode. -comment Gadget mode requires USB Gadget support to be enabled - -config USB_DWC2_PERIPHERAL - tristate Gadget only mode - depends on USB_GADGET - help - The Designware USB2.0 high-speed gadget controller - integrated into many SoCs. - config USB_DWC2_DEBUG bool Enable Debugging Messages help diff --git
[PATCHv7 7/8] usb: dwc2: move usb_disabled() call to host driver only
From: Dinh Nguyen dingu...@opensource.altera.com Since platform.c will get built for both Host and Gadget, if we leave the usb_disabled() call in platform.c, it results in the following build error when (!USB USB_GADGET) condition is met. ERROR: usb_disabled [drivers/usb/dwc2/dwc2_platform.ko] undefined! Since usb_disabled() is mostly used to disable USB host functionality, move the call the host portion for the DWC2 driver. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/hcd.c | 3 +++ drivers/usb/dwc2/platform.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index fa60f4a..755e16b 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2780,6 +2780,9 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, int i, num_channels; int retval; + if (usb_disabled()) + return -ENODEV; + dev_dbg(hsotg-dev, DWC OTG HCD INIT\n); /* Detect config values from hardware */ diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 3552602..57eb8a3 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -157,9 +157,6 @@ static int dwc2_driver_probe(struct platform_device *dev) int retval; int irq; - if (usb_disabled()) - return -ENODEV; - match = of_match_device(dwc2_of_match_table, dev-dev); if (match match-data) { params = match-data; -- 2.0.3 -- 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
[PATCHv7 5/8] usb: dwc2: Update common interrupt handler to call gadget interrupt handler
From: Dinh Nguyen dingu...@opensource.altera.com Make dwc2_handle_common_intr call the gadget interrupt function when operating in peripheral mode. Remove the spinlock functions in s3c_hsotg_irq as dwc2_handle_common_intr() already has the spinlocks. Move the registeration of the IRQ to common code for platform and PCI. Remove duplicate interrupt conditions that was in gadget, as those are handled by dwc2 common interrupt handler. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- v7: Use IRQF_SHARED v5: remove individual devm_request_irq from gadget and hcd, and place a single devm_request_irq in platform and pci. v2: Keep interrupt handler for host and peripheral modes separate --- drivers/usb/dwc2/core.c | 10 -- drivers/usb/dwc2/gadget.c | 46 +++-- drivers/usb/dwc2/pci.c | 6 ++ drivers/usb/dwc2/platform.c | 8 4 files changed, 17 insertions(+), 53 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index d926945..7605850b 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -458,16 +458,6 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) /* Clear the SRP success bit for FS-I2c */ hsotg-srp_success = 0; - if (irq = 0) { - dev_dbg(hsotg-dev, registering common handler for irq%d\n, - irq); - retval = devm_request_irq(hsotg-dev, irq, - dwc2_handle_common_intr, IRQF_SHARED, - dev_name(hsotg-dev), hsotg); - if (retval) - return retval; - } - /* Enable common interrupts */ dwc2_enable_common_interrupts(hsotg); diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index ec85340..37c7916 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2285,33 +2285,12 @@ irq_retry: gintsts = gintmsk; - if (gintsts GINTSTS_OTGINT) { - u32 otgint = readl(hsotg-regs + GOTGINT); - - dev_info(hsotg-dev, OTGInt: %08x\n, otgint); - - writel(otgint, hsotg-regs + GOTGINT); - } - - if (gintsts GINTSTS_SESSREQINT) { - dev_dbg(hsotg-dev, %s: SessReqInt\n, __func__); - writel(GINTSTS_SESSREQINT, hsotg-regs + GINTSTS); - } - if (gintsts GINTSTS_ENUMDONE) { writel(GINTSTS_ENUMDONE, hsotg-regs + GINTSTS); s3c_hsotg_irq_enumdone(hsotg); } - if (gintsts GINTSTS_CONIDSTSCHNG) { - dev_dbg(hsotg-dev, ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n, - readl(hsotg-regs + DSTS), - readl(hsotg-regs + GOTGCTL)); - - writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); - } - if (gintsts (GINTSTS_OEPINT | GINTSTS_IEPINT)) { u32 daint = readl(hsotg-regs + DAINT); u32 daintmsk = readl(hsotg-regs + DAINTMSK); @@ -2392,25 +2371,6 @@ irq_retry: s3c_hsotg_handle_rx(hsotg); } - if (gintsts GINTSTS_MODEMIS) { - dev_warn(hsotg-dev, warning, mode mismatch triggered\n); - writel(GINTSTS_MODEMIS, hsotg-regs + GINTSTS); - } - - if (gintsts GINTSTS_USBSUSP) { - dev_info(hsotg-dev, GINTSTS_USBSusp\n); - writel(GINTSTS_USBSUSP, hsotg-regs + GINTSTS); - - call_gadget(hsotg, suspend); - } - - if (gintsts GINTSTS_WKUPINT) { - dev_info(hsotg-dev, GINTSTS_WkUpIn\n); - writel(GINTSTS_WKUPINT, hsotg-regs + GINTSTS); - - call_gadget(hsotg, resume); - } - if (gintsts GINTSTS_ERLYSUSP) { dev_dbg(hsotg-dev, GINTSTS_ErlySusp\n); writel(GINTSTS_ERLYSUSP, hsotg-regs + GINTSTS); @@ -3510,14 +3470,14 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) s3c_hsotg_hw_cfg(hsotg); s3c_hsotg_init(hsotg); - ret = devm_request_irq(dev, irq, s3c_hsotg_irq, 0, - dev_name(dev), hsotg); + ret = devm_request_irq(hsotg-dev, irq, s3c_hsotg_irq, IRQF_SHARED, + dev_name(hsotg-dev), hsotg); if (ret 0) { s3c_hsotg_phy_disable(hsotg); clk_disable_unprepare(hsotg-clk); regulator_bulk_disable(ARRAY_SIZE(hsotg-supplies), hsotg-supplies); - dev_err(dev, cannot claim IRQ\n); + dev_err(dev, cannot claim IRQ for gadget\n); goto err_clk; } diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index 6d33ecf..a4e724b 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c @@ -141,6 +141,12 @@ static int dwc2_driver_probe(struct pci_dev *dev,
[PATCHv7 6/8] usb: dwc2: gadget: Do not fail probe if there isn't a clock node
From: Dinh Nguyen dingu...@opensource.altera.com Since the dwc2 hcd driver is currently not looking for a clock node during init, we should not completely fail if there isn't a clock provided. By assigning clk = NULL, this allows the driver, when configured for dual-role mode, to be able to continue loading the host portion of the driver when a clock node is not specified. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- v7: Reworked to use clk=NULL and remove the need to is IS_ERR(clk) v6: none v5: reworked to not access gadget functions from the hcd. --- drivers/usb/dwc2/gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 37c7916..367689b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3431,6 +3431,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) hsotg-clk = devm_clk_get(dev, otg); if (IS_ERR(hsotg-clk)) { + hsotg-clk = NULL; dev_err(dev, cannot get otg clock\n); return PTR_ERR(hsotg-clk); } -- 2.0.3 -- 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
[PATCHv7 1/8] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure
From: Dinh Nguyen dingu...@opensource.altera.com Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. To keep the driver data dereference code looking clean, the gadget variable declares are only available for peripheral and dual-role mode. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Updates gadget.c to use the dwc2_hsotg data structure and gadget pointers that have been moved into the common dwc2_hsotg structure. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Signed-off-by: Paul Zimmerman pa...@synopsys.com --- v7: Addressed comments from Felipe Balbi on which variables should not be just limited to gadget(phy, uphy, regulator_bulk_data_supplies, irq, clk, debug_root, debug_file, and debug_fifo). v6: None v5: Keep the changes to mininum and maintain hcd and gadget driver to build and work separately. Use IS_ENABLED() instead of #if defined v3: Updated with paulz's suggestion to avoid double pointers. v2: Left the function parameter name as 'hsotg' and just changed its type. --- drivers/usb/dwc2/core.h | 155 -- drivers/usb/dwc2/gadget.c | 146 +-- 2 files changed, 153 insertions(+), 148 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 55c90c5..7bcdc10 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -84,7 +84,7 @@ static const char * const s3c_hsotg_supply_names[] = { */ #define EP0_MPS_LIMIT 64 -struct s3c_hsotg; +struct dwc2_hsotg; struct s3c_hsotg_req; /** @@ -130,7 +130,7 @@ struct s3c_hsotg_req; struct s3c_hsotg_ep { struct usb_ep ep; struct list_headqueue; - struct s3c_hsotg*parent; + struct dwc2_hsotg *parent; struct s3c_hsotg_req*req; struct dentry *debugfs; @@ -155,67 +155,6 @@ struct s3c_hsotg_ep { }; /** - * struct s3c_hsotg - driver state. - * @dev: The parent device supplied to the probe function - * @driver: USB gadget driver - * @phy: The otg phy transceiver structure for phy control. - * @uphy: The otg phy transceiver structure for old USB phy control. - * @plat: The platform specific configuration data. This can be removed once - * all SoCs support usb transceiver. - * @regs: The memory area mapped for accessing registers. - * @irq: The IRQ number we are using - * @supplies: Definition of USB power supplies - * @phyif: PHY interface width - * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. - * @num_of_eps: Number of available EPs (excluding EP0) - * @debug_root: root directrory for debugfs. - * @debug_file: main status file for debugfs. - * @debug_fifo: FIFO status file for debugfs. - * @ep0_reply: Request used for ep0 reply. - * @ep0_buff: Buffer for EP0 reply data, if needed. - * @ctrl_buff: Buffer for EP0 control requests. - * @ctrl_req: Request for EP0 control packets. - * @setup: NAK management for EP0 SETUP - * @last_rst: Time of last reset - * @eps: The endpoints being supplied to the gadget framework - */ -struct s3c_hsotg { - struct device*dev; - struct usb_gadget_driver *driver; - struct phy *phy; - struct usb_phy *uphy; - struct s3c_hsotg_plat*plat; - - spinlock_t lock; - - void __iomem*regs; - int irq; - struct clk *clk; - - struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; - - u32 phyif; - int fifo_mem; - unsigned intdedicated_fifos:1; - unsigned char num_of_eps; - u32 fifo_map; - - struct dentry *debug_root; - struct dentry *debug_file; - struct dentry *debug_fifo; - - struct usb_request *ep0_reply; - struct usb_request *ctrl_req; - u8 ep0_buff[8]; - u8 ctrl_buff[8]; - - struct usb_gadget gadget; - unsigned intsetup; - unsigned long last_rst; - struct s3c_hsotg_ep *eps; -}; - -/** * struct s3c_hsotg_req - data transfer request * @req: The USB gadget request * @queue: The list of requests for the endpoint this is queued for. @@ -229,6 +168,7 @@ struct s3c_hsotg_req { unsigned char mapped; }; +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) #define call_gadget(_hs, _entry) \ do { \ if ((_hs)-gadget.speed != USB_SPEED_UNKNOWN \ @@ -238,6 +178,9 @@ do { \ spin_lock(_hs-lock); \ } \ } while (0) +#else +#define call_gadget(_hs, _entry) do {} while (0) +#endif struct dwc2_hsotg; struct dwc2_host_chan; @@ -495,11
[PATCHv7 2/8] usb: dwc2: Move gadget probe function into platform code
From: Dinh Nguyen dingu...@opensource.altera.com This patch will aggregate the probing of gadget/hcd driver into platform.c. The gadget probe funtion is converted into gadget_init that is now only responsible for gadget only initialization. All the gadget resources are now handled by platform.c Since the host workqueue will not get initialized if the driver is configured for peripheral mode only. Thus we need to check for wq_otg before calling queue_work(). Also, we move spin_lock_init to common location for both host and gadget that is either in platform.c or pci.c. We also move suspend/resume code to common platform code. Lastly, move the samsung,s3c6400-hsotg binding into dwc2_of_match_table. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v7: Move the conversion to use pm_ops to a separate patch v6: None v5: Reworked by squashing the following commits into this one: * [PATCHv4 02/12] usb: dwc2: move samsung,s3c6400-hsotg into common platform * [PATCHv4 03/12] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure * [PATCHv4 09/12] usb: dwc2: initialize the spin_lock for both host and gadget * [PATCHv4 10/12] usb: dwc2: Add suspend/resume for gadget * [PATCHv4 11/12] usb: dwc2: check that the host work queue is valid Also use IS_ENABLED instead of #if defined --- drivers/usb/dwc2/core.h | 33 +++ drivers/usb/dwc2/core_intr.c | 8 ++-- drivers/usb/dwc2/gadget.c| 99 ++-- drivers/usb/dwc2/hcd.c | 1 - drivers/usb/dwc2/hcd.h | 10 - drivers/usb/dwc2/pci.c | 1 + drivers/usb/dwc2/platform.c | 28 + 7 files changed, 88 insertions(+), 92 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 7bcdc10..4905d88 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -960,4 +960,37 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); */ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); +/* Gadget defines */ +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) +extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); +extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); +extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +#else +static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) +{ return 0; } +#endif + +#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) +extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); +#else +static inline void dwc2_set_all_params(struct dwc2_core_params *params, int value) {} +static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) +{ return 0; } +static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} +static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, + const struct dwc2_core_params *params) +{ return 0; } +#endif + #endif /* __DWC2_CORE_H__ */ diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index c93918b..b176c2f 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -287,9 +287,11 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) * Release lock before scheduling workq as it holds spinlock during * scheduling. */ - spin_unlock(hsotg-lock); - queue_work(hsotg-wq_otg, hsotg-wf_otg); - spin_lock(hsotg-lock); + if (hsotg-wq_otg) { + spin_unlock(hsotg-lock); + queue_work(hsotg-wq_otg, hsotg-wf_otg); + spin_lock(hsotg-lock); + } /* Clear interrupt */ writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 5a24e95..9caea51 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3423,26 +3423,21 @@ static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_probe - probe function for hsotg driver - * @pdev: The platform information for the driver + * dwc2_gadget_init - init function for gadget + * @dwc2: The data structure for the DWC2 driver. + * @irq: The IRQ number for the controller. */ -static int s3c_hsotg_probe(struct platform_device *pdev) +int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { - struct s3c_hsotg_plat *plat
[PATCHv7 3/8] usb: dwc2: convert to use dev_pm_ops API
From: Dinh Nguyen dingu...@opensource.altera.com Update suspend/resume to use dev_pm_ops API. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/platform.c | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index eeba8a4..b94867b 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -219,9 +219,9 @@ static int dwc2_driver_probe(struct platform_device *dev) return retval; } -static int dwc2_suspend(struct platform_device *dev, pm_message_t state) +static int dwc2_suspend(struct device *dev) { - struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); int ret = 0; if (dwc2_is_device_mode(dwc2)) @@ -229,9 +229,9 @@ static int dwc2_suspend(struct platform_device *dev, pm_message_t state) return ret; } -static int dwc2_resume(struct platform_device *dev) +static int dwc2_resume(struct device *dev) { - struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); int ret = 0; if (dwc2_is_device_mode(dwc2)) @@ -239,15 +239,18 @@ static int dwc2_resume(struct platform_device *dev) return ret; } +static const struct dev_pm_ops dwc2_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(dwc2_suspend, dwc2_resume) +}; + static struct platform_driver dwc2_platform_driver = { .driver = { .name = dwc2_driver_name, .of_match_table = dwc2_of_match_table, + .pm = dwc2_dev_pm_ops, }, .probe = dwc2_driver_probe, .remove = dwc2_driver_remove, - .suspend = dwc2_suspend, - .resume = dwc2_resume, }; module_platform_driver(dwc2_platform_driver); -- 2.0.3 -- 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
[PATCHv6 6/8] usb: dwc2: gadget: Do not fail probe if there isn't a clock node
From: Dinh Nguyen dingu...@opensource.altera.com Since the dwc2 hcd driver is currently not looking for a clock node during init, we should not completely fail if there isn't a clock provided. For dual-role mode, we will only fail init for a non-clock node error. We then update the HCD to only call gadget funtions if there is a proper clock node. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- v5: reworked to not access gadget functions from the hcd. --- drivers/usb/dwc2/core.h | 3 +-- drivers/usb/dwc2/core_intr.c | 9 ++--- drivers/usb/dwc2/hcd.c | 3 ++- drivers/usb/dwc2/platform.c | 19 +++ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index ec70862..48120c8 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -660,6 +660,7 @@ struct dwc2_hsotg { #endif #endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */ + struct clk *clk; #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) /* Gadget structures */ struct usb_gadget_driver *driver; @@ -667,8 +668,6 @@ struct dwc2_hsotg { struct usb_phy *uphy; struct s3c_hsotg_plat *plat; - struct clk *clk; - struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; u32 phyif; diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 1240875..1608037 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -339,7 +339,8 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Change to L0 state */ hsotg-lx_state = DWC2_L0; - call_gadget(hsotg, resume); + if (!IS_ERR(hsotg-clk)) + call_gadget(hsotg, resume); } else { if (hsotg-lx_state != DWC2_L1) { u32 pcgcctl = readl(hsotg-regs + PCGCTL); @@ -400,7 +401,8 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n, !!(dsts DSTS_SUSPSTS), hsotg-hw_params.power_optimized); - call_gadget(hsotg, suspend); + if (!IS_ERR(hsotg-clk)) + call_gadget(hsotg, suspend); } else { if (hsotg-op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg-dev, a_peripheral-a_host\n); @@ -477,7 +479,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) spin_lock(hsotg-lock); if (dwc2_is_device_mode(hsotg)) - retval = s3c_hsotg_irq(irq, dev); + if (!IS_ERR(hsotg-clk)) + retval = s3c_hsotg_irq(irq, dev); gintsts = dwc2_read_common_intr(hsotg); if (gintsts ~GINTSTS_PRTINT) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 44c609f..fa49c72 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1371,7 +1371,8 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg-op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); - s3c_hsotg_core_init(hsotg); + if (!IS_ERR(hsotg-clk)) + s3c_hsotg_core_init(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg-dev, connId A\n); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 72f32f7..77c8417 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -217,8 +217,17 @@ static int dwc2_driver_probe(struct platform_device *dev) spin_lock_init(hsotg-lock); retval = dwc2_gadget_init(hsotg, irq); - if (retval) - return retval; + if (retval) { + /* +* We will not fail the driver initialization for dual-role +* if no clock node is supplied. However, all gadget +* functionality will be disabled if a clock node is not +* provided. Host functionality will continue. +* TO-DO: make clock node a requirement for the HCD. +*/ + if (!IS_ERR(hsotg-clk)) + return retval; + } retval = dwc2_hcd_init(hsotg, irq, params); if (retval) return retval; @@ -234,7 +243,8 @@ static int dwc2_suspend(struct device *dev) int ret = 0; if (dwc2_is_device_mode(dwc2)) - ret = s3c_hsotg_suspend(dwc2); + if (!IS_ERR(dwc2-clk)) + ret = s3c_hsotg_suspend(dwc2); return ret; } @@ -244,7 +254,8 @@ static int dwc2_resume(struct device *dev) int ret = 0; if
[PATCHv6 7/8] usb: dwc2: Update Kconfig to support dual-role
From: Dinh Nguyen dingu...@opensource.altera.com Update DWC2 kconfig and makefile to support dual-role mode. The platform file will always get compiled for the case where the controller is directly connected to the CPU. So for loadable modules, dwc2.ko is built for host, peripheral, and dual-role mode. The PCI bus interface will be called dwc2_pci.ko and the platform interface module will be called dwc2_platform.ko. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v6: Correct notes for USB_DWC2_DUAL_ROLE and USB_DWC2_PERIPHERAL Remove extra default for USB_DWC2_PLATFORM and make it a condition for building dwc2_platform.ko. In addition USB_DWC2_PLATFORM and USB_DWC2_PCI are now tristate. v5: dwc2.ko for all modes along with dwc2_platform.ko and dwc2_pci.ko will get built for kernel modules. v3: Add USB_GADGET=y and USB_GADGET=USB_DWC2 for peripheral and dual-role config options. v2: Remove reference to dwc2_gadget --- drivers/usb/dwc2/Kconfig | 66 --- drivers/usb/dwc2/Makefile | 32 +++ 2 files changed, 55 insertions(+), 43 deletions(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index 4d02718..b323c4c 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,5 +1,5 @@ config USB_DWC2 - bool DesignWare USB2 DRD Core Support + tristate DesignWare USB2 DRD Core Support depends on USB || USB_GADGET help Say Y here if your system has a Dual Role Hi-Speed USB @@ -10,49 +10,61 @@ config USB_DWC2 bus interface module (if you have a PCI bus system) will be called dwc2_pci.ko, and the platform interface module (for controllers directly connected to the CPU) will be called - dwc2_platform.ko. For gadget mode, there will be a single - module called dwc2_gadget.ko. - - NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. The - host and gadget drivers are still currently separate drivers. - There are plans to merge the dwc2_gadget driver with the dwc2 - host driver in the near future to create a dual-role driver. + dwc2_platform.ko. For all modes(host, gadget and dual-role), there + will be an additional module named dwc2.ko. if USB_DWC2 +choice + bool DWC2 Mode Selection + default USB_DWC2_DUAL_ROLE if (USB USB_GADGET) + default USB_DWC2_HOST if (USB !USB_GADGET) + default USB_DWC2_PERIPHERAL if (!USB USB_GADGET) + config USB_DWC2_HOST - tristate Host only mode + bool Host only mode depends on USB help The Designware USB2.0 high-speed host controller - integrated into many SoCs. + integrated into many SoCs. Select this option if you want the + driver to operate in Host-only mode. -config USB_DWC2_PLATFORM - bool DWC2 Platform - depends on USB_DWC2_HOST - default USB_DWC2_HOST +comment Gadget/Dual-role mode requires USB Gadget support to be enabled + +config USB_DWC2_PERIPHERAL + bool Gadget only mode + depends on USB_GADGET=y || USB_GADGET=USB_DWC2 + help + The Designware USB2.0 high-speed gadget controller + integrated into many SoCs. Select this option if you want the + driver to operate in Peripheral-only mode. This option requires + USB_GADGET to be enabled. + +config USB_DWC2_DUAL_ROLE + bool Dual Role mode + depends on (USB=y || USB=USB_DWC2) (USB_GADGET=y || USB_GADGET=USB_DWC2) help - The Designware USB2.0 platform interface module for - controllers directly connected to the CPU. This is only - used for host mode. + Select this option if you want the driver to work in a dual-role + mode. In this mode both host and gadget features are enabled, and + the role will be determined by the cable that gets plugged-in. This + option requires USB_GADGET to be enabled. +endchoice + +config USB_DWC2_PLATFORM + tristate DWC2 Platform + default USB_DWC2_HOST || USB_DWC2_PERIPHERAL +help + The Designware USB2.0 platform interface module for + controllers directly connected to the CPU. config USB_DWC2_PCI - bool DWC2 PCI + tristate DWC2 PCI depends on USB_DWC2_HOST PCI default USB_DWC2_HOST help The Designware USB2.0 PCI interface module for controllers connected to a PCI bus. This is only used for host mode. -comment Gadget mode requires USB Gadget support to be enabled - -config USB_DWC2_PERIPHERAL - tristate Gadget only mode - depends on USB_GADGET - help - The Designware USB2.0 high-speed gadget controller - integrated into many SoCs. - config USB_DWC2_DEBUG bool Enable Debugging Messages help diff --git
[PATCHv6 2/8] usb: dwc2: Move gadget probe function into platform code
From: Dinh Nguyen dingu...@opensource.altera.com This patch will aggregate the probing of gadget/hcd driver into platform.c. The gadget probe funtion is converted into gadget_init that is now only responsible for gadget only initialization. All the gadget resources is now handled by platform.c Since the host workqueue will not get initialized if the driver is configured for peripheral mode only. Thus we need to check for wq_otg before calling queue_work(). Also, we move spin_lock_init to common location for both host and gadget that is either in platform.c or pci.c. We also ove suspend/resume code to common platform code, and update it to use the new PM API (struct dev_pm_ops). Lastly, move the samsung,s3c6400-hsotg binding into dwc2_of_match_table. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v5: Reworked by squashing the following commits into this one: * [PATCHv4 02/12] usb: dwc2: move samsung,s3c6400-hsotg into common platform * [PATCHv4 03/12] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure * [PATCHv4 09/12] usb: dwc2: initialize the spin_lock for both host and gadget * [PATCHv4 10/12] usb: dwc2: Add suspend/resume for gadget * [PATCHv4 11/12] usb: dwc2: check that the host work queue is valid Also use IS_ENABLED instead of #if defined --- drivers/usb/dwc2/core.h | 34 ++- drivers/usb/dwc2/core_intr.c | 8 ++-- drivers/usb/dwc2/gadget.c| 99 ++-- drivers/usb/dwc2/hcd.c | 1 - drivers/usb/dwc2/hcd.h | 10 - drivers/usb/dwc2/pci.c | 1 + drivers/usb/dwc2/platform.c | 32 ++ 7 files changed, 92 insertions(+), 93 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 96c283d..de2b194 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -667,7 +667,6 @@ struct dwc2_hsotg { struct usb_phy *uphy; struct s3c_hsotg_plat *plat; - int irq; struct clk *clk; struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; @@ -961,4 +960,37 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); */ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); +/* Gadget defines */ +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) +extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); +extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); +extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +#else +static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) +{ return 0; } +#endif + +#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) +extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); +#else +static inline void dwc2_set_all_params(struct dwc2_core_params *params, int value) {} +static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) +{ return 0; } +static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} +static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, + const struct dwc2_core_params *params) +{ return 0; } +#endif + #endif /* __DWC2_CORE_H__ */ diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index c93918b..b176c2f 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -287,9 +287,11 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) * Release lock before scheduling workq as it holds spinlock during * scheduling. */ - spin_unlock(hsotg-lock); - queue_work(hsotg-wq_otg, hsotg-wf_otg); - spin_lock(hsotg-lock); + if (hsotg-wq_otg) { + spin_unlock(hsotg-lock); + queue_work(hsotg-wq_otg, hsotg-wf_otg); + spin_lock(hsotg-lock); + } /* Clear interrupt */ writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 78b3d1a..38ec1cc 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3404,26 +3404,21 @@ static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_probe - probe function for hsotg driver - * @pdev: The platform information for the driver + * dwc2_gadget_init - init function for gadget + * @dwc2: The data
[PATCHv6 5/8] usb: dwc2: Add call_gadget functions for perpheral mode interrupts
From: Dinh Nguyen dingu...@opensource.altera.com Update the dwc2 wakeup and suspend interrupt functions to use call_gadget when the IP is in peripheral mode. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- drivers/usb/dwc2/core_intr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index b0c14e0..1240875 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -339,6 +339,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Change to L0 state */ hsotg-lx_state = DWC2_L0; + call_gadget(hsotg, resume); } else { if (hsotg-lx_state != DWC2_L1) { u32 pcgcctl = readl(hsotg-regs + PCGCTL); @@ -399,6 +400,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n, !!(dsts DSTS_SUSPSTS), hsotg-hw_params.power_optimized); + call_gadget(hsotg, suspend); } else { if (hsotg-op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg-dev, a_peripheral-a_host\n); -- 2.0.3 -- 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
[PATCHv6 4/8] usb: dwc2: Update common interrupt handler to call gadget interrupt handler
From: Dinh Nguyen dingu...@opensource.altera.com Make dwc2_handle_common_intr call the gadget interrupt function when operating in peripheral mode. Remove the spinlock functions in s3c_hsotg_irq as dwc2_handle_common_intr() already has the spinlocks. Move the registeration of the IRQ to common code for platform and PCI. Remove duplicate interrupt conditions that was in gadget, as those are handled by dwc2 common interrupt handler. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v5: remove individual devm_request_irq from gadget and hcd, and place a single devm_request_irq in platform and pci. v2: Keep interrupt handler for host and peripheral modes separate --- drivers/usb/dwc2/core.c | 10 drivers/usb/dwc2/core.h | 3 +++ drivers/usb/dwc2/core_intr.c | 3 +++ drivers/usb/dwc2/gadget.c| 57 ++-- drivers/usb/dwc2/pci.c | 6 + drivers/usb/dwc2/platform.c | 9 +++ 6 files changed, 23 insertions(+), 65 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index d926945..7605850b 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -458,16 +458,6 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) /* Clear the SRP success bit for FS-I2c */ hsotg-srp_success = 0; - if (irq = 0) { - dev_dbg(hsotg-dev, registering common handler for irq%d\n, - irq); - retval = devm_request_irq(hsotg-dev, irq, - dwc2_handle_common_intr, IRQF_SHARED, - dev_name(hsotg-dev), hsotg); - if (retval) - return retval; - } - /* Enable common interrupts */ dwc2_enable_common_interrupts(hsotg); diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 80d29c7..ec70862 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -967,6 +967,7 @@ extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); +irqreturn_t s3c_hsotg_irq(int irq, void *pw); #else static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } @@ -977,6 +978,8 @@ static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} +static inline irqreturn_t s3c_hsotg_irq(int irq, void *pw) +{ return IRQ_HANDLED; } #endif #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index b176c2f..b0c14e0 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -474,6 +474,9 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) spin_lock(hsotg-lock); + if (dwc2_is_device_mode(hsotg)) + retval = s3c_hsotg_irq(irq, dev); + gintsts = dwc2_read_common_intr(hsotg); if (gintsts ~GINTSTS_PRTINT) retval = IRQ_HANDLED; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 19d1b03..202f8cc 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2257,14 +2257,13 @@ void s3c_hsotg_core_init(struct dwc2_hsotg *hsotg) * @irq: The IRQ number triggered * @pw: The pw value when registered the handler. */ -static irqreturn_t s3c_hsotg_irq(int irq, void *pw) +irqreturn_t s3c_hsotg_irq(int irq, void *pw) { struct dwc2_hsotg *hsotg = pw; int retry_count = 8; u32 gintsts; u32 gintmsk; - spin_lock(hsotg-lock); irq_retry: gintsts = readl(hsotg-regs + GINTSTS); gintmsk = readl(hsotg-regs + GINTMSK); @@ -2274,33 +2273,12 @@ irq_retry: gintsts = gintmsk; - if (gintsts GINTSTS_OTGINT) { - u32 otgint = readl(hsotg-regs + GOTGINT); - - dev_info(hsotg-dev, OTGInt: %08x\n, otgint); - - writel(otgint, hsotg-regs + GOTGINT); - } - - if (gintsts GINTSTS_SESSREQINT) { - dev_dbg(hsotg-dev, %s: SessReqInt\n, __func__); - writel(GINTSTS_SESSREQINT, hsotg-regs + GINTSTS); - } - if (gintsts GINTSTS_ENUMDONE) { writel(GINTSTS_ENUMDONE, hsotg-regs + GINTSTS); s3c_hsotg_irq_enumdone(hsotg); } - if (gintsts GINTSTS_CONIDSTSCHNG) { - dev_dbg(hsotg-dev, ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n, - readl(hsotg-regs + DSTS), - readl(hsotg-regs + GOTGCTL)); - - writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); - } - if
[PATCHv6 1/8] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure
From: Dinh Nguyen dingu...@opensource.altera.com Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. To keep the driver data dereference code looking clean, the gadget variable declares are only available for peripheral and dual-role mode. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Updates gadget.c to use the dwc2_hsotg data structure and gadget pointers that have been moved into the common dwc2_hsotg structure. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Signed-off-by: Paul Zimmerman pa...@synopsys.com --- v5: Keep the changes to mininum and maintain hcd and gadget driver to build and work separately. Use IS_ENABLED() instead of #if defined v3: Updated with paulz's suggestion to avoid double pointers. v2: Left the function parameter name as 'hsotg' and just changed its type. --- drivers/usb/dwc2/core.h | 156 -- drivers/usb/dwc2/gadget.c | 145 +- 2 files changed, 154 insertions(+), 147 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 55c90c5..96c283d 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -84,7 +84,7 @@ static const char * const s3c_hsotg_supply_names[] = { */ #define EP0_MPS_LIMIT 64 -struct s3c_hsotg; +struct dwc2_hsotg; struct s3c_hsotg_req; /** @@ -130,7 +130,7 @@ struct s3c_hsotg_req; struct s3c_hsotg_ep { struct usb_ep ep; struct list_headqueue; - struct s3c_hsotg*parent; + struct dwc2_hsotg *parent; struct s3c_hsotg_req*req; struct dentry *debugfs; @@ -155,67 +155,6 @@ struct s3c_hsotg_ep { }; /** - * struct s3c_hsotg - driver state. - * @dev: The parent device supplied to the probe function - * @driver: USB gadget driver - * @phy: The otg phy transceiver structure for phy control. - * @uphy: The otg phy transceiver structure for old USB phy control. - * @plat: The platform specific configuration data. This can be removed once - * all SoCs support usb transceiver. - * @regs: The memory area mapped for accessing registers. - * @irq: The IRQ number we are using - * @supplies: Definition of USB power supplies - * @phyif: PHY interface width - * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. - * @num_of_eps: Number of available EPs (excluding EP0) - * @debug_root: root directrory for debugfs. - * @debug_file: main status file for debugfs. - * @debug_fifo: FIFO status file for debugfs. - * @ep0_reply: Request used for ep0 reply. - * @ep0_buff: Buffer for EP0 reply data, if needed. - * @ctrl_buff: Buffer for EP0 control requests. - * @ctrl_req: Request for EP0 control packets. - * @setup: NAK management for EP0 SETUP - * @last_rst: Time of last reset - * @eps: The endpoints being supplied to the gadget framework - */ -struct s3c_hsotg { - struct device*dev; - struct usb_gadget_driver *driver; - struct phy *phy; - struct usb_phy *uphy; - struct s3c_hsotg_plat*plat; - - spinlock_t lock; - - void __iomem*regs; - int irq; - struct clk *clk; - - struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; - - u32 phyif; - int fifo_mem; - unsigned intdedicated_fifos:1; - unsigned char num_of_eps; - u32 fifo_map; - - struct dentry *debug_root; - struct dentry *debug_file; - struct dentry *debug_fifo; - - struct usb_request *ep0_reply; - struct usb_request *ctrl_req; - u8 ep0_buff[8]; - u8 ctrl_buff[8]; - - struct usb_gadget gadget; - unsigned intsetup; - unsigned long last_rst; - struct s3c_hsotg_ep *eps; -}; - -/** * struct s3c_hsotg_req - data transfer request * @req: The USB gadget request * @queue: The list of requests for the endpoint this is queued for. @@ -229,6 +168,7 @@ struct s3c_hsotg_req { unsigned char mapped; }; +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) #define call_gadget(_hs, _entry) \ do { \ if ((_hs)-gadget.speed != USB_SPEED_UNKNOWN \ @@ -238,6 +178,9 @@ do { \ spin_lock(_hs-lock); \ } \ } while (0) +#else +#define call_gadget(_hs, _entry) do {} while (0) +#endif struct dwc2_hsotg; struct dwc2_host_chan; @@ -495,11 +438,13 @@ struct dwc2_hw_params { * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic * and periodic schedules * + * These are common for both host and peripheral modes: +
[PATCHv6 3/8] usb: dwc2: Initialize the USB core for peripheral mode
From: Dinh Nguyen dingu...@opensource.altera.com Initialize the USB driver to peripheral mode when a B-Device connector is attached. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v5: move the export of s3c_hsotg_core_init into this patch --- drivers/usb/dwc2/core.h | 2 ++ drivers/usb/dwc2/gadget.c | 2 +- drivers/usb/dwc2/hcd.c| 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index de2b194..80d29c7 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -966,6 +966,7 @@ extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); #else static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } @@ -975,6 +976,7 @@ static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) { return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } +static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} #endif #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 38ec1cc..19d1b03 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2125,7 +2125,7 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg) * * Issue a soft reset to the core, and await the core finishing it. */ -static void s3c_hsotg_core_init(struct dwc2_hsotg *hsotg) +void s3c_hsotg_core_init(struct dwc2_hsotg *hsotg) { s3c_hsotg_corereset(hsotg); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 4a3cce0..44c609f 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1371,6 +1371,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg-op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); + s3c_hsotg_core_init(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg-dev, connId A\n); -- 2.0.3 -- 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
[PATCHv6 0/8] usb: dwc2: Add support for dual-role
From: Dinh Nguyen dingu...@opensource.altera.com Hello, This is version 6 of the patch series that combines the dwc2 gadget and host driver into a single dual role driver. Here are the main differences from V5: - Added a new patch 8/8 - usb: dwc2: move usb_disabled() call to host driver only. This patch is needed to avoid a build error when (!USB USB_GADGET) condition is met. - Addressed comments in the Kconfig/Makefile. USB_DWC2_PLATFORM and USB_DWC2_PCI are now tristate. For v6, the series is rebased on top of Felipe Balbi's tree on testing/next branch. I thought this might be appropriate as there are dwc2 patches already on this branch. As usual, tested on SOCFPGA(host, gadget, and dual-role) and on Rpi-B (host mode only). I have pushed this series to a git repo to make it more convenient for people to test/review. git://git.rocketboards.org/linux-socfpga-next.git dwc2_dual_role_v6 Thanks, Dinh Nguyen (8): usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure usb: dwc2: Move gadget probe function into platform code usb: dwc2: Initialize the USB core for peripheral mode usb: dwc2: Update common interrupt handler to call gadget interrupt handler usb: dwc2: Add call_gadget functions for perpheral mode interrupts usb: dwc2: gadget: Do not fail probe if there isn't a clock node usb: dwc2: Update Kconfig to support dual-role usb: dwc2: move usb_disabled() call to host driver only drivers/usb/dwc2/Kconfig | 66 +- drivers/usb/dwc2/Makefile| 32 ++--- drivers/usb/dwc2/core.c | 10 -- drivers/usb/dwc2/core.h | 192 + drivers/usb/dwc2/core_intr.c | 16 ++- drivers/usb/dwc2/gadget.c| 283 +-- drivers/usb/dwc2/hcd.c | 6 +- drivers/usb/dwc2/hcd.h | 10 -- drivers/usb/dwc2/pci.c | 7 ++ drivers/usb/dwc2/platform.c | 55 - 10 files changed, 336 insertions(+), 341 deletions(-) -- 2.0.3 -- 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] usb: dwc2: allow dwc2 to get built when USB_GADGET=m
From: Dinh Nguyen dingu...@opensource.altera.com This patch allows the gadget portion of the DWC2 driver to get built when (!USB USB_GADGET) condition is encountered. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index f93807b..4d02718 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,6 +1,6 @@ config USB_DWC2 bool DesignWare USB2 DRD Core Support - depends on USB + depends on USB || USB_GADGET help Say Y here if your system has a Dual Role Hi-Speed USB controller based on the DesignWare HSOTG IP Core. -- 2.0.3 -- 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
[PATCHv5 0/7] usb: dwc2: Add support for dual-role
From: Dinh Nguyen dingu...@opensource.altera.com Hello, This is version 5 of the patch series that combines the dwc2 gadget and host driver into a single dual role driver. Here are the main differences from V4: - Squashed 5 patches from V4 into patch 2. Patchset is now only 7 patches. - Makefile moved to be the last patch in the series. - When building for kernel modules, dwc2.ko will get built for all modes(host, gadget, and dual-role). dwc2_platform.ko and dwc2_pci.ko will get built for platform SOC and PCI. For v5, the series is rebased on top of v3.18-rc1. As usual, tested on SOCFPGA(host, gadget, and dual-role) and on Rpi-B (host mode only). I have pushed this series to a git repo to make it more convenient for people to test/review. git://git.rocketboards.org/linux-socfpga-next.git dwc2_dual_role_v5 Thanks, Dinh Nguyen (7): usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure usb: dwc2: Move gadget probe function into platform code usb: dwc2: Initialize the USB core for peripheral mode usb: dwc2: Update common interrupt handler to call gadget interrupt handler usb: dwc2: Add call_gadget functions for perpheral mode interrupts usb: dwc2: gadget: Do not fail probe if there isn't a clock node usb: dwc2: Update Kconfig to support dual-role drivers/usb/dwc2/Kconfig | 61 ++ drivers/usb/dwc2/Makefile| 32 ++--- drivers/usb/dwc2/core.c | 10 -- drivers/usb/dwc2/core.h | 192 + drivers/usb/dwc2/core_intr.c | 16 ++- drivers/usb/dwc2/gadget.c| 283 +-- drivers/usb/dwc2/hcd.c | 3 +- drivers/usb/dwc2/hcd.h | 10 -- drivers/usb/dwc2/pci.c | 7 ++ drivers/usb/dwc2/platform.c | 52 10 files changed, 331 insertions(+), 335 deletions(-) -- 2.0.3 -- 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
[PATCHv5 3/7] usb: dwc2: Initialize the USB core for peripheral mode
From: Dinh Nguyen dingu...@opensource.altera.com Initialize the USB driver to peripheral mode when a B-Device connector is attached. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v5: move the export of s3c_hsotg_core_init into this patch --- drivers/usb/dwc2/core.h | 2 ++ drivers/usb/dwc2/gadget.c | 2 +- drivers/usb/dwc2/hcd.c| 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index b21aace..de1f357 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -966,6 +966,7 @@ extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); #else static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } @@ -975,6 +976,7 @@ static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) { return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } +static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} #endif #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index c407d33..6793ca8 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2125,7 +2125,7 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg) * * Issue a soft reset to the core, and await the core finishing it. */ -static void s3c_hsotg_core_init(struct dwc2_hsotg *hsotg) +void s3c_hsotg_core_init(struct dwc2_hsotg *hsotg) { s3c_hsotg_corereset(hsotg); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 4a3cce0..44c609f 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1371,6 +1371,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg-op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); + s3c_hsotg_core_init(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg-dev, connId A\n); -- 2.0.3 -- 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
[PATCHv5 7/7] usb: dwc2: Update Kconfig to support dual-role
From: Dinh Nguyen dingu...@opensource.altera.com Update DWC2 kconfig and makefile to support dual-role mode. The platform file will always get compiled for the case where the controller is directly connected to the CPU. So for loadable modules, dwc2.ko is built for host, peripheral, and dual-role mode. The PCI bus interface will be called dwc2_pci.ko and the platform interface module will be called dwc2_platform.ko. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v5: dwc2.ko for all modes along with dwc2_platform.ko and dwc2_pci.ko will get built for kernel modules. v3: Add USB_GADGET=y and USB_GADGET=USB_DWC2 for peripheral and dual-role config options. v2: Remove reference to dwc2_gadget --- drivers/usb/dwc2/Kconfig | 61 --- drivers/usb/dwc2/Makefile | 32 - 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index f93807b..1ea702e 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,5 +1,5 @@ config USB_DWC2 - bool DesignWare USB2 DRD Core Support + tristate DesignWare USB2 DRD Core Support depends on USB help Say Y here if your system has a Dual Role Hi-Speed USB @@ -10,31 +10,53 @@ config USB_DWC2 bus interface module (if you have a PCI bus system) will be called dwc2_pci.ko, and the platform interface module (for controllers directly connected to the CPU) will be called - dwc2_platform.ko. For gadget mode, there will be a single - module called dwc2_gadget.ko. - - NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. The - host and gadget drivers are still currently separate drivers. - There are plans to merge the dwc2_gadget driver with the dwc2 - host driver in the near future to create a dual-role driver. + dwc2_platform.ko. For all modes(host, gadget and dual-role), there + will be a single module called dwc2.ko. if USB_DWC2 +choice + bool DWC2 Mode Selection + default USB_DWC2_DUAL_ROLE if (USB USB_GADGET) + default USB_DWC2_HOST if (USB !USB_GADGET) + default USB_DWC2_PERIPHERAL if (!USB USB_GADGET) + config USB_DWC2_HOST - tristate Host only mode + bool Host only mode depends on USB help The Designware USB2.0 high-speed host controller - integrated into many SoCs. + integrated into many SoCs. Select this option if you want the + driver to operate in Host-only mode. + +comment Gadget/Dual-role mode requires USB Gadget support to be enabled + +config USB_DWC2_PERIPHERAL + bool Gadget only mode + depends on USB_GADGET=y || USB_GADGET=USB_DWC2 + help + The Designware USB2.0 high-speed gadget controller + integrated into many SoCs. Select this option if you want the + driver to operate in Peripheral-only mode. This option requires + USB_GADGET=y. + +config USB_DWC2_DUAL_ROLE + bool Dual Role mode + depends on (USB=y || USB=USB_DWC2) (USB_GADGET=y || USB_GADGET=USB_DWC2) + help + Select this option if you want the driver to work in a dual-role + mode. In this mode both host and gadget features are enabled, and + the role will be determined by the cable that gets plugged-in. This + option requires USB_GADGET=y. +endchoice config USB_DWC2_PLATFORM bool DWC2 Platform - depends on USB_DWC2_HOST default USB_DWC2_HOST - help - The Designware USB2.0 platform interface module for - controllers directly connected to the CPU. This is only - used for host mode. +default y +help + The Designware USB2.0 platform interface module for + controllers directly connected to the CPU. config USB_DWC2_PCI bool DWC2 PCI @@ -44,15 +66,6 @@ config USB_DWC2_PCI The Designware USB2.0 PCI interface module for controllers connected to a PCI bus. This is only used for host mode. -comment Gadget mode requires USB Gadget support to be enabled - -config USB_DWC2_PERIPHERAL - tristate Gadget only mode - depends on USB_GADGET - help - The Designware USB2.0 high-speed gadget controller - integrated into many SoCs. - config USB_DWC2_DEBUG bool Enable Debugging Messages help diff --git a/drivers/usb/dwc2/Makefile b/drivers/usb/dwc2/Makefile index b73d2a5..2175d93 100644 --- a/drivers/usb/dwc2/Makefile +++ b/drivers/usb/dwc2/Makefile @@ -1,28 +1,28 @@ ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG -obj-$(CONFIG_USB_DWC2_HOST)+= dwc2.o +obj-$(CONFIG_USB_DWC2) += dwc2.o dwc2-y := core.o
[PATCHv5 4/7] usb: dwc2: Update common interrupt handler to call gadget interrupt handler
From: Dinh Nguyen dingu...@opensource.altera.com Make dwc2_handle_common_intr call the gadget interrupt function when operating in peripheral mode. Remove the spinlock functions in s3c_hsotg_irq as dwc2_handle_common_intr() already has the spinlocks. Move the registeration of the IRQ to common code for platform and PCI. Remove duplicate interrupt conditions that was in gadget, as those are handled by dwc2 common interrupt handler. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v5: remove individual devm_request_irq from gadget and hcd, and place a single devm_request_irq in platform and pci. v2: Keep interrupt handler for host and peripheral modes separate --- drivers/usb/dwc2/core.c | 10 drivers/usb/dwc2/core.h | 3 +++ drivers/usb/dwc2/core_intr.c | 3 +++ drivers/usb/dwc2/gadget.c| 57 ++-- drivers/usb/dwc2/pci.c | 6 + drivers/usb/dwc2/platform.c | 9 +++ 6 files changed, 23 insertions(+), 65 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index d926945..7605850b 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -458,16 +458,6 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) /* Clear the SRP success bit for FS-I2c */ hsotg-srp_success = 0; - if (irq = 0) { - dev_dbg(hsotg-dev, registering common handler for irq%d\n, - irq); - retval = devm_request_irq(hsotg-dev, irq, - dwc2_handle_common_intr, IRQF_SHARED, - dev_name(hsotg-dev), hsotg); - if (retval) - return retval; - } - /* Enable common interrupts */ dwc2_enable_common_interrupts(hsotg); diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index de1f357..ba488ec 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -967,6 +967,7 @@ extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); +irqreturn_t s3c_hsotg_irq(int irq, void *pw); #else static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } @@ -977,6 +978,8 @@ static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} +static inline irqreturn_t s3c_hsotg_irq(int irq, void *pw) +{ return IRQ_HANDLED; } #endif #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index b176c2f..b0c14e0 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -474,6 +474,9 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) spin_lock(hsotg-lock); + if (dwc2_is_device_mode(hsotg)) + retval = s3c_hsotg_irq(irq, dev); + gintsts = dwc2_read_common_intr(hsotg); if (gintsts ~GINTSTS_PRTINT) retval = IRQ_HANDLED; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6793ca8..6ffbfc2 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2257,14 +2257,13 @@ void s3c_hsotg_core_init(struct dwc2_hsotg *hsotg) * @irq: The IRQ number triggered * @pw: The pw value when registered the handler. */ -static irqreturn_t s3c_hsotg_irq(int irq, void *pw) +irqreturn_t s3c_hsotg_irq(int irq, void *pw) { struct dwc2_hsotg *hsotg = pw; int retry_count = 8; u32 gintsts; u32 gintmsk; - spin_lock(hsotg-lock); irq_retry: gintsts = readl(hsotg-regs + GINTSTS); gintmsk = readl(hsotg-regs + GINTMSK); @@ -2274,33 +2273,12 @@ irq_retry: gintsts = gintmsk; - if (gintsts GINTSTS_OTGINT) { - u32 otgint = readl(hsotg-regs + GOTGINT); - - dev_info(hsotg-dev, OTGInt: %08x\n, otgint); - - writel(otgint, hsotg-regs + GOTGINT); - } - - if (gintsts GINTSTS_SESSREQINT) { - dev_dbg(hsotg-dev, %s: SessReqInt\n, __func__); - writel(GINTSTS_SESSREQINT, hsotg-regs + GINTSTS); - } - if (gintsts GINTSTS_ENUMDONE) { writel(GINTSTS_ENUMDONE, hsotg-regs + GINTSTS); s3c_hsotg_irq_enumdone(hsotg); } - if (gintsts GINTSTS_CONIDSTSCHNG) { - dev_dbg(hsotg-dev, ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n, - readl(hsotg-regs + DSTS), - readl(hsotg-regs + GOTGCTL)); - - writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); - } - if
[PATCHv5 5/7] usb: dwc2: Add call_gadget functions for perpheral mode interrupts
From: Dinh Nguyen dingu...@opensource.altera.com Update the dwc2 wakeup and suspend interrupt functions to use call_gadget when the IP is in peripheral mode. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- drivers/usb/dwc2/core_intr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index b0c14e0..1240875 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -339,6 +339,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Change to L0 state */ hsotg-lx_state = DWC2_L0; + call_gadget(hsotg, resume); } else { if (hsotg-lx_state != DWC2_L1) { u32 pcgcctl = readl(hsotg-regs + PCGCTL); @@ -399,6 +400,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n, !!(dsts DSTS_SUSPSTS), hsotg-hw_params.power_optimized); + call_gadget(hsotg, suspend); } else { if (hsotg-op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg-dev, a_peripheral-a_host\n); -- 2.0.3 -- 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
[PATCHv5 1/7] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure
From: Dinh Nguyen dingu...@opensource.altera.com Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. To keep the driver data dereference code looking clean, the gadget variable declares are only available for peripheral and dual-role mode. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Updates gadget.c to use the dwc2_hsotg data structure and gadget pointers that have been moved into the common dwc2_hsotg structure. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Signed-off-by: Paul Zimmerman pa...@synopsys.com --- v5: Keep the changes to mininum and maintain hcd and gadget driver to build and work separately. Use IS_ENABLED() instead of #if defined v3: Updated with paulz's suggestion to avoid double pointers. v2: Left the function parameter name as 'hsotg' and just changed its type. --- drivers/usb/dwc2/core.h | 156 -- drivers/usb/dwc2/gadget.c | 147 +-- 2 files changed, 155 insertions(+), 148 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index bf015ab..5412f57 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -84,7 +84,7 @@ static const char * const s3c_hsotg_supply_names[] = { */ #define EP0_MPS_LIMIT 64 -struct s3c_hsotg; +struct dwc2_hsotg; struct s3c_hsotg_req; /** @@ -130,7 +130,7 @@ struct s3c_hsotg_req; struct s3c_hsotg_ep { struct usb_ep ep; struct list_headqueue; - struct s3c_hsotg*parent; + struct dwc2_hsotg *parent; struct s3c_hsotg_req*req; struct dentry *debugfs; @@ -155,67 +155,6 @@ struct s3c_hsotg_ep { }; /** - * struct s3c_hsotg - driver state. - * @dev: The parent device supplied to the probe function - * @driver: USB gadget driver - * @phy: The otg phy transceiver structure for phy control. - * @uphy: The otg phy transceiver structure for old USB phy control. - * @plat: The platform specific configuration data. This can be removed once - * all SoCs support usb transceiver. - * @regs: The memory area mapped for accessing registers. - * @irq: The IRQ number we are using - * @supplies: Definition of USB power supplies - * @phyif: PHY interface width - * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. - * @num_of_eps: Number of available EPs (excluding EP0) - * @debug_root: root directrory for debugfs. - * @debug_file: main status file for debugfs. - * @debug_fifo: FIFO status file for debugfs. - * @ep0_reply: Request used for ep0 reply. - * @ep0_buff: Buffer for EP0 reply data, if needed. - * @ctrl_buff: Buffer for EP0 control requests. - * @ctrl_req: Request for EP0 control packets. - * @setup: NAK management for EP0 SETUP - * @last_rst: Time of last reset - * @eps: The endpoints being supplied to the gadget framework - */ -struct s3c_hsotg { - struct device*dev; - struct usb_gadget_driver *driver; - struct phy *phy; - struct usb_phy *uphy; - struct s3c_hsotg_plat*plat; - - spinlock_t lock; - - void __iomem*regs; - int irq; - struct clk *clk; - - struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; - - u32 phyif; - int fifo_mem; - unsigned intdedicated_fifos:1; - unsigned char num_of_eps; - u32 fifo_map; - - struct dentry *debug_root; - struct dentry *debug_file; - struct dentry *debug_fifo; - - struct usb_request *ep0_reply; - struct usb_request *ctrl_req; - u8 ep0_buff[8]; - u8 ctrl_buff[8]; - - struct usb_gadget gadget; - unsigned intsetup; - unsigned long last_rst; - struct s3c_hsotg_ep *eps; -}; - -/** * struct s3c_hsotg_req - data transfer request * @req: The USB gadget request * @queue: The list of requests for the endpoint this is queued for. @@ -229,6 +168,7 @@ struct s3c_hsotg_req { unsigned char mapped; }; +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) #define call_gadget(_hs, _entry) \ do { \ if ((_hs)-gadget.speed != USB_SPEED_UNKNOWN \ @@ -238,6 +178,9 @@ do { \ spin_lock(_hs-lock); \ } \ } while (0) +#else +#define call_gadget(_hs, _entry) do {} while (0) +#endif struct dwc2_hsotg; struct dwc2_host_chan; @@ -495,11 +438,13 @@ struct dwc2_hw_params { * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic * and periodic schedules * + * These are common for both host and peripheral modes:
[PATCHv5 2/7] usb: dwc2: Move gadget probe function into platform code
From: Dinh Nguyen dingu...@opensource.altera.com This patch will aggregate the probing of gadget/hcd driver into platform.c. The gadget probe funtion is converted into gadget_init that is now only responsible for gadget only initialization. All the gadget resources is now handled by platform.c Since the host workqueue will not get initialized if the driver is configured for peripheral mode only. Thus we need to check for wq_otg before calling queue_work(). Also, we move spin_lock_init to common location for both host and gadget that is either in platform.c or pci.c. We also ove suspend/resume code to common platform code, and update it to use the new PM API (struct dev_pm_ops). Lastly, move the samsung,s3c6400-hsotg binding into dwc2_of_match_table. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v5: Reworked by squashing the following commits into this one: * [PATCHv4 02/12] usb: dwc2: move samsung,s3c6400-hsotg into common platform * [PATCHv4 03/12] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure * [PATCHv4 09/12] usb: dwc2: initialize the spin_lock for both host and gadget * [PATCHv4 10/12] usb: dwc2: Add suspend/resume for gadget * [PATCHv4 11/12] usb: dwc2: check that the host work queue is valid Also use IS_ENABLED instead of #if defined --- drivers/usb/dwc2/core.h | 34 +++- drivers/usb/dwc2/core_intr.c | 8 ++-- drivers/usb/dwc2/gadget.c| 97 +--- drivers/usb/dwc2/hcd.c | 1 - drivers/usb/dwc2/hcd.h | 10 - drivers/usb/dwc2/pci.c | 1 + drivers/usb/dwc2/platform.c | 32 +++ 7 files changed, 91 insertions(+), 92 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 5412f57..b21aace 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -667,7 +667,6 @@ struct dwc2_hsotg { struct usb_phy *uphy; struct s3c_hsotg_plat *plat; - int irq; struct clk *clk; struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; @@ -961,4 +960,37 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); */ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); +/* Gadget defines */ +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) +extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); +extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); +extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +#else +static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) +{ return 0; } +#endif + +#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) +extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); +#else +static inline void dwc2_set_all_params(struct dwc2_core_params *params, int value) {} +static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) +{ return 0; } +static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} +static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, + const struct dwc2_core_params *params) +{ return 0; } +#endif + #endif /* __DWC2_CORE_H__ */ diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index c93918b..b176c2f 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -287,9 +287,11 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) * Release lock before scheduling workq as it holds spinlock during * scheduling. */ - spin_unlock(hsotg-lock); - queue_work(hsotg-wq_otg, hsotg-wf_otg); - spin_lock(hsotg-lock); + if (hsotg-wq_otg) { + spin_unlock(hsotg-lock); + queue_work(hsotg-wq_otg, hsotg-wf_otg); + spin_lock(hsotg-lock); + } /* Clear interrupt */ writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6611ea3..c407d33 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3404,26 +3404,21 @@ static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_probe - probe function for hsotg driver - * @pdev: The platform information for the driver + * dwc2_gadget_init - init function for gadget + * @dwc2: The data
[PATCHv5 6/7] usb: dwc2: gadget: Do not fail probe if there isn't a clock node
From: Dinh Nguyen dingu...@opensource.altera.com Since the dwc2 hcd driver is currently not looking for a clock node during init, we should not completely fail if there isn't a clock provided. For dual-role mode, we will only fail init for a non-clock node error. We then update the HCD to only call gadget funtions if there is a proper clock node. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- v5: reworked to not access gadget functions from the hcd. --- drivers/usb/dwc2/core.h | 3 +-- drivers/usb/dwc2/core_intr.c | 9 ++--- drivers/usb/dwc2/hcd.c | 3 ++- drivers/usb/dwc2/platform.c | 19 +++ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index ba488ec..8794c08 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -660,6 +660,7 @@ struct dwc2_hsotg { #endif #endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */ + struct clk *clk; #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) /* Gadget structures */ struct usb_gadget_driver *driver; @@ -667,8 +668,6 @@ struct dwc2_hsotg { struct usb_phy *uphy; struct s3c_hsotg_plat *plat; - struct clk *clk; - struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; u32 phyif; diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 1240875..1608037 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -339,7 +339,8 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Change to L0 state */ hsotg-lx_state = DWC2_L0; - call_gadget(hsotg, resume); + if (!IS_ERR(hsotg-clk)) + call_gadget(hsotg, resume); } else { if (hsotg-lx_state != DWC2_L1) { u32 pcgcctl = readl(hsotg-regs + PCGCTL); @@ -400,7 +401,8 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n, !!(dsts DSTS_SUSPSTS), hsotg-hw_params.power_optimized); - call_gadget(hsotg, suspend); + if (!IS_ERR(hsotg-clk)) + call_gadget(hsotg, suspend); } else { if (hsotg-op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg-dev, a_peripheral-a_host\n); @@ -477,7 +479,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) spin_lock(hsotg-lock); if (dwc2_is_device_mode(hsotg)) - retval = s3c_hsotg_irq(irq, dev); + if (!IS_ERR(hsotg-clk)) + retval = s3c_hsotg_irq(irq, dev); gintsts = dwc2_read_common_intr(hsotg); if (gintsts ~GINTSTS_PRTINT) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 44c609f..fa49c72 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1371,7 +1371,8 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg-op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); - s3c_hsotg_core_init(hsotg); + if (!IS_ERR(hsotg-clk)) + s3c_hsotg_core_init(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg-dev, connId A\n); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 72f32f7..77c8417 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -217,8 +217,17 @@ static int dwc2_driver_probe(struct platform_device *dev) spin_lock_init(hsotg-lock); retval = dwc2_gadget_init(hsotg, irq); - if (retval) - return retval; + if (retval) { + /* +* We will not fail the driver initialization for dual-role +* if no clock node is supplied. However, all gadget +* functionality will be disabled if a clock node is not +* provided. Host functionality will continue. +* TO-DO: make clock node a requirement for the HCD. +*/ + if (!IS_ERR(hsotg-clk)) + return retval; + } retval = dwc2_hcd_init(hsotg, irq, params); if (retval) return retval; @@ -234,7 +243,8 @@ static int dwc2_suspend(struct device *dev) int ret = 0; if (dwc2_is_device_mode(dwc2)) - ret = s3c_hsotg_suspend(dwc2); + if (!IS_ERR(dwc2-clk)) + ret = s3c_hsotg_suspend(dwc2); return ret; } @@ -244,7 +254,8 @@ static int dwc2_resume(struct device *dev) int ret = 0; if
[RFC PATCH 0/2] usb: dwc2: Enable URB giveback in a tasklet context
From: Dinh Nguyen dingu...@opensource.altera.com Hi Ming-Lei, Thanks for your patch to enable the URB giveback in a tasklet context for the EHCI driver. I found your patch to fix a USB webcam timeout/stutter issue on the DWC2 HCD in the SOCFPGA platform. However, I need your help trying to figure out why I need the 2nd patch to get your URB giveback patch to fully work. I enable tracepoints in the dwc2 dwc2_handle_hcd_intr for irq:irq_handler_entry and irq:irq_handler_exit. However, I did not see any measurable differences between enabling HCD_BH and no enabling HCD_BH. But I am able to get a full image from a webcam with the following 2 patches, and timeouts/green screen without the 2 patches. I am using a Logitech HD C270 webcam. Opening video decoder: [raw] RAW Uncompressed Video Movie-Aspect is undefined - no prescaling applied. VO: [sdl] 640x480 = 640x480 Packed YUY2 Selected video codec: [rawyuy2] vfm: raw (RAW YUY2) Can you provide any comments on the following issues: 1) Am I placing the tracepoints in the right place for this non-ehci hcd? 2) I don't quite understand why removing local_irq_save/local_irq_restore around the the complete makes the webcam work? Thanks in advance for your comments. Dinh Dinh Nguyen (2): usb: dwc2: Enable HCD_BH in the dwc2 driver usb-core: Remove the local_irq_save/local_irq_restore around complete drivers/usb/core/hcd.c | 2 -- drivers/usb/dwc2/hcd.c | 6 +- 2 files changed, 1 insertion(+), 7 deletions(-) -- 2.0.3 -- 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
[RFC PATCH 2/2] usb-core: Remove the local_irq_save/local_irq_restore around complete
From: Dinh Nguyen dingu...@opensource.altera.com When enabling HCD_BH for the DWC2 HCD, these local_irq_save/local_irq_restore was causing a timeout with a webcam. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/core/hcd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 487abcf..463dc44 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1678,9 +1678,7 @@ static void __usb_hcd_giveback_urb(struct urb *urb) * and no one may trigger the above deadlock situation when * running complete() in tasklet. */ - local_irq_save(flags); urb-complete(urb); - local_irq_restore(flags); usb_anchor_resume_wakeups(anchor); atomic_dec(urb-use_count); -- 2.0.3 -- 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
[RFC PATCH 1/2] usb: dwc2: Enable HCD_BH in the dwc2 driver
From: Dinh Nguyen dingu...@opensource.altera.com Enable the support of running URB giveback in tasklet context. Remove spinlocks around URB giveback as these are not needed when running in the tasklet. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/hcd.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 4d918ed..9bdc077 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2193,9 +2193,7 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, kfree(qtd-urb); qtd-urb = NULL; - spin_unlock(hsotg-lock); usb_hcd_giveback_urb(dwc2_hsotg_to_hcd(hsotg), urb, status); - spin_lock(hsotg-lock); } /* @@ -2528,9 +2526,7 @@ static int _dwc2_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, urb-hcpriv = NULL; /* Higher layer software sets URB status */ - spin_unlock(hsotg-lock); usb_hcd_giveback_urb(hcd, urb, status); - spin_lock(hsotg-lock); dev_dbg(hsotg-dev, Called usb_hcd_giveback_urb()\n); dev_dbg(hsotg-dev, urb-status = %d\n, urb-status); @@ -2640,7 +2636,7 @@ static struct hc_driver dwc2_hc_driver = { .hcd_priv_size = sizeof(struct wrapper_priv_data), .irq = _dwc2_hcd_irq, - .flags = HCD_MEMORY | HCD_USB2, + .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, .start = _dwc2_hcd_start, .stop = _dwc2_hcd_stop, -- 2.0.3 -- 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
[PATCHv4 00/12] usb: dwc2: Add support for dual role
From: Dinh Nguyen dingu...@opensource.altera.com Hello, This is version 4 of the patch series that combines the dwc2 gadget and host driver into a single dual role driver. Here are the main differences from V2: - Patch 9/12 : Move spin_lock_init() earlier up in the function to guarantee no locks can be taken before the initializing the spin_lock. - Patch 12/12 : Same as patch 9/12. - Added Acked-by: paulz for all patches except patch 9/12 and 12/12. For v4, I have rebased the series on top of Greg KH's USB usb-linus tree [9b2667f usb: dwc2: gadget: Set the default EP max packet value as 8 bytes] and on top of the following patches that have not yet been applied: Doug Anderson: usb: dwc2: Read GNPTXFSIZ when in forced HOST mode Kever Yang : usb: dwc2: add 'mode' which based on Kconfig select or dts setting Robert Baldyga : usb: dwc2/gadget: fix series - 12 patches As usual, tested on SOCFPGA(host, gadget, and dual-role) and on Rpi-B (host mode only). I have pushed this series to a git repo to make it more convenient for people to test/review. git://git.rocketboards.org/linux-socfpga-next.git dwc2_dual_role_v4 Thanks, Dinh Nguyen (12): usb: dwc2: Update Kconfig to support dual-role usb: dwc2: move samsung,s3c6400-hsotg into common platform usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure usb: dwc2: Add the appropriate init calls in platform code usb: dwc2: Initialize the USB core for peripheral mode usb: dwc2: Update common interrupt handler to call gadget interrupt handler usb: dwc2: Add call_gadget functions for perpheral mode interrupts usb: dwc2: gadget: Do not fail probe if there isn't a clock node usb: dwc2: initialize the spin_lock for both host and gadget usb: dwc2: Add suspend/resume for gadget usb: dwc2: check that the host work queue is valid usb: dwc2: pci: Update pci portion of the dwc2 driver drivers/usb/dwc2/Kconfig | 63 + drivers/usb/dwc2/Makefile| 21 +-- drivers/usb/dwc2/core.h | 198 --- drivers/usb/dwc2/core_intr.c | 13 +- drivers/usb/dwc2/gadget.c| 311 +++ drivers/usb/dwc2/hcd.c | 2 +- drivers/usb/dwc2/hcd.h | 10 -- drivers/usb/dwc2/pci.c | 1 + drivers/usb/dwc2/platform.c | 53 +++- 9 files changed, 339 insertions(+), 333 deletions(-) -- 2.0.3 -- 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
[PATCHv4 03/12] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure
From: Dinh Nguyen dingu...@opensource.altera.com Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. To keep the driver data dereference code looking clean, the gadget variable declares are only available for peripheral and dual-role mode. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Updates gadget.c to use the dwc2_hsotg data structure and gadget pointers that have been moved into the common dwc2_hsotg structure. Along with the updating the gadget driver to use the common dwc2_hsotg structure, a few other things are required in order for this patch to build properly. Those are: - Remove gadget module defines. Since the driver probing will be handled by either the platform or pci code. - Change the gadget probe function into gadget_init. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Signed-off-by: Paul Zimmerman pa...@synopsys.com --- v3: Updated with paulz's suggestion to avoid double pointers. v2: Left the function parameter name as 'hsotg' and just changed its type. --- drivers/usb/dwc2/core.h | 176 +--- drivers/usb/dwc2/gadget.c | 226 +- drivers/usb/dwc2/hcd.h| 10 -- 3 files changed, 184 insertions(+), 228 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index bf015ab..f55e62d 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -84,7 +84,7 @@ static const char * const s3c_hsotg_supply_names[] = { */ #define EP0_MPS_LIMIT 64 -struct s3c_hsotg; +struct dwc2_hsotg; struct s3c_hsotg_req; /** @@ -130,7 +130,7 @@ struct s3c_hsotg_req; struct s3c_hsotg_ep { struct usb_ep ep; struct list_headqueue; - struct s3c_hsotg*parent; + struct dwc2_hsotg *parent; struct s3c_hsotg_req*req; struct dentry *debugfs; @@ -155,67 +155,6 @@ struct s3c_hsotg_ep { }; /** - * struct s3c_hsotg - driver state. - * @dev: The parent device supplied to the probe function - * @driver: USB gadget driver - * @phy: The otg phy transceiver structure for phy control. - * @uphy: The otg phy transceiver structure for old USB phy control. - * @plat: The platform specific configuration data. This can be removed once - * all SoCs support usb transceiver. - * @regs: The memory area mapped for accessing registers. - * @irq: The IRQ number we are using - * @supplies: Definition of USB power supplies - * @phyif: PHY interface width - * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. - * @num_of_eps: Number of available EPs (excluding EP0) - * @debug_root: root directrory for debugfs. - * @debug_file: main status file for debugfs. - * @debug_fifo: FIFO status file for debugfs. - * @ep0_reply: Request used for ep0 reply. - * @ep0_buff: Buffer for EP0 reply data, if needed. - * @ctrl_buff: Buffer for EP0 control requests. - * @ctrl_req: Request for EP0 control packets. - * @setup: NAK management for EP0 SETUP - * @last_rst: Time of last reset - * @eps: The endpoints being supplied to the gadget framework - */ -struct s3c_hsotg { - struct device*dev; - struct usb_gadget_driver *driver; - struct phy *phy; - struct usb_phy *uphy; - struct s3c_hsotg_plat*plat; - - spinlock_t lock; - - void __iomem*regs; - int irq; - struct clk *clk; - - struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; - - u32 phyif; - int fifo_mem; - unsigned intdedicated_fifos:1; - unsigned char num_of_eps; - u32 fifo_map; - - struct dentry *debug_root; - struct dentry *debug_file; - struct dentry *debug_fifo; - - struct usb_request *ep0_reply; - struct usb_request *ctrl_req; - u8 ep0_buff[8]; - u8 ctrl_buff[8]; - - struct usb_gadget gadget; - unsigned intsetup; - unsigned long last_rst; - struct s3c_hsotg_ep *eps; -}; - -/** * struct s3c_hsotg_req - data transfer request * @req: The USB gadget request * @queue: The list of requests for the endpoint this is queued for. @@ -229,6 +168,7 @@ struct s3c_hsotg_req { unsigned char mapped; }; +#if defined(CONFIG_USB_DWC2_PERIPHERAL) || defined(CONFIG_USB_DWC2_DUAL_ROLE) #define call_gadget(_hs, _entry) \ do { \ if ((_hs)-gadget.speed != USB_SPEED_UNKNOWN \ @@ -238,6 +178,9 @@ do { \ spin_lock(_hs-lock); \ } \ } while (0) +#else +#define call_gadget(_hs, _entry) do {} while (0) +#endif struct dwc2_hsotg; struct dwc2_host_chan; @@
[PATCHv4 01/12] usb: dwc2: Update Kconfig to support dual-role
From: Dinh Nguyen dingu...@opensource.altera.com Update DWC2 kconfig and makefile to support dual-role mode. The platform file will always get compiled for the case where the controller is directly connected to the CPU. So for loadable modules, only dwc2.ko is needed. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- v3: Add USB_GADGET=y and USB_GADGET=USB_DWC2 for peripheral and dual-role config options. v2: Remove reference to dwc2_gadget --- drivers/usb/dwc2/Kconfig | 63 +++ drivers/usb/dwc2/Makefile | 21 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index f93807b..4396a1f 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,40 +1,29 @@ config USB_DWC2 - bool DesignWare USB2 DRD Core Support + tristate DesignWare USB2 DRD Core Support depends on USB help Say Y here if your system has a Dual Role Hi-Speed USB controller based on the DesignWare HSOTG IP Core. - For host mode, if you choose to build the driver as dynamically - linked modules, the core module will be called dwc2.ko, the PCI - bus interface module (if you have a PCI bus system) will be - called dwc2_pci.ko, and the platform interface module (for - controllers directly connected to the CPU) will be called - dwc2_platform.ko. For gadget mode, there will be a single - module called dwc2_gadget.ko. - - NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. The - host and gadget drivers are still currently separate drivers. - There are plans to merge the dwc2_gadget driver with the dwc2 - host driver in the near future to create a dual-role driver. + If you choose to build the driver as dynamically + linked modules, a single dwc2.ko(regardless of mode of operation) + will get built for both platform IPs and PCI. if USB_DWC2 +choice + bool DWC2 Mode Selection + default USB_DWC2_DUAL_ROLE if (USB USB_GADGET) + default USB_DWC2_HOST if (USB !USB_GADGET) + default USB_DWC2_PERIPHERAL if (!USB USB_GADGET) + config USB_DWC2_HOST - tristate Host only mode + bool Host only mode depends on USB help The Designware USB2.0 high-speed host controller - integrated into many SoCs. - -config USB_DWC2_PLATFORM - bool DWC2 Platform - depends on USB_DWC2_HOST - default USB_DWC2_HOST - help - The Designware USB2.0 platform interface module for - controllers directly connected to the CPU. This is only - used for host mode. + integrated into many SoCs. Select this option if you want the + driver to operate in Host-only mode. config USB_DWC2_PCI bool DWC2 PCI @@ -47,11 +36,31 @@ config USB_DWC2_PCI comment Gadget mode requires USB Gadget support to be enabled config USB_DWC2_PERIPHERAL - tristate Gadget only mode - depends on USB_GADGET + bool Gadget only mode + depends on USB_GADGET=y || USB_GADGET=USB_DWC2 help The Designware USB2.0 high-speed gadget controller - integrated into many SoCs. + integrated into many SoCs. Select this option if you want the + driver to operate in Peripheral-only mode. This option requires + USB_GADGET=y. + +config USB_DWC2_DUAL_ROLE + bool Dual Role mode + depends on ((USB=y || USB=USB_DWC2) (USB_GADGET=y || USB_GADGET=USB_DWC2)) + help + Select this option if you want the driver to work in a dual-role + mode. In this mode both host and gadget features are enabled, and + the role will be determined by the cable that gets plugged-in. This + option requires USB_GADGET=y. +endchoice + +config USB_DWC2_PLATFORM + bool +depends on !PCI +default y +help + The Designware USB2.0 platform interface module for + controllers directly connected to the CPU. config USB_DWC2_DEBUG bool Enable Debugging Messages diff --git a/drivers/usb/dwc2/Makefile b/drivers/usb/dwc2/Makefile index b73d2a5..3026135 100644 --- a/drivers/usb/dwc2/Makefile +++ b/drivers/usb/dwc2/Makefile @@ -1,10 +1,17 @@ ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG -obj-$(CONFIG_USB_DWC2_HOST)+= dwc2.o +obj-$(CONFIG_USB_DWC2) += dwc2.o dwc2-y := core.o core_intr.o -dwc2-y += hcd.o hcd_intr.o -dwc2-y += hcd_queue.o hcd_ddma.o + +ifneq ($(filter y,$(CONFIG_USB_DWC2_HOST) $(CONFIG_USB_DWC2_DUAL_ROLE)),) + dwc2-y += hcd.o hcd_intr.o + dwc2-y
[PATCHv4 07/12] usb: dwc2: Add call_gadget functions for perpheral mode interrupts
From: Dinh Nguyen dingu...@opensource.altera.com Update the dwc2 wakeup and suspend interrupt functions to use call_gadget when the IP is in peripheral mode. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- drivers/usb/dwc2/core_intr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 24d4c0d..651785d 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -337,6 +337,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Change to L0 state */ hsotg-lx_state = DWC2_L0; + call_gadget(hsotg, resume); } else { if (hsotg-lx_state != DWC2_L1) { u32 pcgcctl = readl(hsotg-regs + PCGCTL); @@ -397,6 +398,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n, !!(dsts DSTS_SUSPSTS), hsotg-hw_params.power_optimized); + call_gadget(hsotg, suspend); } else { if (hsotg-op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg-dev, a_peripheral-a_host\n); -- 2.0.3 -- 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
[PATCHv4 09/12] usb: dwc2: initialize the spin_lock for both host and gadget
From: Dinh Nguyen dingu...@opensource.altera.com Move spin_lock_init to common location for both host and gadget. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- v4: move spin_lock_init up to make sure sure no locks can be taken before the init. --- drivers/usb/dwc2/hcd.c | 1 - drivers/usb/dwc2/platform.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 07a7bcd..c6778d9 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2824,7 +2824,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, hcd-has_tt = 1; - spin_lock_init(hsotg-lock); ((struct wrapper_priv_data *) hcd-hcd_priv)-hsotg = hsotg; hsotg-priv = hcd; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 2871f351..278135d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -183,6 +183,7 @@ static int dwc2_driver_probe(struct platform_device *dev) hsotg-dr_mode = of_usb_get_dr_mode(dev-dev.of_node); + spin_lock_init(hsotg-lock); if (IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)) { retval = dwc2_gadget_init(hsotg, irq); if (retval) -- 2.0.3 -- 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
[PATCHv4 05/12] usb: dwc2: Initialize the USB core for peripheral mode
From: Dinh Nguyen dingu...@opensource.altera.com Initialize the USB driver to peripheral mode when a B-Device connector is attached. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- drivers/usb/dwc2/hcd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 4d918ed..07a7bcd 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1355,6 +1355,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg-op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); + s3c_hsotg_core_init(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg-dev, connId A\n); -- 2.0.3 -- 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
[PATCHv4 10/12] usb: dwc2: Add suspend/resume for gadget
From: Dinh Nguyen dingu...@opensource.altera.com Move suspend/resume code to common platform code. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- drivers/usb/dwc2/core.h | 6 ++ drivers/usb/dwc2/gadget.c | 4 ++-- drivers/usb/dwc2/platform.c | 23 +++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index bbb0f52..5bb7e801 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -964,12 +964,18 @@ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); #if defined(CONFIG_USB_DWC2_PERIPHERAL) || defined(CONFIG_USB_DWC2_DUAL_ROLE) extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); irqreturn_t s3c_hsotg_irq(int irq, void *pw); #else static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } +static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) +{ return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } static inline irqreturn_t s3c_hsotg_irq(int irq, void *pw) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index aab1b45..09d591e 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3552,7 +3552,7 @@ int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) return 0; } -static int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) +int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) { unsigned long flags; int ret = 0; @@ -3581,7 +3581,7 @@ static int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) return ret; } -static int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) +int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) { unsigned long flags; int ret = 0; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 278135d..59265ad 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -206,6 +206,27 @@ static int dwc2_driver_probe(struct platform_device *dev) return retval; } +static int dwc2_suspend(struct platform_device *dev, pm_message_t state) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_suspend(dwc2); + return ret; +} + +static int dwc2_resume(struct platform_device *dev) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_resume(dwc2); + + return ret; +} + static struct platform_driver dwc2_platform_driver = { .driver = { .name = dwc2_driver_name, @@ -213,6 +234,8 @@ static struct platform_driver dwc2_platform_driver = { }, .probe = dwc2_driver_probe, .remove = dwc2_driver_remove, + .suspend = dwc2_suspend, + .resume = dwc2_resume, }; module_platform_driver(dwc2_platform_driver); -- 2.0.3 -- 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
[PATCHv4 12/12] usb: dwc2: pci: Update pci portion of the dwc2 driver
From: Dinh Nguyen dingu...@opensource.altera.com Initialize the spinlock here as the original spinlock in the host driver has been removed. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- v4: moved spin_lock_init() up to make sure no locks can be taken before the init. --- drivers/usb/dwc2/pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index c291fca..6d33ecf 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c @@ -141,6 +141,7 @@ static int dwc2_driver_probe(struct pci_dev *dev, pci_set_master(dev); + spin_lock_init(hsotg-lock); retval = dwc2_hcd_init(hsotg, dev-irq, dwc2_module_params); if (retval) { pci_disable_device(dev); -- 2.0.3 -- 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
[PATCHv4 11/12] usb: dwc2: check that the host work queue is valid
From: Dinh Nguyen dingu...@opensource.altera.com The Host workqueue will not get initialized if the driver is configured for peripheral mode only. Thus we need to check for wq_otg before calling queue_work(). Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- drivers/usb/dwc2/core_intr.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 651785d..1240875 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -287,9 +287,11 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) * Release lock before scheduling workq as it holds spinlock during * scheduling. */ - spin_unlock(hsotg-lock); - queue_work(hsotg-wq_otg, hsotg-wf_otg); - spin_lock(hsotg-lock); + if (hsotg-wq_otg) { + spin_unlock(hsotg-lock); + queue_work(hsotg-wq_otg, hsotg-wf_otg); + spin_lock(hsotg-lock); + } /* Clear interrupt */ writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); -- 2.0.3 -- 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
[PATCHv4 04/12] usb: dwc2: Add the appropriate init calls in platform code
From: Dinh Nguyen dingu...@opensource.altera.com Add the proper init calls for either host, gadget or both in platform.c Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Acked-by: Paul Zimmerman pa...@synopsys.com --- drivers/usb/dwc2/core.h | 13 + drivers/usb/dwc2/gadget.c | 2 +- drivers/usb/dwc2/platform.c | 28 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index f55e62d..3a49a00 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -960,6 +960,19 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); */ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); +/* Gadget defines */ +#if defined(CONFIG_USB_DWC2_PERIPHERAL) || defined(CONFIG_USB_DWC2_DUAL_ROLE) +extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); +extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); +extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +#else +static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} +static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) +{ return 0; } +#endif + #if defined(CONFIG_USB_DWC2_HOST) || defined(CONFIG_USB_DWC2_DUAL_ROLE) /** * dwc2_hcd_get_frame_number() - Returns current frame number diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 96f868f..efa68a0 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3572,7 +3572,7 @@ err_clk: * s3c_hsotg_remove - remove function for hsotg driver * @pdev: The platform information for the driver */ -static int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) +int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) { usb_del_gadget_udc(hsotg-gadget); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index dd2f8f5..2871f351 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -92,7 +92,14 @@ static int dwc2_driver_remove(struct platform_device *dev) { struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); - dwc2_hcd_remove(hsotg); + if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) + s3c_hsotg_remove(hsotg); + else if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) + dwc2_hcd_remove(hsotg); + else { /* dual role */ + dwc2_hcd_remove(hsotg); + s3c_hsotg_remove(hsotg); + } return 0; } @@ -176,9 +183,22 @@ static int dwc2_driver_probe(struct platform_device *dev) hsotg-dr_mode = of_usb_get_dr_mode(dev-dev.of_node); - retval = dwc2_hcd_init(hsotg, irq, params); - if (retval) - return retval; + if (IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)) { + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + return retval; + retval = dwc2_hcd_init(hsotg, irq, params); + if (retval) + return retval; + } else if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) { + retval = dwc2_hcd_init(hsotg, irq, params); + if (retval) + return retval; + } else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) { + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + return retval; + } platform_set_drvdata(dev, hsotg); -- 2.0.3 -- 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 11/12] usb: dwc2: check that the host work queue is valid
From: Dinh Nguyen dingu...@opensource.altera.com The Host workqueue will not get initialized if the driver is configured for peripheral mode only. Thus we need to check for wq_otg before calling queue_work(). Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/core_intr.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 651785d..1240875 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -287,9 +287,11 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) * Release lock before scheduling workq as it holds spinlock during * scheduling. */ - spin_unlock(hsotg-lock); - queue_work(hsotg-wq_otg, hsotg-wf_otg); - spin_lock(hsotg-lock); + if (hsotg-wq_otg) { + spin_unlock(hsotg-lock); + queue_work(hsotg-wq_otg, hsotg-wf_otg); + spin_lock(hsotg-lock); + } /* Clear interrupt */ writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); -- 2.0.3 -- 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 10/12] usb: dwc2: Add suspend/resume for gadget
From: Dinh Nguyen dingu...@opensource.altera.com Move suspend/resume code to common platform code. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/core.h | 6 ++ drivers/usb/dwc2/gadget.c | 4 ++-- drivers/usb/dwc2/platform.c | 23 +++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index bbb0f52..5bb7e801 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -964,12 +964,18 @@ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); #if defined(CONFIG_USB_DWC2_PERIPHERAL) || defined(CONFIG_USB_DWC2_DUAL_ROLE) extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); irqreturn_t s3c_hsotg_irq(int irq, void *pw); #else static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } +static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) +{ return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } static inline irqreturn_t s3c_hsotg_irq(int irq, void *pw) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index a3a3d31..2d98100 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3555,7 +3555,7 @@ int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) return 0; } -static int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) +int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) { unsigned long flags; int ret = 0; @@ -3584,7 +3584,7 @@ static int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) return ret; } -static int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) +int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) { unsigned long flags; int ret = 0; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 6e30289..2a67dad 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -206,6 +206,27 @@ static int dwc2_driver_probe(struct platform_device *dev) return retval; } +static int dwc2_suspend(struct platform_device *dev, pm_message_t state) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_suspend(dwc2); + return ret; +} + +static int dwc2_resume(struct platform_device *dev) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_resume(dwc2); + + return ret; +} + static struct platform_driver dwc2_platform_driver = { .driver = { .name = dwc2_driver_name, @@ -213,6 +234,8 @@ static struct platform_driver dwc2_platform_driver = { }, .probe = dwc2_driver_probe, .remove = dwc2_driver_remove, + .suspend = dwc2_suspend, + .resume = dwc2_resume, }; module_platform_driver(dwc2_platform_driver); -- 2.0.3 -- 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 02/12] usb: dwc2: move samsung,s3c6400-hsotg into common platform
From: Dinh Nguyen dingu...@opensource.altera.com Move the samsung,s3c6400-hsotg binding as the probe function in the gadget driver will get removed when the dual-role driver is implemented. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/gadget.c | 1 - drivers/usb/dwc2/platform.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index cc31088..c62f6c2 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3678,7 +3678,6 @@ static int s3c_hsotg_resume(struct platform_device *pdev) #ifdef CONFIG_OF static const struct of_device_id s3c_hsotg_of_ids[] = { - { .compatible = samsung,s3c6400-hsotg, }, { .compatible = snps,dwc2, }, { /* sentinel */ } }; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 5f0c4bb..dd2f8f5 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -100,6 +100,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = brcm,bcm2835-usb, .data = params_bcm2835 }, { .compatible = snps,dwc2, .data = NULL }, + { .compatible = samsung,s3c6400-hsotg, .data = NULL}, {}, }; MODULE_DEVICE_TABLE(of, dwc2_of_match_table); -- 2.0.3 -- 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 04/12] usb: dwc2: Add the appropriate init calls in platform code
From: Dinh Nguyen dingu...@opensource.altera.com Add the proper init calls for either host, gadget or both in platform.c Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/core.h | 13 + drivers/usb/dwc2/gadget.c | 2 +- drivers/usb/dwc2/platform.c | 28 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index f55e62d..3a49a00 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -960,6 +960,19 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); */ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); +/* Gadget defines */ +#if defined(CONFIG_USB_DWC2_PERIPHERAL) || defined(CONFIG_USB_DWC2_DUAL_ROLE) +extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); +extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); +extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +#else +static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} +static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) +{ return 0; } +#endif + #if defined(CONFIG_USB_DWC2_HOST) || defined(CONFIG_USB_DWC2_DUAL_ROLE) /** * dwc2_hcd_get_frame_number() - Returns current frame number diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index ff000c9..d40f765 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3575,7 +3575,7 @@ err_clk: * s3c_hsotg_remove - remove function for hsotg driver * @pdev: The platform information for the driver */ -static int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) +int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) { usb_del_gadget_udc(hsotg-gadget); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index dd2f8f5..2871f351 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -92,7 +92,14 @@ static int dwc2_driver_remove(struct platform_device *dev) { struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); - dwc2_hcd_remove(hsotg); + if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) + s3c_hsotg_remove(hsotg); + else if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) + dwc2_hcd_remove(hsotg); + else { /* dual role */ + dwc2_hcd_remove(hsotg); + s3c_hsotg_remove(hsotg); + } return 0; } @@ -176,9 +183,22 @@ static int dwc2_driver_probe(struct platform_device *dev) hsotg-dr_mode = of_usb_get_dr_mode(dev-dev.of_node); - retval = dwc2_hcd_init(hsotg, irq, params); - if (retval) - return retval; + if (IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)) { + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + return retval; + retval = dwc2_hcd_init(hsotg, irq, params); + if (retval) + return retval; + } else if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) { + retval = dwc2_hcd_init(hsotg, irq, params); + if (retval) + return retval; + } else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) { + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + return retval; + } platform_set_drvdata(dev, hsotg); -- 2.0.3 -- 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 08/12] usb: dwc2: gadget: Do not fail probe if there isn't a clock node
From: Dinh Nguyen dingu...@opensource.altera.com Since the dwc2 hcd driver is currently not looking for a clock node during init, we should not completely fail if there isn't a clock provided. Add a check for a valid clock before calling clock functions. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/gadget.c | 36 ++-- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index d8b86a3..a3a3d31 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2854,7 +2854,8 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, hsotg-gadget.dev.of_node = hsotg-dev-of_node; hsotg-gadget.speed = USB_SPEED_UNKNOWN; - clk_enable(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_enable(hsotg-clk); ret = regulator_bulk_enable(ARRAY_SIZE(hsotg-supplies), hsotg-supplies); @@ -2905,7 +2906,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, regulator_bulk_disable(ARRAY_SIZE(hsotg-supplies), hsotg-supplies); - clk_disable(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_disable(hsotg-clk); return 0; } @@ -2938,10 +2940,12 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) spin_lock_irqsave(hsotg-lock, flags); if (is_on) { s3c_hsotg_phy_enable(hsotg); - clk_enable(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_enable(hsotg-clk); s3c_hsotg_core_init(hsotg); } else { - clk_disable(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_disable(hsotg-clk); s3c_hsotg_phy_disable(hsotg); } @@ -3412,16 +3416,15 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) } hsotg-clk = devm_clk_get(dev, otg); - if (IS_ERR(hsotg-clk)) { - dev_err(dev, cannot get otg clock\n); - return PTR_ERR(hsotg-clk); - } + if (IS_ERR(hsotg-clk)) + dev_warn(dev, cannot get otg clock\n); hsotg-gadget.max_speed = USB_SPEED_HIGH; hsotg-gadget.ops = s3c_hsotg_gadget_ops; hsotg-gadget.name = dev_name(dev); - clk_prepare_enable(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_prepare_enable(hsotg-clk); /* regulators */ @@ -3454,7 +3457,8 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) dev_name(dev), hsotg); if (ret 0) { s3c_hsotg_phy_disable(hsotg); - clk_disable_unprepare(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_disable_unprepare(hsotg-clk); regulator_bulk_disable(ARRAY_SIZE(hsotg-supplies), hsotg-supplies); dev_err(dev, cannot claim IRQ\n); @@ -3524,7 +3528,8 @@ err_ep_mem: err_supplies: s3c_hsotg_phy_disable(hsotg); err_clk: - clk_disable_unprepare(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_disable_unprepare(hsotg-clk); return ret; } @@ -3544,7 +3549,8 @@ int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) usb_gadget_unregister_driver(hsotg-driver); } - clk_disable_unprepare(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_disable_unprepare(hsotg-clk); return 0; } @@ -3571,7 +3577,8 @@ static int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) ret = regulator_bulk_disable(ARRAY_SIZE(hsotg-supplies), hsotg-supplies); - clk_disable(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_disable(hsotg-clk); } return ret; @@ -3586,7 +3593,8 @@ static int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) dev_info(hsotg-dev, resuming usb gadget %s\n, hsotg-driver-driver.name); - clk_enable(hsotg-clk); + if (!IS_ERR(hsotg-clk)) + clk_enable(hsotg-clk); ret = regulator_bulk_enable(ARRAY_SIZE(hsotg-supplies), hsotg-supplies); } -- 2.0.3 -- 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 09/12] usb: dwc2: initialize the spin_lock for both host and gadget
From: Dinh Nguyen dingu...@opensource.altera.com Move spin_lock_init to common location for both host and gadget. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/hcd.c | 1 - drivers/usb/dwc2/platform.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 07a7bcd..c6778d9 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2824,7 +2824,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, hcd-has_tt = 1; - spin_lock_init(hsotg-lock); ((struct wrapper_priv_data *) hcd-hcd_priv)-hsotg = hsotg; hsotg-priv = hcd; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 2871f351..6e30289 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -201,6 +201,7 @@ static int dwc2_driver_probe(struct platform_device *dev) } platform_set_drvdata(dev, hsotg); + spin_lock_init(hsotg-lock); return retval; } -- 2.0.3 -- 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 05/12] usb: dwc2: Initialize the USB core for peripheral mode
From: Dinh Nguyen dingu...@opensource.altera.com Initialize the USB driver to peripheral mode when a B-Device connector is attached. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/hcd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 4d918ed..07a7bcd 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1355,6 +1355,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg-op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); + s3c_hsotg_core_init(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg-dev, connId A\n); -- 2.0.3 -- 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 03/12] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure
From: Dinh Nguyen dingu...@opensource.altera.com Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. To keep the driver data dereference code looking clean, the gadget variable declares are only available for peripheral and dual-role mode. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Updates gadget.c to use the dwc2_hsotg data structure and gadget pointers that have been moved into the common dwc2_hsotg structure. Along with the updating the gadget driver to use the common dwc2_hsotg structure, a few other things are required in order for this patch to build properly. Those are: - Remove gadget module defines. Since the driver probing will be handled by either the platform or pci code. - Change the gadget probe function into gadget_init. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com Signed-off-by: Paul Zimmerman pa...@synopsys.com --- v3: Updated with paulz's suggestion to avoid double pointers. v2: Left the function parameter name as 'hsotg' and just changed its type. --- drivers/usb/dwc2/core.h | 176 --- drivers/usb/dwc2/gadget.c | 229 +- drivers/usb/dwc2/hcd.h| 10 -- 3 files changed, 185 insertions(+), 230 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index bf015ab..f55e62d 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -84,7 +84,7 @@ static const char * const s3c_hsotg_supply_names[] = { */ #define EP0_MPS_LIMIT 64 -struct s3c_hsotg; +struct dwc2_hsotg; struct s3c_hsotg_req; /** @@ -130,7 +130,7 @@ struct s3c_hsotg_req; struct s3c_hsotg_ep { struct usb_ep ep; struct list_headqueue; - struct s3c_hsotg*parent; + struct dwc2_hsotg *parent; struct s3c_hsotg_req*req; struct dentry *debugfs; @@ -155,67 +155,6 @@ struct s3c_hsotg_ep { }; /** - * struct s3c_hsotg - driver state. - * @dev: The parent device supplied to the probe function - * @driver: USB gadget driver - * @phy: The otg phy transceiver structure for phy control. - * @uphy: The otg phy transceiver structure for old USB phy control. - * @plat: The platform specific configuration data. This can be removed once - * all SoCs support usb transceiver. - * @regs: The memory area mapped for accessing registers. - * @irq: The IRQ number we are using - * @supplies: Definition of USB power supplies - * @phyif: PHY interface width - * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. - * @num_of_eps: Number of available EPs (excluding EP0) - * @debug_root: root directrory for debugfs. - * @debug_file: main status file for debugfs. - * @debug_fifo: FIFO status file for debugfs. - * @ep0_reply: Request used for ep0 reply. - * @ep0_buff: Buffer for EP0 reply data, if needed. - * @ctrl_buff: Buffer for EP0 control requests. - * @ctrl_req: Request for EP0 control packets. - * @setup: NAK management for EP0 SETUP - * @last_rst: Time of last reset - * @eps: The endpoints being supplied to the gadget framework - */ -struct s3c_hsotg { - struct device*dev; - struct usb_gadget_driver *driver; - struct phy *phy; - struct usb_phy *uphy; - struct s3c_hsotg_plat*plat; - - spinlock_t lock; - - void __iomem*regs; - int irq; - struct clk *clk; - - struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; - - u32 phyif; - int fifo_mem; - unsigned intdedicated_fifos:1; - unsigned char num_of_eps; - u32 fifo_map; - - struct dentry *debug_root; - struct dentry *debug_file; - struct dentry *debug_fifo; - - struct usb_request *ep0_reply; - struct usb_request *ctrl_req; - u8 ep0_buff[8]; - u8 ctrl_buff[8]; - - struct usb_gadget gadget; - unsigned intsetup; - unsigned long last_rst; - struct s3c_hsotg_ep *eps; -}; - -/** * struct s3c_hsotg_req - data transfer request * @req: The USB gadget request * @queue: The list of requests for the endpoint this is queued for. @@ -229,6 +168,7 @@ struct s3c_hsotg_req { unsigned char mapped; }; +#if defined(CONFIG_USB_DWC2_PERIPHERAL) || defined(CONFIG_USB_DWC2_DUAL_ROLE) #define call_gadget(_hs, _entry) \ do { \ if ((_hs)-gadget.speed != USB_SPEED_UNKNOWN \ @@ -238,6 +178,9 @@ do { \ spin_lock(_hs-lock); \ } \ } while (0) +#else +#define call_gadget(_hs, _entry) do {} while (0) +#endif struct dwc2_hsotg; struct dwc2_host_chan; @@
[PATCHv3 07/12] usb: dwc2: Add call_gadget functions for perpheral mode interrupts
From: Dinh Nguyen dingu...@opensource.altera.com Update the dwc2 wakeup and suspend interrupt functions to use call_gadget when the IP is in peripheral mode. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/core_intr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 24d4c0d..651785d 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -337,6 +337,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Change to L0 state */ hsotg-lx_state = DWC2_L0; + call_gadget(hsotg, resume); } else { if (hsotg-lx_state != DWC2_L1) { u32 pcgcctl = readl(hsotg-regs + PCGCTL); @@ -397,6 +398,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n, !!(dsts DSTS_SUSPSTS), hsotg-hw_params.power_optimized); + call_gadget(hsotg, suspend); } else { if (hsotg-op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg-dev, a_peripheral-a_host\n); -- 2.0.3 -- 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 01/12] usb: dwc2: Update Kconfig to support dual-role
From: Dinh Nguyen dingu...@opensource.altera.com Update DWC2 kconfig and makefile to support dual-role mode. The platform file will always get compiled for the case where the controller is directly connected to the CPU. So for loadable modules, only dwc2.ko is needed. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- v3: Add USB_GADGET=y and USB_GADGET=USB_DWC2 for peripheral and dual-role config options. v2: Remove reference to dwc2_gadget --- drivers/usb/dwc2/Kconfig | 63 +++ drivers/usb/dwc2/Makefile | 21 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index f93807b..4396a1f 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,40 +1,29 @@ config USB_DWC2 - bool DesignWare USB2 DRD Core Support + tristate DesignWare USB2 DRD Core Support depends on USB help Say Y here if your system has a Dual Role Hi-Speed USB controller based on the DesignWare HSOTG IP Core. - For host mode, if you choose to build the driver as dynamically - linked modules, the core module will be called dwc2.ko, the PCI - bus interface module (if you have a PCI bus system) will be - called dwc2_pci.ko, and the platform interface module (for - controllers directly connected to the CPU) will be called - dwc2_platform.ko. For gadget mode, there will be a single - module called dwc2_gadget.ko. - - NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. The - host and gadget drivers are still currently separate drivers. - There are plans to merge the dwc2_gadget driver with the dwc2 - host driver in the near future to create a dual-role driver. + If you choose to build the driver as dynamically + linked modules, a single dwc2.ko(regardless of mode of operation) + will get built for both platform IPs and PCI. if USB_DWC2 +choice + bool DWC2 Mode Selection + default USB_DWC2_DUAL_ROLE if (USB USB_GADGET) + default USB_DWC2_HOST if (USB !USB_GADGET) + default USB_DWC2_PERIPHERAL if (!USB USB_GADGET) + config USB_DWC2_HOST - tristate Host only mode + bool Host only mode depends on USB help The Designware USB2.0 high-speed host controller - integrated into many SoCs. - -config USB_DWC2_PLATFORM - bool DWC2 Platform - depends on USB_DWC2_HOST - default USB_DWC2_HOST - help - The Designware USB2.0 platform interface module for - controllers directly connected to the CPU. This is only - used for host mode. + integrated into many SoCs. Select this option if you want the + driver to operate in Host-only mode. config USB_DWC2_PCI bool DWC2 PCI @@ -47,11 +36,31 @@ config USB_DWC2_PCI comment Gadget mode requires USB Gadget support to be enabled config USB_DWC2_PERIPHERAL - tristate Gadget only mode - depends on USB_GADGET + bool Gadget only mode + depends on USB_GADGET=y || USB_GADGET=USB_DWC2 help The Designware USB2.0 high-speed gadget controller - integrated into many SoCs. + integrated into many SoCs. Select this option if you want the + driver to operate in Peripheral-only mode. This option requires + USB_GADGET=y. + +config USB_DWC2_DUAL_ROLE + bool Dual Role mode + depends on ((USB=y || USB=USB_DWC2) (USB_GADGET=y || USB_GADGET=USB_DWC2)) + help + Select this option if you want the driver to work in a dual-role + mode. In this mode both host and gadget features are enabled, and + the role will be determined by the cable that gets plugged-in. This + option requires USB_GADGET=y. +endchoice + +config USB_DWC2_PLATFORM + bool +depends on !PCI +default y +help + The Designware USB2.0 platform interface module for + controllers directly connected to the CPU. config USB_DWC2_DEBUG bool Enable Debugging Messages diff --git a/drivers/usb/dwc2/Makefile b/drivers/usb/dwc2/Makefile index b73d2a5..3026135 100644 --- a/drivers/usb/dwc2/Makefile +++ b/drivers/usb/dwc2/Makefile @@ -1,10 +1,17 @@ ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG -obj-$(CONFIG_USB_DWC2_HOST)+= dwc2.o +obj-$(CONFIG_USB_DWC2) += dwc2.o dwc2-y := core.o core_intr.o -dwc2-y += hcd.o hcd_intr.o -dwc2-y += hcd_queue.o hcd_ddma.o + +ifneq ($(filter y,$(CONFIG_USB_DWC2_HOST) $(CONFIG_USB_DWC2_DUAL_ROLE)),) + dwc2-y += hcd.o hcd_intr.o + dwc2-y += hcd_queue.o hcd_ddma.o
[PATCHv3 12/12] usb: dwc2: pci: Update pci portion of the dwc2 driver
From: Dinh Nguyen dingu...@opensource.altera.com Initialize the spinlock here as the original spinlock in the host driver has been removed. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- drivers/usb/dwc2/pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index c291fca..faacac9 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c @@ -148,6 +148,7 @@ static int dwc2_driver_probe(struct pci_dev *dev, } pci_set_drvdata(dev, hsotg); + spin_lock_init(hsotg-lock); return retval; } -- 2.0.3 -- 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 00/12] usb: dwc2: Add support for dual role
From: Dinh Nguyen dingu...@opensource.altera.com Hello, This is version 3 of the patch series that combines the dwc2 gadget and host driver into a single dual role driver. Here are the main differences from V2: - less code change: v3: 9 files changed, 340 insertions(+), 335 deletions(-) v2: 9 files changed, 368 insertions(+), 357 deletions(-) v1: 9 files changed, 877 insertions(+), 904 deletions(-) - Patch 1/12 : Add a USB_GADGET=USB_DWC2 dependency for peripheral and dual-role builds - Patch 3/12 : Per paulz's code suggestion to avoid a double pointer usage in order to keep the gadget driver cleaner, the gadget variable declarations are only visible for peripheral and dual-role builds of the driver. Also, in a effort to maintain bisectability, move v2's [usb: dwc2: Moves s3c_hsotg gadget data structure into dwc2_hsotg] and [usb: dwc2: update gadget portion to use common dwc2_hsotg structure] into a single patch for v3. In V3, a single patch [usb: dwc2: Moves s3c_hsotg gadget data structure into dwc2_hsotg] is the result. For this series, there are 12 patches instead of 13. For v3, I have rebased the series on top of the following patches: Doug Anderson: usb: dwc2: Read GNPTXFSIZ when in forced HOST mode Kever Yang : usb: dwc2: add 'mode' which based on Kconfig select or dts setting Robert Baldyga : usb: dwc2/gadget: fix series - 12 patches As usual, tested on SOCFPGA(host, gadget, and dual-role) and on Rpi-B(host mode). This patch series is based on v3.16. I have pushed this a git repo to make it more convenient for people to test/review. git://git.rocketboards.org/linux-socfpga-next.git dwc2_dual_role_v3 Thanks, Dinh Nguyen (12): usb: dwc2: Update Kconfig to support dual-role usb: dwc2: move samsung,s3c6400-hsotg into common platform usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure usb: dwc2: Add the appropriate init calls in platform code usb: dwc2: Initialize the USB core for peripheral mode usb: dwc2: Update common interrupt handler to call gadget interrupt handler usb: dwc2: Add call_gadget functions for perpheral mode interrupts usb: dwc2: gadget: Do not fail probe if there isn't a clock node usb: dwc2: initialize the spin_lock for both host and gadget usb: dwc2: Add suspend/resume for gadget usb: dwc2: check that the host work queue is valid usb: dwc2: pci: Update pci portion of the dwc2 driver drivers/usb/dwc2/Kconfig | 63 + drivers/usb/dwc2/Makefile| 21 +-- drivers/usb/dwc2/core.h | 198 --- drivers/usb/dwc2/core_intr.c | 13 +- drivers/usb/dwc2/gadget.c| 314 +++ drivers/usb/dwc2/hcd.c | 2 +- drivers/usb/dwc2/hcd.h | 10 -- drivers/usb/dwc2/pci.c | 1 + drivers/usb/dwc2/platform.c | 53 +++- 9 files changed, 340 insertions(+), 335 deletions(-) -- 2.0.3 -- 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 06/12] usb: dwc2: Update common interrupt handler to call gadget interrupt handler
From: Dinh Nguyen dingu...@opensource.altera.com Make dwc2_handle_common_intr call the gadget interrupt function when operating in peripheral mode. Remove the spinlock functions in s3c_hsotg_irq as dwc2_handle_common_intr() already has the spinlocks. Remove duplicate interrupt conditions that was in gadget, as those are handled by dwc2 common interrupt handler. Signed-off-by: Dinh Nguyen dingu...@opensource.altera.com --- v2: Keep interrupt handler for host and peripheral modes separate --- drivers/usb/dwc2/core.h | 3 +++ drivers/usb/dwc2/core_intr.c | 3 +++ drivers/usb/dwc2/gadget.c| 50 3 files changed, 10 insertions(+), 46 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3a49a00..bbb0f52 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -965,12 +965,15 @@ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +irqreturn_t s3c_hsotg_irq(int irq, void *pw); #else static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } +static inline irqreturn_t s3c_hsotg_irq(int irq, void *pw) +{ return IRQ_HANDLED; } #endif #if defined(CONFIG_USB_DWC2_HOST) || defined(CONFIG_USB_DWC2_DUAL_ROLE) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index c93918b..24d4c0d 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -472,6 +472,9 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) spin_lock(hsotg-lock); + if (dwc2_is_device_mode(hsotg)) + retval = s3c_hsotg_irq(irq, dev); + gintsts = dwc2_read_common_intr(hsotg); if (gintsts ~GINTSTS_PRTINT) retval = IRQ_HANDLED; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index d40f765..d8b86a3 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2259,14 +2259,13 @@ void s3c_hsotg_core_init(struct dwc2_hsotg *hsotg) * @irq: The IRQ number triggered * @pw: The pw value when registered the handler. */ -static irqreturn_t s3c_hsotg_irq(int irq, void *pw) +irqreturn_t s3c_hsotg_irq(int irq, void *pw) { struct dwc2_hsotg *hsotg = pw; int retry_count = 8; u32 gintsts; u32 gintmsk; - spin_lock(hsotg-lock); irq_retry: gintsts = readl(hsotg-regs + GINTSTS); gintmsk = readl(hsotg-regs + GINTMSK); @@ -2276,33 +2275,12 @@ irq_retry: gintsts = gintmsk; - if (gintsts GINTSTS_OTGINT) { - u32 otgint = readl(hsotg-regs + GOTGINT); - - dev_info(hsotg-dev, OTGInt: %08x\n, otgint); - - writel(otgint, hsotg-regs + GOTGINT); - } - - if (gintsts GINTSTS_SESSREQINT) { - dev_dbg(hsotg-dev, %s: SessReqInt\n, __func__); - writel(GINTSTS_SESSREQINT, hsotg-regs + GINTSTS); - } - if (gintsts GINTSTS_ENUMDONE) { writel(GINTSTS_ENUMDONE, hsotg-regs + GINTSTS); s3c_hsotg_irq_enumdone(hsotg); } - if (gintsts GINTSTS_CONIDSTSCHNG) { - dev_dbg(hsotg-dev, ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n, - readl(hsotg-regs + DSTS), - readl(hsotg-regs + GOTGCTL)); - - writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); - } - if (gintsts (GINTSTS_OEPINT | GINTSTS_IEPINT)) { u32 daint = readl(hsotg-regs + DAINT); u32 daintmsk = readl(hsotg-regs + DAINTMSK); @@ -2383,25 +2361,6 @@ irq_retry: s3c_hsotg_handle_rx(hsotg); } - if (gintsts GINTSTS_MODEMIS) { - dev_warn(hsotg-dev, warning, mode mismatch triggered\n); - writel(GINTSTS_MODEMIS, hsotg-regs + GINTSTS); - } - - if (gintsts GINTSTS_USBSUSP) { - dev_info(hsotg-dev, GINTSTS_USBSusp\n); - writel(GINTSTS_USBSUSP, hsotg-regs + GINTSTS); - - call_gadget(hsotg, suspend); - } - - if (gintsts GINTSTS_WKUPINT) { - dev_info(hsotg-dev, GINTSTS_WkUpIn\n); - writel(GINTSTS_WKUPINT, hsotg-regs + GINTSTS); - - call_gadget(hsotg, resume); - } - if (gintsts GINTSTS_ERLYSUSP) { dev_dbg(hsotg-dev, GINTSTS_ErlySusp\n); writel(GINTSTS_ERLYSUSP, hsotg-regs + GINTSTS); @@ -2437,10 +2396,9 @@ irq_retry: if (gintsts IRQ_RETRY_MASK --retry_count 0) goto irq_retry; - spin_unlock(hsotg-lock); - return IRQ_HANDLED; } +EXPORT_SYMBOL(s3c_hsotg_irq); /** *
[PATCHv2 00/13] usb: dwc2: Add support for dual role
From: Dinh Nguyen dingu...@altera.com Hello, This is version 2 of the patch series that combines the dwc2 gadget and host driver into a single dual role driver. Here are the main differences from V1: - less code change: v1: 9 files changed, 877 insertions(+), 904 deletions(-) v2: 9 files changed, 368 insertions(+), 357 deletions(-) - patch 4/13 : simplified the patch by only changing the 'hsotg' type and not change it's name. - Add patch 3/12 : Moves the samsung,s3c6400-hsotg compatible binding into platform.c. - Kept the interrupt handlers separate. dwc2_handle_common_intr() will check to see if the driver is in peripheral mode and make the call into the dwc2 gadget interrupt handler. This patch series is based on top of Robert Baldyga's [PATCH v3 00/12] usb: dwc2/gadget: fix series. I thought it might be appropriate since that series already has paulz's Acked-by:. This patch series is based on v3.16-rc7. I have pushed this a git repo to make it more convenient for people to test/review. git://git.rocketboards.org/linux-socfpga-next.git dwc2_dual_role_v2 Also, I have tested on 2 platforms. SOCFPGA(device, host and dual-role), RPi-B(Host mode only in Host and dual-role mode). Thanks, Dinh Nguyen (13): usb: dwc2: Update Kconfig to support dual-role usb: dwc2: Moves s3c_hsotg gadget data structure into dwc2_hsotg usb: dwc2: move samsung,s3c6400-hsotg into common platform usb: dwc2: update gadget portion to use common dwc2_hsotg structure usb: dwc2: Add the appropriate init calls in platform code usb: dwc2: Initialize the USB core for peripheral mode usb: dwc2: Update common interrupt handler to call gadget interrupt handler usb: dwc2: Add call_gadget functions for perpheral mode interrupts usb: dwc2: gadget: Do not fail probe if there isn't a clock node usb: dwc2: initialize the spin_lock for both host and gadget usb: dwc2: Add suspend/resume for gadget usb: dwc2: check that the host work queue is valid usb: dwc2: pci: Update pci portion of the dwc2 driver drivers/usb/dwc2/Kconfig | 59 ++--- drivers/usb/dwc2/Makefile| 21 +- drivers/usb/dwc2/core.h | 53 - drivers/usb/dwc2/core_intr.c | 13 +- drivers/usb/dwc2/gadget.c| 513 +- drivers/usb/dwc2/hcd.c |2 +- drivers/usb/dwc2/hcd.h | 10 - drivers/usb/dwc2/pci.c |1 + drivers/usb/dwc2/platform.c | 53 - 9 files changed, 368 insertions(+), 357 deletions(-) -- 1.7.9.5 -- 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 13/13] usb: dwc2: pci: Update pci portion of the dwc2 driver
From: Dinh Nguyen dingu...@altera.com Initialize the spinlock here as the original spinlock in the host driver has been removed. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/pci.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index c291fca..faacac9 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c @@ -148,6 +148,7 @@ static int dwc2_driver_probe(struct pci_dev *dev, } pci_set_drvdata(dev, hsotg); + spin_lock_init(hsotg-lock); return retval; } -- 1.7.9.5 -- 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 08/13] usb: dwc2: Add call_gadget functions for perpheral mode interrupts
From: Dinh Nguyen dingu...@altera.com Update the dwc2 wakeup and suspend interrupt functions to use call_gadget when the IP is in peripheral mode. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core_intr.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 24d4c0d..651785d 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -337,6 +337,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Change to L0 state */ hsotg-lx_state = DWC2_L0; + call_gadget(hsotg, resume); } else { if (hsotg-lx_state != DWC2_L1) { u32 pcgcctl = readl(hsotg-regs + PCGCTL); @@ -397,6 +398,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n, !!(dsts DSTS_SUSPSTS), hsotg-hw_params.power_optimized); + call_gadget(hsotg, suspend); } else { if (hsotg-op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg-dev, a_peripheral-a_host\n); -- 1.7.9.5 -- 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 04/13] usb: dwc2: update gadget portion to use common dwc2_hsotg structure
From: Dinh Nguyen dingu...@altera.com Update gadget.c to use the dwc2_hsotg data structure and gadget pointers that have been moved into the common dwc2_hsotg structure. Along with the updating the gadget driver to use the common dwc2_hsotg structure, a few other things are required in order for this patch to build properly. Those are: - Add proper externs for functions that need to be shared between host and peripheral drivers. - Remove gadget module defines. Since the driver probing will be handled by either the platform or pci code. - Change the gadget probe function into gadget_init. Signed-off-by: Dinh Nguyen dingu...@altera.com --- v2: Left the function parameter name as 'hsotg' and just changed its type. --- drivers/usb/dwc2/core.h | 25 ++- drivers/usb/dwc2/gadget.c | 451 - drivers/usb/dwc2/hcd.h| 10 - 3 files changed, 221 insertions(+), 265 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index ee34ee1..8d901b3 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -84,7 +84,7 @@ static const char * const s3c_hsotg_supply_names[] = { */ #define EP0_MPS_LIMIT 64 -struct s3c_hsotg; +struct dwc2_hsotg; struct s3c_hsotg_req; /** @@ -130,7 +130,7 @@ struct s3c_hsotg_req; struct s3c_hsotg_ep { struct usb_ep ep; struct list_headqueue; - struct s3c_hsotg*parent; + struct dwc2_hsotg *parent; struct s3c_hsotg_req*req; struct dentry *debugfs; @@ -956,4 +956,25 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); */ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); +#if defined(CONFIG_USB_DWC2_HOST) || defined(CONFIG_USB_DWC2_DUAL_ROLE) +/** + * dwc2_hcd_get_frame_number() - Returns current frame number + * + * @hsotg: The DWC2 HCD + */ +extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); +#else +static inline void dwc2_set_all_params(struct dwc2_core_params *params, int value) {} +static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) +{ return 0; } +static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} +static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, + const struct dwc2_core_params *params) +{ return 0; } +#endif + #endif /* __DWC2_CORE_H__ */ diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index c62f6c2..c9c0d51 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -38,6 +38,7 @@ #include linux/platform_data/s3c-hsotg.h #include core.h +#include hw.h /* conversion functions */ static inline struct s3c_hsotg_req *our_req(struct usb_request *req) @@ -50,9 +51,9 @@ static inline struct s3c_hsotg_ep *our_ep(struct usb_ep *ep) return container_of(ep, struct s3c_hsotg_ep, ep); } -static inline struct s3c_hsotg *to_hsotg(struct usb_gadget *gadget) +static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget) { - return container_of(gadget, struct s3c_hsotg, gadget); + return container_of(gadget, struct dwc2_hsotg, gadget); } static inline void __orr32(void __iomem *ptr, u32 val) @@ -66,7 +67,7 @@ static inline void __bic32(void __iomem *ptr, u32 val) } /* forward decleration of functions */ -static void s3c_hsotg_dump(struct s3c_hsotg *hsotg); +static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg); /** * using_dma - return the DMA status of the driver. @@ -97,7 +98,7 @@ static inline bool using_dma(struct s3c_hsotg *hsotg) * @hsotg: The device state * @ints: A bitmask of the interrupts to enable */ -static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints) +static void s3c_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints) { u32 gsintmsk = readl(hsotg-regs + GINTMSK); u32 new_gsintmsk; @@ -115,7 +116,7 @@ static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints) * @hsotg: The device state * @ints: A bitmask of the interrupts to enable */ -static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints) +static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints) { u32 gsintmsk = readl(hsotg-regs + GINTMSK); u32 new_gsintmsk; @@ -136,7 +137,7 @@ static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints) * Set or clear the mask for an individual endpoint's interrupt * request. */ -static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg, +static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg, unsigned int ep, unsigned int dir_in, unsigned int en) { @@ -161,7 +162,7 @@ static void
[PATCHv2 06/13] usb: dwc2: Initialize the USB core for peripheral mode
From: Dinh Nguyen dingu...@altera.com Initialize the USB driver to peripheral mode when a B-Device connector is attached. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/hcd.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 4d918ed..07a7bcd 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1355,6 +1355,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg-op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); + s3c_hsotg_core_init(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg-dev, connId A\n); -- 1.7.9.5 -- 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 11/13] usb: dwc2: Add suspend/resume for gadget
From: Dinh Nguyen dingu...@altera.com Move suspend/resume code to common platform code. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core.h |6 ++ drivers/usb/dwc2/gadget.c |4 ++-- drivers/usb/dwc2/platform.c | 23 +++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index b86673c..c0a895b 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -960,12 +960,18 @@ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); #if defined(CONFIG_USB_DWC2_PERIPHERAL) || defined(CONFIG_USB_DWC2_DUAL_ROLE) extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); irqreturn_t s3c_hsotg_irq(int irq, void *pw); #else static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } +static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) +{ return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } static inline irqreturn_t s3c_hsotg_irq(int irq, void *pw) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index dbcdee0..281b33a 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3561,7 +3561,7 @@ int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) return 0; } -static int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) +int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) { unsigned long flags; int ret = 0; @@ -3591,7 +3591,7 @@ static int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) return ret; } -static int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) +int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) { unsigned long flags; int ret = 0; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 4898268..e0a4e0d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -202,6 +202,27 @@ static int dwc2_driver_probe(struct platform_device *dev) return retval; } +static int dwc2_suspend(struct platform_device *dev, pm_message_t state) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_suspend(dwc2); + return ret; +} + +static int dwc2_resume(struct platform_device *dev) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_resume(dwc2); + + return ret; +} + static struct platform_driver dwc2_platform_driver = { .driver = { .name = dwc2_driver_name, @@ -209,6 +230,8 @@ static struct platform_driver dwc2_platform_driver = { }, .probe = dwc2_driver_probe, .remove = dwc2_driver_remove, + .suspend = dwc2_suspend, + .resume = dwc2_resume, }; module_platform_driver(dwc2_platform_driver); -- 1.7.9.5 -- 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 01/13] usb: dwc2: Update Kconfig to support dual-role
From: Dinh Nguyen dingu...@altera.com Update DWC2 kconfig and makefile to support dual-role mode. The platform file will always get compiled for the case where the controller is directly connected to the CPU. So for loadable modules, only dwc2.ko is needed. Signed-off-by: Dinh Nguyen dingu...@altera.com --- v2: Remove reference to dwc2_gadget --- drivers/usb/dwc2/Kconfig | 59 + drivers/usb/dwc2/Makefile | 21 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index f93807b..3d69928 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,40 +1,29 @@ config USB_DWC2 - bool DesignWare USB2 DRD Core Support + tristate DesignWare USB2 DRD Core Support depends on USB help Say Y here if your system has a Dual Role Hi-Speed USB controller based on the DesignWare HSOTG IP Core. - For host mode, if you choose to build the driver as dynamically - linked modules, the core module will be called dwc2.ko, the PCI - bus interface module (if you have a PCI bus system) will be - called dwc2_pci.ko, and the platform interface module (for - controllers directly connected to the CPU) will be called - dwc2_platform.ko. For gadget mode, there will be a single - module called dwc2_gadget.ko. - - NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. The - host and gadget drivers are still currently separate drivers. - There are plans to merge the dwc2_gadget driver with the dwc2 - host driver in the near future to create a dual-role driver. + If you choose to build the driver as dynamically + linked modules, a single dwc2.ko(regardless of mode of operation) + will get built for both platform IPs and PCI. if USB_DWC2 +choice + bool DWC2 Mode Selection + default USB_DWC2_DUAL_ROLE if (USB USB_GADGET) + default USB_DWC2_HOST if (USB !USB_GADGET) + default USB_DWC2_PERIPHERAL if (!USB USB_GADGET) + config USB_DWC2_HOST - tristate Host only mode + bool Host only mode depends on USB help The Designware USB2.0 high-speed host controller - integrated into many SoCs. - -config USB_DWC2_PLATFORM - bool DWC2 Platform - depends on USB_DWC2_HOST - default USB_DWC2_HOST - help - The Designware USB2.0 platform interface module for - controllers directly connected to the CPU. This is only - used for host mode. + integrated into many SoCs. Select this option if you want the + driver to operate in Host-only mode. config USB_DWC2_PCI bool DWC2 PCI @@ -47,11 +36,29 @@ config USB_DWC2_PCI comment Gadget mode requires USB Gadget support to be enabled config USB_DWC2_PERIPHERAL - tristate Gadget only mode + bool Gadget only mode depends on USB_GADGET help The Designware USB2.0 high-speed gadget controller - integrated into many SoCs. + integrated into many SoCs. Select this option if you want the + driver to operate in Peripheral-only mode. + +config USB_DWC2_DUAL_ROLE + bool Dual Role mode + depends on ((USB=y || USB=USB_DWC2) (USB_GADGET=y)) + help + Select this option if you want the driver to work in a dual-role + mode. In this mode both host and gadget features are enabled, and + the role will be determined by the cable that gets plugged-in. +endchoice + +config USB_DWC2_PLATFORM + bool +depends on !PCI +default y +help + The Designware USB2.0 platform interface module for + controllers directly connected to the CPU. config USB_DWC2_DEBUG bool Enable Debugging Messages diff --git a/drivers/usb/dwc2/Makefile b/drivers/usb/dwc2/Makefile index b73d2a5..3026135 100644 --- a/drivers/usb/dwc2/Makefile +++ b/drivers/usb/dwc2/Makefile @@ -1,10 +1,17 @@ ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG -obj-$(CONFIG_USB_DWC2_HOST)+= dwc2.o +obj-$(CONFIG_USB_DWC2) += dwc2.o dwc2-y := core.o core_intr.o -dwc2-y += hcd.o hcd_intr.o -dwc2-y += hcd_queue.o hcd_ddma.o + +ifneq ($(filter y,$(CONFIG_USB_DWC2_HOST) $(CONFIG_USB_DWC2_DUAL_ROLE)),) + dwc2-y += hcd.o hcd_intr.o + dwc2-y += hcd_queue.o hcd_ddma.o +endif + +ifneq ($(filter y,$(CONFIG_USB_DWC2_PERIPHERAL) $(CONFIG_USB_DWC2_DUAL_ROLE)),) + dwc2-y += gadget.o +endif # NOTE: The previous s3c-hsotg peripheral mode only driver has been moved to # this location and renamed gadget.c. When building for
[PATCHv2 05/13] usb: dwc2: Add the appropriate init calls in platform code
From: Dinh Nguyen dingu...@altera.com Add the proper init calls for either host, gadget or both in platform.c Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core.h | 13 + drivers/usb/dwc2/gadget.c |2 +- drivers/usb/dwc2/platform.c | 28 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 8d901b3..28541a8 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -956,6 +956,19 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); */ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); +/* Gadget defines */ +#if defined(CONFIG_USB_DWC2_PERIPHERAL) || defined(CONFIG_USB_DWC2_DUAL_ROLE) +extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); +extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); +extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +#else +static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} +static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) +{ return 0; } +#endif + #if defined(CONFIG_USB_DWC2_HOST) || defined(CONFIG_USB_DWC2_DUAL_ROLE) /** * dwc2_hcd_get_frame_number() - Returns current frame number diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index c9c0d51..e8abbe8 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3581,7 +3581,7 @@ err_clk: * s3c_hsotg_remove - remove function for hsotg driver * @pdev: The platform information for the driver */ -static int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) +int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) { usb_del_gadget_udc(hsotg-gadget); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index b531632..eb2a131 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -90,7 +90,14 @@ static int dwc2_driver_remove(struct platform_device *dev) { struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); - dwc2_hcd_remove(hsotg); + if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) + s3c_hsotg_remove(hsotg); + else if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) + dwc2_hcd_remove(hsotg); + else { /* dual role */ + dwc2_hcd_remove(hsotg); + s3c_hsotg_remove(hsotg); + } return 0; } @@ -172,9 +179,22 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(dev-dev, mapped PA %08lx to VA %p\n, (unsigned long)res-start, hsotg-regs); - retval = dwc2_hcd_init(hsotg, irq, params); - if (retval) - return retval; + if (IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)) { + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + return retval; + retval = dwc2_hcd_init(hsotg, irq, params); + if (retval) + return retval; + } else if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) { + retval = dwc2_hcd_init(hsotg, irq, params); + if (retval) + return retval; + } else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) { + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + return retval; + } platform_set_drvdata(dev, hsotg); -- 1.7.9.5 -- 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 02/13] usb: dwc2: Moves s3c_hsotg gadget data structure into dwc2_hsotg
From: Dinh Nguyen dingu...@altera.com Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core.h |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 3b4bd4c..ee34ee1 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -604,6 +604,12 @@ struct dwc2_hsotg { struct timer_list wkp_timer; enum dwc2_lx_state lx_state; + /* Gadget structures */ + struct s3c_hsotg *s3c_hsotg; + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + struct s3c_hsotg_ep *eps; + union dwc2_hcd_internal_flags { u32 d32; struct { -- 1.7.9.5 -- 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 07/13] usb: dwc2: Update common interrupt handler to call gadget interrupt handler
From: Dinh Nguyen dingu...@altera.com Make dwc2_handle_common_intr call the gadget interrupt function when operating in peripheral mode. Remove the spinlock functions in s3c_hsotg_irq as dwc2_handle_common_intr() already has the spinlocks. Remove duplicate interrupt conditions that was in gadget, as those are handled by dwc2 common interrupt handler. Signed-off-by: Dinh Nguyen dingu...@altera.com --- v2: Keep interrupt handler for host and peripheral modes separate --- drivers/usb/dwc2/core.h |3 +++ drivers/usb/dwc2/core_intr.c |3 +++ drivers/usb/dwc2/gadget.c| 50 -- 3 files changed, 10 insertions(+), 46 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 28541a8..b86673c 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -961,12 +961,15 @@ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +irqreturn_t s3c_hsotg_irq(int irq, void *pw); #else static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } +static inline irqreturn_t s3c_hsotg_irq(int irq, void *pw) +{ return IRQ_HANDLED; } #endif #if defined(CONFIG_USB_DWC2_HOST) || defined(CONFIG_USB_DWC2_DUAL_ROLE) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index c93918b..24d4c0d 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -472,6 +472,9 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) spin_lock(hsotg-lock); + if (dwc2_is_device_mode(hsotg)) + retval = s3c_hsotg_irq(irq, dev); + gintsts = dwc2_read_common_intr(hsotg); if (gintsts ~GINTSTS_PRTINT) retval = IRQ_HANDLED; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index e8abbe8..737e979 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2259,14 +2259,13 @@ void s3c_hsotg_core_init(struct dwc2_hsotg *hsotg) * @irq: The IRQ number triggered * @pw: The pw value when registered the handler. */ -static irqreturn_t s3c_hsotg_irq(int irq, void *pw) +irqreturn_t s3c_hsotg_irq(int irq, void *pw) { struct dwc2_hsotg *hsotg = pw; int retry_count = 8; u32 gintsts; u32 gintmsk; - spin_lock(hsotg-lock); irq_retry: gintsts = readl(hsotg-regs + GINTSTS); gintmsk = readl(hsotg-regs + GINTMSK); @@ -2276,33 +2275,12 @@ irq_retry: gintsts = gintmsk; - if (gintsts GINTSTS_OTGINT) { - u32 otgint = readl(hsotg-regs + GOTGINT); - - dev_info(hsotg-dev, OTGInt: %08x\n, otgint); - - writel(otgint, hsotg-regs + GOTGINT); - } - - if (gintsts GINTSTS_SESSREQINT) { - dev_dbg(hsotg-dev, %s: SessReqInt\n, __func__); - writel(GINTSTS_SESSREQINT, hsotg-regs + GINTSTS); - } - if (gintsts GINTSTS_ENUMDONE) { writel(GINTSTS_ENUMDONE, hsotg-regs + GINTSTS); s3c_hsotg_irq_enumdone(hsotg); } - if (gintsts GINTSTS_CONIDSTSCHNG) { - dev_dbg(hsotg-dev, ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n, - readl(hsotg-regs + DSTS), - readl(hsotg-regs + GOTGCTL)); - - writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); - } - if (gintsts (GINTSTS_OEPINT | GINTSTS_IEPINT)) { u32 daint = readl(hsotg-regs + DAINT); u32 daintmsk = readl(hsotg-regs + DAINTMSK); @@ -2383,25 +2361,6 @@ irq_retry: s3c_hsotg_handle_rx(hsotg); } - if (gintsts GINTSTS_MODEMIS) { - dev_warn(hsotg-dev, warning, mode mismatch triggered\n); - writel(GINTSTS_MODEMIS, hsotg-regs + GINTSTS); - } - - if (gintsts GINTSTS_USBSUSP) { - dev_info(hsotg-dev, GINTSTS_USBSusp\n); - writel(GINTSTS_USBSUSP, hsotg-regs + GINTSTS); - - call_gadget(hsotg, suspend); - } - - if (gintsts GINTSTS_WKUPINT) { - dev_info(hsotg-dev, GINTSTS_WkUpIn\n); - writel(GINTSTS_WKUPINT, hsotg-regs + GINTSTS); - - call_gadget(hsotg, resume); - } - if (gintsts GINTSTS_ERLYSUSP) { dev_dbg(hsotg-dev, GINTSTS_ErlySusp\n); writel(GINTSTS_ERLYSUSP, hsotg-regs + GINTSTS); @@ -2437,10 +2396,9 @@ irq_retry: if (gintsts IRQ_RETRY_MASK --retry_count 0) goto irq_retry; - spin_unlock(hsotg-lock); - return IRQ_HANDLED; } +EXPORT_SYMBOL(s3c_hsotg_irq); /** * s3c_hsotg_ep_enable -
[PATCHv2 03/13] usb: dwc2: move samsung,s3c6400-hsotg into common platform
From: Dinh Nguyen dingu...@altera.com Move the samsung,s3c6400-hsotg binding as the probe function in the gadget driver will get removed when the dual-role driver is implemented. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/gadget.c |1 - drivers/usb/dwc2/platform.c |1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index cc31088..c62f6c2 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3678,7 +3678,6 @@ static int s3c_hsotg_resume(struct platform_device *pdev) #ifdef CONFIG_OF static const struct of_device_id s3c_hsotg_of_ids[] = { - { .compatible = samsung,s3c6400-hsotg, }, { .compatible = snps,dwc2, }, { /* sentinel */ } }; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..b531632 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -98,6 +98,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = brcm,bcm2835-usb, .data = params_bcm2835 }, { .compatible = snps,dwc2, .data = NULL }, + { .compatible = samsung,s3c6400-hsotg, .data = NULL}, {}, }; MODULE_DEVICE_TABLE(of, dwc2_of_match_table); -- 1.7.9.5 -- 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 09/13] usb: dwc2: gadget: Do not fail probe if there isn't a clock node
From: Dinh Nguyen dingu...@altera.com Since the dwc2 hcd driver is currently not looking for a clock node during init, we should not completely fail if there isn't a clock provided. Add a check for a valid clock before calling clock functions. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/gadget.c | 37 +++-- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 737e979..dbcdee0 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2854,7 +2854,8 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, hsotg-gadget.dev.of_node = hsotg-dev-of_node; hsotg-gadget.speed = USB_SPEED_UNKNOWN; - clk_enable(hsotg-s3c_hsotg-clk); + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_enable(hsotg-s3c_hsotg-clk); ret = regulator_bulk_enable(ARRAY_SIZE(hsotg-s3c_hsotg-supplies), hsotg-s3c_hsotg-supplies); @@ -2905,7 +2906,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, regulator_bulk_disable(ARRAY_SIZE(hsotg-s3c_hsotg-supplies), hsotg-s3c_hsotg-supplies); - clk_disable(hsotg-s3c_hsotg-clk); + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_disable(hsotg-s3c_hsotg-clk); return 0; } @@ -2938,10 +2940,12 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) spin_lock_irqsave(hsotg-lock, flags); if (is_on) { s3c_hsotg_phy_enable(hsotg); - clk_enable(hsotg-s3c_hsotg-clk); + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_enable(hsotg-s3c_hsotg-clk); s3c_hsotg_core_init(hsotg); } else { - clk_disable(hsotg-s3c_hsotg-clk); + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_disable(hsotg-s3c_hsotg-clk); s3c_hsotg_phy_disable(hsotg); } @@ -3418,16 +3422,15 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) } hsotg-s3c_hsotg-clk = devm_clk_get(dev, otg); - if (IS_ERR(hsotg-s3c_hsotg-clk)) { - dev_err(dev, cannot get otg clock\n); - return PTR_ERR(hsotg-s3c_hsotg-clk); - } + if (IS_ERR(hsotg-s3c_hsotg-clk)) + dev_warn(dev, cannot get otg clock\n); hsotg-gadget.max_speed = USB_SPEED_HIGH; hsotg-gadget.ops = s3c_hsotg_gadget_ops; hsotg-gadget.name = dev_name(dev); - clk_prepare_enable(hsotg-s3c_hsotg-clk); + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_prepare_enable(hsotg-s3c_hsotg-clk); /* regulators */ @@ -3460,7 +3463,8 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) dev_name(dev), hsotg); if (ret 0) { s3c_hsotg_phy_disable(hsotg); - clk_disable_unprepare(hsotg-s3c_hsotg-clk); + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_disable_unprepare(hsotg-s3c_hsotg-clk); regulator_bulk_disable(ARRAY_SIZE(hsotg-s3c_hsotg-supplies), hsotg-s3c_hsotg-supplies); dev_err(dev, cannot claim IRQ\n); @@ -3530,7 +3534,8 @@ err_ep_mem: err_supplies: s3c_hsotg_phy_disable(hsotg); err_clk: - clk_disable_unprepare(hsotg-s3c_hsotg-clk); + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_disable_unprepare(hsotg-s3c_hsotg-clk); return ret; } @@ -3550,7 +3555,8 @@ int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) usb_gadget_unregister_driver(hsotg-driver); } - clk_disable_unprepare(hsotg-s3c_hsotg-clk); + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_disable_unprepare(hsotg-s3c_hsotg-clk); return 0; } @@ -3577,7 +3583,9 @@ static int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) ret = regulator_bulk_disable(ARRAY_SIZE(hsotg-s3c_hsotg-supplies), hsotg-s3c_hsotg-supplies); - clk_disable(hsotg-s3c_hsotg-clk); + + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_disable(hsotg-s3c_hsotg-clk); } return ret; @@ -3592,7 +3600,8 @@ static int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) dev_info(hsotg-dev, resuming usb gadget %s\n, hsotg-driver-driver.name); - clk_enable(hsotg-s3c_hsotg-clk); + if (!IS_ERR(hsotg-s3c_hsotg-clk)) + clk_enable(hsotg-s3c_hsotg-clk); ret = regulator_bulk_enable(ARRAY_SIZE(hsotg-s3c_hsotg-supplies), hsotg-s3c_hsotg-supplies); } -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More
[PATCHv2 10/13] usb: dwc2: initialize the spin_lock for both host and gadget
From: Dinh Nguyen dingu...@altera.com Move spin_lock_init to common location for both host and gadget. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/hcd.c |1 - drivers/usb/dwc2/platform.c |1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 07a7bcd..c6778d9 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2824,7 +2824,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, hcd-has_tt = 1; - spin_lock_init(hsotg-lock); ((struct wrapper_priv_data *) hcd-hcd_priv)-hsotg = hsotg; hsotg-priv = hcd; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index eb2a131..4898268 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -197,6 +197,7 @@ static int dwc2_driver_probe(struct platform_device *dev) } platform_set_drvdata(dev, hsotg); + spin_lock_init(hsotg-lock); return retval; } -- 1.7.9.5 -- 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 12/13] usb: dwc2: check that the host work queue is valid
From: Dinh Nguyen dingu...@altera.com The Host workqueue will not get initialized if the driver is configured for peripheral mode only. Thus we need to check for wq_otg before calling queue_work(). Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core_intr.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 651785d..1240875 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -287,9 +287,11 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) * Release lock before scheduling workq as it holds spinlock during * scheduling. */ - spin_unlock(hsotg-lock); - queue_work(hsotg-wq_otg, hsotg-wf_otg); - spin_lock(hsotg-lock); + if (hsotg-wq_otg) { + spin_unlock(hsotg-lock); + queue_work(hsotg-wq_otg, hsotg-wf_otg); + spin_lock(hsotg-lock); + } /* Clear interrupt */ writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); -- 1.7.9.5 -- 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 08/12] usb: dwc2: gadget: Do not fail probe if there isn't a clock node
From: Dinh Nguyen dingu...@altera.com Since the dwc2 hcd driver is currently not looking for a clock node during init, we should not completely fail if there isn't a clock provided. Add a check for a valid clock before calling clock functions. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/gadget.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index aa57d3e..9989c36 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3228,16 +3228,15 @@ int dwc2_gadget_init(struct dwc2_hsotg *dwc2, int irq) dwc2-s3c_hsotg-phy = phy; dwc2-s3c_hsotg-clk = devm_clk_get(dev, otg); - if (IS_ERR(dwc2-s3c_hsotg-clk)) { - dev_err(dev, cannot get otg clock\n); - return PTR_ERR(dwc2-s3c_hsotg-clk); - } + if (IS_ERR(dwc2-s3c_hsotg-clk)) + dev_warn(dev, cannot get otg clock\n); dwc2-gadget.max_speed = USB_SPEED_HIGH; dwc2-gadget.ops = s3c_hsotg_gadget_ops; dwc2-gadget.name = dev_name(dev); - clk_prepare_enable(dwc2-s3c_hsotg-clk); + if (!IS_ERR(dwc2-s3c_hsotg-clk)) + clk_prepare_enable(dwc2-s3c_hsotg-clk); /* regulators */ @@ -3342,7 +3341,8 @@ err_ep_mem: err_supplies: s3c_hsotg_phy_disable(dwc2); err_clk: - clk_disable_unprepare(dwc2-s3c_hsotg-clk); + if (!IS_ERR(dwc2-s3c_hsotg-clk)) + clk_disable_unprepare(dwc2-s3c_hsotg-clk); return ret; } @@ -3365,7 +3365,8 @@ int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) s3c_hsotg_phy_disable(dwc2); if (dwc2-s3c_hsotg-phy) phy_exit(dwc2-s3c_hsotg-phy); - clk_disable_unprepare(dwc2-s3c_hsotg-clk); + if (!IS_ERR(dwc2-s3c_hsotg-clk)) + clk_disable_unprepare(dwc2-s3c_hsotg-clk); return 0; } -- 1.7.9.5 -- 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 05/12] usb: dwc2: Add the appropriate init calls in platform code
From: Dinh Nguyen dingu...@altera.com Add the proper init calls for either host, gadget or both in platform.c Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core.h |3 +++ drivers/usb/dwc2/gadget.c |2 +- drivers/usb/dwc2/platform.c | 29 + 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 0fc4e41..7fbf7f0 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -964,6 +964,7 @@ extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); extern void s3c_hsotg_disable_gsint(struct dwc2_hsotg *dwc2, u32 ints); extern void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *dwc2, bool periodic); extern void s3c_hsotg_handle_rx(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_remove(struct dwc2_hsotg *dwc2); extern void s3c_hsotg_dump(struct dwc2_hsotg *dwc2); extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); @@ -980,6 +981,8 @@ static inline void s3c_hsotg_disable_gsint(struct dwc2_hsotg *dwc2, u32 ints) static inline void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *dwc2, bool periodic) {} static inline void s3c_hsotg_handle_rx(struct dwc2_hsotg *dwc2) {} +static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +{ return 0; } static inline void s3c_hsotg_dump(struct dwc2_hsotg *dwc2) {} static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) { return 0; } diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 42d1d60..b8c466f 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3539,7 +3539,7 @@ err_clk: * s3c_hsotg_remove - remove function for hsotg driver * @pdev: The platform information for the driver */ -static int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { usb_del_gadget_udc(dwc2-gadget); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 53e6c90..714e128 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -41,6 +41,7 @@ #include linux/dma-mapping.h #include linux/of_device.h #include linux/platform_device.h +#include linux/usb/otg.h #include core.h #include hcd.h @@ -90,7 +91,14 @@ static int dwc2_driver_remove(struct platform_device *dev) { struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); - dwc2_hcd_remove(hsotg); + if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) + s3c_hsotg_remove(hsotg); + else if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) + dwc2_hcd_remove(hsotg); + else { /* dual role */ + dwc2_hcd_remove(hsotg); + s3c_hsotg_remove(hsotg); + } return 0; } @@ -176,9 +184,22 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(dev-dev, mapped PA %08lx to VA %p\n, (unsigned long)res-start, hsotg-regs); - retval = dwc2_hcd_init(hsotg, irq, params); - if (retval) - return retval; + if (IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)) { + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + return retval; + retval = dwc2_hcd_init(hsotg, irq, params); + if (retval) + return retval; + } else if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) { + retval = dwc2_hcd_init(hsotg, irq, params); + if (retval) + return retval; + } else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) { + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + return retval; + } platform_set_drvdata(dev, hsotg); -- 1.7.9.5 -- 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 12/12] usb: dwc2: pci: Update pci portion of the dwc2 driver
From: Dinh Nguyen dingu...@altera.com Initialize the spinlock here as the original spinlock in the host driver has been removed. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/pci.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index c291fca..faacac9 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c @@ -148,6 +148,7 @@ static int dwc2_driver_probe(struct pci_dev *dev, } pci_set_drvdata(dev, hsotg); + spin_lock_init(hsotg-lock); return retval; } -- 1.7.9.5 -- 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 02/12] usb: dwc2: Moves s3c_hsotg gadget data structure into dwc2_hsotg
From: Dinh Nguyen dingu...@altera.com Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core.h |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1efd10c..0c6efbf 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -601,6 +601,12 @@ struct dwc2_hsotg { struct timer_list wkp_timer; enum dwc2_lx_state lx_state; + /* Gadget structures */ + struct s3c_hsotg *s3c_hsotg; + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + struct s3c_hsotg_ep *eps; + union dwc2_hcd_internal_flags { u32 d32; struct { -- 1.7.9.5 -- 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 07/12] usb: dwc2: Move gadget interrupts to common interrupt handler
From: Dinh Nguyen dingu...@altera.com Update dwc2_handle_common_intr() to handle both hcd and gadget interrupts. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core_intr.c | 116 +- drivers/usb/dwc2/gadget.c| 188 -- 2 files changed, 114 insertions(+), 190 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index c93918b..7500621 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -337,6 +337,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Change to L0 state */ hsotg-lx_state = DWC2_L0; + call_gadget(hsotg, resume); } else { if (hsotg-lx_state != DWC2_L1) { u32 pcgcctl = readl(hsotg-regs + PCGCTL); @@ -397,6 +398,8 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n, !!(dsts DSTS_SUSPSTS), hsotg-hw_params.power_optimized); + + call_gadget(hsotg, suspend); } else { if (hsotg-op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg-dev, a_peripheral-a_host\n); @@ -421,6 +424,11 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) GINTSTS_MODEMIS | GINTSTS_DISCONNINT | \ GINTSTS_USBSUSP | GINTSTS_PRTINT) +/* IRQ flags which will trigger a retry around the IRQ loop */ +#define IRQ_RETRY_MASK (GINTSTS_NPTXFEMP | \ + GINTSTS_PTXFEMP | \ + GINTSTS_RXFLVL) + /* * This function returns the Core Interrupt register */ @@ -441,7 +449,7 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg) gintsts, gintmsk); if (gahbcfg GAHBCFG_GLBL_INTR_EN) - return gintsts gintmsk gintmsk_common; + return gintsts gintmsk; else return 0; } @@ -463,7 +471,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) { struct dwc2_hsotg *hsotg = dev; u32 gintsts; - irqreturn_t retval = IRQ_NONE; + int retry_count = 8; + irqreturn_t retval = IRQ_HANDLED; if (!dwc2_is_controller_alive(hsotg)) { dev_warn(hsotg-dev, Controller is dead\n); @@ -472,16 +481,90 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) spin_lock(hsotg-lock); +irq_retry: gintsts = dwc2_read_common_intr(hsotg); if (gintsts ~GINTSTS_PRTINT) retval = IRQ_HANDLED; + if (gintsts GINTSTS_ENUMDONE) { + writel(GINTSTS_ENUMDONE, hsotg-regs + GINTSTS); + s3c_hsotg_irq_enumdone(hsotg); + } + if (gintsts GINTSTS_MODEMIS) dwc2_handle_mode_mismatch_intr(hsotg); if (gintsts GINTSTS_OTGINT) dwc2_handle_otg_intr(hsotg); if (gintsts GINTSTS_CONIDSTSCHNG) dwc2_handle_conn_id_status_change_intr(hsotg); + + if (gintsts (GINTSTS_OEPINT | GINTSTS_IEPINT)) { + u32 daint = readl(hsotg-regs + DAINT); + u32 daint_out = daint DAINT_OUTEP_SHIFT; + u32 daint_in = daint ~(daint_out DAINT_OUTEP_SHIFT); + int ep; + + dev_dbg(hsotg-dev, %s: daint=%08x\n, __func__, daint); + for (ep = 0; ep 15 daint_out; ep++, daint_out = 1) { + if (daint_out 1) + s3c_hsotg_epint(hsotg, ep, 0); + } + + for (ep = 0; ep 15 daint_in; ep++, daint_in = 1) { + if (daint_in 1) + s3c_hsotg_epint(hsotg, ep, 1); + } + } + + if (gintsts GINTSTS_USBRST) { + u32 usb_status = readl(hsotg-regs + GOTGCTL); + + dev_dbg(hsotg-dev, %s: USBRST\n, __func__); + dev_dbg(hsotg-dev, GNPTXSTS=%08x\n, + readl(hsotg-regs + GNPTXSTS)); + + writel(GINTSTS_USBRST, hsotg-regs + GINTSTS); + + if (usb_status GOTGCTL_BSESVLD) { + if (time_after(jiffies, hsotg-s3c_hsotg-last_rst + + msecs_to_jiffies(200))) { + kill_all_requests(hsotg, hsotg-eps[0], + -ECONNRESET, true); + s3c_hsotg_core_init(hsotg); + hsotg-s3c_hsotg-last_rst = jiffies; + } + } + } + + if (gintsts GINTSTS_NPTXFEMP) { + dev_dbg(hsotg-dev, NPTXFEMP\n); + + /* +* Disable the interrupt to stop it happening again +* unless
[PATCH 01/12] usb: dwc2: Update Kconfig to support dual-role
From: Dinh Nguyen dingu...@altera.com Update DWC2 kconfig and makefile to support dual-role mode. The platform file will always get compiled for the case where the controller is directly connected to the CPU. So for loadable modules, only dwc2.ko is needed. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/Kconfig | 59 ++--- drivers/usb/dwc2/Makefile | 21 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index f93807b..5f32e62 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,40 +1,31 @@ config USB_DWC2 - bool DesignWare USB2 DRD Core Support + tristate DesignWare USB2 DRD Core Support depends on USB help Say Y here if your system has a Dual Role Hi-Speed USB controller based on the DesignWare HSOTG IP Core. - For host mode, if you choose to build the driver as dynamically - linked modules, the core module will be called dwc2.ko, the PCI - bus interface module (if you have a PCI bus system) will be - called dwc2_pci.ko, and the platform interface module (for - controllers directly connected to the CPU) will be called - dwc2_platform.ko. For gadget mode, there will be a single - module called dwc2_gadget.ko. + If you choose to build the driver as dynamically + linked modules, a single dwc2.ko(regardless of mode of operation) + will get built for both platform IPs and PCI. - NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. The - host and gadget drivers are still currently separate drivers. - There are plans to merge the dwc2_gadget driver with the dwc2 - host driver in the near future to create a dual-role driver. + NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. if USB_DWC2 +choice + bool DWC2 Mode Selection + default USB_DWC2_DUAL_ROLE if (USB USB_GADGET) + default USB_DWC2_HOST if (USB !USB_GADGET) + default USB_DWC2_PERIPHERAL if (!USB USB_GADGET) + config USB_DWC2_HOST - tristate Host only mode + bool Host only mode depends on USB help The Designware USB2.0 high-speed host controller - integrated into many SoCs. - -config USB_DWC2_PLATFORM - bool DWC2 Platform - depends on USB_DWC2_HOST - default USB_DWC2_HOST - help - The Designware USB2.0 platform interface module for - controllers directly connected to the CPU. This is only - used for host mode. + integrated into many SoCs. Select this option if you want the + driver to operate in Host-only mode. config USB_DWC2_PCI bool DWC2 PCI @@ -47,11 +38,29 @@ config USB_DWC2_PCI comment Gadget mode requires USB Gadget support to be enabled config USB_DWC2_PERIPHERAL - tristate Gadget only mode + bool Gadget only mode depends on USB_GADGET help The Designware USB2.0 high-speed gadget controller - integrated into many SoCs. + integrated into many SoCs. Select this option if you want the + driver to operate in Peripheral-only mode. + +config USB_DWC2_DUAL_ROLE + bool Dual Role mode + depends on ((USB=y || USB=USB_DWC2) (USB_GADGET=y)) + help + Select this option if you want the driver to work in a dual-role + mode. In this mode both host and gadget features are enabled, and + the role will be determined by the cable that gets plugged-in. +endchoice + +config USB_DWC2_PLATFORM + bool +depends on !PCI +default y +help + The Designware USB2.0 platform interface module for + controllers directly connected to the CPU. config USB_DWC2_DEBUG bool Enable Debugging Messages diff --git a/drivers/usb/dwc2/Makefile b/drivers/usb/dwc2/Makefile index b73d2a5..3026135 100644 --- a/drivers/usb/dwc2/Makefile +++ b/drivers/usb/dwc2/Makefile @@ -1,10 +1,17 @@ ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG -obj-$(CONFIG_USB_DWC2_HOST)+= dwc2.o +obj-$(CONFIG_USB_DWC2) += dwc2.o dwc2-y := core.o core_intr.o -dwc2-y += hcd.o hcd_intr.o -dwc2-y += hcd_queue.o hcd_ddma.o + +ifneq ($(filter y,$(CONFIG_USB_DWC2_HOST) $(CONFIG_USB_DWC2_DUAL_ROLE)),) + dwc2-y += hcd.o hcd_intr.o + dwc2-y += hcd_queue.o hcd_ddma.o +endif + +ifneq ($(filter y,$(CONFIG_USB_DWC2_PERIPHERAL) $(CONFIG_USB_DWC2_DUAL_ROLE)),) + dwc2-y += gadget.o +endif # NOTE: The previous s3c-hsotg peripheral mode only driver has been moved to # this location and renamed
[PATCH 04/12] usb: dwc2: Add DTS compatible string to dwc2_of_match_table
From: Dinh Nguyen dingu...@altera.com Puts back samsung,s3c6400-hsotg into the dwc2_of_match_table[]. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/platform.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 5785fd6..53e6c90 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -98,6 +98,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = brcm,bcm2835-usb, .data = params_bcm2835 }, { .compatible = snps,dwc2, .data = NULL }, + { .compatible = samsung,s3c6400-hsotg, }, {}, }; MODULE_DEVICE_TABLE(of, dwc2_of_match_table); -- 1.7.9.5 -- 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 09/12] usb: dwc2: initialize the spin_lock for both host and gadget
From: Dinh Nguyen dingu...@altera.com Move spin_lock_init to common location for both host and gadget. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/hcd.c |1 - drivers/usb/dwc2/platform.c |1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 1936544..a9b35f5 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2819,7 +2819,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, hcd-has_tt = 1; - spin_lock_init(hsotg-lock); ((struct wrapper_priv_data *) hcd-hcd_priv)-hsotg = hsotg; hsotg-priv = hcd; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 714e128..dfadf5a 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -202,6 +202,7 @@ static int dwc2_driver_probe(struct platform_device *dev) } platform_set_drvdata(dev, hsotg); + spin_lock_init(hsotg-lock); return retval; } -- 1.7.9.5 -- 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 06/12] usb: dwc2: Initialize the USB core for peripheral mode
From: Dinh Nguyen dingu...@altera.com Initialize the USB driver to peripheral mode when a B-Device connector is attached. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/hcd.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index e6acb17..1936544 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1355,6 +1355,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg-op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); + s3c_hsotg_core_init(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg-dev, connId A\n); -- 1.7.9.5 -- 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 10/12] usb: dwc2: Add suspend/resume for gadget
From: Dinh Nguyen dingu...@altera.com Move suspend/resume code to common platform code. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/platform.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index dfadf5a..69136cc 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -207,6 +207,27 @@ static int dwc2_driver_probe(struct platform_device *dev) return retval; } +static int dwc2_suspend(struct platform_device *dev, pm_message_t state) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_suspend(dwc2); + return ret; +} + +static int dwc2_resume(struct platform_device *dev) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_resume(dwc2); + + return ret; +} + static struct platform_driver dwc2_platform_driver = { .driver = { .name = dwc2_driver_name, @@ -214,6 +235,8 @@ static struct platform_driver dwc2_platform_driver = { }, .probe = dwc2_driver_probe, .remove = dwc2_driver_remove, + .suspend = dwc2_suspend, + .resume = dwc2_resume, }; module_platform_driver(dwc2_platform_driver); -- 1.7.9.5 -- 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 00/12] usb: dwc2: Add support for dual role
From: Dinh Nguyen dingu...@altera.com Hello, This patch series combines the dwc2 gadget and host driver into a single dual role driver. Here is a breakdown of what each patch does: 1/2 : usb: dwc2: Update Kconfig to support dual-role - Changes the Kconfig and Makefile to build a single dwc2.ko for all modes of operation(peripheral, host and dual-role), and only dwc2.ko is the output for both platforms that have the IP directly connected and PCI platforms. 2/12 : usb: dwc2: Moves s3c_hsotg gadget data structure into dwc2_hsotg - Adds the gadget data structure to dwc2_hsotg. Adds pointers to the dwc2 gadget structure. 3/12 : usb: dwc2: update gadget portion to use common dwc2_hsotg structure - This patch contains the bulk of the changes in this series. This patch edits the dwc2 gadget driver to use the update data pointers in the common dwc2_hsotg structure. The other changes in this patch is to provide the proper function declarations for building the driver with the 3 different modes. The last bit of change is removing the dwc2 probe function from the gadget driver, as there will be a single probe function that will be in platform.c or pci.c. 4/12 : usb: dwc2: Add DTS compatible string to dwc2_of_match_table 5/12 : usb: dwc2: Add the appropriate init calls in platform code - This patch add the appropriate init/remove function calls for the 3 different modes that the driver can operate in. 6/12 : usb: dwc2: Initialize the USB core for peripheral mode - This patch add the gadget init call when a B-Device connector cable is detected. 7/12 : usb: dwc2: Move gadget interrupts to common interrupt handler - This patch moves the dwc2 gadget interrupt handlder into the common dwc2 interrupt handler. 8/12 : usb: dwc2: gadget: Do not fail probe if there isn't a clock node - Since the dwc2 host driver is not dependent on a clock node, and the gadget driver is looking for a clock node, add a check for the clock node in the gadget driver and do not fail even if a clock node is not provided. This enables platforms(i.e.RPi) that weren't providing a clock node to still use the driver in dual-role mode. 9/12 : usb: dwc2: initialize the spin_lock for both host and gadget - Moves the spinlock init call to a common location. 10/12 : usb: dwc2: Add suspend/resume for gadget 11/12 : usb: dwc2: check that the host work queue is valid - Because the workqueue_struct was a host only feature, we should check the struct was initialized, which in peripheral it would not be. 12/12 : usb: dwc2: pci: Update pci portion of the dwc2 driver - Call the spinlock init here as it was removed from the host driver. This patch series has passed the 0-DAY kernel build testing, and every patch has been compiled tested. I tested on 2 platforms, SOCFPGA and Raspberry-Pi B. On the Raspberry-pi, I tested the driver in host and dual-role mode, but since the RPi does not have an OTG connector, only host functionality was tested. This patch series is based on v3.16-rc5. I have pushed this a git repo to make it more convenient for people to test/review. git://git.rocketboards.org/linux-socfpga-next.git dwc2_dual_role_v1 Thanks, Dinh Nguyen (12): usb: dwc2: Update Kconfig to support dual-role usb: dwc2: Moves s3c_hsotg gadget data structure into dwc2_hsotg usb: dwc2: update gadget portion to use common dwc2_hsotg structure usb: dwc2: Add DTS compatible string to dwc2_of_match_table usb: dwc2: Add the appropriate init calls in platform code usb: dwc2: Initialize the USB core for peripheral mode usb: dwc2: Move gadget interrupts to common interrupt handler usb: dwc2: gadget: Do not fail probe if there isn't a clock node usb: dwc2: initialize the spin_lock for both host and gadget usb: dwc2: Add suspend/resume for gadget usb: dwc2: check that the host work queue is valid usb: dwc2: pci: Update pci portion of the dwc2 driver drivers/usb/dwc2/Kconfig | 59 +- drivers/usb/dwc2/Makefile| 21 +- drivers/usb/dwc2/core.h | 70 ++- drivers/usb/dwc2/core_intr.c | 124 +++- drivers/usb/dwc2/gadget.c| 1431 +- drivers/usb/dwc2/hcd.c |7 +- drivers/usb/dwc2/hcd.h | 10 - drivers/usb/dwc2/pci.c |1 + drivers/usb/dwc2/platform.c | 58 +- 9 files changed, 877 insertions(+), 904 deletions(-) -- 1.7.9.5 -- 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 11/12] usb: dwc2: check that the host work queue is valid
From: Dinh Nguyen dingu...@altera.com The Host workqueue will not get initialized if the driver is configured for peripheral mode only. Thus we need to check for wq_otg before calling queue_work(). Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core_intr.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 7500621..d36e64f 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -287,9 +287,11 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) * Release lock before scheduling workq as it holds spinlock during * scheduling. */ - spin_unlock(hsotg-lock); - queue_work(hsotg-wq_otg, hsotg-wf_otg); - spin_lock(hsotg-lock); + if (hsotg-wq_otg) { + spin_unlock(hsotg-lock); + queue_work(hsotg-wq_otg, hsotg-wf_otg); + spin_lock(hsotg-lock); + } /* Clear interrupt */ writel(GINTSTS_CONIDSTSCHNG, hsotg-regs + GINTSTS); -- 1.7.9.5 -- 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] usb: dwc2: fix sparse warning in platform.c
From: Dinh Nguyen dingu...@altera.com This patch fixes this sparse warning: drivers/usb/dwc2/platform.c:168:25: warning: incorrect type in argument 1 (different address spaces) drivers/usb/dwc2/platform.c:168:25:expected void const *ptr drivers/usb/dwc2/platform.c:168:25:got void [noderef] asn:2*regs drivers/usb/dwc2/platform.c:169:37: warning: incorrect type in argument 1 (different address spaces) drivers/usb/dwc2/platform.c:169:37:expected void const *ptr drivers/usb/dwc2/platform.c:169:37:got void [noderef] asn:2*regs Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/platform.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..443c321 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -165,8 +165,8 @@ static int dwc2_driver_probe(struct platform_device *dev) res = platform_get_resource(dev, IORESOURCE_MEM, 0); hsotg-regs = devm_ioremap_resource(dev-dev, res); - if (IS_ERR(hsotg-regs)) - return PTR_ERR(hsotg-regs); + if (!hsotg-regs) + return -ENOMEM; dev_dbg(dev-dev, mapped PA %08lx to VA %p\n, (unsigned long)res-start, hsotg-regs); -- 1.7.9.5 -- 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 02/15] usb: dwc2: add necessary function declares for dual role
From: Dinh Nguyen dingu...@altera.com There are functions in gadget driver that needs to get exported so that the common interrupt handler can call. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core.h | 52 +++ drivers/usb/dwc2/hcd.h | 12 +-- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 95fc6e9..a064d48 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -953,4 +953,56 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); */ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); +/* Gadget defines */ +#if defined(CONFIG_USB_DWC2_PERIPHERAL) || defined(CONFIG_USB_DWC2_DUAL_ROLE) +extern void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *dwc2); +extern void s3c_hsotg_epint(struct dwc2_hsotg *dwc2, unsigned int idx, + int dir_in); +extern void kill_all_requests(struct dwc2_hsotg *dwc2, + struct s3c_hsotg_ep *ep, int result, bool force); +extern void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2); +extern void s3c_hsotg_disable_gsint(struct dwc2_hsotg *dwc2, u32 ints); +extern void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *dwc2, bool periodic); +extern void s3c_hsotg_handle_rx(struct dwc2_hsotg *dwc2); +extern void s3c_hsotg_remove(struct dwc2_hsotg *dwc2); +extern void s3c_hsotg_dump(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); +#else +static inline void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *dwc2) {} +static inline void s3c_hsotg_epint(struct dwc2_hsotg *dwc2, unsigned int idx, + int dir_in) {} +static inline void kill_all_requests(struct dwc2_hsotg *dwc2, + struct s3c_hsotg_ep *ep, int result, bool force) {} +static inline void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2) {} +static inline void s3c_hsotg_disable_gsint(struct dwc2_hsotg *dwc2, u32 ints) +{} +static inline void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *dwc2, + bool periodic) {} +static inline void s3c_hsotg_handle_rx(struct dwc2_hsotg *dwc2) {} +static inline void s3c_hsotg_remove(struct dwc2_hsotg *dwc2) {} +static inline void s3c_hsotg_dump(struct dwc2_hsotg *dwc2) {} +static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) +{ return 0; } +#endif + +extern void dwc2_set_all_params(struct dwc2_core_params *params, int value); +#if defined(CONFIG_USB_DWC2_HOST) || defined(CONFIG_USB_DWC2_DUAL_ROLE) +/** + * dwc2_hcd_get_frame_number() - Returns current frame number + * + * @hsotg: The DWC2 HCD + */ +extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); +#else +static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) +{ return 0; } +static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} +#endif + #endif /* __DWC2_CORE_H__ */ diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index fdc6d48..9705abf 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -449,12 +449,12 @@ static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe) return !dwc2_hcd_is_pipe_in(pipe); } +extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, const struct dwc2_core_params *params); extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg); extern void dwc2_set_parameters(struct dwc2_hsotg *hsotg, const struct dwc2_core_params *params); -extern void dwc2_set_all_params(struct dwc2_core_params *params, int value); extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg); /* Transaction Execution Functions */ @@ -666,9 +666,6 @@ extern irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg); */ extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg); -extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); -extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); - /** * dwc2_hcd_is_b_host() - Returns 1 if core currently is acting as B host, * and 0 otherwise @@ -678,13 +675,6 @@ extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg); /** - * dwc2_hcd_get_frame_number() - Returns current frame number - * - * @hsotg: The DWC2 HCD - */ -extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); - -/** * dwc2_hcd_dump_state() - Dumps hsotg state * * @hsotg: The DWC2 HCD -- 1.7.9.5 -- 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
[PATCH 00/15] usb: dwc2: Add support for dual-role
From: Dinh Nguyen dingu...@altera.com Hi, This patch series combines the dwc2 host and gadget driver into a single dual-role driver. I have tested this on the SOCFPGA platform. I compile tested for bcm2835_defconfig and a PCI platform. I split up the patches to make the review a bit easier, but each individual patch can't really stand on it's own. Any comments/testing is greatly appreciated. I have pushed this to: git://git.rocketboards.org/linux-socfpga-next.git/dwc2_dual_role_v1 Dinh Nguyen (15): usb: dwc2: Moves s3c_hsotg gadget data structure into dwc2_hsotg usb: dwc2: add necessary function declares for dual role usb: dwc2: gadget: convert gadget driver to use common dwc2_hsotg structure usb: dwc2: gadget: Change the gadget probe function into gadget_init usb: dwc2: Move gadget interrupts to common interrupt handler usb: dwc2: gadget: remove gadget module defines usb: dwc2: gadget: Do not fail probe if there isn't a clock node usb: dwc2: Add the appropriate init calls in platform code usb: dwc2: move allocation of core_params usb: dwc2: initialize the spin_lock for both host and gadget usb: dwc2: Add suspend/resume for gadget usb: dwc2: move dwc2_set_all_params to platform code usb: dwc2: check that the host work queue is valid usb: dwc2: pci: Update pci portion of the dwc2 driver usb: dwc2: Update Kconfig to support dual-role drivers/usb/dwc2/Kconfig | 52 +- drivers/usb/dwc2/Makefile| 21 +- drivers/usb/dwc2/core.c | 15 + drivers/usb/dwc2/core.h | 62 +- drivers/usb/dwc2/core_intr.c | 119 +++- drivers/usb/dwc2/gadget.c| 1433 +- drivers/usb/dwc2/hcd.c | 23 +- drivers/usb/dwc2/hcd.h | 12 +- drivers/usb/dwc2/pci.c | 28 +- drivers/usb/dwc2/platform.c | 58 +- 10 files changed, 902 insertions(+), 921 deletions(-) -- 1.7.9.5 -- 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 01/15] usb: dwc2: Moves s3c_hsotg gadget data structure into dwc2_hsotg
From: Dinh Nguyen dingu...@altera.com Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/core.h | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1efd10c..95fc6e9 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -84,7 +84,7 @@ static const char * const s3c_hsotg_supply_names[] = { */ #define EP0_MPS_LIMIT 64 -struct s3c_hsotg; +struct dwc2_hsotg; struct s3c_hsotg_req; /** @@ -130,7 +130,7 @@ struct s3c_hsotg_req; struct s3c_hsotg_ep { struct usb_ep ep; struct list_headqueue; - struct s3c_hsotg*parent; + struct dwc2_hsotg *parent; struct s3c_hsotg_req*req; struct dentry *debugfs; @@ -601,6 +601,12 @@ struct dwc2_hsotg { struct timer_list wkp_timer; enum dwc2_lx_state lx_state; + /* Gadget structures */ + struct s3c_hsotg *s3c_hsotg; + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + struct s3c_hsotg_ep *eps; + union dwc2_hcd_internal_flags { u32 d32; struct { -- 1.7.9.5 -- 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 04/15] usb: dwc2: gadget: Change the gadget probe function into gadget_init
From: Dinh Nguyen dingu...@altera.com gadget_init() will get called from the platform probe function. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/gadget.c | 144 + 1 file changed, 55 insertions(+), 89 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 171ed28..e74656c 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3372,25 +3372,24 @@ static void s3c_hsotg_delete_debug(struct dwc2_hsotg *dwc2) } /** - * s3c_hsotg_probe - probe function for hsotg driver - * @pdev: The platform information for the driver + * dwc2_gadget_init - init function for gadget + * @dwc2: The data structure for the DWC2 driver. + * @irq: The IRQ number for the controller. */ -static int s3c_hsotg_probe(struct platform_device *pdev) +static int dwc2_gadget_init(struct dwc2_hsotg *dwc2, int irq) { - struct s3c_hsotg_plat *plat = dev_get_platdata(pdev-dev); + struct s3c_hsotg_plat *plat = dwc2-dev-platform_data; struct phy *phy; struct usb_phy *uphy; - struct device *dev = pdev-dev; + struct device *dev = dwc2-dev; struct s3c_hsotg_ep *eps; - struct s3c_hsotg *hsotg; - struct resource *res; int epnum; int ret; int i; - hsotg = devm_kzalloc(pdev-dev, sizeof(struct s3c_hsotg), GFP_KERNEL); - if (!hsotg) { + dwc2-s3c_hsotg = devm_kzalloc(dev, sizeof(struct s3c_hsotg), GFP_KERNEL); + if (!dwc2-s3c_hsotg) { dev_err(dev, cannot get memory\n); return -ENOMEM; } @@ -3399,117 +3398,84 @@ static int s3c_hsotg_probe(struct platform_device *pdev) * Attempt to find a generic PHY, then look for an old style * USB PHY, finally fall back to pdata */ - phy = devm_phy_get(pdev-dev, usb2-phy); + phy = devm_phy_get(dev, usb2-phy); if (IS_ERR(phy)) { uphy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); if (IS_ERR(uphy)) { /* Fallback for pdata */ - plat = dev_get_platdata(pdev-dev); + plat = dev_get_platdata(dev); if (!plat) { - dev_err(pdev-dev, + dev_err(dev, no platform data or transceiver defined\n); return -EPROBE_DEFER; } - hsotg-plat = plat; + dwc2-s3c_hsotg-plat = plat; } else - hsotg-uphy = uphy; + dwc2-s3c_hsotg-uphy = uphy; } else - hsotg-phy = phy; + dwc2-s3c_hsotg-phy = phy; - hsotg-dev = dev; - - hsotg-clk = devm_clk_get(pdev-dev, otg); - if (IS_ERR(hsotg-clk)) { + dwc2-s3c_hsotg-clk = devm_clk_get(dev, otg); + if (IS_ERR(dwc2-s3c_hsotg-clk)) { dev_err(dev, cannot get otg clock\n); - return PTR_ERR(hsotg-clk); - } - - platform_set_drvdata(pdev, hsotg); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - hsotg-regs = devm_ioremap_resource(pdev-dev, res); - if (IS_ERR(hsotg-regs)) { - ret = PTR_ERR(hsotg-regs); - goto err_clk; - } - - ret = platform_get_irq(pdev, 0); - if (ret 0) { - dev_err(dev, cannot find IRQ\n); - goto err_clk; - } - - spin_lock_init(hsotg-lock); - - hsotg-irq = ret; - - ret = devm_request_irq(pdev-dev, hsotg-irq, s3c_hsotg_irq, 0, - dev_name(dev), hsotg); - if (ret 0) { - dev_err(dev, cannot claim IRQ\n); - goto err_clk; + return PTR_ERR(dwc2-s3c_hsotg-clk); } - dev_info(dev, regs %p, irq %d\n, hsotg-regs, hsotg-irq); - - hsotg-gadget.max_speed = USB_SPEED_HIGH; - hsotg-gadget.ops = s3c_hsotg_gadget_ops; - hsotg-gadget.name = dev_name(dev); + dwc2-gadget.max_speed = USB_SPEED_HIGH; + dwc2-gadget.ops = s3c_hsotg_gadget_ops; + dwc2-gadget.name = dev_name(dev); - /* reset the system */ - - clk_prepare_enable(hsotg-clk); + clk_prepare_enable(dwc2-s3c_hsotg-clk); /* regulators */ - for (i = 0; i ARRAY_SIZE(hsotg-supplies); i++) - hsotg-supplies[i].supply = s3c_hsotg_supply_names[i]; + for (i = 0; i ARRAY_SIZE(dwc2-s3c_hsotg-supplies); i++) + dwc2-s3c_hsotg-supplies[i].supply = s3c_hsotg_supply_names[i]; - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg-supplies), -hsotg-supplies); + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dwc2-s3c_hsotg-supplies), +dwc2-s3c_hsotg-supplies); if (ret) {
[PATCH 07/15] usb: dwc2: gadget: Do not fail probe if there isn't a clock node
From: Dinh Nguyen dingu...@altera.com Since the dwc2 hcd driver is currently not looking for a clock node during init, we should not completely fail if there isn't a clock provided. Add a check for a valid clock before calling clock functions. Signed-off-by: Dinh Nguyen dingu...@altera.com --- drivers/usb/dwc2/gadget.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index ca5c64a..51ee052 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3228,16 +3228,15 @@ static int dwc2_gadget_init(struct dwc2_hsotg *dwc2, int irq) dwc2-s3c_hsotg-phy = phy; dwc2-s3c_hsotg-clk = devm_clk_get(dev, otg); - if (IS_ERR(dwc2-s3c_hsotg-clk)) { - dev_err(dev, cannot get otg clock\n); - return PTR_ERR(dwc2-s3c_hsotg-clk); - } + if (IS_ERR(dwc2-s3c_hsotg-clk)) + dev_warn(dev, cannot get otg clock\n); dwc2-gadget.max_speed = USB_SPEED_HIGH; dwc2-gadget.ops = s3c_hsotg_gadget_ops; dwc2-gadget.name = dev_name(dev); - clk_prepare_enable(dwc2-s3c_hsotg-clk); + if (dwc2-s3c_hsotg-clk) + clk_prepare_enable(dwc2-s3c_hsotg-clk); /* regulators */ @@ -3342,7 +3341,8 @@ err_ep_mem: err_supplies: s3c_hsotg_phy_disable(dwc2); err_clk: - clk_disable_unprepare(dwc2-s3c_hsotg-clk); + if (dwc2-s3c_hsotg-clk) + clk_disable_unprepare(dwc2-s3c_hsotg-clk); return ret; } @@ -3365,7 +3365,8 @@ static int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) s3c_hsotg_phy_disable(dwc2); if (dwc2-s3c_hsotg-phy) phy_exit(dwc2-s3c_hsotg-phy); - clk_disable_unprepare(dwc2-s3c_hsotg-clk); + if (dwc2-s3c_hsotg-clk) + clk_disable_unprepare(dwc2-s3c_hsotg-clk); return 0; } -- 1.7.9.5 -- 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