summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSakethram Bommisetti <sakethram.bommisetti@stericsson.com>2011-11-15 13:49:23 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-01-04 09:50:27 +0100
commit71afa14dad23bdacf2d98c32a2b2c1c1260398c3 (patch)
tree6b0ca8e04e2cf805d9691ec4af99a2a3f3b8e8ce
parente5c9e251051cc58fa7c924abab671ef28d1695cd (diff)
u8500:USB:Handle multiple Link status fn calls
During boot time, multiple calls are made to Link status function by otg_set_host and otg_set_peripheral. This in turn calls clock and regulator enabling multiple times which creates problem with the reference count of regulators. Hence this blocks the CPU idle since the regulators are not released properly due to multiple acquire. So, Link status function calls are removed from otg_set_host and otg_set_peripheral which are not needed. The Link status call during boot shall be handled by the ab8500_usb_boot_detect function. ST-Ericsson ID: 373105 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I2ead5b546273be822b3e9e9f588a1954b3fa10f2 Signed-off-by: Sakethram Bommisetti <sakethram.bommisetti@stericsson.com>
-rw-r--r--drivers/usb/otg/ab8500-usb.c67
1 files changed, 6 insertions, 61 deletions
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c
index 3420c800852..735a6c51ff2 100644
--- a/drivers/usb/otg/ab8500-usb.c
+++ b/drivers/usb/otg/ab8500-usb.c
@@ -475,23 +475,13 @@ static int ab8500_usb_set_peripheral(struct otg_transceiver *otg,
ab = xceiv_to_ab(otg);
+ ab->otg.gadget = gadget;
/* Some drivers call this function in atomic context.
* Do not update ab8500 registers directly till this
* is fixed.
*/
-
- if (!gadget) {
- ab->otg.gadget = NULL;
+ if (!gadget)
schedule_work(&ab->phy_dis_work);
- } else {
- ab->otg.gadget = gadget;
-
- /* Phy will not be enabled if cable is already
- * plugged-in. Schedule to enable phy.
- * Use same delay to avoid any race condition.
- */
- schedule_delayed_work(&ab->dwork, ab->link_status_wait);
- }
return 0;
}
@@ -506,22 +496,14 @@ static int ab8500_usb_set_host(struct otg_transceiver *otg,
ab = xceiv_to_ab(otg);
+ ab->otg.host = host;
+
/* Some drivers call this function in atomic context.
* Do not update ab8500 registers directly till this
* is fixed.
*/
-
- if (!host) {
- ab->otg.host = NULL;
+ if (!host)
schedule_work(&ab->phy_dis_work);
- } else {
- ab->otg.host = host;
- /* Phy will not be enabled if cable is already
- * plugged-in. Schedule to enable phy.
- * Use same delay to avoid any race condition.
- */
- schedule_delayed_work(&ab->dwork, ab->link_status_wait);
- }
return 0;
}
@@ -533,11 +515,6 @@ static int ab8500_usb_set_host(struct otg_transceiver *otg,
*/
static int ab8500_usb_boot_detect(struct ab8500_usb *ab)
{
- int err;
- struct device *device = ab->dev;
- u8 usb_status = 0;
- u8 val = 0;
-
/* Disabling PHY before selective enable or disable */
abx500_mask_and_set_register_interruptible(ab->dev,
AB8500_USB,
@@ -567,39 +544,7 @@ static int ab8500_usb_boot_detect(struct ab8500_usb *ab)
AB8500_BIT_PHY_CTRL_HOST_EN,
0);
-
- err = abx500_get_register_interruptible(device,
- AB8500_INTERRUPT, AB8500_IT_SOURCE20_REG,
- &usb_status);
- if (err < 0) {
- dev_err(device, "Read IT 20 failed\n");
- return err;
- }
-
- if (usb_status & AB8500_SRC_INT_USB_HOST)
- ab8500_usb_host_phy_en(ab);
-
-
- err = abx500_get_register_interruptible(device,
- AB8500_INTERRUPT, AB8500_IT_SOURCE2_REG,
- &usb_status);
- if (err < 0) {
- dev_err(device, "Read IT 2 failed\n");
- return err;
- }
-
- if (usb_status & AB8500_SRC_INT_USB_DEVICE) {
- /* Check if it is a dedicated charger */
- (void)abx500_get_register_interruptible(device,
- AB8500_USB, AB8500_USB_LINE_STAT_REG, &val);
-
- val = (val >> 3) & 0x0F;
-
- if (val == USB_LINK_DEDICATED_CHG)
- ab->mode = USB_DEDICATED_CHG;
- else
- ab8500_usb_peri_phy_en(ab);
- }
+ ab8500_usb_link_status_update(ab);
return 0;
}