Message ID | 1567771431-13235-3-git-send-email-external.veeraiyan.c@de.adit-jv.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v2,1/3] usb: renesas_usbhs: enable DVSE interrupt | expand |
Hi Veeraiyan, Thank you for your patch! > From: Veeraiyan Chidambaram, Sent: Friday, September 6, 2019 9:04 PM <snip> > When R-Car Gen3 USB 3.0 is in Gadget mode, if host is detached an interrupt This should be "USB 2.0" instead of "USB 3.0". Best regards, Yoshihiro Shimoda > will be generated and Suspended state bit is set in interrupt status > register. Interrupt handler will call driver->suspend(composite_suspend) > if suspended state bit is set. composite_suspend will call > ffs_func_suspend which will post FUNCTIONFS_SUSPEND and will be consumed > by user space application via /dev/ep0. > > To be able to detect host detach, extend the DVSQ_MASK to cover the > Suspended bit of the DVSQ[2:0] bitfield from the Interrupt Status > Register 0 (INTSTS0) register and perform appropriate action in the > DVST interrupt handler (usbhsg_irq_dev_state). > > Without this commit, disconnection of the phone from R-Car H3 ES2.0 > Salvator-X CN9 port is not recognized and reverse role switch does > not not happen. If phone is connected again it does not enumerate. > > With this commit, disconnection will be recognized and reverse role > switch will happen by a user space application. If phone is connected > again it will enumerate properly and will become visible in the output > of 'lsusb'. > > Signed-off-by: Veeraiyan Chidambaram <veeraiyan.chidambaram@in.bosch.com> > Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com> > --- > v2: if conditions changed > v1: https://patchwork.kernel.org/patch/10581489/ > > drivers/usb/renesas_usbhs/common.h | 3 ++- > drivers/usb/renesas_usbhs/mod_gadget.c | 12 +++++++++--- > 2 files changed, 11 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h > index 3777af848a35..142319c7585d 100644 > --- a/drivers/usb/renesas_usbhs/common.h > +++ b/drivers/usb/renesas_usbhs/common.h > @@ -159,11 +159,12 @@ struct usbhs_priv; > #define VBSTS (1 << 7) /* VBUS_0 and VBUSIN_0 Input Status */ > #define VALID (1 << 3) /* USB Request Receive */ > > -#define DVSQ_MASK (0x3 << 4) /* Device State */ > +#define DVSQ_MASK (0x7 << 4) /* Device State */ > #define POWER_STATE (0 << 4) > #define DEFAULT_STATE (1 << 4) > #define ADDRESS_STATE (2 << 4) > #define CONFIGURATION_STATE (3 << 4) > +#define SUSPENDED_STATE (4 << 4) > > #define CTSQ_MASK (0x7) /* Control Transfer Stage */ > #define IDLE_SETUP_STAGE 0 /* Idle stage or setup stage */ > diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c > index 34ee9ebe12a3..d8972ab3c2f9 100644 > --- a/drivers/usb/renesas_usbhs/mod_gadget.c > +++ b/drivers/usb/renesas_usbhs/mod_gadget.c > @@ -456,12 +456,18 @@ static int usbhsg_irq_dev_state(struct usbhs_priv *priv, > { > struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); > struct device *dev = usbhsg_gpriv_to_dev(gpriv); > + int state = usbhs_status_get_device_state(irq_state); > > gpriv->gadget.speed = usbhs_bus_get_speed(priv); > > - dev_dbg(dev, "state = %x : speed : %d\n", > - usbhs_status_get_device_state(irq_state), > - gpriv->gadget.speed); > + dev_dbg(dev, "state = %x : speed : %d\n", state, gpriv->gadget.speed); > + > + if (gpriv->gadget.speed != USB_SPEED_UNKNOWN && > + (state & SUSPENDED_STATE)) { > + if (gpriv->driver && gpriv->driver->suspend) > + gpriv->driver->suspend(&gpriv->gadget); > + usb_gadget_set_state(&gpriv->gadget, USB_STATE_SUSPENDED); > + } > > return 0; > } > -- > 2.7.4
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 3777af848a35..142319c7585d 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -159,11 +159,12 @@ struct usbhs_priv; #define VBSTS (1 << 7) /* VBUS_0 and VBUSIN_0 Input Status */ #define VALID (1 << 3) /* USB Request Receive */ -#define DVSQ_MASK (0x3 << 4) /* Device State */ +#define DVSQ_MASK (0x7 << 4) /* Device State */ #define POWER_STATE (0 << 4) #define DEFAULT_STATE (1 << 4) #define ADDRESS_STATE (2 << 4) #define CONFIGURATION_STATE (3 << 4) +#define SUSPENDED_STATE (4 << 4) #define CTSQ_MASK (0x7) /* Control Transfer Stage */ #define IDLE_SETUP_STAGE 0 /* Idle stage or setup stage */ diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 34ee9ebe12a3..d8972ab3c2f9 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -456,12 +456,18 @@ static int usbhsg_irq_dev_state(struct usbhs_priv *priv, { struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); struct device *dev = usbhsg_gpriv_to_dev(gpriv); + int state = usbhs_status_get_device_state(irq_state); gpriv->gadget.speed = usbhs_bus_get_speed(priv); - dev_dbg(dev, "state = %x : speed : %d\n", - usbhs_status_get_device_state(irq_state), - gpriv->gadget.speed); + dev_dbg(dev, "state = %x : speed : %d\n", state, gpriv->gadget.speed); + + if (gpriv->gadget.speed != USB_SPEED_UNKNOWN && + (state & SUSPENDED_STATE)) { + if (gpriv->driver && gpriv->driver->suspend) + gpriv->driver->suspend(&gpriv->gadget); + usb_gadget_set_state(&gpriv->gadget, USB_STATE_SUSPENDED); + } return 0; }