summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRakesh Bodla <rbodla@nvidia.com>2011-08-20 23:25:19 +0530
committerNiket Sirsi <nsirsi@nvidia.com>2011-08-22 17:46:53 -0700
commit67b7a1e686bd6822930f8936d89a85460b9aa884 (patch)
tree2e3e2214dca7bba634cce100c2b4840a37bd9af8
parent96a6d869cf22757430bdd7f54d53f73c0baefe79 (diff)
usb: gadget: fsl: proper handling of regulator apis
Regulator apis for setting current should not be called from interrupt context. Hence, scheduling a separate work for that. Bug 854993 Change-Id: I7ff75bb2b9b2f8c0c658cf9097e93d3cfe599775 Reviewed-on: http://git-master/r/48331 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> Tested-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-by: Rakesh Bodla <rbodla@nvidia.com>
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c19
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.h2
2 files changed, 18 insertions, 3 deletions
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 275c4ee38281..d4b689d631df 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1320,9 +1320,8 @@ static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA)
udc = container_of(gadget, struct fsl_udc, gadget);
/* check udc regulator is available for drawing the vbus current */
if (udc->vbus_regulator) {
- /* set the current limit in uA and return */
- return regulator_set_current_limit(
- udc->vbus_regulator, 0, mA*1000);
+ udc->current_limit = mA;
+ schedule_work(&udc->charger_work);
}
if (udc->transceiver)
@@ -2066,6 +2065,19 @@ static void reset_irq(struct fsl_udc *udc)
#endif
}
+static void fsl_udc_set_current_limit_work(struct work_struct* work)
+{
+ struct fsl_udc *udc = container_of (work, struct fsl_udc, charger_work);
+
+ /* check udc regulator is available for drawing vbus current*/
+ if (udc->vbus_regulator) {
+ /* set the current limit in uA */
+ regulator_set_current_limit(
+ udc->vbus_regulator, 0,
+ udc->current_limit *1000);
+ }
+}
+
/*
* If VBUS is detected and setup packet is not received in 100ms then
* work thread starts and checks for the USB charger detection.
@@ -2865,6 +2877,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
/* create a delayed work for detecting the USB charger */
INIT_DELAYED_WORK(&udc_controller->work, fsl_udc_charger_detect_work);
+ INIT_WORK(&udc_controller->charger_work, fsl_udc_set_current_limit_work);
#ifdef CONFIG_USB_OTG_UTILS
udc_controller->transceiver = otg_get_transceiver();
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
index 5c99d07933e4..59807af2b27f 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -634,6 +634,8 @@ struct fsl_udc {
u8 device_address; /* Device USB address */
struct delayed_work work; /* delayed work for charger detection */
struct regulator *vbus_regulator; /* regulator for drawing VBUS */
+ u32 current_limit;
+ struct work_struct charger_work; /* work for settting regulator current limit */
};
/*-------------------------------------------------------------------------*/