From 29d4eacf5258e197aba417e9b1b2abe620215afe Mon Sep 17 00:00:00 2001 From: Linyu Yuan Date: Thu, 18 Mar 2021 10:42:41 +0800 Subject: [PATCH] usb: dwc3: fix msm_dwc3_perf_vote_work() there is error when one static variable last_irq_cnt used for multiple dwc3 instance. Change-Id: I93201baec84a208d72ac4f4316eb50013e40a4da Signed-off-by: Linyu Yuan --- drivers/usb/dwc3/core.h | 2 +- drivers/usb/dwc3/dwc3-msm.c | 16 ++++++++-------- drivers/usb/dwc3/gadget.c | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index ce6f601c67de..1fda5cd9bc14 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1382,7 +1382,7 @@ struct dwc3 { /* IRQ timing statistics */ int irq; - unsigned long irq_cnt; + atomic_t irq_cnt; ktime_t bh_start_time[MAX_INTR_STATS]; unsigned int bh_completion_time[MAX_INTR_STATS]; unsigned int bh_handled_evt_cnt[MAX_INTR_STATS]; diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 68080bf4a557..21804573c574 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -521,6 +521,8 @@ struct dwc3_msm { struct device_node *ss_redriver_node; bool dual_port; + + bool perf_mode; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ @@ -2366,7 +2368,7 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, case DWC3_CONTROLLER_ERROR_EVENT: dev_info(mdwc->dev, "DWC3_CONTROLLER_ERROR_EVENT received, irq cnt %lu\n", - dwc->irq_cnt); + atomic_read(&dwc->irq_cnt)); dwc3_msm_write_reg(mdwc->base, DWC3_DEVTEN, 0x00); @@ -5056,10 +5058,9 @@ static int dwc3_msm_host_notifier(struct notifier_block *nb, static void msm_dwc3_perf_vote_update(struct dwc3_msm *mdwc, bool perf_mode) { - static bool curr_perf_mode; int latency = mdwc->pm_qos_latency; - if ((curr_perf_mode == perf_mode) || !latency) + if ((mdwc->perf_mode == perf_mode) || !latency) return; if (perf_mode) @@ -5068,7 +5069,7 @@ static void msm_dwc3_perf_vote_update(struct dwc3_msm *mdwc, bool perf_mode) pm_qos_update_request(&mdwc->pm_qos_req_dma, PM_QOS_DEFAULT_VALUE); - curr_perf_mode = perf_mode; + mdwc->perf_mode = perf_mode; pr_debug("%s: latency updated to: %d\n", __func__, perf_mode ? latency : PM_QOS_DEFAULT_VALUE); } @@ -5078,16 +5079,15 @@ static void msm_dwc3_perf_vote_work(struct work_struct *w) struct dwc3_msm *mdwc = container_of(w, struct dwc3_msm, perf_vote_work.work); struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); - static unsigned long last_irq_cnt; + unsigned int irq_cnt = atomic_xchg(&dwc->irq_cnt, 0); bool in_perf_mode = false; - if (dwc->irq_cnt - last_irq_cnt >= PM_QOS_THRESHOLD) + if (irq_cnt >= PM_QOS_THRESHOLD) in_perf_mode = true; pr_debug("%s: in_perf_mode:%u, interrupts in last sample:%lu\n", - __func__, in_perf_mode, (dwc->irq_cnt - last_irq_cnt)); + __func__, in_perf_mode, irq_cnt); - last_irq_cnt = dwc->irq_cnt; msm_dwc3_perf_vote_update(mdwc, in_perf_mode); schedule_delayed_work(&mdwc->perf_vote_work, msecs_to_jiffies(1000 * PM_QOS_SAMPLE_SEC)); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 2fafcc244f66..d7cc25635afc 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -4107,7 +4107,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt) dwc = evt->dwc; start_time = ktime_get(); - dwc->irq_cnt++; + atomic_inc(&dwc->irq_cnt); /* controller reset is still pending */ if (dwc->err_evt_seen)