diff options
| author | Lucas Martins Alves <lucas.alves@lumal21.com.br> | 2026-07-17 19:44:53 +0000 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-09-10 14:41:35 +0200 |
| commit | d3c4ac41bf1e7989c773370e55c9784e4282894d (patch) | |
| tree | 1441046b79ba437dcd5e85252c0f0106ee19be68 | |
| parent | 0c4470927e3c2af2b46362fcb7231e3f598610ab (diff) | |
| download | linux-next-d3c4ac41bf1e7989c773370e55c9784e4282894d.tar.gz linux-next-d3c4ac41bf1e7989c773370e55c9784e4282894d.zip | |
usb: musb: dsps: implement vbus_status and set_vbus platform ops
The DSPS glue layer (used on TI AM335x SoCs) was missing implementations
for the vbus_status and set_vbus platform ops defined in struct
musb_platform_ops.
Add dsps_musb_vbus_status() to report VBUS presence by reading the VBUS
field of MUSB_DEVCTL, and dsps_musb_set_vbus() to drive the SESSION bit
on MUSB_DEVCTL, enabling or disabling the USB session.
Register both callbacks in dsps_ops to allow the MUSB core to control
VBUS on AM335x-based platforms. This enables the USB core to perform a
VBUS power cycle as a recovery mechanism when a USB error condition is
detected, and also allows userspace to control VBUS state via the
standard USB sysfs interface.
Signed-off-by: Lucas Martins Alves <lucas.alves@lumal21.com.br>
Link: https://patch.msgid.link/20260717194449.317520-1-lucas.alves@lumal21.com.br
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/usb/musb/musb_dsps.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index e3935f18dd56..efd1f0dbb926 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -618,6 +618,29 @@ static int dsps_musb_recover(struct musb *musb) return session_restart ? 0 : -EPIPE; } +static int dsps_musb_vbus_status(struct musb *musb) +{ + u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); + + return (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS; +} + +static void dsps_musb_set_vbus(struct musb *musb, int is_on) +{ + u8 devctl; + + devctl = musb_readb(musb->mregs, MUSB_DEVCTL); + + if (is_on) { + devctl |= MUSB_DEVCTL_SESSION; + } else { + musb_root_disconnect(musb); + devctl &= ~MUSB_DEVCTL_SESSION; + } + + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); +} + /* Similar to am35x, dm81xx support only 32-bit read operation */ static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) { @@ -702,6 +725,8 @@ static struct musb_platform_ops dsps_ops = { .set_mode = dsps_musb_set_mode, .recover = dsps_musb_recover, + .vbus_status = dsps_musb_vbus_status, + .set_vbus = dsps_musb_set_vbus, .clear_ep_rxintr = dsps_musb_clear_ep_rxintr, }; |
