summaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea
diff options
context:
space:
mode:
authorXu Yang <xu.yang_2@nxp.com>2023-06-27 19:03:51 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-07-25 18:24:17 +0200
commitb7a62611fab72e585c729a7fcf666aa9c4144214 (patch)
tree864f36813025245f0176a183acd885bd6f48c012 /drivers/usb/chipidea
parent7713aaf464599091d7a43fdae69fd69f0dd942f9 (diff)
downloadlinux-stable-b7a62611fab72e585c729a7fcf666aa9c4144214.tar.gz
linux-stable-b7a62611fab72e585c729a7fcf666aa9c4144214.tar.bz2
linux-stable-b7a62611fab72e585c729a7fcf666aa9c4144214.zip
usb: chipidea: add USB PHY event
Add USB PHY event for below situation: - usb role changed - vbus connect - vbus disconnect - gadget driver is enumerated USB PHY driver can get the last event after above situation occurs and deal with different situations. Signed-off-by: Xu Yang <xu.yang_2@nxp.com> Acked-by: Peter Chen <peter.chen@kernel.org> Link: https://lore.kernel.org/r/20230627110353.1879477-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/chipidea')
-rw-r--r--drivers/usb/chipidea/ci.h18
-rw-r--r--drivers/usb/chipidea/udc.c10
2 files changed, 26 insertions, 2 deletions
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index f210b7489fd5..d262b9df7b3d 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -281,8 +281,19 @@ static inline int ci_role_start(struct ci_hdrc *ci, enum ci_role role)
return -ENXIO;
ret = ci->roles[role]->start(ci);
- if (!ret)
- ci->role = role;
+ if (ret)
+ return ret;
+
+ ci->role = role;
+
+ if (ci->usb_phy) {
+ if (role == CI_ROLE_HOST)
+ usb_phy_set_event(ci->usb_phy, USB_EVENT_ID);
+ else
+ /* in device mode but vbus is invalid*/
+ usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE);
+ }
+
return ret;
}
@@ -296,6 +307,9 @@ static inline void ci_role_stop(struct ci_hdrc *ci)
ci->role = CI_ROLE_END;
ci->roles[role]->stop(ci);
+
+ if (ci->usb_phy)
+ usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE);
}
static inline enum usb_role ci_role_to_usb_role(struct ci_hdrc *ci)
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 54c09245ad05..d58355427eeb 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1718,6 +1718,13 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
ret = ci->platdata->notify_event(ci,
CI_HDRC_CONTROLLER_VBUS_EVENT);
+ if (ci->usb_phy) {
+ if (is_active)
+ usb_phy_set_event(ci->usb_phy, USB_EVENT_VBUS);
+ else
+ usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE);
+ }
+
if (ci->driver)
ci_hdrc_gadget_connect(_gadget, is_active);
@@ -2034,6 +2041,9 @@ static irqreturn_t udc_irq(struct ci_hdrc *ci)
if (USBi_PCI & intr) {
ci->gadget.speed = hw_port_is_high_speed(ci) ?
USB_SPEED_HIGH : USB_SPEED_FULL;
+ if (ci->usb_phy)
+ usb_phy_set_event(ci->usb_phy,
+ USB_EVENT_ENUMERATED);
if (ci->suspended) {
if (ci->driver->resume) {
spin_unlock(&ci->lock);