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> --- v3: Replace pr_err to dev_err. drivers/usb/dwc3/debugfs.c | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 850df0e6bcab..4a9d0994f3b4 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -544,6 +544,12 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused) u32 reg; u8 speed; + if (pm_runtime_suspended(dwc->dev)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + spin_lock_irqsave(&dwc->lock, flags); reg = dwc3_readl(dwc->regs, DWC3_GSTS); if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) { @@ -580,6 +586,12 @@ static ssize_t dwc3_link_state_write(struct file *file, u32 reg; u8 speed; + if (pm_runtime_suspended(dwc->dev)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) return -EFAULT; @@ -641,6 +653,12 @@ static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused) u32 mdwidth; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_TXFIFO); @@ -663,6 +681,12 @@ static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused) u32 mdwidth; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_RXFIFO); @@ -684,6 +708,12 @@ static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_TXREQQ); seq_printf(s, "%u\n", val); @@ -699,6 +729,12 @@ static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_RXREQQ); seq_printf(s, "%u\n", val); @@ -714,6 +750,12 @@ static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ); seq_printf(s, "%u\n", val); @@ -729,6 +771,12 @@ static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ); seq_printf(s, "%u\n", val); @@ -744,6 +792,12 @@ static int dwc3_event_queue_show(struct seq_file *s, void *unused) unsigned long flags; u32 val; + if (pm_runtime_suspended(dwc->dev)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_EVENTQ); seq_printf(s, "%u\n", val); @@ -835,6 +889,12 @@ 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)) { + dev_err(dwc->dev, + "Invalid operation, DWC3 suspended!"); + return -EINVAL; + } + spin_lock_irqsave(&dwc->lock, flags); reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number); dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); -- 2.17.1