]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
usb: dwc2: host: Fix hibernation flow
authorMinas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Wed, 13 Mar 2024 09:21:11 +0000 (09:21 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Apr 2024 14:19:32 +0000 (16:19 +0200)
commit 3c7b9856a82227db01a20171d2e24c7ce305d59b upstream.

Added to backup/restore registers HFLBADDR, HCCHARi, HCSPLTi,
HCTSIZi, HCDMAi and HCDMABi.

Fixes: 58e52ff6a6c3 ("usb: dwc2: Move register save and restore functions")
Fixes: d17ee77b3044 ("usb: dwc2: add controller hibernation support")
CC: stable@vger.kernel.org
Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Link: https://lore.kernel.org/r/c2d10ee6098b9b009a8e94191e046004747d3bdd.1708945444.git.Minas.Harutyunyan@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc2/core.h
drivers/usb/dwc2/hcd.c

index c7b999ef6b9b7383a1f929309c947a8fab02c69e..a505e963ef60e9d62c82ea0c5bde5e3b6bdd5e20 100644 (file)
@@ -755,8 +755,14 @@ struct dwc2_dregs_backup {
  * struct dwc2_hregs_backup - Holds host registers state before
  * entering partial power down
  * @hcfg:              Backup of HCFG register
+ * @hflbaddr:          Backup of HFLBADDR register
  * @haintmsk:          Backup of HAINTMSK register
+ * @hcchar:            Backup of HCCHAR register
+ * @hcsplt:            Backup of HCSPLT register
  * @hcintmsk:          Backup of HCINTMSK register
+ * @hctsiz:            Backup of HCTSIZ register
+ * @hdma:              Backup of HCDMA register
+ * @hcdmab:            Backup of HCDMAB register
  * @hprt0:             Backup of HPTR0 register
  * @hfir:              Backup of HFIR register
  * @hptxfsiz:          Backup of HPTXFSIZ register
@@ -764,8 +770,14 @@ struct dwc2_dregs_backup {
  */
 struct dwc2_hregs_backup {
        u32 hcfg;
+       u32 hflbaddr;
        u32 haintmsk;
+       u32 hcchar[MAX_EPS_CHANNELS];
+       u32 hcsplt[MAX_EPS_CHANNELS];
        u32 hcintmsk[MAX_EPS_CHANNELS];
+       u32 hctsiz[MAX_EPS_CHANNELS];
+       u32 hcidma[MAX_EPS_CHANNELS];
+       u32 hcidmab[MAX_EPS_CHANNELS];
        u32 hprt0;
        u32 hfir;
        u32 hptxfsiz;
index 40fafba8c8769b970d9e5df30f3be5744cf7859d..cc0d0d961d418ed3504d2e42566edabdce38f7ea 100644 (file)
@@ -5437,9 +5437,16 @@ int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
        /* Backup Host regs */
        hr = &hsotg->hr_backup;
        hr->hcfg = dwc2_readl(hsotg, HCFG);
+       hr->hflbaddr = dwc2_readl(hsotg, HFLBADDR);
        hr->haintmsk = dwc2_readl(hsotg, HAINTMSK);
-       for (i = 0; i < hsotg->params.host_channels; ++i)
+       for (i = 0; i < hsotg->params.host_channels; ++i) {
+               hr->hcchar[i] = dwc2_readl(hsotg, HCCHAR(i));
+               hr->hcsplt[i] = dwc2_readl(hsotg, HCSPLT(i));
                hr->hcintmsk[i] = dwc2_readl(hsotg, HCINTMSK(i));
+               hr->hctsiz[i] = dwc2_readl(hsotg, HCTSIZ(i));
+               hr->hcidma[i] = dwc2_readl(hsotg, HCDMA(i));
+               hr->hcidmab[i] = dwc2_readl(hsotg, HCDMAB(i));
+       }
 
        hr->hprt0 = dwc2_read_hprt0(hsotg);
        hr->hfir = dwc2_readl(hsotg, HFIR);
@@ -5473,10 +5480,17 @@ int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
        hr->valid = false;
 
        dwc2_writel(hsotg, hr->hcfg, HCFG);
+       dwc2_writel(hsotg, hr->hflbaddr, HFLBADDR);
        dwc2_writel(hsotg, hr->haintmsk, HAINTMSK);
 
-       for (i = 0; i < hsotg->params.host_channels; ++i)
+       for (i = 0; i < hsotg->params.host_channels; ++i) {
+               dwc2_writel(hsotg, hr->hcchar[i], HCCHAR(i));
+               dwc2_writel(hsotg, hr->hcsplt[i], HCSPLT(i));
                dwc2_writel(hsotg, hr->hcintmsk[i], HCINTMSK(i));
+               dwc2_writel(hsotg, hr->hctsiz[i], HCTSIZ(i));
+               dwc2_writel(hsotg, hr->hcidma[i], HCDMA(i));
+               dwc2_writel(hsotg, hr->hcidmab[i], HCDMAB(i));
+       }
 
        dwc2_writel(hsotg, hr->hprt0, HPRT0);
        dwc2_writel(hsotg, hr->hfir, HFIR);