Skip to content

Commit 614ce6a

Browse files
Udipto Goswamigregkh
authored andcommitted
usb: dwc3: debugfs: Resume dwc3 before accessing registers
When the dwc3 device is runtime suspended, various required clocks are in disabled state 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, make sure to resume dwc3 then allow the function to proceed. Fixes: 72246da ("usb: Introduce DesignWare USB3 DRD Driver") Cc: [email protected] #3.2: 30332ee: debugfs: regset32: Add Runtime PM support Signed-off-by: Udipto Goswami <[email protected]> Reviewed-by: Johan Hovold <[email protected]> Tested-by: Johan Hovold <[email protected]> Acked-by: Thinh Nguyen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent dddb342 commit 614ce6a

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

drivers/usb/dwc3/debugfs.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@ static int dwc3_lsp_show(struct seq_file *s, void *unused)
332332
unsigned int current_mode;
333333
unsigned long flags;
334334
u32 reg;
335+
int ret;
336+
337+
ret = pm_runtime_resume_and_get(dwc->dev);
338+
if (ret < 0)
339+
return ret;
335340

336341
spin_lock_irqsave(&dwc->lock, flags);
337342
reg = dwc3_readl(dwc->regs, DWC3_GSTS);
@@ -350,6 +355,8 @@ static int dwc3_lsp_show(struct seq_file *s, void *unused)
350355
}
351356
spin_unlock_irqrestore(&dwc->lock, flags);
352357

358+
pm_runtime_put_sync(dwc->dev);
359+
353360
return 0;
354361
}
355362

@@ -395,6 +402,11 @@ static int dwc3_mode_show(struct seq_file *s, void *unused)
395402
struct dwc3 *dwc = s->private;
396403
unsigned long flags;
397404
u32 reg;
405+
int ret;
406+
407+
ret = pm_runtime_resume_and_get(dwc->dev);
408+
if (ret < 0)
409+
return ret;
398410

399411
spin_lock_irqsave(&dwc->lock, flags);
400412
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
@@ -414,6 +426,8 @@ static int dwc3_mode_show(struct seq_file *s, void *unused)
414426
seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
415427
}
416428

429+
pm_runtime_put_sync(dwc->dev);
430+
417431
return 0;
418432
}
419433

@@ -463,6 +477,11 @@ static int dwc3_testmode_show(struct seq_file *s, void *unused)
463477
struct dwc3 *dwc = s->private;
464478
unsigned long flags;
465479
u32 reg;
480+
int ret;
481+
482+
ret = pm_runtime_resume_and_get(dwc->dev);
483+
if (ret < 0)
484+
return ret;
466485

467486
spin_lock_irqsave(&dwc->lock, flags);
468487
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
@@ -493,6 +512,8 @@ static int dwc3_testmode_show(struct seq_file *s, void *unused)
493512
seq_printf(s, "UNKNOWN %d\n", reg);
494513
}
495514

515+
pm_runtime_put_sync(dwc->dev);
516+
496517
return 0;
497518
}
498519

@@ -509,6 +530,7 @@ static ssize_t dwc3_testmode_write(struct file *file,
509530
unsigned long flags;
510531
u32 testmode = 0;
511532
char buf[32];
533+
int ret;
512534

513535
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
514536
return -EFAULT;
@@ -526,10 +548,16 @@ static ssize_t dwc3_testmode_write(struct file *file,
526548
else
527549
testmode = 0;
528550

551+
ret = pm_runtime_resume_and_get(dwc->dev);
552+
if (ret < 0)
553+
return ret;
554+
529555
spin_lock_irqsave(&dwc->lock, flags);
530556
dwc3_gadget_set_test_mode(dwc, testmode);
531557
spin_unlock_irqrestore(&dwc->lock, flags);
532558

559+
pm_runtime_put_sync(dwc->dev);
560+
533561
return count;
534562
}
535563

@@ -548,12 +576,18 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused)
548576
enum dwc3_link_state state;
549577
u32 reg;
550578
u8 speed;
579+
int ret;
580+
581+
ret = pm_runtime_resume_and_get(dwc->dev);
582+
if (ret < 0)
583+
return ret;
551584

552585
spin_lock_irqsave(&dwc->lock, flags);
553586
reg = dwc3_readl(dwc->regs, DWC3_GSTS);
554587
if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
555588
seq_puts(s, "Not available\n");
556589
spin_unlock_irqrestore(&dwc->lock, flags);
590+
pm_runtime_put_sync(dwc->dev);
557591
return 0;
558592
}
559593

@@ -566,6 +600,8 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused)
566600
dwc3_gadget_hs_link_string(state));
567601
spin_unlock_irqrestore(&dwc->lock, flags);
568602

603+
pm_runtime_put_sync(dwc->dev);
604+
569605
return 0;
570606
}
571607

@@ -584,6 +620,7 @@ static ssize_t dwc3_link_state_write(struct file *file,
584620
char buf[32];
585621
u32 reg;
586622
u8 speed;
623+
int ret;
587624

588625
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
589626
return -EFAULT;
@@ -603,10 +640,15 @@ static ssize_t dwc3_link_state_write(struct file *file,
603640
else
604641
return -EINVAL;
605642

643+
ret = pm_runtime_resume_and_get(dwc->dev);
644+
if (ret < 0)
645+
return ret;
646+
606647
spin_lock_irqsave(&dwc->lock, flags);
607648
reg = dwc3_readl(dwc->regs, DWC3_GSTS);
608649
if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
609650
spin_unlock_irqrestore(&dwc->lock, flags);
651+
pm_runtime_put_sync(dwc->dev);
610652
return -EINVAL;
611653
}
612654

@@ -616,12 +658,15 @@ static ssize_t dwc3_link_state_write(struct file *file,
616658
if (speed < DWC3_DSTS_SUPERSPEED &&
617659
state != DWC3_LINK_STATE_RECOV) {
618660
spin_unlock_irqrestore(&dwc->lock, flags);
661+
pm_runtime_put_sync(dwc->dev);
619662
return -EINVAL;
620663
}
621664

622665
dwc3_gadget_set_link_state(dwc, state);
623666
spin_unlock_irqrestore(&dwc->lock, flags);
624667

668+
pm_runtime_put_sync(dwc->dev);
669+
625670
return count;
626671
}
627672

@@ -645,6 +690,11 @@ static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused)
645690
unsigned long flags;
646691
u32 mdwidth;
647692
u32 val;
693+
int ret;
694+
695+
ret = pm_runtime_resume_and_get(dwc->dev);
696+
if (ret < 0)
697+
return ret;
648698

649699
spin_lock_irqsave(&dwc->lock, flags);
650700
val = dwc3_core_fifo_space(dep, DWC3_TXFIFO);
@@ -657,6 +707,8 @@ static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused)
657707
seq_printf(s, "%u\n", val);
658708
spin_unlock_irqrestore(&dwc->lock, flags);
659709

710+
pm_runtime_put_sync(dwc->dev);
711+
660712
return 0;
661713
}
662714

@@ -667,6 +719,11 @@ static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused)
667719
unsigned long flags;
668720
u32 mdwidth;
669721
u32 val;
722+
int ret;
723+
724+
ret = pm_runtime_resume_and_get(dwc->dev);
725+
if (ret < 0)
726+
return ret;
670727

671728
spin_lock_irqsave(&dwc->lock, flags);
672729
val = dwc3_core_fifo_space(dep, DWC3_RXFIFO);
@@ -679,6 +736,8 @@ static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused)
679736
seq_printf(s, "%u\n", val);
680737
spin_unlock_irqrestore(&dwc->lock, flags);
681738

739+
pm_runtime_put_sync(dwc->dev);
740+
682741
return 0;
683742
}
684743

@@ -688,12 +747,19 @@ static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused)
688747
struct dwc3 *dwc = dep->dwc;
689748
unsigned long flags;
690749
u32 val;
750+
int ret;
751+
752+
ret = pm_runtime_resume_and_get(dwc->dev);
753+
if (ret < 0)
754+
return ret;
691755

692756
spin_lock_irqsave(&dwc->lock, flags);
693757
val = dwc3_core_fifo_space(dep, DWC3_TXREQQ);
694758
seq_printf(s, "%u\n", val);
695759
spin_unlock_irqrestore(&dwc->lock, flags);
696760

761+
pm_runtime_put_sync(dwc->dev);
762+
697763
return 0;
698764
}
699765

@@ -703,12 +769,19 @@ static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused)
703769
struct dwc3 *dwc = dep->dwc;
704770
unsigned long flags;
705771
u32 val;
772+
int ret;
773+
774+
ret = pm_runtime_resume_and_get(dwc->dev);
775+
if (ret < 0)
776+
return ret;
706777

707778
spin_lock_irqsave(&dwc->lock, flags);
708779
val = dwc3_core_fifo_space(dep, DWC3_RXREQQ);
709780
seq_printf(s, "%u\n", val);
710781
spin_unlock_irqrestore(&dwc->lock, flags);
711782

783+
pm_runtime_put_sync(dwc->dev);
784+
712785
return 0;
713786
}
714787

@@ -718,12 +791,19 @@ static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused)
718791
struct dwc3 *dwc = dep->dwc;
719792
unsigned long flags;
720793
u32 val;
794+
int ret;
795+
796+
ret = pm_runtime_resume_and_get(dwc->dev);
797+
if (ret < 0)
798+
return ret;
721799

722800
spin_lock_irqsave(&dwc->lock, flags);
723801
val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ);
724802
seq_printf(s, "%u\n", val);
725803
spin_unlock_irqrestore(&dwc->lock, flags);
726804

805+
pm_runtime_put_sync(dwc->dev);
806+
727807
return 0;
728808
}
729809

@@ -733,12 +813,19 @@ static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused)
733813
struct dwc3 *dwc = dep->dwc;
734814
unsigned long flags;
735815
u32 val;
816+
int ret;
817+
818+
ret = pm_runtime_resume_and_get(dwc->dev);
819+
if (ret < 0)
820+
return ret;
736821

737822
spin_lock_irqsave(&dwc->lock, flags);
738823
val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ);
739824
seq_printf(s, "%u\n", val);
740825
spin_unlock_irqrestore(&dwc->lock, flags);
741826

827+
pm_runtime_put_sync(dwc->dev);
828+
742829
return 0;
743830
}
744831

@@ -748,12 +835,19 @@ static int dwc3_event_queue_show(struct seq_file *s, void *unused)
748835
struct dwc3 *dwc = dep->dwc;
749836
unsigned long flags;
750837
u32 val;
838+
int ret;
839+
840+
ret = pm_runtime_resume_and_get(dwc->dev);
841+
if (ret < 0)
842+
return ret;
751843

752844
spin_lock_irqsave(&dwc->lock, flags);
753845
val = dwc3_core_fifo_space(dep, DWC3_EVENTQ);
754846
seq_printf(s, "%u\n", val);
755847
spin_unlock_irqrestore(&dwc->lock, flags);
756848

849+
pm_runtime_put_sync(dwc->dev);
850+
757851
return 0;
758852
}
759853

@@ -798,6 +892,11 @@ static int dwc3_trb_ring_show(struct seq_file *s, void *unused)
798892
struct dwc3 *dwc = dep->dwc;
799893
unsigned long flags;
800894
int i;
895+
int ret;
896+
897+
ret = pm_runtime_resume_and_get(dwc->dev);
898+
if (ret < 0)
899+
return ret;
801900

802901
spin_lock_irqsave(&dwc->lock, flags);
803902
if (dep->number <= 1) {
@@ -827,6 +926,8 @@ static int dwc3_trb_ring_show(struct seq_file *s, void *unused)
827926
out:
828927
spin_unlock_irqrestore(&dwc->lock, flags);
829928

929+
pm_runtime_put_sync(dwc->dev);
930+
830931
return 0;
831932
}
832933

@@ -839,6 +940,11 @@ static int dwc3_ep_info_register_show(struct seq_file *s, void *unused)
839940
u32 lower_32_bits;
840941
u32 upper_32_bits;
841942
u32 reg;
943+
int ret;
944+
945+
ret = pm_runtime_resume_and_get(dwc->dev);
946+
if (ret < 0)
947+
return ret;
842948

843949
spin_lock_irqsave(&dwc->lock, flags);
844950
reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number);
@@ -851,6 +957,8 @@ static int dwc3_ep_info_register_show(struct seq_file *s, void *unused)
851957
seq_printf(s, "0x%016llx\n", ep_info);
852958
spin_unlock_irqrestore(&dwc->lock, flags);
853959

960+
pm_runtime_put_sync(dwc->dev);
961+
854962
return 0;
855963
}
856964

@@ -910,6 +1018,7 @@ void dwc3_debugfs_init(struct dwc3 *dwc)
9101018
dwc->regset->regs = dwc3_regs;
9111019
dwc->regset->nregs = ARRAY_SIZE(dwc3_regs);
9121020
dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START;
1021+
dwc->regset->dev = dwc->dev;
9131022

9141023
root = debugfs_create_dir(dev_name(dwc->dev), usb_debug_root);
9151024
dwc->debug_root = root;

0 commit comments

Comments
 (0)