diff options
author | Sakethram Bommisetti <sakethram.bommisetti@stericsson.com> | 2011-11-15 13:49:23 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:03:12 +0200 |
commit | ed6b8a71d3ab63d73749278896ac515fc2ad0ca2 (patch) | |
tree | 9e35f56bf181a1db1d9e2d27280e44710f3c06cd | |
parent | 8ec6202f325cc95f90c8769368f9684abe68b3f9 (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.c | 67 |
1 files changed, 6 insertions, 61 deletions
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index 6b1b268acbc..189e764a68d 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c @@ -504,23 +504,13 @@ static int ab8500_usb_set_peripheral(struct usb_otg *otg, ab = phy_to_ab(otg->phy); + ab->otg.gadget = gadget; /* Some drivers call this function in atomic context. * Do not update ab8500 registers directly till this * is fixed. */ - - if (!gadget) { - otg->gadget = NULL; + if (!gadget) schedule_work(&ab->phy_dis_work); - } else { - 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; } @@ -534,22 +524,14 @@ static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) ab = phy_to_ab(otg->phy); + ab->otg.host = host; + /* Some drivers call this function in atomic context. * Do not update ab8500 registers directly till this * is fixed. */ - - if (!host) { - otg->host = NULL; + if (!host) schedule_work(&ab->phy_dis_work); - } else { - 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; } @@ -561,11 +543,6 @@ static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) */ 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, @@ -595,39 +572,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; } |