[RFC/PATCH] usb: musb: only enable musb clock when necessary

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This will allow us to conserve some power by shutting down
musb when it's not in use. We can also have less problems
while dealing with usb charger detection if we:

sysfs_notify(tranceiver->kobj, NULL, "vbus");

echo 1 > /sys/devices/platform/musb_hdrc/wakeup (??? example only)

detect_usb_charger();

musb_writeb(musb->mregs, MUSB_POWER, power | MUSB_POWER_SOFTCONN);

setup_timer(&musb->wait_host_side_connection_timer);

if (host_on_the_other_end())
	load_gadget_driver();
else
	power_down_musb_again();

I still have to think about how to handle all of those, but
the idea is to start pushing more control to userland, then
we can make somehow a more generic interface for otg controllers,
usb battery charging, etc.

Comments are very welcome as this is still an idea. I can point
out the problems we had with RX51 in order to get usb charger
detection not to screw usb enumeration if it's needed.

NOT-YET-Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxx>
---
 drivers/usb/musb/musb_core.c   |    9 +++++++++
 drivers/usb/musb/musb_gadget.c |    7 +++++++
 2 files changed, 16 insertions(+), 0 deletions(-)

DO NOT APPLY THIS PATCH ANYWHERE, IT CAN BE USED FOR TESTING PURPOSES
TO BE SURE MUSB WILL PROBE FINE AND A GADGET DRIVER CAN BE LOADED, BUT
THAT'S IT.

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index b998c2d..4f9adbe 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1924,6 +1924,10 @@ bad_config:
 			musb->clock = NULL;
 			goto fail;
 		}
+
+		status = clk_enable(musb->clock);
+		if (status < 0)
+			goto fail2;
 	}
 
 	/* The musb_platform_init() call:
@@ -2063,10 +2067,15 @@ bad_config:
 	if (status)
 		goto fail2;
 
+	clk_disable(musb->clock);
+
 	return 0;
 
 fail2:
 	musb_platform_exit(musb);
+
+	if (musb->clock)
+		clk_disable(musb->clock);
 fail:
 	dev_err(musb->controller,
 		"musb_init_controller failed with status %d\n", status);
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 8012fdd..13c36d4 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1741,6 +1741,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	spin_unlock_irqrestore(&musb->lock, flags);
 
 	if (retval == 0) {
+		/* enable our clock, we will have register write soon */
+		retval = clk_enable(musb->clock);
+		if (retval < 0)
+			return retval;
+
 		retval = driver->bind(&musb->g);
 		if (retval != 0) {
 			DBG(3, "bind to driver %s failed --> %d\n",
@@ -1887,6 +1892,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 		 */
 	}
 
+	clk_disable(musb->clock);
+
 	return retval;
 }
 EXPORT_SYMBOL(usb_gadget_unregister_driver);
-- 
1.6.6.rc0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux