All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] USB: gadget: atmel_usba_udc: Enable/disable USB PLL on Vbus change
@ 2015-01-16 22:21 Sylvain Rochet
  2015-01-17  1:42 ` Alexandre Belloni
  0 siblings, 1 reply; 20+ messages in thread
From: Sylvain Rochet @ 2015-01-16 22:21 UTC (permalink / raw)
  To: linux-arm-kernel

Prepare_enable on rising edge, disable_unprepare on falling edge. Reduce
power consumption if USB PLL is not already necessary for OHCI or EHCI.
If USB host is not connected we can sleep with USB PLL stopped.

This driver does not support suspend/resume yet, not suspending if we
are still attached to an USB host is fine for what I need, this patch
allow suspending with USB PLL stopped when USB device is not currently
used.

Signed-off-by: Sylvain Rochet <sylvain.rochet@finsecur.com>
---
 drivers/usb/gadget/udc/atmel_usba_udc.c | 37 +++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
index ce88237..8ea0a63 100644
--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
@@ -1723,6 +1723,7 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid)
 {
 	struct usba_udc *udc = devid;
 	int vbus;
+	int ret;
 
 	/* debounce */
 	udelay(10);
@@ -1736,6 +1737,15 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid)
 	vbus = vbus_is_present(udc);
 	if (vbus != udc->vbus_prev) {
 		if (vbus) {
+			ret = clk_prepare_enable(udc->pclk);
+			if (ret)
+				goto out;
+			ret = clk_prepare_enable(udc->hclk);
+			if (ret) {
+				clk_disable_unprepare(udc->pclk);
+				goto out;
+			}
+
 			toggle_bias(1);
 			usba_writel(udc, CTRL, USBA_ENABLE_MASK);
 			usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
@@ -1744,6 +1754,10 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid)
 			reset_all_endpoints(udc);
 			toggle_bias(0);
 			usba_writel(udc, CTRL, USBA_DISABLE_MASK);
+
+			clk_disable_unprepare(udc->hclk);
+			clk_disable_unprepare(udc->pclk);
+
 			if (udc->driver->disconnect) {
 				spin_unlock(&udc->lock);
 				udc->driver->disconnect(&udc->gadget);
@@ -1772,15 +1786,6 @@ static int atmel_usba_start(struct usb_gadget *gadget,
 	udc->driver = driver;
 	spin_unlock_irqrestore(&udc->lock, flags);
 
-	ret = clk_prepare_enable(udc->pclk);
-	if (ret)
-		return ret;
-	ret = clk_prepare_enable(udc->hclk);
-	if (ret) {
-		clk_disable_unprepare(udc->pclk);
-		return ret;
-	}
-
 	udc->vbus_prev = 0;
 	if (gpio_is_valid(udc->vbus_pin))
 		enable_irq(gpio_to_irq(udc->vbus_pin));
@@ -1788,13 +1793,27 @@ static int atmel_usba_start(struct usb_gadget *gadget,
 	/* If Vbus is present, enable the controller and wait for reset */
 	spin_lock_irqsave(&udc->lock, flags);
 	if (vbus_is_present(udc) && udc->vbus_prev == 0) {
+		ret = clk_prepare_enable(udc->pclk);
+		if (ret)
+			goto out;
+		ret = clk_prepare_enable(udc->hclk);
+		if (ret) {
+			clk_disable_unprepare(udc->pclk);
+			goto out;
+		}
+
 		toggle_bias(1);
 		usba_writel(udc, CTRL, USBA_ENABLE_MASK);
 		usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
+
+		udc->vbus_prev = 1;
 	}
 	spin_unlock_irqrestore(&udc->lock, flags);
 
 	return 0;
+out:
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return ret;
 }
 
 static int atmel_usba_stop(struct usb_gadget *gadget)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2015-01-20 11:11 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-16 22:21 [PATCH] USB: gadget: atmel_usba_udc: Enable/disable USB PLL on Vbus change Sylvain Rochet
2015-01-17  1:42 ` Alexandre Belloni
2015-01-17  9:43   ` Boris Brezillon
2015-01-17 11:07     ` Sylvain Rochet
2015-01-18 14:51       ` [PATCHv2 0/2] " Sylvain Rochet
2015-01-18 14:51         ` [PATCHv2 1/2] USB: gadget: atmel_usba_udc: Fixed vbus_prev initial state Sylvain Rochet
2015-01-18 14:51         ` [PATCH 2/2] USB: gadget: atmel_usba_udc: Enable/disable USB PLL on Vbus change Sylvain Rochet
2015-01-18 16:56           ` Boris Brezillon
2015-01-18 17:24             ` [PATCHv3 0/2] " Sylvain Rochet
2015-01-18 17:24               ` [PATCHv3 1/2] USB: gadget: atmel_usba_udc: Fixed vbus_prev initial state Sylvain Rochet
2015-01-19 14:09                 ` Nicolas Ferre
2015-01-19 18:55                   ` Felipe Balbi
2015-01-20 11:02                     ` Sylvain Rochet
2015-01-20 11:11                       ` Nicolas Ferre
2015-01-18 17:24               ` [PATCHv3 2/2] USB: gadget: atmel_usba_udc: Enable/disable USB PLL on Vbus change Sylvain Rochet
2015-01-19 16:55                 ` Nicolas Ferre
2015-01-19 17:46                   ` Sylvain Rochet
2015-01-19 20:15                     ` Boris Brezillon
2015-01-20  9:02                       ` Nicolas Ferre
2015-01-18 17:34           ` [PATCH " Boris Brezillon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.