mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
usb: dwc_otg: fix issue with race condition of competition
between hcd_reinit() and cil_interrupt handler. hcd_reinit() should get core_if->lock before modify this lock, so that can prevent competition between cil_interrupt handler and hcd_reinit(), hcd_reinit() be scheduled while cil_interrupt handler holding core_if->lock, hcd_reinit() modify the lock then previous core_if->lock will never be unlocked. Signed-off-by: lyz <lyz@rock-chips.com>
This commit is contained in:
@@ -966,9 +966,9 @@ static void dwc_otg_hcd_reinit(dwc_otg_hcd_t *hcd)
|
||||
dwc_hc_t *channel;
|
||||
dwc_hc_t *channel_tmp;
|
||||
dwc_irqflags_t flags;
|
||||
dwc_spinlock_t *temp_lock;
|
||||
|
||||
hcd->flags.d32 = 0;
|
||||
|
||||
hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
|
||||
hcd->non_periodic_channels = 0;
|
||||
hcd->periodic_channels = 0;
|
||||
@@ -995,7 +995,15 @@ static void dwc_otg_hcd_reinit(dwc_otg_hcd_t *hcd)
|
||||
dwc_otg_core_host_init(hcd->core_if);
|
||||
|
||||
/* Set core_if's lock pointer to the hcd->lock */
|
||||
hcd->core_if->lock = hcd->lock;
|
||||
/* Should get this lock before modify it */
|
||||
if (hcd->core_if->lock) {
|
||||
DWC_SPINLOCK_IRQSAVE(hcd->core_if->lock, &flags);
|
||||
temp_lock = hcd->core_if->lock;
|
||||
hcd->core_if->lock = hcd->lock;
|
||||
DWC_SPINUNLOCK_IRQRESTORE(temp_lock, flags);
|
||||
} else {
|
||||
hcd->core_if->lock = hcd->lock;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user