diff mbox

[RFC,3/5] usb: hub: add device_path regulator control to generic hub

Message ID 20121126124544.18106.60130.stgit@build.warmcat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andy Green Nov. 26, 2012, 12:45 p.m. UTC
This adds the config option to associate a regulator with each hub,
when the hub on a specific, interesting device path appears, then
the regular is powered while the logical hub exists.

Signed-off-by: Andy Green <andy.green@linaro.org>
---
 drivers/usb/core/Kconfig |   10 ++++++++++
 drivers/usb/core/hub.c   |   26 +++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)


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

Comments

Greg KH Nov. 26, 2012, 7:23 p.m. UTC | #1
On Mon, Nov 26, 2012 at 12:45:45PM +0000, Andy Green wrote:
> This adds the config option to associate a regulator with each hub,
> when the hub on a specific, interesting device path appears, then
> the regular is powered while the logical hub exists.
> 
> Signed-off-by: Andy Green <andy.green@linaro.org>
> ---
>  drivers/usb/core/Kconfig |   10 ++++++++++
>  drivers/usb/core/hub.c   |   26 +++++++++++++++++++++++++-
>  2 files changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
> index f70c1a1..4a91eb1 100644
> --- a/drivers/usb/core/Kconfig
> +++ b/drivers/usb/core/Kconfig
> @@ -95,3 +95,13 @@ config USB_OTG_BLACKLIST_HUB
>  	  and software costs by not supporting external hubs.  So
>  	  are "Embedded Hosts" that don't offer OTG support.
>  
> +config USB_HUB_DEVICE_PATH_REGULATOR
> +	bool "Support generic regulators at hubs"
> +	select DEVICEPATH
> +	depends on USB
> +	default n
> +	help
> +	  Allows you to use the device_path APIs to associate kernel regulators
> +	  with dynamically probed USB hubs, so the regulators are enabled
> +	  as the appropriate hub instance gets created and disabled as it
> +	  is destroyed.

Even if I did like the device_path code (which I do not), this needs to
be rewritten to actually make sense to a user who would have to pick
this option, not a kernel developer.

> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index a815fd2..49ebb5e 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -26,6 +26,7 @@
>  #include <linux/mutex.h>
>  #include <linux/freezer.h>
>  #include <linux/random.h>
> +#include <linux/regulator/consumer.h>
>  
>  #include <asm/uaccess.h>
>  #include <asm/byteorder.h>
> @@ -54,7 +55,9 @@ struct usb_hub {
>  	struct usb_device	*hdev;
>  	struct kref		kref;
>  	struct urb		*urb;		/* for interrupt polling pipe */
> -
> +#ifdef CONFIG_USB_HUB_DEVICE_PATH_REGULATOR

No #ifdefs in .c files, if at all possible please.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index f70c1a1..4a91eb1 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -95,3 +95,13 @@  config USB_OTG_BLACKLIST_HUB
 	  and software costs by not supporting external hubs.  So
 	  are "Embedded Hosts" that don't offer OTG support.
 
+config USB_HUB_DEVICE_PATH_REGULATOR
+	bool "Support generic regulators at hubs"
+	select DEVICEPATH
+	depends on USB
+	default n
+	help
+	  Allows you to use the device_path APIs to associate kernel regulators
+	  with dynamically probed USB hubs, so the regulators are enabled
+	  as the appropriate hub instance gets created and disabled as it
+	  is destroyed.
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a815fd2..49ebb5e 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@ 
 #include <linux/mutex.h>
 #include <linux/freezer.h>
 #include <linux/random.h>
+#include <linux/regulator/consumer.h>
 
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
@@ -54,7 +55,9 @@  struct usb_hub {
 	struct usb_device	*hdev;
 	struct kref		kref;
 	struct urb		*urb;		/* for interrupt polling pipe */
-
+#ifdef CONFIG_USB_HUB_DEVICE_PATH_REGULATOR
+	struct regulator	*regulator;	/* optional power control */
+#endif
 	/* buffer for urb ... with extra space in case of babble */
 	char			(*buffer)[8];
 	union {
@@ -1594,6 +1597,12 @@  static void hub_disconnect(struct usb_interface *intf)
 	if (hub->hdev->speed == USB_SPEED_HIGH)
 		highspeed_hubs--;
 
+#ifdef CONFIG_USB_HUB_DEVICE_PATH_REGULATOR
+	if (hub->regulator && !IS_ERR(hub->regulator)) {
+		regulator_disable(hub->regulator);
+		regulator_put(hub->regulator);
+	}
+#endif
 	usb_free_urb(hub->urb);
 	kfree(hub->ports);
 	kfree(hub->descriptor);
@@ -1609,6 +1618,9 @@  static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_device *hdev;
 	struct usb_hub *hub;
+#ifdef CONFIG_USB_HUB_DEVICE_PATH_REGULATOR
+	char *dev_path;
+#endif
 
 	desc = intf->cur_altsetting;
 	hdev = interface_to_usbdev(intf);
@@ -1692,6 +1704,18 @@  descriptor_error:
 		return -ENOMEM;
 	}
 
+#ifdef CONFIG_USB_HUB_DEVICE_PATH_REGULATOR
+	/* if a regulator is associated on our device_path, use it */
+	dev_path = kmalloc(MAX_DEV_PATH_SIZE, GFP_KERNEL);
+	if (!device_path_generate(&hdev->dev, dev_path, MAX_DEV_PATH_SIZE)) {
+		dev_info(&hdev->dev, "device_path: %s\n", dev_path);
+		hub->regulator = regulator_get(&hdev->dev, dev_path);
+		if (!IS_ERR(hub->regulator))
+			regulator_enable(hub->regulator);
+	}
+	kfree(dev_path);
+#endif
+
 	kref_init(&hub->kref);
 	INIT_LIST_HEAD(&hub->event_list);
 	hub->intfdev = &intf->dev;