diff options
author | John Youn <johnyoun@synopsys.com> | 2016-02-23 22:54:57 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@kernel.org> | 2016-03-04 08:14:46 -0500 |
commit | 58e52ff6a6c3ce964c71b2dd9f06be426f993524 (patch) | |
tree | c3cfca9fe11fa5b11ac640c68dbc5b9b2725b9b5 | |
parent | 9bbe91a1ea4cae20ff9f8f175c92e1e49b4296d9 (diff) |
usb: dwc2: Move register save and restore functions
Move the register save and restore functions into the host and gadget
specific files.
Tested-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
-rw-r--r-- | drivers/usb/dwc2/core.c | 183 | ||||
-rw-r--r-- | drivers/usb/dwc2/core.h | 13 | ||||
-rw-r--r-- | drivers/usb/dwc2/gadget.c | 102 | ||||
-rw-r--r-- | drivers/usb/dwc2/hcd.c | 64 |
4 files changed, 179 insertions, 183 deletions
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 28d3abd780fd..d5091b91ba49 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c | |||
@@ -56,189 +56,6 @@ | |||
56 | #include "core.h" | 56 | #include "core.h" |
57 | #include "hcd.h" | 57 | #include "hcd.h" |
58 | 58 | ||
59 | #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) | ||
60 | /** | ||
61 | * dwc2_backup_host_registers() - Backup controller host registers. | ||
62 | * When suspending usb bus, registers needs to be backuped | ||
63 | * if controller power is disabled once suspended. | ||
64 | * | ||
65 | * @hsotg: Programming view of the DWC_otg controller | ||
66 | */ | ||
67 | static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) | ||
68 | { | ||
69 | struct dwc2_hregs_backup *hr; | ||
70 | int i; | ||
71 | |||
72 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
73 | |||
74 | /* Backup Host regs */ | ||
75 | hr = &hsotg->hr_backup; | ||
76 | hr->hcfg = dwc2_readl(hsotg->regs + HCFG); | ||
77 | hr->haintmsk = dwc2_readl(hsotg->regs + HAINTMSK); | ||
78 | for (i = 0; i < hsotg->core_params->host_channels; ++i) | ||
79 | hr->hcintmsk[i] = dwc2_readl(hsotg->regs + HCINTMSK(i)); | ||
80 | |||
81 | hr->hprt0 = dwc2_read_hprt0(hsotg); | ||
82 | hr->hfir = dwc2_readl(hsotg->regs + HFIR); | ||
83 | hr->valid = true; | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * dwc2_restore_host_registers() - Restore controller host registers. | ||
90 | * When resuming usb bus, device registers needs to be restored | ||
91 | * if controller power were disabled. | ||
92 | * | ||
93 | * @hsotg: Programming view of the DWC_otg controller | ||
94 | */ | ||
95 | static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) | ||
96 | { | ||
97 | struct dwc2_hregs_backup *hr; | ||
98 | int i; | ||
99 | |||
100 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
101 | |||
102 | /* Restore host regs */ | ||
103 | hr = &hsotg->hr_backup; | ||
104 | if (!hr->valid) { | ||
105 | dev_err(hsotg->dev, "%s: no host registers to restore\n", | ||
106 | __func__); | ||
107 | return -EINVAL; | ||
108 | } | ||
109 | hr->valid = false; | ||
110 | |||
111 | dwc2_writel(hr->hcfg, hsotg->regs + HCFG); | ||
112 | dwc2_writel(hr->haintmsk, hsotg->regs + HAINTMSK); | ||
113 | |||
114 | for (i = 0; i < hsotg->core_params->host_channels; ++i) | ||
115 | dwc2_writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i)); | ||
116 | |||
117 | dwc2_writel(hr->hprt0, hsotg->regs + HPRT0); | ||
118 | dwc2_writel(hr->hfir, hsotg->regs + HFIR); | ||
119 | hsotg->frame_number = 0; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | #else | ||
124 | static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) | ||
125 | { return 0; } | ||
126 | |||
127 | static inline int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) | ||
128 | { return 0; } | ||
129 | #endif | ||
130 | |||
131 | #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \ | ||
132 | IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) | ||
133 | /** | ||
134 | * dwc2_backup_device_registers() - Backup controller device registers. | ||
135 | * When suspending usb bus, registers needs to be backuped | ||
136 | * if controller power is disabled once suspended. | ||
137 | * | ||
138 | * @hsotg: Programming view of the DWC_otg controller | ||
139 | */ | ||
140 | static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) | ||
141 | { | ||
142 | struct dwc2_dregs_backup *dr; | ||
143 | int i; | ||
144 | |||
145 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
146 | |||
147 | /* Backup dev regs */ | ||
148 | dr = &hsotg->dr_backup; | ||
149 | |||
150 | dr->dcfg = dwc2_readl(hsotg->regs + DCFG); | ||
151 | dr->dctl = dwc2_readl(hsotg->regs + DCTL); | ||
152 | dr->daintmsk = dwc2_readl(hsotg->regs + DAINTMSK); | ||
153 | dr->diepmsk = dwc2_readl(hsotg->regs + DIEPMSK); | ||
154 | dr->doepmsk = dwc2_readl(hsotg->regs + DOEPMSK); | ||
155 | |||
156 | for (i = 0; i < hsotg->num_of_eps; i++) { | ||
157 | /* Backup IN EPs */ | ||
158 | dr->diepctl[i] = dwc2_readl(hsotg->regs + DIEPCTL(i)); | ||
159 | |||
160 | /* Ensure DATA PID is correctly configured */ | ||
161 | if (dr->diepctl[i] & DXEPCTL_DPID) | ||
162 | dr->diepctl[i] |= DXEPCTL_SETD1PID; | ||
163 | else | ||
164 | dr->diepctl[i] |= DXEPCTL_SETD0PID; | ||
165 | |||
166 | dr->dieptsiz[i] = dwc2_readl(hsotg->regs + DIEPTSIZ(i)); | ||
167 | dr->diepdma[i] = dwc2_readl(hsotg->regs + DIEPDMA(i)); | ||
168 | |||
169 | /* Backup OUT EPs */ | ||
170 | dr->doepctl[i] = dwc2_readl(hsotg->regs + DOEPCTL(i)); | ||
171 | |||
172 | /* Ensure DATA PID is correctly configured */ | ||
173 | if (dr->doepctl[i] & DXEPCTL_DPID) | ||
174 | dr->doepctl[i] |= DXEPCTL_SETD1PID; | ||
175 | else | ||
176 | dr->doepctl[i] |= DXEPCTL_SETD0PID; | ||
177 | |||
178 | dr->doeptsiz[i] = dwc2_readl(hsotg->regs + DOEPTSIZ(i)); | ||
179 | dr->doepdma[i] = dwc2_readl(hsotg->regs + DOEPDMA(i)); | ||
180 | } | ||
181 | dr->valid = true; | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * dwc2_restore_device_registers() - Restore controller device registers. | ||
187 | * When resuming usb bus, device registers needs to be restored | ||
188 | * if controller power were disabled. | ||
189 | * | ||
190 | * @hsotg: Programming view of the DWC_otg controller | ||
191 | */ | ||
192 | static int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) | ||
193 | { | ||
194 | struct dwc2_dregs_backup *dr; | ||
195 | u32 dctl; | ||
196 | int i; | ||
197 | |||
198 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
199 | |||
200 | /* Restore dev regs */ | ||
201 | dr = &hsotg->dr_backup; | ||
202 | if (!dr->valid) { | ||
203 | dev_err(hsotg->dev, "%s: no device registers to restore\n", | ||
204 | __func__); | ||
205 | return -EINVAL; | ||
206 | } | ||
207 | dr->valid = false; | ||
208 | |||
209 | dwc2_writel(dr->dcfg, hsotg->regs + DCFG); | ||
210 | dwc2_writel(dr->dctl, hsotg->regs + DCTL); | ||
211 | dwc2_writel(dr->daintmsk, hsotg->regs + DAINTMSK); | ||
212 | dwc2_writel(dr->diepmsk, hsotg->regs + DIEPMSK); | ||
213 | dwc2_writel(dr->doepmsk, hsotg->regs + DOEPMSK); | ||
214 | |||
215 | for (i = 0; i < hsotg->num_of_eps; i++) { | ||
216 | /* Restore IN EPs */ | ||
217 | dwc2_writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i)); | ||
218 | dwc2_writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i)); | ||
219 | dwc2_writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i)); | ||
220 | |||
221 | /* Restore OUT EPs */ | ||
222 | dwc2_writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i)); | ||
223 | dwc2_writel(dr->doeptsiz[i], hsotg->regs + DOEPTSIZ(i)); | ||
224 | dwc2_writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i)); | ||
225 | } | ||
226 | |||
227 | /* Set the Power-On Programming done bit */ | ||
228 | dctl = dwc2_readl(hsotg->regs + DCTL); | ||
229 | dctl |= DCTL_PWRONPRGDONE; | ||
230 | dwc2_writel(dctl, hsotg->regs + DCTL); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | #else | ||
235 | static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) | ||
236 | { return 0; } | ||
237 | |||
238 | static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) | ||
239 | { return 0; } | ||
240 | #endif | ||
241 | |||
242 | /** | 59 | /** |
243 | * dwc2_backup_global_registers() - Backup global controller registers. | 60 | * dwc2_backup_global_registers() - Backup global controller registers. |
244 | * When suspending usb bus, registers needs to be backuped | 61 | * When suspending usb bus, registers needs to be backuped |
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 115925909390..606629aed2a8 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h | |||
@@ -1295,6 +1295,8 @@ extern void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg); | |||
1295 | extern void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2); | 1295 | extern void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2); |
1296 | extern int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode); | 1296 | extern int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode); |
1297 | #define dwc2_is_device_connected(hsotg) (hsotg->connected) | 1297 | #define dwc2_is_device_connected(hsotg) (hsotg->connected) |
1298 | int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg); | ||
1299 | int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg); | ||
1298 | #else | 1300 | #else |
1299 | static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2) | 1301 | static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2) |
1300 | { return 0; } | 1302 | { return 0; } |
@@ -1312,6 +1314,10 @@ static inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, | |||
1312 | int testmode) | 1314 | int testmode) |
1313 | { return 0; } | 1315 | { return 0; } |
1314 | #define dwc2_is_device_connected(hsotg) (0) | 1316 | #define dwc2_is_device_connected(hsotg) (0) |
1317 | static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) | ||
1318 | { return 0; } | ||
1319 | static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) | ||
1320 | { return 0; } | ||
1315 | #endif | 1321 | #endif |
1316 | 1322 | ||
1317 | #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) | 1323 | #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) |
@@ -1320,6 +1326,8 @@ extern int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us); | |||
1320 | extern void dwc2_hcd_connect(struct dwc2_hsotg *hsotg); | 1326 | extern void dwc2_hcd_connect(struct dwc2_hsotg *hsotg); |
1321 | extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force); | 1327 | extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force); |
1322 | extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); | 1328 | extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); |
1329 | int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg); | ||
1330 | int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg); | ||
1323 | #else | 1331 | #else |
1324 | static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) | 1332 | static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) |
1325 | { return 0; } | 1333 | { return 0; } |
@@ -1332,6 +1340,11 @@ static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} | |||
1332 | static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} | 1340 | static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} |
1333 | static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) | 1341 | static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) |
1334 | { return 0; } | 1342 | { return 0; } |
1343 | static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) | ||
1344 | { return 0; } | ||
1345 | static inline int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) | ||
1346 | { return 0; } | ||
1347 | |||
1335 | #endif | 1348 | #endif |
1336 | 1349 | ||
1337 | #endif /* __DWC2_CORE_H__ */ | 1350 | #endif /* __DWC2_CORE_H__ */ |
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 422ab7da4eb5..e9940dd004e4 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
@@ -3668,3 +3668,105 @@ int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg) | |||
3668 | 3668 | ||
3669 | return 0; | 3669 | return 0; |
3670 | } | 3670 | } |
3671 | |||
3672 | /** | ||
3673 | * dwc2_backup_device_registers() - Backup controller device registers. | ||
3674 | * When suspending usb bus, registers needs to be backuped | ||
3675 | * if controller power is disabled once suspended. | ||
3676 | * | ||
3677 | * @hsotg: Programming view of the DWC_otg controller | ||
3678 | */ | ||
3679 | int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) | ||
3680 | { | ||
3681 | struct dwc2_dregs_backup *dr; | ||
3682 | int i; | ||
3683 | |||
3684 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
3685 | |||
3686 | /* Backup dev regs */ | ||
3687 | dr = &hsotg->dr_backup; | ||
3688 | |||
3689 | dr->dcfg = dwc2_readl(hsotg->regs + DCFG); | ||
3690 | dr->dctl = dwc2_readl(hsotg->regs + DCTL); | ||
3691 | dr->daintmsk = dwc2_readl(hsotg->regs + DAINTMSK); | ||
3692 | dr->diepmsk = dwc2_readl(hsotg->regs + DIEPMSK); | ||
3693 | dr->doepmsk = dwc2_readl(hsotg->regs + DOEPMSK); | ||
3694 | |||
3695 | for (i = 0; i < hsotg->num_of_eps; i++) { | ||
3696 | /* Backup IN EPs */ | ||
3697 | dr->diepctl[i] = dwc2_readl(hsotg->regs + DIEPCTL(i)); | ||
3698 | |||
3699 | /* Ensure DATA PID is correctly configured */ | ||
3700 | if (dr->diepctl[i] & DXEPCTL_DPID) | ||
3701 | dr->diepctl[i] |= DXEPCTL_SETD1PID; | ||
3702 | else | ||
3703 | dr->diepctl[i] |= DXEPCTL_SETD0PID; | ||
3704 | |||
3705 | dr->dieptsiz[i] = dwc2_readl(hsotg->regs + DIEPTSIZ(i)); | ||
3706 | dr->diepdma[i] = dwc2_readl(hsotg->regs + DIEPDMA(i)); | ||
3707 | |||
3708 | /* Backup OUT EPs */ | ||
3709 | dr->doepctl[i] = dwc2_readl(hsotg->regs + DOEPCTL(i)); | ||
3710 | |||
3711 | /* Ensure DATA PID is correctly configured */ | ||
3712 | if (dr->doepctl[i] & DXEPCTL_DPID) | ||
3713 | dr->doepctl[i] |= DXEPCTL_SETD1PID; | ||
3714 | else | ||
3715 | dr->doepctl[i] |= DXEPCTL_SETD0PID; | ||
3716 | |||
3717 | dr->doeptsiz[i] = dwc2_readl(hsotg->regs + DOEPTSIZ(i)); | ||
3718 | dr->doepdma[i] = dwc2_readl(hsotg->regs + DOEPDMA(i)); | ||
3719 | } | ||
3720 | dr->valid = true; | ||
3721 | return 0; | ||
3722 | } | ||
3723 | |||
3724 | /** | ||
3725 | * dwc2_restore_device_registers() - Restore controller device registers. | ||
3726 | * When resuming usb bus, device registers needs to be restored | ||
3727 | * if controller power were disabled. | ||
3728 | * | ||
3729 | * @hsotg: Programming view of the DWC_otg controller | ||
3730 | */ | ||
3731 | int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) | ||
3732 | { | ||
3733 | struct dwc2_dregs_backup *dr; | ||
3734 | u32 dctl; | ||
3735 | int i; | ||
3736 | |||
3737 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
3738 | |||
3739 | /* Restore dev regs */ | ||
3740 | dr = &hsotg->dr_backup; | ||
3741 | if (!dr->valid) { | ||
3742 | dev_err(hsotg->dev, "%s: no device registers to restore\n", | ||
3743 | __func__); | ||
3744 | return -EINVAL; | ||
3745 | } | ||
3746 | dr->valid = false; | ||
3747 | |||
3748 | dwc2_writel(dr->dcfg, hsotg->regs + DCFG); | ||
3749 | dwc2_writel(dr->dctl, hsotg->regs + DCTL); | ||
3750 | dwc2_writel(dr->daintmsk, hsotg->regs + DAINTMSK); | ||
3751 | dwc2_writel(dr->diepmsk, hsotg->regs + DIEPMSK); | ||
3752 | dwc2_writel(dr->doepmsk, hsotg->regs + DOEPMSK); | ||
3753 | |||
3754 | for (i = 0; i < hsotg->num_of_eps; i++) { | ||
3755 | /* Restore IN EPs */ | ||
3756 | dwc2_writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i)); | ||
3757 | dwc2_writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i)); | ||
3758 | dwc2_writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i)); | ||
3759 | |||
3760 | /* Restore OUT EPs */ | ||
3761 | dwc2_writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i)); | ||
3762 | dwc2_writel(dr->doeptsiz[i], hsotg->regs + DOEPTSIZ(i)); | ||
3763 | dwc2_writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i)); | ||
3764 | } | ||
3765 | |||
3766 | /* Set the Power-On Programming done bit */ | ||
3767 | dctl = dwc2_readl(hsotg->regs + DCTL); | ||
3768 | dctl |= DCTL_PWRONPRGDONE; | ||
3769 | dwc2_writel(dctl, hsotg->regs + DCTL); | ||
3770 | |||
3771 | return 0; | ||
3772 | } | ||
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 2b5a706e7c32..b403f6ad27b9 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c | |||
@@ -3433,3 +3433,67 @@ void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) | |||
3433 | kfree(hsotg->frame_num_array); | 3433 | kfree(hsotg->frame_num_array); |
3434 | #endif | 3434 | #endif |
3435 | } | 3435 | } |
3436 | |||
3437 | /** | ||
3438 | * dwc2_backup_host_registers() - Backup controller host registers. | ||
3439 | * When suspending usb bus, registers needs to be backuped | ||
3440 | * if controller power is disabled once suspended. | ||
3441 | * | ||
3442 | * @hsotg: Programming view of the DWC_otg controller | ||
3443 | */ | ||
3444 | int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) | ||
3445 | { | ||
3446 | struct dwc2_hregs_backup *hr; | ||
3447 | int i; | ||
3448 | |||
3449 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
3450 | |||
3451 | /* Backup Host regs */ | ||
3452 | hr = &hsotg->hr_backup; | ||
3453 | hr->hcfg = dwc2_readl(hsotg->regs + HCFG); | ||
3454 | hr->haintmsk = dwc2_readl(hsotg->regs + HAINTMSK); | ||
3455 | for (i = 0; i < hsotg->core_params->host_channels; ++i) | ||
3456 | hr->hcintmsk[i] = dwc2_readl(hsotg->regs + HCINTMSK(i)); | ||
3457 | |||
3458 | hr->hprt0 = dwc2_read_hprt0(hsotg); | ||
3459 | hr->hfir = dwc2_readl(hsotg->regs + HFIR); | ||
3460 | hr->valid = true; | ||
3461 | |||
3462 | return 0; | ||
3463 | } | ||
3464 | |||
3465 | /** | ||
3466 | * dwc2_restore_host_registers() - Restore controller host registers. | ||
3467 | * When resuming usb bus, device registers needs to be restored | ||
3468 | * if controller power were disabled. | ||
3469 | * | ||
3470 | * @hsotg: Programming view of the DWC_otg controller | ||
3471 | */ | ||
3472 | int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) | ||
3473 | { | ||
3474 | struct dwc2_hregs_backup *hr; | ||
3475 | int i; | ||
3476 | |||
3477 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
3478 | |||
3479 | /* Restore host regs */ | ||
3480 | hr = &hsotg->hr_backup; | ||
3481 | if (!hr->valid) { | ||
3482 | dev_err(hsotg->dev, "%s: no host registers to restore\n", | ||
3483 | __func__); | ||
3484 | return -EINVAL; | ||
3485 | } | ||
3486 | hr->valid = false; | ||
3487 | |||
3488 | dwc2_writel(hr->hcfg, hsotg->regs + HCFG); | ||
3489 | dwc2_writel(hr->haintmsk, hsotg->regs + HAINTMSK); | ||
3490 | |||
3491 | for (i = 0; i < hsotg->core_params->host_channels; ++i) | ||
3492 | dwc2_writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i)); | ||
3493 | |||
3494 | dwc2_writel(hr->hprt0, hsotg->regs + HPRT0); | ||
3495 | dwc2_writel(hr->hfir, hsotg->regs + HFIR); | ||
3496 | hsotg->frame_number = 0; | ||
3497 | |||
3498 | return 0; | ||
3499 | } | ||