From 103e127d1f8f985e8a662da6537ebc5e08902ee3 Mon Sep 17 00:00:00 2001 From: Valentine Barshak Date: Wed, 4 Dec 2013 01:42:21 +0400 Subject: usb: hcd: Remove USB phy if needed This adds remove_phy flag to the HCD structure. If the flag is set and if hcd->phy is valid, the phy is shutdown and released whenever usb_add_hcd fails or usb_hcd_remove is called. This can be used by the HCD drivers to auto-remove the external USB phy when it is no longer needed. Signed-off-by: Valentine Barshak Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/usb/core/hcd.c') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 6bffb8c87bc9..7527c8e4ec64 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -44,6 +44,7 @@ #include #include +#include #include "usb.h" @@ -2603,7 +2604,7 @@ int usb_add_hcd(struct usb_hcd *hcd, */ if ((retval = hcd_buffer_create(hcd)) != 0) { dev_dbg(hcd->self.controller, "pool alloc failed\n"); - return retval; + goto err_remove_phy; } if ((retval = usb_register_bus(&hcd->self)) < 0) @@ -2734,6 +2735,12 @@ err_allocate_root_hub: usb_deregister_bus(&hcd->self); err_register_bus: hcd_buffer_destroy(hcd); +err_remove_phy: + if (hcd->remove_phy && hcd->phy) { + usb_phy_shutdown(hcd->phy); + usb_put_phy(hcd->phy); + hcd->phy = NULL; + } return retval; } EXPORT_SYMBOL_GPL(usb_add_hcd); @@ -2806,6 +2813,11 @@ void usb_remove_hcd(struct usb_hcd *hcd) usb_put_dev(hcd->self.root_hub); usb_deregister_bus(&hcd->self); hcd_buffer_destroy(hcd); + if (hcd->remove_phy && hcd->phy) { + usb_phy_shutdown(hcd->phy); + usb_put_phy(hcd->phy); + hcd->phy = NULL; + } } EXPORT_SYMBOL_GPL(usb_remove_hcd); -- cgit v1.2.3