On Mon, Dec 30, 2019 at 04:39:47PM +0530, Nagarjuna Kristam wrote: > usb-phy is used to get notified on the USB role changes. Get usb-phy from > the utmi phy. s/utmi phy/UTMI PHY/ > > Signed-off-by: Nagarjuna Kristam > --- > V2-V3: > - No changes in this version > --- > drivers/usb/gadget/udc/tegra-xudc.c | 39 +++++++++++++++++++++++++++++++++---- > 1 file changed, 35 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c > index 6ddb974..0f27d57 100644 > --- a/drivers/usb/gadget/udc/tegra-xudc.c > +++ b/drivers/usb/gadget/udc/tegra-xudc.c > @@ -26,7 +26,9 @@ > #include > #include > #include > +#include > #include > +#include > #include > > /* XUSB_DEV registers */ > @@ -488,6 +490,9 @@ struct tegra_xudc { > bool suspended; > bool powergated; > > + struct usb_phy *usbphy; > + struct notifier_block vbus_nb; > + > struct completion disconnect_complete; > > bool selfpowered; > @@ -678,7 +683,22 @@ static void tegra_xudc_usb_role_sw_work(struct work_struct *work) > tegra_xudc_device_mode_on(xudc); > else > tegra_xudc_device_mode_off(xudc); > +} > + > +static int tegra_xudc_vbus_notifier(struct notifier_block *nb, > + unsigned long action, void *data) > +{ > + struct tegra_xudc *xudc = container_of(nb, struct tegra_xudc, > + vbus_nb); > + > + dev_dbg(xudc->dev, "%s action is %ld\n", __func__, action); I'd add the parentheses here, too. Maybe also a colon: "%s(): action is %ld\n" > + > + xudc->role = (enum usb_role)action; > > + if (!xudc->suspended) > + schedule_work(&xudc->usb_role_sw_work); > + > + return NOTIFY_OK; > } > > static void tegra_xudc_plc_reset_work(struct work_struct *work) > @@ -1949,6 +1969,9 @@ static int tegra_xudc_gadget_start(struct usb_gadget *gadget, > xudc_writel(xudc, val, CTRL); > } > > + if (xudc->usbphy) > + otg_set_peripheral(xudc->usbphy->otg, gadget); > + > xudc->driver = driver; > unlock: > dev_dbg(xudc->dev, "%s: ret value is %d", __func__, ret); > @@ -1969,6 +1992,9 @@ static int tegra_xudc_gadget_stop(struct usb_gadget *gadget) > > spin_lock_irqsave(&xudc->lock, flags); > > + if (xudc->usbphy) > + otg_set_peripheral(xudc->usbphy->otg, NULL); > + > val = xudc_readl(xudc, CTRL); > val &= ~(CTRL_IE | CTRL_ENABLE); > xudc_writel(xudc, val, CTRL); > @@ -3573,10 +3599,15 @@ static int tegra_xudc_probe(struct platform_device *pdev) > INIT_DELAYED_WORK(&xudc->port_reset_war_work, > tegra_xudc_port_reset_war_work); > > - /* Set the mode as device mode and this keeps phy always ON */ > - dev_info(xudc->dev, "Set usb role to device mode always"); This obsoletes my comment in the previous patch, but maybe consider not adding it in the first place. > - xudc->role = USB_ROLE_DEVICE; > - schedule_work(&xudc->usb_role_sw_work); > + xudc->vbus_nb.notifier_call = tegra_xudc_vbus_notifier; > + xudc->usbphy = devm_usb_get_phy_by_node(xudc->dev, > + xudc->utmi_phy->dev.of_node, > + &xudc->vbus_nb); > + if (IS_ERR(xudc->usbphy)) { > + err = PTR_ERR(xudc->usbphy); > + dev_err(xudc->dev, "failed to get usbphy phy: %d\n", err); I'd make this: "failed to get USB PHY: %d\n", which is easier to read than the above. Thierry > + goto free_eps; > + } > > pm_runtime_enable(&pdev->dev); > > -- > 2.7.4 >