From 754bfcc92a7e66fff94766ae7f0fb5a190ca094f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Jun 2021 17:34:33 +0200 Subject: [PATCH] 5.4-stable patches 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 --- ...map-replace-setup_irq-by-request_irq.patch | 141 ++++++++++ ...d-clockevent-and-clocksource-support.patch | 241 ++++++++++++++++++ ...m-handle-dra7-timer-wrap-errata-i940.patch | 219 ++++++++++++++++ ...pare-to-handle-dra7-timer-wrap-issue.patch | 99 +++++++ ...ix-kvm_vgic_v3_addr_type_redist-read.patch | 42 +++ queue-5.4/series | 7 + ...core-fix-kernel-panic-when-do-reboot.patch | 86 +++++++ ...and-remove-endpoint-dirs-dynamically.patch | 122 +++++++++ 8 files changed, 957 insertions(+) create mode 100644 queue-5.4/arm-omap-replace-setup_irq-by-request_irq.patch create mode 100644 queue-5.4/clocksource-drivers-timer-ti-dm-add-clockevent-and-clocksource-support.patch create mode 100644 queue-5.4/clocksource-drivers-timer-ti-dm-handle-dra7-timer-wrap-errata-i940.patch create mode 100644 queue-5.4/clocksource-drivers-timer-ti-dm-prepare-to-handle-dra7-timer-wrap-issue.patch create mode 100644 queue-5.4/kvm-arm-arm64-fix-kvm_vgic_v3_addr_type_redist-read.patch create mode 100644 queue-5.4/usb-dwc3-core-fix-kernel-panic-when-do-reboot.patch create mode 100644 queue-5.4/usb-dwc3-debugfs-add-and-remove-endpoint-dirs-dynamically.patch 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 index 00000000000..167b599a7b1 --- /dev/null +++ b/queue-5.4/arm-omap-replace-setup_irq-by-request_irq.patch @@ -0,0 +1,141 @@ +From foo@baz Mon Jun 21 05:29:17 PM CEST 2021 +From: Tony Lindgren +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 , Daniel Lezcano , Keerthy , Tero Kristo +Message-ID: <20210616123112.65068-1-tony@atomide.com> + +From: afzal mohammed + +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 +Cc: Keerthy +Cc: Tero Kristo +Signed-off-by: afzal mohammed +Signed-off-by: Tony Lindgren +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..9aa6e4257cc --- /dev/null +++ b/queue-5.4/clocksource-drivers-timer-ti-dm-add-clockevent-and-clocksource-support.patch @@ -0,0 +1,241 @@ +From foo@baz Mon Jun 21 05:29:17 PM CEST 2021 +From: Tony Lindgren +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 , Keerthy , Tero Kristo +Message-ID: <20210616123112.65068-2-tony@atomide.com> + +From: Tony Lindgren + +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 . 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 +Cc: Keerthy +Cc: Tero Kristo +[tony@atomide.com: backported to 5.4.y] +Signed-off-by: Tony Lindgren +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..c1852b3b26d --- /dev/null +++ b/queue-5.4/clocksource-drivers-timer-ti-dm-handle-dra7-timer-wrap-errata-i940.patch @@ -0,0 +1,219 @@ +From foo@baz Mon Jun 21 05:29:17 PM CEST 2021 +From: Tony Lindgren +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 , Keerthy , Tero Kristo +Message-ID: <20210616123112.65068-4-tony@atomide.com> + +From: Tony Lindgren + +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 +Cc: Keerthy +Cc: Tero Kristo +[tony@atomide.com: backported to 5.4.y] +Signed-off-by: Tony Lindgren +Signed-off-by: Greg Kroah-Hartman +--- + 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 = , + , + , +@@ -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 + #include + #include ++#include + + #include + +@@ -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 index 00000000000..905c0d6bfcc --- /dev/null +++ b/queue-5.4/clocksource-drivers-timer-ti-dm-prepare-to-handle-dra7-timer-wrap-issue.patch @@ -0,0 +1,99 @@ +From foo@baz Mon Jun 21 05:29:17 PM CEST 2021 +From: Tony Lindgren +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 , Keerthy , Tero Kristo +Message-ID: <20210616123112.65068-3-tony@atomide.com> + +From: Tony Lindgren + +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 +Cc: Keerthy +Cc: Tero Kristo +[tony@atomide.com: backported to 5.4.y] +Signed-off-by: Tony Lindgren +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..7cd4947c30d --- /dev/null +++ b/queue-5.4/kvm-arm-arm64-fix-kvm_vgic_v3_addr_type_redist-read.patch @@ -0,0 +1,42 @@ +From 94ac0835391efc1a30feda6fc908913ec012951e Mon Sep 17 00:00:00 2001 +From: Eric Auger +Date: Mon, 12 Apr 2021 17:00:34 +0200 +Subject: KVM: arm/arm64: Fix KVM_VGIC_V3_ADDR_TYPE_REDIST read + +From: Eric Auger + +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: # v4.18+ +Signed-off-by: Eric Auger +Reported-by: Gavin Shan +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20210412150034.29185-1-eric.auger@redhat.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 diff --git a/queue-5.4/series b/queue-5.4/series index fe404a14962..1fe00da65d0 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -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 index 00000000000..6a56f094a98 --- /dev/null +++ b/queue-5.4/usb-dwc3-core-fix-kernel-panic-when-do-reboot.patch @@ -0,0 +1,86 @@ +From 4bf584a03eec674975ee9fe36c8583d9d470dab1 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Tue, 8 Jun 2021 18:56:56 +0800 +Subject: usb: dwc3: core: fix kernel panic when do reboot + +From: Peter Chen + +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 +Tested-by: Jack Pham +Signed-off-by: Peter Chen +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 +--- + 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 index 00000000000..3a5a191c0c6 --- /dev/null +++ b/queue-5.4/usb-dwc3-debugfs-add-and-remove-endpoint-dirs-dynamically.patch @@ -0,0 +1,122 @@ +From 8d396bb0a5b62b326f6be7594d8bd46b088296bd Mon Sep 17 00:00:00 2001 +From: Jack Pham +Date: Sat, 29 May 2021 12:29:32 -0700 +Subject: usb: dwc3: debugfs: Add and remove endpoint dirs dynamically + +From: Jack Pham + +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 +Reviewed-by: Peter Chen +Signed-off-by: Jack Pham +Link: https://lore.kernel.org/r/20210529192932.22912-1-jackp@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } + } -- 2.47.2