phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function
Subsystems (4)
PATCH 1/2 phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function
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). The phy-sun4i-usb code already has code to force a session end for devices without Vbus control.
This commit adds a sun4i_usb_phy_force_session_end() function exporting this functionality to the sunxi-musb glue, so that it can force a session end to fixup the stuck state after a babble error.
--- drivers/phy/phy-sun4i-usb.c | 11 +++++++++++ include/linux/phy/phy-sun4i-usb.h | 7 +++++++ 2 files changed, 18 insertions(+)
drivers/phy/phy-sun4i-usb.c +11 -0
@@ -470,6 +470,17 @@ void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) }EXPORT_SYMBOL_GPL (sun4i_usb_phy_set_squelch_detect); +void sun4i_usb_phy_force_session_end (struct phy *_phy) +{ +struct sun4i_usb_phy *phy =phy_get_drvdata (_phy); +struct sun4i_usb_phy_data *data =to_sun4i_usb_phy_data (phy); + + data->id_det =-1 ; + data->force_session_end = true; +queue_delayed_work (system_wq, &data->detect,0 ); +} +EXPORT_SYMBOL_GPL (sun4i_usb_phy_force_session_end); +static const struct phy_ops sun4i_usb_phy_ops = { .init = sun4i_usb_phy_init, .exit = sun4i_usb_phy_exit,
include/linux/phy/phy-sun4i-usb.h +7 -0
@@ -23,4 +23,11 @@*/ void sun4i_usb_phy_set_squelch_detect (struct phy *phy,bool enabled); +/** +* sun4i_usb_force_session_end() - Force the current session to end +* by reporting VBus low for 200+ ms +* @phy: reference to a sun4i usb phy +*/ +void sun4i_usb_phy_force_session_end (struct phy *phy); +#endif
Signature · 1 line
2.9.3
PATCH 2/2 musb: sunxi: Force session end on babble errors in host-mode
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 calls sun4i_usb_phy_force_session_end() on babble errors in host-mode, fixing the musb controller being 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.
--- drivers/usb/musb/sunxi.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/usb/musb/sunxi.c +10 -0
@@ -192,8 +192,18 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)* normally babble never happens treat it as disconnect. */ if ((musb->int_usb &MUSB_INTR_BABBLE ) &&is_host_active (musb)) { +struct sunxi_glue *glue = +dev_get_drvdata (musb->controller->parent); + +dev_warn (musb->controller->parent,"babble, treating as disconnect\n" ); + musb->int_usb &= ~MUSB_INTR_BABBLE ; musb->int_usb |=MUSB_INTR_DISCONNECT ; +/* +* Fix the musb controller sometimes getting stuck in +* bdevice state after a babble error. +*/ +sun4i_usb_phy_force_session_end (glue->phy); }if ((musb->int_usb &MUSB_INTR_RESET ) && !is_host_active (musb)) {
Signature · 1 line
2.9.3
Bin Liu
maintainerPATCH 2/2 musb: sunxi: Force session end on babble errors in host-mode
Hi,
Quoted 26 lines · Hans de Goede
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_SESSIONand setsMUSB_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 calls
sun4i_usb_phy_force_session_end()on babble errors in host-mode, fixing the musb controller being 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 <[email protected]>--- drivers/usb/musb/sunxi.c | 10 ++++++++++ 1 file changed, 10 insertions(+)drivers/usb/musb/sunxi.c +0
-0
drivers/usb/musb/sunxi.c static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci) · line 194
Quoted 3 lines
drivers/usb/musb/sunxi.c +0
-0@@ -192,8 +192,18 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)* normally babble never happens treat it as disconnect. */ if ((musb->int_usb &MUSB_INTR_BABBLE ) &&is_host_active (musb)) {
musb_interrupt() handle BABBLE in host mode, and has a glue hook musb_platform_recover() in musb_recover_from_babble().
Maybe you can use it?
drivers/usb/musb/sunxi.c static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci) · line 206
Quoted 12 lines
drivers/usb/musb/sunxi.c +10
-0+struct sunxi_glue *glue = +dev_get_drvdata (musb->controller->parent); + +dev_warn (musb->controller->parent,"babble, treating as disconnect\n" ); + musb->int_usb &= ~MUSB_INTR_BABBLE ; musb->int_usb |=MUSB_INTR_DISCONNECT ; +/* +* Fix the musb controller sometimes getting stuck in +* bdevice state after a babble error. +*/ +sun4i_usb_phy_force_session_end (glue->phy);
As I commented in PATCH 1/2, can you somehow reuse sun4i_usb_phy_set_mode() instead?
Quoted 5 lines
drivers/usb/musb/sunxi.c +0
-0}if ((musb->int_usb &MUSB_INTR_RESET ) && !is_host_active (musb)) {Signature · 1 line
2.9.3
Regards,
-Bin.
PATCH 2/2 musb: sunxi: Force session end on babble errors in host-mode
Hi,
Quoted 36 lines · Bin Liu
Hi,
Quoted 26 lines · Hans de Goede
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_SESSIONand setsMUSB_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 calls
sun4i_usb_phy_force_session_end()on babble errors in host-mode, fixing the musb controller being 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 <[email protected]>--- drivers/usb/musb/sunxi.c | 10 ++++++++++ 1 file changed, 10 insertions(+)drivers/usb/musb/sunxi.c +0
-0drivers/usb/musb/sunxi.c static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci) · line 194
Quoted 3 lines
drivers/usb/musb/sunxi.c +0
-0@@ -192,8 +192,18 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)* normally babble never happens treat it as disconnect. */ if ((musb->int_usb &MUSB_INTR_BABBLE ) &&is_host_active (musb)) {
musb_interrupt()handle BABBLE in host mode, and has a glue hookmusb_platform_recover()inmusb_recover_from_babble().
Quoted 1 line
Maybe you can use it?
Ah yes, I looked at this at the past, but that was before the babble recover rework by Felipe Balbi which got commited on 2015-03-10.
With this rework the sunxi code should indeed be able to use the core recovery, and we can use the musb_platform_recover() to force a session end.
And thinking more about you're other remark, I do think I can actually modify the sun4i phy_set_mode callback so that it can be used for this.
I'll post a v2 with these changes soon-ish.
Regards,
Hans
Quoted 25 lines
drivers/usb/musb/sunxi.c static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci) · line 206
Quoted 12 lines
drivers/usb/musb/sunxi.c +10
-0+struct sunxi_glue *glue = +dev_get_drvdata (musb->controller->parent); + +dev_warn (musb->controller->parent,"babble, treating as disconnect\n" ); + musb->int_usb &= ~MUSB_INTR_BABBLE ; musb->int_usb |=MUSB_INTR_DISCONNECT ; +/* +* Fix the musb controller sometimes getting stuck in +* bdevice state after a babble error. +*/ +sun4i_usb_phy_force_session_end (glue->phy);As I commented in PATCH 1/2, can you somehow reuse
sun4i_usb_phy_set_mode()instead?Quoted 5 lines
drivers/usb/musb/sunxi.c +0
-1}if ((musb->int_usb &MUSB_INTR_RESET ) && !is_host_active (musb)) { --2.9.3
Regards,
-Bin.
PATCH 1/2 phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function
In reply to Hans de GoedeHi,
Quoted 29 lines · Hans de Goede
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_SESSIONand setsMUSB_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). The phy-sun4i-usb code already has code to force a session end for devices without Vbus control.
This commit adds a
sun4i_usb_phy_force_session_end()function exporting this functionality to the sunxi-musb glue, so that it can force a session end to fixup the stuck state after a babble error.Signed-off-by Hans de Goede <[email protected]>--- drivers/phy/phy-sun4i-usb.c | 11 +++++++++++ include/linux/phy/phy-sun4i-usb.h | 7 +++++++ 2 files changed, 18 insertions(+)drivers/phy/phy-sun4i-usb.c +0
-0@@ -470,6 +470,17 @@ void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) }EXPORT_SYMBOL_GPL (sun4i_usb_phy_set_squelch_detect);
drivers/phy/phy-sun4i-usb.c void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) · line 482
Quoted 10 lines
drivers/phy/phy-sun4i-usb.c +10
-0+void sun4i_usb_phy_force_session_end (struct phy *_phy) +{ +struct sun4i_usb_phy *phy =phy_get_drvdata (_phy); +struct sun4i_usb_phy_data *data =to_sun4i_usb_phy_data (phy); + + data->id_det =-1 ; + data->force_session_end = true; +queue_delayed_work (system_wq, &data->detect,0 ); +} +EXPORT_SYMBOL_GPL (sun4i_usb_phy_force_session_end);
Er.. one more export symbol :-(
Quoted 9 lines
drivers/phy/phy-sun4i-usb.c +1
-0+static const struct phy_ops sun4i_usb_phy_ops = { .init = sun4i_usb_phy_init, .exit = sun4i_usb_phy_exit,include/linux/phy/phy-sun4i-usb.h +0
-0
include/linux/phy/phy-sun4i-usb.h line 31
Quoted 9 lines
include/linux/phy/phy-sun4i-usb.h +6
-0@@ -23,4 +23,11 @@*/ void sun4i_usb_phy_set_squelch_detect (struct phy *phy,bool enabled); +/** +* sun4i_usb_force_session_end() - Force the current session to end +* by reporting VBus low for 200+ ms +* @phy: reference to a sun4i usb phy +*/ +void sun4i_usb_phy_force_session_end (struct phy *phy);
Should we include a static inline function if sun4i phy is not defined?
Thanks
Kishon
PATCH 1/2 phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function
Hi,
Quoted 32 lines · Kishon Vijay Abraham I
Hi,
Quoted 29 lines · Hans de Goede
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_SESSIONand setsMUSB_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). The phy-sun4i-usb code already has code to force a session end for devices without Vbus control.
This commit adds a
sun4i_usb_phy_force_session_end()function exporting this functionality to the sunxi-musb glue, so that it can force a session end to fixup the stuck state after a babble error.Signed-off-by Hans de Goede <[email protected]>--- drivers/phy/phy-sun4i-usb.c | 11 +++++++++++ include/linux/phy/phy-sun4i-usb.h | 7 +++++++ 2 files changed, 18 insertions(+)drivers/phy/phy-sun4i-usb.c +0
-0@@ -470,6 +470,17 @@ void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) }EXPORT_SYMBOL_GPL (sun4i_usb_phy_set_squelch_detect);
Quoted 12 lines
drivers/phy/phy-sun4i-usb.c void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) · line 482
Quoted 10 lines
drivers/phy/phy-sun4i-usb.c +10
-0+void sun4i_usb_phy_force_session_end (struct phy *_phy) +{ +struct sun4i_usb_phy *phy =phy_get_drvdata (_phy); +struct sun4i_usb_phy_data *data =to_sun4i_usb_phy_data (phy); + + data->id_det =-1 ; + data->force_session_end = true; +queue_delayed_work (system_wq, &data->detect,0 ); +} +EXPORT_SYMBOL_GPL (sun4i_usb_phy_force_session_end);Er.. one more export symbol :-(
Yes unfortunately we need one more to work around sunxi musb / phy bugs.
Quoted 12 lines
Quoted 12 lines
drivers/phy/phy-sun4i-usb.c +1
-0+static const struct phy_ops sun4i_usb_phy_ops = { .init = sun4i_usb_phy_init, .exit = sun4i_usb_phy_exit,include/linux/phy/phy-sun4i-usb.h +0
-0@@ -23,4 +23,11 @@*/ void sun4i_usb_phy_set_squelch_detect (struct phy *phy,bool enabled);
Quoted 8 lines
include/linux/phy/phy-sun4i-usb.h line 31
Quoted 6 lines
include/linux/phy/phy-sun4i-usb.h +6
-0+/** +* sun4i_usb_force_session_end() - Force the current session to end +* by reporting VBus low for 200+ ms +* @phy: reference to a sun4i usb phy +*/ +void sun4i_usb_phy_force_session_end (struct phy *phy);Should we include a static inline function if sun4i phy is not defined?
No, we're also not doing that for the already exported sun4i_usb_phy_set_squelch_detect()
And it is not necessary since the only caller is drivers/usb/musb/sunxi.c, and drivers/usb/musb/Kconfig has:
config USB_MUSB_SUNXI
tristate "Allwinner (sunxi)"
depends on PHY_SUN4I_USB
Regards,
Hans
Bin Liu
maintainerPATCH 1/2 phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function
Hi,
Quoted 48 lines · Hans de Goede
Hi,
Quoted 32 lines · Kishon Vijay Abraham I
Hi,
Quoted 29 lines · Hans de Goede
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_SESSIONand setsMUSB_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). The phy-sun4i-usb code already has code to force a session end for devices without Vbus control.
This commit adds a
sun4i_usb_phy_force_session_end()function exporting this functionality to the sunxi-musb glue, so that it can force a session end to fixup the stuck state after a babble error.Signed-off-by Hans de Goede <[email protected]>---
drivers/phy/phy-sun4i-usb.c| 11 +++++++++++include/linux/phy/phy-sun4i-usb.h| 7 +++++++2 files changed, 18 insertions(+)drivers/phy/phy-sun4i-usb.c +0
-0@@ -470,6 +470,17 @@ void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) }EXPORT_SYMBOL_GPL (sun4i_usb_phy_set_squelch_detect);Quoted 12 lines
drivers/phy/phy-sun4i-usb.c void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) · line 482
Quoted 10 lines
drivers/phy/phy-sun4i-usb.c +10
-0+void sun4i_usb_phy_force_session_end (struct phy *_phy) +{ +struct sun4i_usb_phy *phy =phy_get_drvdata (_phy); +struct sun4i_usb_phy_data *data =to_sun4i_usb_phy_data (phy); + + data->id_det =-1 ; + data->force_session_end = true; +queue_delayed_work (system_wq, &data->detect,0 ); +} +EXPORT_SYMBOL_GPL (sun4i_usb_phy_force_session_end);Er.. one more export symbol :-(
Quoted 1 line
Yes unfortunately we need one more to work around sunxi musb / phy bugs.
Instead, can you somehow reuse sun4i_usb_phy_set_mode()?
Regards,
-Bin.
Quoted 35 lines
Quoted 13 lines
Quoted 13 lines
drivers/phy/phy-sun4i-usb.c +1
-0+static const struct phy_ops sun4i_usb_phy_ops = { .init = sun4i_usb_phy_init, .exit = sun4i_usb_phy_exit,include/linux/phy/phy-sun4i-usb.h +0
-0@@ -23,4 +23,11 @@*/ void sun4i_usb_phy_set_squelch_detect (struct phy *phy,bool enabled);Quoted 8 lines
include/linux/phy/phy-sun4i-usb.h line 31
Quoted 6 lines
include/linux/phy/phy-sun4i-usb.h +6
-0+/** +* sun4i_usb_force_session_end() - Force the current session to end +* by reporting VBus low for 200+ ms +* @phy: reference to a sun4i usb phy +*/ +void sun4i_usb_phy_force_session_end (struct phy *phy);Should we include a static inline function if sun4i phy is not defined?
No, we're also not doing that for the already exported
sun4i_usb_phy_set_squelch_detect()And it is not necessary since the only caller is
drivers/usb/musb/sunxi.c, anddrivers/usb/musb/Kconfighas:config
USB_MUSB_SUNXI
tristate "Allwinner (sunxi)"
depends onPHY_SUN4I_USBRegards,
Hans
PATCH 1/2 phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function
Hi,
Quoted 51 lines · Bin Liu
Hi,
Quoted 48 lines · Hans de Goede
Hi,
Quoted 44 lines · Kishon Vijay Abraham I
Hi,
Quoted 29 lines · Hans de Goede
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_SESSIONand setsMUSB_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). The phy-sun4i-usb code already has code to force a session end for devices without Vbus control.
This commit adds a
sun4i_usb_phy_force_session_end()function exporting this functionality to the sunxi-musb glue, so that it can force a session end to fixup the stuck state after a babble error.Signed-off-by Hans de Goede <[email protected]>---
drivers/phy/phy-sun4i-usb.c| 11 +++++++++++include/linux/phy/phy-sun4i-usb.h| 7 +++++++2 files changed, 18 insertions(+)drivers/phy/phy-sun4i-usb.c +0
-0@@ -470,6 +470,17 @@ void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) }EXPORT_SYMBOL_GPL (sun4i_usb_phy_set_squelch_detect);drivers/phy/phy-sun4i-usb.c void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) · line 482
Quoted 10 lines
drivers/phy/phy-sun4i-usb.c +10
-0+void sun4i_usb_phy_force_session_end (struct phy *_phy) +{ +struct sun4i_usb_phy *phy =phy_get_drvdata (_phy); +struct sun4i_usb_phy_data *data =to_sun4i_usb_phy_data (phy); + + data->id_det =-1 ; + data->force_session_end = true; +queue_delayed_work (system_wq, &data->detect,0 ); +} +EXPORT_SYMBOL_GPL (sun4i_usb_phy_force_session_end);Er.. one more export symbol :-(
Quoted 3 lines
Quoted 1 line
Yes unfortunately we need one more to work around sunxi musb / phy bugs.
Instead, can you somehow reuse
sun4i_usb_phy_set_mode()?
That was my first thought too, and I looked into this, but it did not work out.
Regards,
Hans
Quoted 39 lines
Regards,
-Bin.Quoted 35 lines
Quoted 13 lines
Quoted 13 lines
drivers/phy/phy-sun4i-usb.c +1
-0+static const struct phy_ops sun4i_usb_phy_ops = { .init = sun4i_usb_phy_init, .exit = sun4i_usb_phy_exit,include/linux/phy/phy-sun4i-usb.h +0
-0@@ -23,4 +23,11 @@*/ void sun4i_usb_phy_set_squelch_detect (struct phy *phy,bool enabled);Quoted 8 lines
include/linux/phy/phy-sun4i-usb.h line 31
Quoted 6 lines
include/linux/phy/phy-sun4i-usb.h +6
-0+/** +* sun4i_usb_force_session_end() - Force the current session to end +* by reporting VBus low for 200+ ms +* @phy: reference to a sun4i usb phy +*/ +void sun4i_usb_phy_force_session_end (struct phy *phy);Should we include a static inline function if sun4i phy is not defined?
No, we're also not doing that for the already exported
sun4i_usb_phy_set_squelch_detect()And it is not necessary since the only caller is
drivers/usb/musb/sunxi.c, anddrivers/usb/musb/Kconfighas:config
USB_MUSB_SUNXI
tristate "Allwinner (sunxi)"
depends onPHY_SUN4I_USBRegards,
Hans