]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Jun 2021 15:34:33 +0000 (17:34 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Jun 2021 15:34:33 +0000 (17:34 +0200)
added patches:
arm-omap-replace-setup_irq-by-request_irq.patch
clocksource-drivers-timer-ti-dm-add-clockevent-and-clocksource-support.patch
clocksource-drivers-timer-ti-dm-handle-dra7-timer-wrap-errata-i940.patch
clocksource-drivers-timer-ti-dm-prepare-to-handle-dra7-timer-wrap-issue.patch
kvm-arm-arm64-fix-kvm_vgic_v3_addr_type_redist-read.patch
usb-dwc3-core-fix-kernel-panic-when-do-reboot.patch
usb-dwc3-debugfs-add-and-remove-endpoint-dirs-dynamically.patch

queue-5.4/arm-omap-replace-setup_irq-by-request_irq.patch [new file with mode: 0644]
queue-5.4/clocksource-drivers-timer-ti-dm-add-clockevent-and-clocksource-support.patch [new file with mode: 0644]
queue-5.4/clocksource-drivers-timer-ti-dm-handle-dra7-timer-wrap-errata-i940.patch [new file with mode: 0644]
queue-5.4/clocksource-drivers-timer-ti-dm-prepare-to-handle-dra7-timer-wrap-issue.patch [new file with mode: 0644]
queue-5.4/kvm-arm-arm64-fix-kvm_vgic_v3_addr_type_redist-read.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/usb-dwc3-core-fix-kernel-panic-when-do-reboot.patch [new file with mode: 0644]
queue-5.4/usb-dwc3-debugfs-add-and-remove-endpoint-dirs-dynamically.patch [new file with mode: 0644]

diff --git a/queue-5.4/arm-omap-replace-setup_irq-by-request_irq.patch b/queue-5.4/arm-omap-replace-setup_irq-by-request_irq.patch
new file mode 100644 (file)
index 0000000..167b599
--- /dev/null
@@ -0,0 +1,141 @@
+From foo@baz Mon Jun 21 05:29:17 PM CEST 2021
+From: Tony Lindgren <tony@atomide.com>
+Date: Wed, 16 Jun 2021 15:31:09 +0300
+Subject: ARM: OMAP: replace setup_irq() by request_irq()
+To: stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, afzal mohammed <afzal.mohd.ma@gmail.com>, Daniel Lezcano <daniel.lezcano@linaro.org>, Keerthy <j-keerthy@ti.com>, Tero Kristo <kristo@kernel.org>
+Message-ID: <20210616123112.65068-1-tony@atomide.com>
+
+From: afzal mohammed <afzal.mohd.ma@gmail.com>
+
+commit b75ca5217743e4d7076cf65e044e88389e44318d upstream.
+
+request_irq() is preferred over setup_irq(). Invocations of setup_irq()
+occur after memory allocators are ready.
+
+Per tglx[1], setup_irq() existed in olden days when allocators were not
+ready by the time early interrupts were initialized.
+
+Hence replace setup_irq() by request_irq().
+
+[1] https://lkml.kernel.org/r/alpine.DEB.2.20.1710191609480.1971@nanos
+
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Keerthy <j-keerthy@ti.com>
+Cc: Tero Kristo <kristo@kernel.org>
+Signed-off-by: afzal mohammed <afzal.mohd.ma@gmail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/mach-omap1/pm.c       |   13 ++++++-------
+ arch/arm/mach-omap1/time.c     |   10 +++-------
+ arch/arm/mach-omap1/timer32k.c |   10 +++-------
+ arch/arm/mach-omap2/timer.c    |   11 +++--------
+ 4 files changed, 15 insertions(+), 29 deletions(-)
+
+--- a/arch/arm/mach-omap1/pm.c
++++ b/arch/arm/mach-omap1/pm.c
+@@ -596,11 +596,6 @@ static irqreturn_t omap_wakeup_interrupt
+       return IRQ_HANDLED;
+ }
+-static struct irqaction omap_wakeup_irq = {
+-      .name           = "peripheral wakeup",
+-      .handler        = omap_wakeup_interrupt
+-};
+-
+ static const struct platform_suspend_ops omap_pm_ops = {
+@@ -613,6 +608,7 @@ static const struct platform_suspend_ops
+ static int __init omap_pm_init(void)
+ {
+       int error = 0;
++      int irq;
+       if (!cpu_class_is_omap1())
+               return -ENODEV;
+@@ -656,9 +652,12 @@ static int __init omap_pm_init(void)
+       arm_pm_idle = omap1_pm_idle;
+       if (cpu_is_omap7xx())
+-              setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq);
++              irq = INT_7XX_WAKE_UP_REQ;
+       else if (cpu_is_omap16xx())
+-              setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
++              irq = INT_1610_WAKE_UP_REQ;
++      if (request_irq(irq, omap_wakeup_interrupt, 0, "peripheral wakeup",
++                      NULL))
++              pr_err("Failed to request irq %d (peripheral wakeup)\n", irq);
+       /* Program new power ramp-up time
+        * (0 for most boards since we don't lower voltage when in deep sleep)
+--- a/arch/arm/mach-omap1/time.c
++++ b/arch/arm/mach-omap1/time.c
+@@ -155,15 +155,11 @@ static irqreturn_t omap_mpu_timer1_inter
+       return IRQ_HANDLED;
+ }
+-static struct irqaction omap_mpu_timer1_irq = {
+-      .name           = "mpu_timer1",
+-      .flags          = IRQF_TIMER | IRQF_IRQPOLL,
+-      .handler        = omap_mpu_timer1_interrupt,
+-};
+-
+ static __init void omap_init_mpu_timer(unsigned long rate)
+ {
+-      setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
++      if (request_irq(INT_TIMER1, omap_mpu_timer1_interrupt,
++                      IRQF_TIMER | IRQF_IRQPOLL, "mpu_timer1", NULL))
++              pr_err("Failed to request irq %d (mpu_timer1)\n", INT_TIMER1);
+       omap_mpu_timer_start(0, (rate / HZ) - 1, 1);
+       clockevent_mpu_timer1.cpumask = cpumask_of(0);
+--- a/arch/arm/mach-omap1/timer32k.c
++++ b/arch/arm/mach-omap1/timer32k.c
+@@ -148,15 +148,11 @@ static irqreturn_t omap_32k_timer_interr
+       return IRQ_HANDLED;
+ }
+-static struct irqaction omap_32k_timer_irq = {
+-      .name           = "32KHz timer",
+-      .flags          = IRQF_TIMER | IRQF_IRQPOLL,
+-      .handler        = omap_32k_timer_interrupt,
+-};
+-
+ static __init void omap_init_32k_timer(void)
+ {
+-      setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
++      if (request_irq(INT_OS_TIMER, omap_32k_timer_interrupt,
++                      IRQF_TIMER | IRQF_IRQPOLL, "32KHz timer", NULL))
++              pr_err("Failed to request irq %d(32KHz timer)\n", INT_OS_TIMER);
+       clockevent_32k_timer.cpumask = cpumask_of(0);
+       clockevents_config_and_register(&clockevent_32k_timer,
+--- a/arch/arm/mach-omap2/timer.c
++++ b/arch/arm/mach-omap2/timer.c
+@@ -91,12 +91,6 @@ static irqreturn_t omap2_gp_timer_interr
+       return IRQ_HANDLED;
+ }
+-static struct irqaction omap2_gp_timer_irq = {
+-      .name           = "gp_timer",
+-      .flags          = IRQF_TIMER | IRQF_IRQPOLL,
+-      .handler        = omap2_gp_timer_interrupt,
+-};
+-
+ static int omap2_gp_timer_set_next_event(unsigned long cycles,
+                                        struct clock_event_device *evt)
+ {
+@@ -382,8 +376,9 @@ static void __init omap2_gp_clockevent_i
+                                    &clockevent_gpt.name, OMAP_TIMER_POSTED);
+       BUG_ON(res);
+-      omap2_gp_timer_irq.dev_id = &clkev;
+-      setup_irq(clkev.irq, &omap2_gp_timer_irq);
++      if (request_irq(clkev.irq, omap2_gp_timer_interrupt,
++                      IRQF_TIMER | IRQF_IRQPOLL, "gp_timer", &clkev))
++              pr_err("Failed to request irq %d (gp_timer)\n", clkev.irq);
+       __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
diff --git a/queue-5.4/clocksource-drivers-timer-ti-dm-add-clockevent-and-clocksource-support.patch b/queue-5.4/clocksource-drivers-timer-ti-dm-add-clockevent-and-clocksource-support.patch
new file mode 100644 (file)
index 0000000..9aa6e42
--- /dev/null
@@ -0,0 +1,241 @@
+From foo@baz Mon Jun 21 05:29:17 PM CEST 2021
+From: Tony Lindgren <tony@atomide.com>
+Date: Wed, 16 Jun 2021 15:31:10 +0300
+Subject: clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support
+To: stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, Daniel Lezcano <daniel.lezcano@linaro.org>, Keerthy <j-keerthy@ti.com>, Tero Kristo <kristo@kernel.org>
+Message-ID: <20210616123112.65068-2-tony@atomide.com>
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit 52762fbd1c4778ac9b173624ca0faacd22ef4724 upstream.
+
+We can move the TI dmtimer clockevent and clocksource to live under
+drivers/clocksource if we rely only on the clock framework, and handle
+the module configuration directly in the clocksource driver based on the
+device tree data.
+
+This removes the early dependency with system timers to the interconnect
+related code, and we can probe pretty much everything else later on at
+the module_init level.
+
+Let's first add a new driver for timer-ti-dm-systimer based on existing
+arch/arm/mach-omap2/timer.c. Then let's start moving SoCs to probe with
+device tree data while still keeping the old timer.c. And eventually we
+can just drop the old timer.c.
+
+Let's take the opportunity to switch to use readl/writel as pointed out
+by Daniel Lezcano <daniel.lezcano@linaro.org>. This allows further
+clean-up of the timer-ti-dm code the a lot of the shared helpers can
+just become static to the non-syster related code.
+
+Note the boards can optionally configure different timer source clocks
+if needed with assigned-clocks and assigned-clock-parents.
+
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Keerthy <j-keerthy@ti.com>
+Cc: Tero Kristo <kristo@kernel.org>
+[tony@atomide.com: backported to 5.4.y]
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/mach-omap2/timer.c |  109 ++++++++++++++++++++++++++------------------
+ 1 file changed, 65 insertions(+), 44 deletions(-)
+
+--- a/arch/arm/mach-omap2/timer.c
++++ b/arch/arm/mach-omap2/timer.c
+@@ -63,15 +63,28 @@
+ /* Clockevent code */
+-static struct omap_dm_timer clkev;
+-static struct clock_event_device clockevent_gpt;
+-
+ /* Clockevent hwmod for am335x and am437x suspend */
+ static struct omap_hwmod *clockevent_gpt_hwmod;
+ /* Clockesource hwmod for am437x suspend */
+ static struct omap_hwmod *clocksource_gpt_hwmod;
++struct dmtimer_clockevent {
++      struct clock_event_device dev;
++      struct omap_dm_timer timer;
++};
++
++static struct dmtimer_clockevent clockevent;
++
++static struct omap_dm_timer *to_dmtimer(struct clock_event_device *clockevent)
++{
++      struct dmtimer_clockevent *clkevt =
++              container_of(clockevent, struct dmtimer_clockevent, dev);
++      struct omap_dm_timer *timer = &clkevt->timer;
++
++      return timer;
++}
++
+ #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
+ static unsigned long arch_timer_freq;
+@@ -83,10 +96,11 @@ void set_cntfreq(void)
+ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
+ {
+-      struct clock_event_device *evt = &clockevent_gpt;
+-
+-      __omap_dm_timer_write_status(&clkev, OMAP_TIMER_INT_OVERFLOW);
++      struct dmtimer_clockevent *clkevt = dev_id;
++      struct clock_event_device *evt = &clkevt->dev;
++      struct omap_dm_timer *timer = &clkevt->timer;
++      __omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW);
+       evt->event_handler(evt);
+       return IRQ_HANDLED;
+ }
+@@ -94,7 +108,9 @@ static irqreturn_t omap2_gp_timer_interr
+ static int omap2_gp_timer_set_next_event(unsigned long cycles,
+                                        struct clock_event_device *evt)
+ {
+-      __omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST,
++      struct omap_dm_timer *timer = to_dmtimer(evt);
++
++      __omap_dm_timer_load_start(timer, OMAP_TIMER_CTRL_ST,
+                                  0xffffffff - cycles, OMAP_TIMER_POSTED);
+       return 0;
+@@ -102,22 +118,26 @@ static int omap2_gp_timer_set_next_event
+ static int omap2_gp_timer_shutdown(struct clock_event_device *evt)
+ {
+-      __omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate);
++      struct omap_dm_timer *timer = to_dmtimer(evt);
++
++      __omap_dm_timer_stop(timer, OMAP_TIMER_POSTED, timer->rate);
++
+       return 0;
+ }
+ static int omap2_gp_timer_set_periodic(struct clock_event_device *evt)
+ {
++      struct omap_dm_timer *timer = to_dmtimer(evt);
+       u32 period;
+-      __omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate);
++      __omap_dm_timer_stop(timer, OMAP_TIMER_POSTED, timer->rate);
+-      period = clkev.rate / HZ;
++      period = timer->rate / HZ;
+       period -= 1;
+       /* Looks like we need to first set the load value separately */
+-      __omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG, 0xffffffff - period,
++      __omap_dm_timer_write(timer, OMAP_TIMER_LOAD_REG, 0xffffffff - period,
+                             OMAP_TIMER_POSTED);
+-      __omap_dm_timer_load_start(&clkev,
++      __omap_dm_timer_load_start(timer,
+                                  OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
+                                  0xffffffff - period, OMAP_TIMER_POSTED);
+       return 0;
+@@ -131,26 +151,17 @@ static void omap_clkevt_idle(struct cloc
+       omap_hwmod_idle(clockevent_gpt_hwmod);
+ }
+-static void omap_clkevt_unidle(struct clock_event_device *unused)
++static void omap_clkevt_unidle(struct clock_event_device *evt)
+ {
++      struct omap_dm_timer *timer = to_dmtimer(evt);
++
+       if (!clockevent_gpt_hwmod)
+               return;
+       omap_hwmod_enable(clockevent_gpt_hwmod);
+-      __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
++      __omap_dm_timer_int_enable(timer, OMAP_TIMER_INT_OVERFLOW);
+ }
+-static struct clock_event_device clockevent_gpt = {
+-      .features               = CLOCK_EVT_FEAT_PERIODIC |
+-                                CLOCK_EVT_FEAT_ONESHOT,
+-      .rating                 = 300,
+-      .set_next_event         = omap2_gp_timer_set_next_event,
+-      .set_state_shutdown     = omap2_gp_timer_shutdown,
+-      .set_state_periodic     = omap2_gp_timer_set_periodic,
+-      .set_state_oneshot      = omap2_gp_timer_shutdown,
+-      .tick_resume            = omap2_gp_timer_shutdown,
+-};
+-
+ static const struct of_device_id omap_timer_match[] __initconst = {
+       { .compatible = "ti,omap2420-timer", },
+       { .compatible = "ti,omap3430-timer", },
+@@ -360,44 +371,54 @@ static void __init omap2_gp_clockevent_i
+                                               const char *fck_source,
+                                               const char *property)
+ {
++      struct dmtimer_clockevent *clkevt = &clockevent;
++      struct omap_dm_timer *timer = &clkevt->timer;
+       int res;
+-      clkev.id = gptimer_id;
+-      clkev.errata = omap_dm_timer_get_errata();
++      timer->id = gptimer_id;
++      timer->errata = omap_dm_timer_get_errata();
++      clkevt->dev.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
++      clkevt->dev.rating = 300;
++      clkevt->dev.set_next_event = omap2_gp_timer_set_next_event;
++      clkevt->dev.set_state_shutdown = omap2_gp_timer_shutdown;
++      clkevt->dev.set_state_periodic = omap2_gp_timer_set_periodic;
++      clkevt->dev.set_state_oneshot = omap2_gp_timer_shutdown;
++      clkevt->dev.tick_resume = omap2_gp_timer_shutdown;
+       /*
+        * For clock-event timers we never read the timer counter and
+        * so we are not impacted by errata i103 and i767. Therefore,
+        * we can safely ignore this errata for clock-event timers.
+        */
+-      __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767);
++      __omap_dm_timer_override_errata(timer, OMAP_TIMER_ERRATA_I103_I767);
+-      res = omap_dm_timer_init_one(&clkev, fck_source, property,
+-                                   &clockevent_gpt.name, OMAP_TIMER_POSTED);
++      res = omap_dm_timer_init_one(timer, fck_source, property,
++                                   &clkevt->dev.name, OMAP_TIMER_POSTED);
+       BUG_ON(res);
+-      if (request_irq(clkev.irq, omap2_gp_timer_interrupt,
+-                      IRQF_TIMER | IRQF_IRQPOLL, "gp_timer", &clkev))
+-              pr_err("Failed to request irq %d (gp_timer)\n", clkev.irq);
+-
+-      __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
+-
+-      clockevent_gpt.cpumask = cpu_possible_mask;
+-      clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev);
+-      clockevents_config_and_register(&clockevent_gpt, clkev.rate,
++      clkevt->dev.cpumask = cpu_possible_mask;
++      clkevt->dev.irq = omap_dm_timer_get_irq(timer);
++
++      if (request_irq(timer->irq, omap2_gp_timer_interrupt,
++                      IRQF_TIMER | IRQF_IRQPOLL, "gp_timer", clkevt))
++              pr_err("Failed to request irq %d (gp_timer)\n", timer->irq);
++
++      __omap_dm_timer_int_enable(timer, OMAP_TIMER_INT_OVERFLOW);
++
++      clockevents_config_and_register(&clkevt->dev, timer->rate,
+                                       3, /* Timer internal resynch latency */
+                                       0xffffffff);
+       if (soc_is_am33xx() || soc_is_am43xx()) {
+-              clockevent_gpt.suspend = omap_clkevt_idle;
+-              clockevent_gpt.resume = omap_clkevt_unidle;
++              clkevt->dev.suspend = omap_clkevt_idle;
++              clkevt->dev.resume = omap_clkevt_unidle;
+               clockevent_gpt_hwmod =
+-                      omap_hwmod_lookup(clockevent_gpt.name);
++                      omap_hwmod_lookup(clkevt->dev.name);
+       }
+-      pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name,
+-              clkev.rate);
++      pr_info("OMAP clockevent source: %s at %lu Hz\n", clkevt->dev.name,
++              timer->rate);
+ }
+ /* Clocksource code */
diff --git a/queue-5.4/clocksource-drivers-timer-ti-dm-handle-dra7-timer-wrap-errata-i940.patch b/queue-5.4/clocksource-drivers-timer-ti-dm-handle-dra7-timer-wrap-errata-i940.patch
new file mode 100644 (file)
index 0000000..c1852b3
--- /dev/null
@@ -0,0 +1,219 @@
+From foo@baz Mon Jun 21 05:29:17 PM CEST 2021
+From: Tony Lindgren <tony@atomide.com>
+Date: Wed, 16 Jun 2021 15:31:12 +0300
+Subject: clocksource/drivers/timer-ti-dm: Handle dra7 timer wrap errata i940
+To: stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, Daniel Lezcano <daniel.lezcano@linaro.org>, Keerthy <j-keerthy@ti.com>, Tero Kristo <kristo@kernel.org>
+Message-ID: <20210616123112.65068-4-tony@atomide.com>
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit 25de4ce5ed02994aea8bc111d133308f6fd62566 upstream.
+
+There is a timer wrap issue on dra7 for the ARM architected timer.
+In a typical clock configuration the timer fails to wrap after 388 days.
+
+To work around the issue, we need to use timer-ti-dm percpu timers instead.
+
+Let's configure dmtimer3 and 4 as percpu timers by default, and warn about
+the issue if the dtb is not configured properly.
+
+For more information, please see the errata for "AM572x Sitara Processors
+Silicon Revisions 1.1, 2.0":
+
+https://www.ti.com/lit/er/sprz429m/sprz429m.pdf
+
+The concept is based on earlier reference patches done by Tero Kristo and
+Keerthy.
+
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Keerthy <j-keerthy@ti.com>
+Cc: Tero Kristo <kristo@kernel.org>
+[tony@atomide.com: backported to 5.4.y]
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/boot/dts/dra7-l4.dtsi      |    4 +-
+ arch/arm/boot/dts/dra7.dtsi         |   20 +++++++++++++
+ arch/arm/mach-omap2/board-generic.c |    4 +-
+ arch/arm/mach-omap2/timer.c         |   53 +++++++++++++++++++++++++++++++++++-
+ drivers/clk/ti/clk-7xx.c            |    1 
+ include/linux/cpuhotplug.h          |    1 
+ 6 files changed, 78 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/boot/dts/dra7-l4.dtsi
++++ b/arch/arm/boot/dts/dra7-l4.dtsi
+@@ -1176,7 +1176,7 @@
+                       };
+               };
+-              target-module@34000 {                   /* 0x48034000, ap 7 46.0 */
++              timer3_target: target-module@34000 {    /* 0x48034000, ap 7 46.0 */
+                       compatible = "ti,sysc-omap4-timer", "ti,sysc";
+                       ti,hwmods = "timer3";
+                       reg = <0x34000 0x4>,
+@@ -1204,7 +1204,7 @@
+                       };
+               };
+-              target-module@36000 {                   /* 0x48036000, ap 9 4e.0 */
++              timer4_target: target-module@36000 {    /* 0x48036000, ap 9 4e.0 */
+                       compatible = "ti,sysc-omap4-timer", "ti,sysc";
+                       ti,hwmods = "timer4";
+                       reg = <0x36000 0x4>,
+--- a/arch/arm/boot/dts/dra7.dtsi
++++ b/arch/arm/boot/dts/dra7.dtsi
+@@ -46,6 +46,7 @@
+       timer {
+               compatible = "arm,armv7-timer";
++              status = "disabled";    /* See ARM architected timer wrap erratum i940 */
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+@@ -766,3 +767,22 @@
+ #include "dra7-l4.dtsi"
+ #include "dra7xx-clocks.dtsi"
++
++/* Local timers, see ARM architected timer wrap erratum i940 */
++&timer3_target {
++      ti,no-reset-on-init;
++      ti,no-idle;
++      timer@0 {
++              assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER3_CLKCTRL 24>;
++              assigned-clock-parents = <&timer_sys_clk_div>;
++      };
++};
++
++&timer4_target {
++      ti,no-reset-on-init;
++      ti,no-idle;
++      timer@0 {
++              assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER4_CLKCTRL 24>;
++              assigned-clock-parents = <&timer_sys_clk_div>;
++      };
++};
+--- a/arch/arm/mach-omap2/board-generic.c
++++ b/arch/arm/mach-omap2/board-generic.c
+@@ -327,7 +327,7 @@ DT_MACHINE_START(DRA74X_DT, "Generic DRA
+       .init_late      = dra7xx_init_late,
+       .init_irq       = omap_gic_of_init,
+       .init_machine   = omap_generic_init,
+-      .init_time      = omap5_realtime_timer_init,
++      .init_time      = omap3_gptimer_timer_init,
+       .dt_compat      = dra74x_boards_compat,
+       .restart        = omap44xx_restart,
+ MACHINE_END
+@@ -350,7 +350,7 @@ DT_MACHINE_START(DRA72X_DT, "Generic DRA
+       .init_late      = dra7xx_init_late,
+       .init_irq       = omap_gic_of_init,
+       .init_machine   = omap_generic_init,
+-      .init_time      = omap5_realtime_timer_init,
++      .init_time      = omap3_gptimer_timer_init,
+       .dt_compat      = dra72x_boards_compat,
+       .restart        = omap44xx_restart,
+ MACHINE_END
+--- a/arch/arm/mach-omap2/timer.c
++++ b/arch/arm/mach-omap2/timer.c
+@@ -42,6 +42,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/dmtimer-omap.h>
+ #include <linux/sched_clock.h>
++#include <linux/cpu.h>
+ #include <asm/mach/time.h>
+@@ -420,6 +421,53 @@ static void __init dmtimer_clkevt_init_c
+               timer->rate);
+ }
++static DEFINE_PER_CPU(struct dmtimer_clockevent, dmtimer_percpu_timer);
++
++static int omap_gptimer_starting_cpu(unsigned int cpu)
++{
++      struct dmtimer_clockevent *clkevt = per_cpu_ptr(&dmtimer_percpu_timer, cpu);
++      struct clock_event_device *dev = &clkevt->dev;
++      struct omap_dm_timer *timer = &clkevt->timer;
++
++      clockevents_config_and_register(dev, timer->rate, 3, ULONG_MAX);
++      irq_force_affinity(dev->irq, cpumask_of(cpu));
++
++      return 0;
++}
++
++static int __init dmtimer_percpu_quirk_init(void)
++{
++      struct dmtimer_clockevent *clkevt;
++      struct clock_event_device *dev;
++      struct device_node *arm_timer;
++      struct omap_dm_timer *timer;
++      int cpu = 0;
++
++      arm_timer = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
++      if (of_device_is_available(arm_timer)) {
++              pr_warn_once("ARM architected timer wrap issue i940 detected\n");
++              return 0;
++      }
++
++      for_each_possible_cpu(cpu) {
++              clkevt = per_cpu_ptr(&dmtimer_percpu_timer, cpu);
++              dev = &clkevt->dev;
++              timer = &clkevt->timer;
++
++              dmtimer_clkevt_init_common(clkevt, 0, "timer_sys_ck",
++                                         CLOCK_EVT_FEAT_ONESHOT,
++                                         cpumask_of(cpu),
++                                         "assigned-clock-parents",
++                                         500, "percpu timer");
++      }
++
++      cpuhp_setup_state(CPUHP_AP_OMAP_DM_TIMER_STARTING,
++                        "clockevents/omap/gptimer:starting",
++                        omap_gptimer_starting_cpu, NULL);
++
++      return 0;
++}
++
+ /* Clocksource code */
+ static struct omap_dm_timer clksrc;
+ static bool use_gptimer_clksrc __initdata;
+@@ -564,6 +612,9 @@ static void __init __omap_sync32k_timer_
+                                       3, /* Timer internal resynch latency */
+                                       0xffffffff);
++      if (soc_is_dra7xx())
++              dmtimer_percpu_quirk_init();
++
+       /* Enable the use of clocksource="gp_timer" kernel parameter */
+       if (use_gptimer_clksrc || gptimer)
+               omap2_gptimer_clocksource_init(clksrc_nr, clksrc_src,
+@@ -591,7 +642,7 @@ void __init omap3_secure_sync32k_timer_i
+ #endif /* CONFIG_ARCH_OMAP3 */
+ #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \
+-      defined(CONFIG_SOC_AM43XX)
++      defined(CONFIG_SOC_AM43XX) || defined(CONFIG_SOC_DRA7XX)
+ void __init omap3_gptimer_timer_init(void)
+ {
+       __omap_sync32k_timer_init(2, "timer_sys_ck", NULL,
+--- a/drivers/clk/ti/clk-7xx.c
++++ b/drivers/clk/ti/clk-7xx.c
+@@ -793,6 +793,7 @@ static struct ti_dt_clk dra7xx_clks[] =
+       DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
+       DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"),
+       DT_CLK(NULL, "sys_clkin", "sys_clkin1"),
++      DT_CLK(NULL, "timer_sys_ck", "timer_sys_clk_div"),
+       DT_CLK(NULL, "atl_dpll_clk_mux", "atl-clkctrl:0000:24"),
+       DT_CLK(NULL, "atl_gfclk_mux", "atl-clkctrl:0000:26"),
+       DT_CLK(NULL, "dcan1_sys_clk_mux", "wkupaon-clkctrl:0068:24"),
+--- a/include/linux/cpuhotplug.h
++++ b/include/linux/cpuhotplug.h
+@@ -119,6 +119,7 @@ enum cpuhp_state {
+       CPUHP_AP_ARM_L2X0_STARTING,
+       CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING,
+       CPUHP_AP_ARM_ARCH_TIMER_STARTING,
++      CPUHP_AP_OMAP_DM_TIMER_STARTING,
+       CPUHP_AP_ARM_GLOBAL_TIMER_STARTING,
+       CPUHP_AP_JCORE_TIMER_STARTING,
+       CPUHP_AP_ARM_TWD_STARTING,
diff --git a/queue-5.4/clocksource-drivers-timer-ti-dm-prepare-to-handle-dra7-timer-wrap-issue.patch b/queue-5.4/clocksource-drivers-timer-ti-dm-prepare-to-handle-dra7-timer-wrap-issue.patch
new file mode 100644 (file)
index 0000000..905c0d6
--- /dev/null
@@ -0,0 +1,99 @@
+From foo@baz Mon Jun 21 05:29:17 PM CEST 2021
+From: Tony Lindgren <tony@atomide.com>
+Date: Wed, 16 Jun 2021 15:31:11 +0300
+Subject: clocksource/drivers/timer-ti-dm: Prepare to handle dra7 timer wrap issue
+To: stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, Daniel Lezcano <daniel.lezcano@linaro.org>, Keerthy <j-keerthy@ti.com>, Tero Kristo <kristo@kernel.org>
+Message-ID: <20210616123112.65068-3-tony@atomide.com>
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit 3efe7a878a11c13b5297057bfc1e5639ce1241ce upstream.
+
+There is a timer wrap issue on dra7 for the ARM architected timer.
+In a typical clock configuration the timer fails to wrap after 388 days.
+
+To work around the issue, we need to use timer-ti-dm timers instead.
+
+Let's prepare for adding support for percpu timers by adding a common
+dmtimer_clkevt_init_common() and call it from __omap_sync32k_timer_init().
+This patch makes no intentional functional changes.
+
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Keerthy <j-keerthy@ti.com>
+Cc: Tero Kristo <kristo@kernel.org>
+[tony@atomide.com: backported to 5.4.y]
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/mach-omap2/timer.c |   34 +++++++++++++++++++---------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+--- a/arch/arm/mach-omap2/timer.c
++++ b/arch/arm/mach-omap2/timer.c
+@@ -367,18 +367,21 @@ void tick_broadcast(const struct cpumask
+ }
+ #endif
+-static void __init omap2_gp_clockevent_init(int gptimer_id,
+-                                              const char *fck_source,
+-                                              const char *property)
++static void __init dmtimer_clkevt_init_common(struct dmtimer_clockevent *clkevt,
++                                            int gptimer_id,
++                                            const char *fck_source,
++                                            unsigned int features,
++                                            const struct cpumask *cpumask,
++                                            const char *property,
++                                            int rating, const char *name)
+ {
+-      struct dmtimer_clockevent *clkevt = &clockevent;
+       struct omap_dm_timer *timer = &clkevt->timer;
+       int res;
+       timer->id = gptimer_id;
+       timer->errata = omap_dm_timer_get_errata();
+-      clkevt->dev.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+-      clkevt->dev.rating = 300;
++      clkevt->dev.features = features;
++      clkevt->dev.rating = rating;
+       clkevt->dev.set_next_event = omap2_gp_timer_set_next_event;
+       clkevt->dev.set_state_shutdown = omap2_gp_timer_shutdown;
+       clkevt->dev.set_state_periodic = omap2_gp_timer_set_periodic;
+@@ -396,19 +399,15 @@ static void __init omap2_gp_clockevent_i
+                                    &clkevt->dev.name, OMAP_TIMER_POSTED);
+       BUG_ON(res);
+-      clkevt->dev.cpumask = cpu_possible_mask;
++      clkevt->dev.cpumask = cpumask;
+       clkevt->dev.irq = omap_dm_timer_get_irq(timer);
+-      if (request_irq(timer->irq, omap2_gp_timer_interrupt,
+-                      IRQF_TIMER | IRQF_IRQPOLL, "gp_timer", clkevt))
+-              pr_err("Failed to request irq %d (gp_timer)\n", timer->irq);
++      if (request_irq(clkevt->dev.irq, omap2_gp_timer_interrupt,
++                      IRQF_TIMER | IRQF_IRQPOLL, name, clkevt))
++              pr_err("Failed to request irq %d (gp_timer)\n", clkevt->dev.irq);
+       __omap_dm_timer_int_enable(timer, OMAP_TIMER_INT_OVERFLOW);
+-      clockevents_config_and_register(&clkevt->dev, timer->rate,
+-                                      3, /* Timer internal resynch latency */
+-                                      0xffffffff);
+-
+       if (soc_is_am33xx() || soc_is_am43xx()) {
+               clkevt->dev.suspend = omap_clkevt_idle;
+               clkevt->dev.resume = omap_clkevt_unidle;
+@@ -558,7 +557,12 @@ static void __init __omap_sync32k_timer_
+ {
+       omap_clk_init();
+       omap_dmtimer_init();
+-      omap2_gp_clockevent_init(clkev_nr, clkev_src, clkev_prop);
++      dmtimer_clkevt_init_common(&clockevent, clkev_nr, clkev_src,
++                                 CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
++                                 cpu_possible_mask, clkev_prop, 300, "clockevent");
++      clockevents_config_and_register(&clockevent.dev, clockevent.timer.rate,
++                                      3, /* Timer internal resynch latency */
++                                      0xffffffff);
+       /* Enable the use of clocksource="gp_timer" kernel parameter */
+       if (use_gptimer_clksrc || gptimer)
diff --git a/queue-5.4/kvm-arm-arm64-fix-kvm_vgic_v3_addr_type_redist-read.patch b/queue-5.4/kvm-arm-arm64-fix-kvm_vgic_v3_addr_type_redist-read.patch
new file mode 100644 (file)
index 0000000..7cd4947
--- /dev/null
@@ -0,0 +1,42 @@
+From 94ac0835391efc1a30feda6fc908913ec012951e Mon Sep 17 00:00:00 2001
+From: Eric Auger <eric.auger@redhat.com>
+Date: Mon, 12 Apr 2021 17:00:34 +0200
+Subject: KVM: arm/arm64: Fix KVM_VGIC_V3_ADDR_TYPE_REDIST read
+
+From: Eric Auger <eric.auger@redhat.com>
+
+commit 94ac0835391efc1a30feda6fc908913ec012951e upstream.
+
+When reading the base address of the a REDIST region
+through KVM_VGIC_V3_ADDR_TYPE_REDIST we expect the
+redistributor region list to be populated with a single
+element.
+
+However list_first_entry() expects the list to be non empty.
+Instead we should use list_first_entry_or_null which effectively
+returns NULL if the list is empty.
+
+Fixes: dbd9733ab674 ("KVM: arm/arm64: Replace the single rdist region by a list")
+Cc: <Stable@vger.kernel.org> # v4.18+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Reported-by: Gavin Shan <gshan@redhat.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20210412150034.29185-1-eric.auger@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ virt/kvm/arm/vgic/vgic-kvm-device.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
++++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
+@@ -87,8 +87,8 @@ int kvm_vgic_addr(struct kvm *kvm, unsig
+                       r = vgic_v3_set_redist_base(kvm, 0, *addr, 0);
+                       goto out;
+               }
+-              rdreg = list_first_entry(&vgic->rd_regions,
+-                                       struct vgic_redist_region, list);
++              rdreg = list_first_entry_or_null(&vgic->rd_regions,
++                                               struct vgic_redist_region, list);
+               if (!rdreg)
+                       addr_ptr = &undef_value;
+               else
index fe404a149621bf91acdeec47c63bf6ab7158f2dc..1fe00da65d05eea008f1a17582fc157b01827f53 100644 (file)
@@ -81,3 +81,10 @@ mm-slub.c-include-swab.h.patch
 net-stmmac-disable-clocks-in-stmmac_remove_config_dt.patch
 net-fec_ptp-add-clock-rate-zero-check.patch
 tools-headers-uapi-sync-linux-in.h-copy-with-the-kernel-sources.patch
+kvm-arm-arm64-fix-kvm_vgic_v3_addr_type_redist-read.patch
+arm-omap-replace-setup_irq-by-request_irq.patch
+clocksource-drivers-timer-ti-dm-add-clockevent-and-clocksource-support.patch
+clocksource-drivers-timer-ti-dm-prepare-to-handle-dra7-timer-wrap-issue.patch
+clocksource-drivers-timer-ti-dm-handle-dra7-timer-wrap-errata-i940.patch
+usb-dwc3-debugfs-add-and-remove-endpoint-dirs-dynamically.patch
+usb-dwc3-core-fix-kernel-panic-when-do-reboot.patch
diff --git a/queue-5.4/usb-dwc3-core-fix-kernel-panic-when-do-reboot.patch b/queue-5.4/usb-dwc3-core-fix-kernel-panic-when-do-reboot.patch
new file mode 100644 (file)
index 0000000..6a56f09
--- /dev/null
@@ -0,0 +1,86 @@
+From 4bf584a03eec674975ee9fe36c8583d9d470dab1 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@kernel.org>
+Date: Tue, 8 Jun 2021 18:56:56 +0800
+Subject: usb: dwc3: core: fix kernel panic when do reboot
+
+From: Peter Chen <peter.chen@kernel.org>
+
+commit 4bf584a03eec674975ee9fe36c8583d9d470dab1 upstream.
+
+When do system reboot, it calls dwc3_shutdown and the whole debugfs
+for dwc3 has removed first, when the gadget tries to do deinit, and
+remove debugfs for its endpoints, it meets NULL pointer dereference
+issue when call debugfs_lookup. Fix it by removing the whole dwc3
+debugfs later than dwc3_drd_exit.
+
+[ 2924.958838] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000002
+....
+[ 2925.030994] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
+[ 2925.037005] pc : inode_permission+0x2c/0x198
+[ 2925.041281] lr : lookup_one_len_common+0xb0/0xf8
+[ 2925.045903] sp : ffff80001276ba70
+[ 2925.049218] x29: ffff80001276ba70 x28: ffff0000c01f0000 x27: 0000000000000000
+[ 2925.056364] x26: ffff800011791e70 x25: 0000000000000008 x24: dead000000000100
+[ 2925.063510] x23: dead000000000122 x22: 0000000000000000 x21: 0000000000000001
+[ 2925.070652] x20: ffff8000122c6188 x19: 0000000000000000 x18: 0000000000000000
+[ 2925.077797] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000004
+[ 2925.084943] x14: ffffffffffffffff x13: 0000000000000000 x12: 0000000000000030
+[ 2925.092087] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f x9 : ffff8000102b2420
+[ 2925.099232] x8 : 7f7f7f7f7f7f7f7f x7 : feff73746e2f6f64 x6 : 0000000000008080
+[ 2925.106378] x5 : 61c8864680b583eb x4 : 209e6ec2d263dbb7 x3 : 000074756f307065
+[ 2925.113523] x2 : 0000000000000001 x1 : 0000000000000000 x0 : ffff8000122c6188
+[ 2925.120671] Call trace:
+[ 2925.123119]  inode_permission+0x2c/0x198
+[ 2925.127042]  lookup_one_len_common+0xb0/0xf8
+[ 2925.131315]  lookup_one_len_unlocked+0x34/0xb0
+[ 2925.135764]  lookup_positive_unlocked+0x14/0x50
+[ 2925.140296]  debugfs_lookup+0x68/0xa0
+[ 2925.143964]  dwc3_gadget_free_endpoints+0x84/0xb0
+[ 2925.148675]  dwc3_gadget_exit+0x28/0x78
+[ 2925.152518]  dwc3_drd_exit+0x100/0x1f8
+[ 2925.156267]  dwc3_remove+0x11c/0x120
+[ 2925.159851]  dwc3_shutdown+0x14/0x20
+[ 2925.163432]  platform_shutdown+0x28/0x38
+[ 2925.167360]  device_shutdown+0x15c/0x378
+[ 2925.171291]  kernel_restart_prepare+0x3c/0x48
+[ 2925.175650]  kernel_restart+0x1c/0x68
+[ 2925.179316]  __do_sys_reboot+0x218/0x240
+[ 2925.183247]  __arm64_sys_reboot+0x28/0x30
+[ 2925.187262]  invoke_syscall+0x48/0x100
+[ 2925.191017]  el0_svc_common.constprop.0+0x48/0xc8
+[ 2925.195726]  do_el0_svc+0x28/0x88
+[ 2925.199045]  el0_svc+0x20/0x30
+[ 2925.202104]  el0_sync_handler+0xa8/0xb0
+[ 2925.205942]  el0_sync+0x148/0x180
+[ 2925.209270] Code: a9025bf5 2a0203f5 121f0056 370802b5 (79400660)
+[ 2925.215372] ---[ end trace 124254d8e485a58b ]---
+[ 2925.220012] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
+[ 2925.227676] Kernel Offset: disabled
+[ 2925.231164] CPU features: 0x00001001,20000846
+[ 2925.235521] Memory Limit: none
+[ 2925.238580] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
+
+Fixes: 8d396bb0a5b6 ("usb: dwc3: debugfs: Add and remove endpoint dirs dynamically")
+Cc: Jack Pham <jackp@codeaurora.org>
+Tested-by: Jack Pham <jackp@codeaurora.org>
+Signed-off-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20210608105656.10795-1-peter.chen@kernel.org
+(cherry picked from commit 2a042767814bd0edf2619f06fecd374e266ea068)
+Link: https://lore.kernel.org/r/20210615080847.GA10432@jackp-linux.qualcomm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1575,8 +1575,8 @@ static int dwc3_remove(struct platform_d
+       pm_runtime_get_sync(&pdev->dev);
+-      dwc3_debugfs_exit(dwc);
+       dwc3_core_exit_mode(dwc);
++      dwc3_debugfs_exit(dwc);
+       dwc3_core_exit(dwc);
+       dwc3_ulpi_exit(dwc);
diff --git a/queue-5.4/usb-dwc3-debugfs-add-and-remove-endpoint-dirs-dynamically.patch b/queue-5.4/usb-dwc3-debugfs-add-and-remove-endpoint-dirs-dynamically.patch
new file mode 100644 (file)
index 0000000..3a5a191
--- /dev/null
@@ -0,0 +1,122 @@
+From 8d396bb0a5b62b326f6be7594d8bd46b088296bd Mon Sep 17 00:00:00 2001
+From: Jack Pham <jackp@codeaurora.org>
+Date: Sat, 29 May 2021 12:29:32 -0700
+Subject: usb: dwc3: debugfs: Add and remove endpoint dirs dynamically
+
+From: Jack Pham <jackp@codeaurora.org>
+
+commit 8d396bb0a5b62b326f6be7594d8bd46b088296bd upstream.
+
+The DWC3 DebugFS directory and files are currently created once
+during probe.  This includes creation of subdirectories for each
+of the gadget's endpoints.  This works fine for peripheral-only
+controllers, as dwc3_core_init_mode() calls dwc3_gadget_init()
+just prior to calling dwc3_debugfs_init().
+
+However, for dual-role controllers, dwc3_core_init_mode() will
+instead call dwc3_drd_init() which is problematic in a few ways.
+First, the initial state must be determined, then dwc3_set_mode()
+will have to schedule drd_work and by then dwc3_debugfs_init()
+could have already been invoked.  Even if the initial mode is
+peripheral, dwc3_gadget_init() happens after the DebugFS files
+are created, and worse so if the initial state is host and the
+controller switches to peripheral much later.  And secondly,
+even if the gadget endpoints' debug entries were successfully
+created, if the controller exits peripheral mode, its dwc3_eps
+are freed so the debug files would now hold stale references.
+
+So it is best if the DebugFS endpoint entries are created and
+removed dynamically at the same time the underlying dwc3_eps are.
+Do this by calling dwc3_debugfs_create_endpoint_dir() as each
+endpoint is created, and conversely remove the DebugFS entry when
+the endpoint is freed.
+
+Fixes: 41ce1456e1db ("usb: dwc3: core: make dwc3_set_mode() work properly")
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Jack Pham <jackp@codeaurora.org>
+Link: https://lore.kernel.org/r/20210529192932.22912-1-jackp@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/debug.h   |    3 +++
+ drivers/usb/dwc3/debugfs.c |   21 ++-------------------
+ drivers/usb/dwc3/gadget.c  |    3 +++
+ 3 files changed, 8 insertions(+), 19 deletions(-)
+
+--- a/drivers/usb/dwc3/debug.h
++++ b/drivers/usb/dwc3/debug.h
+@@ -409,9 +409,12 @@ static inline const char *dwc3_gadget_ge
+ #ifdef CONFIG_DEBUG_FS
++extern void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep);
+ extern void dwc3_debugfs_init(struct dwc3 *);
+ extern void dwc3_debugfs_exit(struct dwc3 *);
+ #else
++static inline void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
++{  }
+ static inline void dwc3_debugfs_init(struct dwc3 *d)
+ {  }
+ static inline void dwc3_debugfs_exit(struct dwc3 *d)
+--- a/drivers/usb/dwc3/debugfs.c
++++ b/drivers/usb/dwc3/debugfs.c
+@@ -878,30 +878,14 @@ static void dwc3_debugfs_create_endpoint
+       }
+ }
+-static void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep,
+-              struct dentry *parent)
++void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
+ {
+       struct dentry           *dir;
+-      dir = debugfs_create_dir(dep->name, parent);
++      dir = debugfs_create_dir(dep->name, dep->dwc->root);
+       dwc3_debugfs_create_endpoint_files(dep, dir);
+ }
+-static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc,
+-              struct dentry *parent)
+-{
+-      int                     i;
+-
+-      for (i = 0; i < dwc->num_eps; i++) {
+-              struct dwc3_ep  *dep = dwc->eps[i];
+-
+-              if (!dep)
+-                      continue;
+-
+-              dwc3_debugfs_create_endpoint_dir(dep, parent);
+-      }
+-}
+-
+ void dwc3_debugfs_init(struct dwc3 *dwc)
+ {
+       struct dentry           *root;
+@@ -935,7 +919,6 @@ void dwc3_debugfs_init(struct dwc3 *dwc)
+                                   &dwc3_testmode_fops);
+               debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, dwc,
+                                   &dwc3_link_state_fops);
+-              dwc3_debugfs_create_endpoint_dirs(dwc, root);
+       }
+ }
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2483,6 +2483,8 @@ static int dwc3_gadget_init_endpoint(str
+       INIT_LIST_HEAD(&dep->started_list);
+       INIT_LIST_HEAD(&dep->cancelled_list);
++      dwc3_debugfs_create_endpoint_dir(dep);
++
+       return 0;
+ }
+@@ -2526,6 +2528,7 @@ static void dwc3_gadget_free_endpoints(s
+                       list_del(&dep->endpoint.ep_list);
+               }
++              debugfs_remove_recursive(debugfs_lookup(dep->name, dwc->root));
+               kfree(dep);
+       }
+ }