Skip to content

Commit 715e4ce

Browse files
jfischer-nofabiobaltieri
authored andcommitted
drivers: udc_dwc2: prevent access to registers if USBHS is not ready
On USBHS, we cannot access the DWC2 register until VBUS is detected and valid. Kernel event API is used to block if a valid VBUS signal is not present when the user tries to force usbd_enable(). Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no> Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
1 parent acd2fa7 commit 715e4ce

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

drivers/usb/udc/udc_dwc2_vendor_quirks.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ DT_INST_FOREACH_STATUS_OKAY(QUIRK_STM32F4_FSOTG_DEFINE)
117117

118118
#define USBHS_DT_WRAPPER_REG_ADDR(n) UINT_TO_POINTER(DT_INST_REG_ADDR_BY_NAME(n, wrapper))
119119

120+
/*
121+
* On USBHS, we cannot access the DWC2 register until VBUS is detected and
122+
* valid. If the user tries to force usbd_enable() and the corresponding
123+
* udc_enable() without a "VBUS ready" notification, the event wait will block
124+
* until a valid VBUS signal is detected.
125+
*/
126+
static K_EVENT_DEFINE(usbhs_events);
127+
#define USBHS_VBUS_READY BIT(0)
128+
120129
static void usbhs_vbus_handler(nrfs_usb_evt_t const *p_evt, void *const context)
121130
{
122131
const struct device *dev = context;
@@ -127,8 +136,10 @@ static void usbhs_vbus_handler(nrfs_usb_evt_t const *p_evt, void *const context)
127136
p_evt->usbhspll_ok, p_evt->vregusb_ok, p_evt->vbus_detected);
128137

129138
if (p_evt->usbhspll_ok && p_evt->vregusb_ok && p_evt->vbus_detected) {
139+
k_event_post(&usbhs_events, USBHS_VBUS_READY);
130140
udc_submit_event(dev, UDC_EVT_VBUS_READY, 0);
131141
} else {
142+
k_event_set_masked(&usbhs_events, 0, USBHS_VBUS_READY);
132143
udc_submit_event(dev, UDC_EVT_VBUS_REMOVED, 0);
133144
}
134145

@@ -172,6 +183,11 @@ static inline int usbhs_enable_core(const struct device *dev)
172183
{
173184
NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0);
174185

186+
if (!k_event_wait(&usbhs_events, USBHS_VBUS_READY, false, K_NO_WAIT)) {
187+
LOG_WRN("VBUS is not ready, block udc_enable()");
188+
k_event_wait(&usbhs_events, USBHS_VBUS_READY, false, K_FOREVER);
189+
}
190+
175191
wrapper->ENABLE = USBHS_ENABLE_PHY_Msk | USBHS_ENABLE_CORE_Msk;
176192
wrapper->TASKS_START = 1UL;
177193

0 commit comments

Comments
 (0)