aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Youn <johnyoun@synopsys.com>2016-02-23 22:54:57 -0500
committerFelipe Balbi <balbi@kernel.org>2016-03-04 08:14:46 -0500
commit58e52ff6a6c3ce964c71b2dd9f06be426f993524 (patch)
treec3cfca9fe11fa5b11ac640c68dbc5b9b2725b9b5
parent9bbe91a1ea4cae20ff9f8f175c92e1e49b4296d9 (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.c183
-rw-r--r--drivers/usb/dwc2/core.h13
-rw-r--r--drivers/usb/dwc2/gadget.c102
-rw-r--r--drivers/usb/dwc2/hcd.c64
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 */
67static 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 */
95static 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
124static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
125{ return 0; }
126
127static 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 */
140static 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 */
192static 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
235static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
236{ return 0; }
237
238static 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);
1295extern void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2); 1295extern void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2);
1296extern int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode); 1296extern 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)
1298int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg);
1299int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg);
1298#else 1300#else
1299static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2) 1301static 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)
1317static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
1318{ return 0; }
1319static 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);
1320extern void dwc2_hcd_connect(struct dwc2_hsotg *hsotg); 1326extern void dwc2_hcd_connect(struct dwc2_hsotg *hsotg);
1321extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force); 1327extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force);
1322extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); 1328extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
1329int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg);
1330int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg);
1323#else 1331#else
1324static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) 1332static 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) {}
1332static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} 1340static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {}
1333static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) 1341static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
1334{ return 0; } 1342{ return 0; }
1343static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
1344{ return 0; }
1345static 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 */
3679int 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 */
3731int 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 */
3444int 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 */
3472int 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}