[PATCH V3 7/9] usb: dwc2: Refactor backup/restore of registers
Stefan Wahren
wahrenst at gmx.net
Thu Aug 22 10:30:49 UTC 2024
Am 21.08.24 um 23:40 schrieb Stefan Wahren:
> The DWC2 runtime PM code reuses similar patterns to backup and
> restore the registers. So consolidate them in USB mode specific
> variants. This also has the advantage it is usable for further
> PM improvements.
>
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
> ---
> drivers/usb/dwc2/core.h | 12 +++++
> drivers/usb/dwc2/gadget.c | 101 +++++++++++++++++++-------------------
> drivers/usb/dwc2/hcd.c | 99 +++++++++++++++++++------------------
> 3 files changed, 114 insertions(+), 98 deletions(-)
>
> diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
> index 2bd74f3033ed..81e8632f29ed 100644
> --- a/drivers/usb/dwc2/core.h
> +++ b/drivers/usb/dwc2/core.h
> @@ -1435,6 +1435,8 @@ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
> int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
> void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg);
> void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg);
> +int dwc2_gadget_backup_critical_registers(struct dwc2_hsotg *hsotg);
> +int dwc2_gadget_restore_critical_registers(struct dwc2_hsotg *hsotg);
> static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg)
> { hsotg->fifo_map = 0; }
> #else
> @@ -1482,6 +1484,10 @@ static inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
> { return 0; }
> static inline void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg) {}
> static inline void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg) {}
> +static inline int dwc2_gadget_backup_critical_registers(struct dwc2_hsotg *hsotg)
> +{ return 0; }
> +static inline int dwc2_gadget_restore_critical_registers(struct dwc2_hsotg *hsotg)
> +{ return 0; }
> static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg) {}
> #endif
>
> @@ -1505,6 +1511,8 @@ int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
> void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg);
> void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg, int rem_wakeup);
> bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2);
> +int dwc2_host_backup_critical_registers(struct dwc2_hsotg *hsotg);
> +int dwc2_host_restore_critical_registers(struct dwc2_hsotg *hsotg);
> static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg)
> { schedule_work(&hsotg->phy_reset_work); }
> #else
> @@ -1544,6 +1552,10 @@ static inline void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg,
> int rem_wakeup) {}
> static inline bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2)
> { return false; }
> +static inline int dwc2_host_backup_critical_registers(struct dwc2_hsotg *hsotg)
> +{ return 0; }
> +static inline int dwc2_host_restore_critical_registers(struct dwc2_hsotg *hsotg)
> +{ return 0; }
> static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg) {}
>
> #endif
> diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
> index e7bf9cc635be..0bff748bcf74 100644
> --- a/drivers/usb/dwc2/gadget.c
> +++ b/drivers/usb/dwc2/gadget.c
> @@ -5309,6 +5309,49 @@ void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg)
> dev_dbg(hsotg->dev, "GREFCLK=0x%08x\n", dwc2_readl(hsotg, GREFCLK));
> }
>
> +int dwc2_gadget_backup_critical_registers(struct dwc2_hsotg *hsotg)
> +{
> + int ret;
> +
> + /* Backup all registers */
> + ret = dwc2_backup_global_registers(hsotg);
> + if (ret) {
> + dev_err(hsotg->dev, "%s: failed to backup global registers\n",
> + __func__);
> + return ret;
> + }
> +
> + ret = dwc2_backup_device_registers(hsotg);
> + if (ret) {
> + dev_err(hsotg->dev, "%s: failed to backup device registers\n",
> + __func__);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +int dwc2_gadget_restore_critical_registers(struct dwc2_hsotg *hsotg)
> +{
> + int ret;
> +
> + ret = dwc2_restore_global_registers(hsotg);
> + if (ret) {
> + dev_err(hsotg->dev, "%s: failed to restore registers\n",
> + __func__);
> + return ret;
> + }
> +
> + ret = dwc2_restore_device_registers(hsotg, 0);
> + if (ret) {
> + dev_err(hsotg->dev, "%s: failed to restore device registers\n",
> + __func__);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> /**
> * dwc2_gadget_enter_hibernation() - Put controller in Hibernation.
> *
> @@ -5326,18 +5369,9 @@ int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg)
> /* Change to L2(suspend) state */
> hsotg->lx_state = DWC2_L2;
> dev_dbg(hsotg->dev, "Start of hibernation completed\n");
> - ret = dwc2_backup_global_registers(hsotg);
> - if (ret) {
> - dev_err(hsotg->dev, "%s: failed to backup global registers\n",
> - __func__);
> - return ret;
> - }
> - ret = dwc2_backup_device_registers(hsotg);
> - if (ret) {
> - dev_err(hsotg->dev, "%s: failed to backup device registers\n",
> - __func__);
> + ret = dwc2_gadget_backup_critical_registers(hsotg);
> + if (ret)
> return ret;
> - }
>
> gpwrdn = GPWRDN_PWRDNRSTN;
> udelay(10);
> @@ -5483,20 +5517,9 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
> dwc2_writel(hsotg, 0xffffffff, GINTSTS);
>
> /* Restore global registers */
> - ret = dwc2_restore_global_registers(hsotg);
> - if (ret) {
> - dev_err(hsotg->dev, "%s: failed to restore registers\n",
> - __func__);
> - return ret;
> - }
> -
> - /* Restore device registers */
> - ret = dwc2_restore_device_registers(hsotg, rem_wakeup);
> - if (ret) {
> - dev_err(hsotg->dev, "%s: failed to restore device registers\n",
> - __func__);
> + ret = dwc2_gadget_restore_critical_registers(hsotg);
> + if (ret)
> return ret;
> - }
>
> if (rem_wakeup) {
> mdelay(10);
> @@ -5530,19 +5553,9 @@ int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg)
> dev_dbg(hsotg->dev, "Entering device partial power down started.\n");
>
> /* Backup all registers */
> - ret = dwc2_backup_global_registers(hsotg);
> - if (ret) {
> - dev_err(hsotg->dev, "%s: failed to backup global registers\n",
> - __func__);
> - return ret;
> - }
> -
> - ret = dwc2_backup_device_registers(hsotg);
> - if (ret) {
> - dev_err(hsotg->dev, "%s: failed to backup device registers\n",
> - __func__);
> + ret = dwc2_gadget_backup_critical_registers(hsotg);
> + if (ret)
> return ret;
> - }
>
> /*
> * Clear any pending interrupts since dwc2 will not be able to
> @@ -5610,21 +5623,9 @@ int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg,
>
> udelay(100);
> if (restore) {
> - ret = dwc2_restore_global_registers(hsotg);
> - if (ret) {
> - dev_err(hsotg->dev, "%s: failed to restore registers\n",
> - __func__);
> - return ret;
> - }
> - /* Restore DCFG */
> - dwc2_writel(hsotg, dr->dcfg, DCFG);
Oh dear, i accidentally dropped that. I will fix this.
Thanks goes to kernel test robot
More information about the dri-devel
mailing list