When the dwc3 device is runtime suspended, various required clocks would get disabled and it is not guaranteed that access to any registers would work. Depending on the SoC glue, a register read could be as benign as returning 0 or be fatal enough to hang the system. In order to prevent such scenarios of fatal errors, bail out of debugfs function is dwc3 is suspended. Signed-off-by: Udipto Goswami <quic_ugoswami@xxxxxxxxxxx> --- drivers/usb/dwc3/debugfs.c | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 850df0e6bcab..f921d4911ffc 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -544,6 +544,11 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused) u32 reg; u8 speed; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + spin_lock_irqsave(&dwc->lock, flags); reg = dwc3_readl(dwc->regs, DWC3_GSTS); if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) { @@ -580,6 +585,11 @@ static ssize_t dwc3_link_state_write(struct file *file, u32 reg; u8 speed; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) return -EFAULT; @@ -641,6 +651,11 @@ static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused) u32 mdwidth; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_TXFIFO); @@ -663,6 +678,11 @@ static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused) u32 mdwidth; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_RXFIFO); @@ -684,6 +704,11 @@ static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_TXREQQ); seq_printf(s, "%u\n", val); @@ -699,6 +724,11 @@ static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_RXREQQ); seq_printf(s, "%u\n", val); @@ -714,6 +744,11 @@ static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ); seq_printf(s, "%u\n", val); @@ -729,6 +764,11 @@ static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ); seq_printf(s, "%u\n", val); @@ -744,6 +784,11 @@ static int dwc3_event_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_EVENTQ); seq_printf(s, "%u\n", val); @@ -835,6 +880,11 @@ static int dwc3_ep_info_register_show(struct seq_file *s, void *unused) u32 upper_32_bits; u32 reg; + if (pm_runtime_suspended(dwc->dev)) { + seq_puts(s, "Invalid operation, DWC3 suspended!"); + return 0; + } + spin_lock_irqsave(&dwc->lock, flags); reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number); dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); -- 2.17.1