Hello,
I added the debug prints and now cannot reproduce the b_idle state.
This somewhat contributes to my suspicion that this is a race
with delivering the initial interrupt. Also the debug prints show
that the first (and only) irq is fired when the phy is not set up:
[ 1.546488] phy phy-1c19400.phy.0: usb phy0 handling irq
[ 1.599174] phy phy-1c19400.phy.0: usb phy0 init missing
[ 1.632560] phy phy-1c19400.phy.0: usb phy0 setting vbus_det to 1
[ 1.632569] phy phy-1c19400.phy.0: usb phy0 handling id_notify
[ 1.632678] phy phy-1c19400.phy.0: Faking usb phy0 id_det 1
[ 2.632988] phy phy-1c19400.phy.0: usb phy0 handling vbus_notify
[ 2.747815] phy phy-1c19400.phy.0: usb phy0 setting vbus_det to 1
[ 2.747824] phy phy-1c19400.phy.0: usb phy0 handling id_notify
[ 2.747833] phy phy-1c19400.phy.0: Faking usb phy0 id_det 1
[ 3.748917] phy phy-1c19400.phy.0: usb phy0 handling vbus_notify
No more messages are logged even unplugging and replugging the cable.
Also it seems that the detection depends on something dynamically
fabricated in the irq handler rather than examining the static phy state.
So if the interrupt is handled before musb is set up it may only see the static
state which is not all that useful.
>
> Or first, I'd suggest to add unconditional "return true" to
> sun4i_usb_phy0_poll, if that fixes anything. This will enable polling on
> the iddet gpio. (Perhaps gpio interrupts are not very reliable?)
That sounds like a good plan. However, it does not change anything.
Events are properly generated on connecting and disconnecting an
OTG cable. Connecting and disconnecting peripherial cable does
nothing in the phy at all. It does change something somewhere and
the gadget starts working, though.
Finally, I have seen the gadget broken with phy mode reporting
b_peripherial rather than b_idle.
In one state the gadget interface is up, has proper IP address set up, and
packets don't go through it. On the other side of the USB cable there is
no trace of the gadget interface. No interface, nothing in lsusb.
This particular state turns out to be a cable problem. The springs holding
the cable in the micro usb socket are worn down and it may
have bad contact.
Surprisingly, replacing the cable leads to another error state which is pretty
much what I have seen initially with the bad cable in b_idle state:
The interface is properly set up on both ends. I can see ARP requests
going from H3 on the other side, replies are sent, and never seen on H3.
Here is a comparison of the broken and working state
In the broken state there is extra "init missing" message which is generated
in the early return branch. The amount of events processed in phy seems the
same but the different init ordering possibly affects something else as well.
Will try to add prints to musb later.
Thanks
Michal
[ 1.553534] phy phy-1c19400.phy.0: usb phy0 handling irq
[ 1.603051] phy phy-1c19400.phy.0: usb phy0 init missing
[ 1.649140] phy phy-1c19400.phy.0: usb phy0 setting vbus_det to 1
[ 1.649148] phy phy-1c19400.phy.0: usb phy0 handling id_notify
[ 1.649278] phy phy-1c19400.phy.0: Faking usb phy0 id_det 1
[ 2.649951] phy phy-1c19400.phy.0: usb phy0 handling vbus_notify
[ 2.765006] phy phy-1c19400.phy.0: usb phy0 setting vbus_det to 1
[ 2.765015] phy phy-1c19400.phy.0: usb phy0 handling id_notify
[ 2.765024] phy phy-1c19400.phy.0: Faking usb phy0 id_det 1
[ 3.765885] phy phy-1c19400.phy.0: usb phy0 handling vbus_notify
[ 1.546315] phy phy-1c19400.phy.0: usb phy0 handling irq
[ 1.616561] phy phy-1c19400.phy.0: usb phy0 setting vbus_det to 1
[ 1.616571] phy phy-1c19400.phy.0: usb phy0 handling id_notify
[ 1.616637] phy phy-1c19400.phy.0: Faking usb phy0 id_det 1
[ 2.616900] phy phy-1c19400.phy.0: usb phy0 handling vbus_notify
[ 2.705023] phy phy-1c19400.phy.0: usb phy0 setting vbus_det to 1
[ 2.705032] phy phy-1c19400.phy.0: usb phy0 handling id_notify
[ 2.705040] phy phy-1c19400.phy.0: Faking usb phy0 id_det 1
[ 3.705918] phy phy-1c19400.phy.0: usb phy0 handling vbus_notify