Skip to content

Commit 96c253e

Browse files
author
Josuah Demangeon
committed
handle regression events sparately
Move as much as the non-critical logic as possible on the event handler rather than the ISR Signed-off-by: Josuah Demangeon <[email protected]>
1 parent c57a780 commit 96c253e

File tree

1 file changed

+40
-26
lines changed

1 file changed

+40
-26
lines changed

drivers/usb/uhc/uhc_dwc2.c

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -889,45 +889,21 @@ static void uhc_dwc2_isr_handler(const struct device *dev)
889889
core_intrs = sys_read32((mem_addr_t)&dwc2->gintsts);
890890
sys_write32(core_intrs, (mem_addr_t)&dwc2->gintsts);
891891

892+
LOG_DBG("GINTSTS=%08Xh, HPRT=%08Xh", core_intrs, port_intrs);
893+
892894
if (core_intrs & USB_DWC2_GINTSTS_PRTINT) {
893895
port_intrs = sys_read32((mem_addr_t)&dwc2->hprt);
894896
/* Clear the interrupt status by writing 1 to the W1C bits, except the PRTENA bit */
895897
sys_write32(port_intrs & (~USB_DWC2_HPRT_PRTENA), (mem_addr_t)&dwc2->hprt);
896898
}
897899

898-
LOG_DBG("GINTSTS=%08Xh, HPRT=%08Xh", core_intrs, port_intrs);
899-
900-
/* Note:
901-
* Do not change order of checks. Regressing events (e.g. enable -> disabled,
902-
* connected -> disconnected) always take precedence.
903-
*/
904900
if (core_intrs & USB_DWC2_GINTSTS_DISCONNINT) {
905901
/* Disconnect event */
906902
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_DISCONNECTION));
907903
uhc_dwc2_debounce_enable(dev);
908904
/* Port still connected, check port event */
909-
} else if (port_intrs & USB_DWC2_HPRT_PRTOVRCURRCHNG) {
910-
/* Check if this is an overcurrent or an overcurrent cleared */
911-
if (port_intrs & USB_DWC2_HPRT_PRTOVRCURRACT) {
912-
/* TODO: Verify handling logic during overcurrent */
913-
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_OVERCURRENT));
914-
} else {
915-
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_OVERCURRENT_CLEAR));
916-
}
917-
} else if (port_intrs & USB_DWC2_HPRT_PRTENCHNG) {
918-
if (port_intrs & USB_DWC2_HPRT_PRTENA) {
919-
/* Host port was enabled */
920-
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_ENABLED));
921-
} else {
922-
/* Host port has been disabled */
923-
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_DISABLED));
924-
}
925-
} else if (port_intrs & USB_DWC2_HPRT_PRTCONNDET && !priv->debouncing) {
926-
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_CONNECTION));
927-
uhc_dwc2_debounce_enable(dev);
928905
}
929906

930-
/* Port events always take precedence over channel events */
931907
if (core_intrs & USB_DWC2_GINTSTS_HCHINT) {
932908
/* One or more channels have pending interrupts. Store the mask of those channels */
933909
channels = sys_read32((mem_addr_t)&dwc2->haint);
@@ -947,6 +923,31 @@ static void uhc_dwc2_isr_handler(const struct device *dev)
947923
}
948924
}
949925

926+
if (port_intrs & USB_DWC2_HPRT_PRTOVRCURRCHNG) {
927+
/* Check if this is an overcurrent or an overcurrent cleared */
928+
if (port_intrs & USB_DWC2_HPRT_PRTOVRCURRACT) {
929+
/* TODO: Verify handling logic during overcurrent */
930+
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_OVERCURRENT));
931+
} else {
932+
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_OVERCURRENT_CLEAR));
933+
}
934+
}
935+
936+
if (port_intrs & USB_DWC2_HPRT_PRTENCHNG) {
937+
if (port_intrs & USB_DWC2_HPRT_PRTENA) {
938+
/* Host port was enabled */
939+
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_ENABLED));
940+
} else {
941+
/* Host port has been disabled */
942+
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_DISABLED));
943+
}
944+
}
945+
946+
if (port_intrs & USB_DWC2_HPRT_PRTCONNDET && !priv->debouncing) {
947+
k_event_set(&priv->event, BIT(UHC_DWC2_EVENT_CONNECTION));
948+
uhc_dwc2_debounce_enable(dev);
949+
}
950+
950951
(void)uhc_dwc2_quirk_irq_clear(dev);
951952
}
952953

@@ -1204,6 +1205,19 @@ static inline void uhc_dwc2_handle_port_events(const struct device *dev, uint32_
12041205

12051206
LOG_DBG("Port events: 0x08%x", events);
12061207

1208+
/* Note:
1209+
* Regressing events (e.g. enable -> disabled, connected -> disconnected) always
1210+
* take precedence.
1211+
*/
1212+
if ((events & BIT(UHC_DWC2_EVENT_ENABLED)) &&
1213+
(events & BIT(UHC_DWC2_EVENT_DISABLED))) {
1214+
events &= ~BIT(UHC_DWC2_EVENT_ENABLED);
1215+
}
1216+
if ((events & BIT(UHC_DWC2_EVENT_CONNECTION)) &&
1217+
(events & BIT(UHC_DWC2_EVENT_DISCONNECTION))) {
1218+
events &= ~BIT(UHC_DWC2_EVENT_CONNECTION);
1219+
}
1220+
12071221
if (events & BIT(UHC_DWC2_EVENT_ENABLED)) {
12081222
/* Initialize remaining host port registers */
12091223
dwc2_port_enable(dev);

0 commit comments

Comments
 (0)