* [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session
@ 2016-09-23 13:40 Hans de Goede
2016-09-23 13:40 ` [PATCH v3 2/3] musb: sunxi: Remove custom babble handling Hans de Goede
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Hans de Goede @ 2016-09-23 13:40 UTC (permalink / raw)
To: linux-arm-kernel
The sunxi musb has a bug where sometimes it will generate a babble
error on device disconnect instead of a disconnect irq. When this
happens the musb-controller switches from host mode to device mode
(it clears MUSB_DEVCTL_SESSION and sets MUSB_DEVCTL_BDEVICE) and
gets stuck in this state.
Clearing this requires reporting Vbus low for 200 or more ms, but
on some devices Vbus is simply always high (host-only mode, no Vbus
control).
This commit modifies sun4i_usb_phy_set_mode so that it will force
end the current session when called with the current mode, before this
commit calling set_mode with the current mode was a nop since id_det
would stay the same resulting in the detect_work not doing anything.
This allows the sunxi-musb glue to use sun4i_usb_phy_set_mode to force
end the current session without changing the mode, to fixup the stuck
state after a babble error.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-New patch in v2 of this series replacing the
"phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function"
from v1
Changes in v3:
-Fix dev_info so that it prints the new-mode instead of the old one
---
drivers/phy/phy-sun4i-usb.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index 43c0d98..cbd338d 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -437,25 +437,31 @@ static int sun4i_usb_phy_set_mode(struct phy *_phy, enum phy_mode mode)
{
struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+ int new_mode;
if (phy->index != 0)
return -EINVAL;
switch (mode) {
case PHY_MODE_USB_HOST:
- data->dr_mode = USB_DR_MODE_HOST;
+ new_mode = USB_DR_MODE_HOST;
break;
case PHY_MODE_USB_DEVICE:
- data->dr_mode = USB_DR_MODE_PERIPHERAL;
+ new_mode = USB_DR_MODE_PERIPHERAL;
break;
case PHY_MODE_USB_OTG:
- data->dr_mode = USB_DR_MODE_OTG;
+ new_mode = USB_DR_MODE_OTG;
break;
default:
return -EINVAL;
}
- dev_info(&_phy->dev, "Changing dr_mode to %d\n", (int)data->dr_mode);
+ if (new_mode != data->dr_mode) {
+ dev_info(&_phy->dev, "Changing dr_mode to %d\n", new_mode);
+ data->dr_mode = new_mode;
+ }
+
+ data->id_det = -1; /* Force reprocessing of id */
data->force_session_end = true;
queue_delayed_work(system_wq, &data->detect, 0);
--
2.9.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/3] musb: sunxi: Remove custom babble handling
2016-09-23 13:40 [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session Hans de Goede
@ 2016-09-23 13:40 ` Hans de Goede
2016-11-15 21:14 ` Bin Liu
2016-09-23 13:40 ` [PATCH v3 3/3] musb: sunxi: Force session end on babble errors in host-mode Hans de Goede
2016-11-15 13:48 ` [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session Kishon Vijay Abraham I
2 siblings, 1 reply; 6+ messages in thread
From: Hans de Goede @ 2016-09-23 13:40 UTC (permalink / raw)
To: linux-arm-kernel
The musb core already handles babble interrupts, so the sunxi glue
having its own custom handling is redundant.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-This is a new patch in v2 of this patch series
Changes in v3:
-Improve commit msg
---
drivers/usb/musb/sunxi.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index 1408245..82eba92 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -186,16 +186,6 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
if (musb->int_usb)
writeb(musb->int_usb, musb->mregs + SUNXI_MUSB_INTRUSB);
- /*
- * sunxi musb often signals babble on low / full speed device
- * disconnect, without ever raising MUSB_INTR_DISCONNECT, since
- * normally babble never happens treat it as disconnect.
- */
- if ((musb->int_usb & MUSB_INTR_BABBLE) && is_host_active(musb)) {
- musb->int_usb &= ~MUSB_INTR_BABBLE;
- musb->int_usb |= MUSB_INTR_DISCONNECT;
- }
-
if ((musb->int_usb & MUSB_INTR_RESET) && !is_host_active(musb)) {
/* ep0 FADDR must be 0 when (re)entering peripheral mode */
musb_ep_select(musb->mregs, 0);
--
2.9.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 3/3] musb: sunxi: Force session end on babble errors in host-mode
2016-09-23 13:40 [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session Hans de Goede
2016-09-23 13:40 ` [PATCH v3 2/3] musb: sunxi: Remove custom babble handling Hans de Goede
@ 2016-09-23 13:40 ` Hans de Goede
2016-11-15 21:14 ` Bin Liu
2016-11-15 13:48 ` [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session Kishon Vijay Abraham I
2 siblings, 1 reply; 6+ messages in thread
From: Hans de Goede @ 2016-09-23 13:40 UTC (permalink / raw)
To: linux-arm-kernel
The sunxi musb has a bug where sometimes it will generate a babble
error on device disconnect instead of a disconnect irq. When this
happens the musb-controller switches from host mode to device mode
(it clears MUSB_DEVCTL_SESSION and sets MUSB_DEVCTL_BDEVICE) and
gets stuck in this state.
Clearing this requires reporting Vbus low for 200 or more ms, but
on some devices Vbus is simply always high (host-only mode, no Vbus
control).
This commit adds a sunxi_musb_recover() callback which makes
sunxi_musb_work call phy_set_mode with the current mode, which
will force end the current session.
This fixes the musb controller getting stuck in this state on systems
without Vbus control; and also fixes the need to unplug the usb-b ->
usb-a cable to get out of this state on systems with Vbus control.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-Use musb_platform_recover callback instead of using DYI code in the
interrupt handler
-Call phy_set_mode with the current mode instead of adding a new custom
sunxi phy callback
---
drivers/usb/musb/sunxi.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index 82eba92..d0be0ea 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -380,6 +380,20 @@ static int sunxi_musb_set_mode(struct musb *musb, u8 mode)
return 0;
}
+static int sunxi_musb_recover(struct musb *musb)
+{
+ struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+ /*
+ * Schedule a phy_set_mode with the current glue->phy_mode value,
+ * this will force end the current session.
+ */
+ set_bit(SUNXI_MUSB_FL_PHY_MODE_PEND, &glue->flags);
+ schedule_work(&glue->work);
+
+ return 0;
+}
+
/*
* sunxi musb register layout
* 0x00 - 0x17 fifo regs, 1 long per fifo
@@ -608,6 +622,7 @@ static const struct musb_platform_ops sunxi_musb_ops = {
.dma_init = sunxi_musb_dma_controller_create,
.dma_exit = sunxi_musb_dma_controller_destroy,
.set_mode = sunxi_musb_set_mode,
+ .recover = sunxi_musb_recover,
.set_vbus = sunxi_musb_set_vbus,
.pre_root_reset_end = sunxi_musb_pre_root_reset_end,
.post_root_reset_end = sunxi_musb_post_root_reset_end,
--
2.9.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session
2016-09-23 13:40 [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session Hans de Goede
2016-09-23 13:40 ` [PATCH v3 2/3] musb: sunxi: Remove custom babble handling Hans de Goede
2016-09-23 13:40 ` [PATCH v3 3/3] musb: sunxi: Force session end on babble errors in host-mode Hans de Goede
@ 2016-11-15 13:48 ` Kishon Vijay Abraham I
2 siblings, 0 replies; 6+ messages in thread
From: Kishon Vijay Abraham I @ 2016-11-15 13:48 UTC (permalink / raw)
To: linux-arm-kernel
On Friday 23 September 2016 07:10 PM, Hans de Goede wrote:
> The sunxi musb has a bug where sometimes it will generate a babble
> error on device disconnect instead of a disconnect irq. When this
> happens the musb-controller switches from host mode to device mode
> (it clears MUSB_DEVCTL_SESSION and sets MUSB_DEVCTL_BDEVICE) and
> gets stuck in this state.
>
> Clearing this requires reporting Vbus low for 200 or more ms, but
> on some devices Vbus is simply always high (host-only mode, no Vbus
> control).
>
> This commit modifies sun4i_usb_phy_set_mode so that it will force
> end the current session when called with the current mode, before this
> commit calling set_mode with the current mode was a nop since id_det
> would stay the same resulting in the detect_work not doing anything.
>
> This allows the sunxi-musb glue to use sun4i_usb_phy_set_mode to force
> end the current session without changing the mode, to fixup the stuck
> state after a babble error.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
merged, thanks.
-Kishon
> ---
> Changes in v2:
> -New patch in v2 of this series replacing the
> "phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function"
> from v1
> Changes in v3:
> -Fix dev_info so that it prints the new-mode instead of the old one
> ---
> drivers/phy/phy-sun4i-usb.c | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
> index 43c0d98..cbd338d 100644
> --- a/drivers/phy/phy-sun4i-usb.c
> +++ b/drivers/phy/phy-sun4i-usb.c
> @@ -437,25 +437,31 @@ static int sun4i_usb_phy_set_mode(struct phy *_phy, enum phy_mode mode)
> {
> struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> + int new_mode;
>
> if (phy->index != 0)
> return -EINVAL;
>
> switch (mode) {
> case PHY_MODE_USB_HOST:
> - data->dr_mode = USB_DR_MODE_HOST;
> + new_mode = USB_DR_MODE_HOST;
> break;
> case PHY_MODE_USB_DEVICE:
> - data->dr_mode = USB_DR_MODE_PERIPHERAL;
> + new_mode = USB_DR_MODE_PERIPHERAL;
> break;
> case PHY_MODE_USB_OTG:
> - data->dr_mode = USB_DR_MODE_OTG;
> + new_mode = USB_DR_MODE_OTG;
> break;
> default:
> return -EINVAL;
> }
>
> - dev_info(&_phy->dev, "Changing dr_mode to %d\n", (int)data->dr_mode);
> + if (new_mode != data->dr_mode) {
> + dev_info(&_phy->dev, "Changing dr_mode to %d\n", new_mode);
> + data->dr_mode = new_mode;
> + }
> +
> + data->id_det = -1; /* Force reprocessing of id */
> data->force_session_end = true;
> queue_delayed_work(system_wq, &data->detect, 0);
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 2/3] musb: sunxi: Remove custom babble handling
2016-09-23 13:40 ` [PATCH v3 2/3] musb: sunxi: Remove custom babble handling Hans de Goede
@ 2016-11-15 21:14 ` Bin Liu
0 siblings, 0 replies; 6+ messages in thread
From: Bin Liu @ 2016-11-15 21:14 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Sep 23, 2016 at 04:40:57PM +0300, Hans de Goede wrote:
> The musb core already handles babble interrupts, so the sunxi glue
> having its own custom handling is redundant.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Applied. Thanks.
-Bin.
> ---
> Changes in v2:
> -This is a new patch in v2 of this patch series
> Changes in v3:
> -Improve commit msg
> ---
> drivers/usb/musb/sunxi.c | 10 ----------
> 1 file changed, 10 deletions(-)
>
> diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
> index 1408245..82eba92 100644
> --- a/drivers/usb/musb/sunxi.c
> +++ b/drivers/usb/musb/sunxi.c
> @@ -186,16 +186,6 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
> if (musb->int_usb)
> writeb(musb->int_usb, musb->mregs + SUNXI_MUSB_INTRUSB);
>
> - /*
> - * sunxi musb often signals babble on low / full speed device
> - * disconnect, without ever raising MUSB_INTR_DISCONNECT, since
> - * normally babble never happens treat it as disconnect.
> - */
> - if ((musb->int_usb & MUSB_INTR_BABBLE) && is_host_active(musb)) {
> - musb->int_usb &= ~MUSB_INTR_BABBLE;
> - musb->int_usb |= MUSB_INTR_DISCONNECT;
> - }
> -
> if ((musb->int_usb & MUSB_INTR_RESET) && !is_host_active(musb)) {
> /* ep0 FADDR must be 0 when (re)entering peripheral mode */
> musb_ep_select(musb->mregs, 0);
> --
> 2.9.3
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 3/3] musb: sunxi: Force session end on babble errors in host-mode
2016-09-23 13:40 ` [PATCH v3 3/3] musb: sunxi: Force session end on babble errors in host-mode Hans de Goede
@ 2016-11-15 21:14 ` Bin Liu
0 siblings, 0 replies; 6+ messages in thread
From: Bin Liu @ 2016-11-15 21:14 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Sep 23, 2016 at 04:40:58PM +0300, Hans de Goede wrote:
> The sunxi musb has a bug where sometimes it will generate a babble
> error on device disconnect instead of a disconnect irq. When this
> happens the musb-controller switches from host mode to device mode
> (it clears MUSB_DEVCTL_SESSION and sets MUSB_DEVCTL_BDEVICE) and
> gets stuck in this state.
>
> Clearing this requires reporting Vbus low for 200 or more ms, but
> on some devices Vbus is simply always high (host-only mode, no Vbus
> control).
>
> This commit adds a sunxi_musb_recover() callback which makes
> sunxi_musb_work call phy_set_mode with the current mode, which
> will force end the current session.
>
> This fixes the musb controller getting stuck in this state on systems
> without Vbus control; and also fixes the need to unplug the usb-b ->
> usb-a cable to get out of this state on systems with Vbus control.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Applied. Thanks.
-Bin.
> ---
> Changes in v2:
> -Use musb_platform_recover callback instead of using DYI code in the
> interrupt handler
> -Call phy_set_mode with the current mode instead of adding a new custom
> sunxi phy callback
> ---
> drivers/usb/musb/sunxi.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
> index 82eba92..d0be0ea 100644
> --- a/drivers/usb/musb/sunxi.c
> +++ b/drivers/usb/musb/sunxi.c
> @@ -380,6 +380,20 @@ static int sunxi_musb_set_mode(struct musb *musb, u8 mode)
> return 0;
> }
>
> +static int sunxi_musb_recover(struct musb *musb)
> +{
> + struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
> +
> + /*
> + * Schedule a phy_set_mode with the current glue->phy_mode value,
> + * this will force end the current session.
> + */
> + set_bit(SUNXI_MUSB_FL_PHY_MODE_PEND, &glue->flags);
> + schedule_work(&glue->work);
> +
> + return 0;
> +}
> +
> /*
> * sunxi musb register layout
> * 0x00 - 0x17 fifo regs, 1 long per fifo
> @@ -608,6 +622,7 @@ static const struct musb_platform_ops sunxi_musb_ops = {
> .dma_init = sunxi_musb_dma_controller_create,
> .dma_exit = sunxi_musb_dma_controller_destroy,
> .set_mode = sunxi_musb_set_mode,
> + .recover = sunxi_musb_recover,
> .set_vbus = sunxi_musb_set_vbus,
> .pre_root_reset_end = sunxi_musb_pre_root_reset_end,
> .post_root_reset_end = sunxi_musb_post_root_reset_end,
> --
> 2.9.3
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-11-15 21:14 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-23 13:40 [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session Hans de Goede
2016-09-23 13:40 ` [PATCH v3 2/3] musb: sunxi: Remove custom babble handling Hans de Goede
2016-11-15 21:14 ` Bin Liu
2016-09-23 13:40 ` [PATCH v3 3/3] musb: sunxi: Force session end on babble errors in host-mode Hans de Goede
2016-11-15 21:14 ` Bin Liu
2016-11-15 13:48 ` [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session Kishon Vijay Abraham I
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.