summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2/gadget.c
diff options
context:
space:
mode:
authorRazmik Karapetyan <razmik@synopsys.com>2018-01-24 17:40:29 +0400
committerFelipe Balbi <felipe.balbi@linux.intel.com>2018-03-13 10:47:46 +0200
commit66e77a24a8c36ff83f0a12f44d23d8141e82fa3b (patch)
tree48d32823c0d551c384da14017bd9c58a24a693df /drivers/usb/dwc2/gadget.c
parent42c6a25235677ad3568af080b0569e05a9f849fc (diff)
downloadlinux-66e77a24a8c36ff83f0a12f44d23d8141e82fa3b.tar.bz2
usb: dwc2: Add ACG support to the driver
Added function for supporting Active Clock Gating functionality in the driver. PCGCCTL1 (Power and Clock Control) register will be used for controlling the core`s active clock gating feature, and the previously reserved 12th bit in GHWCFG4 now indicates that the controller supports the Dynamic Power Reduction (Active Clock Gating) during no traffic scenarios such as L0, idle, resume and suspend states. dwc2_enable_acg() function sets GATEEN bit in PCGCCTL1 register and enables ACG, if it supported. According to ACG functional specification, enabling of ACG feature in host mode done in host initialization, before turning Vbus on, specifically in dwc2_core_host_init function. Enabling of ACG feature in device mode done in device initialization, before clearing the SftDiscon bit in DCTL. This bit was cleared in dwc2_hsotg_core_connect() function.So dwc2_enable_acg() called before dwc2_core_connect() calls. Signed-off-by: Razmik Karapetyan <razmik@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc2/gadget.c')
-rw-r--r--drivers/usb/dwc2/gadget.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 481684385bfe..47b098380f10 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -4346,6 +4346,8 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on)
if (is_on) {
hsotg->enabled = 1;
dwc2_hsotg_core_init_disconnected(hsotg, false);
+ /* Enable ACG feature in device mode,if supported */
+ dwc2_enable_acg(hsotg);
dwc2_hsotg_core_connect(hsotg);
} else {
dwc2_hsotg_core_disconnect(hsotg);
@@ -4378,8 +4380,11 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
hsotg->op_state = OTG_STATE_B_PERIPHERAL;
dwc2_hsotg_core_init_disconnected(hsotg, false);
- if (hsotg->enabled)
+ if (hsotg->enabled) {
+ /* Enable ACG feature in device mode,if supported */
+ dwc2_enable_acg(hsotg);
dwc2_hsotg_core_connect(hsotg);
+ }
} else {
dwc2_hsotg_core_disconnect(hsotg);
dwc2_hsotg_disconnect(hsotg);
@@ -4744,8 +4749,11 @@ int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg)
spin_lock_irqsave(&hsotg->lock, flags);
dwc2_hsotg_core_init_disconnected(hsotg, false);
- if (hsotg->enabled)
+ if (hsotg->enabled) {
+ /* Enable ACG feature in device mode,if supported */
+ dwc2_enable_acg(hsotg);
dwc2_hsotg_core_connect(hsotg);
+ }
spin_unlock_irqrestore(&hsotg->lock, flags);
}