diff options
author | Rakesh Bodla <rbodla@nvidia.com> | 2011-08-20 23:25:19 +0530 |
---|---|---|
committer | Niket Sirsi <nsirsi@nvidia.com> | 2011-08-22 17:46:53 -0700 |
commit | 67b7a1e686bd6822930f8936d89a85460b9aa884 (patch) | |
tree | 2e3e2214dca7bba634cce100c2b4840a37bd9af8 | |
parent | 96a6d869cf22757430bdd7f54d53f73c0baefe79 (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.c | 19 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_usb2_udc.h | 2 |
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 */ }; /*-------------------------------------------------------------------------*/ |