summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@stericsson.com>2012-01-04 10:38:26 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-01-04 10:38:26 +0100
commit29e768a9303bcb2bff71b445ce740ef60a260da4 (patch)
treec7be1ad315cb7a28528818de9dd9ac80b36bbf99
parentff3e21a6ffdc19cd31c211a00abb3bc3e3b80ef7 (diff)
parentd1c951bf6d73d7daaf74bb8e0f83e02531b0f7f6 (diff)
Merge branch 'stable-linux-ux500-3.1' into stable-android-ux500-3.1
-rw-r--r--drivers/usb/musb/musb_host.c1
-rw-r--r--drivers/usb/musb/ux500.c14
-rw-r--r--drivers/usb/otg/ab8500-usb.c76
3 files changed, 24 insertions, 67 deletions
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 07e25fa1bf2..f12b046b0d6 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1169,7 +1169,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
} while ((tx_csr & MUSB_TXCSR_TXPKTRDY) != 0);
dev_dbg(musb->controller, "TXPKTRDY Cleared. Continue...\n");
- return;
} else if (tx_csr & MUSB_TXCSR_H_NAKTIMEOUT) {
dev_dbg(musb->controller, "TX end=%d device not responding\n", epnum);
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c
index 9eaa8b1a8df..2b63da5d48a 100644
--- a/drivers/usb/musb/ux500.c
+++ b/drivers/usb/musb/ux500.c
@@ -228,11 +228,15 @@ static void musb_notify_idle(unsigned long _musb)
switch (musb->xceiv->state) {
case OTG_STATE_A_WAIT_BCON:
- devctl &= ~MUSB_DEVCTL_SESSION;
- musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
- musb->xceiv->state = OTG_STATE_B_IDLE;
- MUSB_DEV_MODE(musb);
+ if (devctl & MUSB_DEVCTL_BDEVICE) {
+ musb->xceiv->state = OTG_STATE_B_IDLE;
+ MUSB_DEV_MODE(musb);
+ } else {
+ musb->xceiv->state = OTG_STATE_A_IDLE;
+ MUSB_HST_MODE(musb);
+ }
break;
+
case OTG_STATE_A_SUSPEND:
default:
break;
@@ -261,6 +265,8 @@ static int musb_otg_notifications(struct notifier_block *nb,
case USB_EVENT_NONE:
dev_dbg(musb->controller, "VBUS Disconnect\n");
+ if (is_otg_enabled(musb))
+ ux500_musb_set_vbus(musb, 0);
break;
default:
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c
index ed82c9859b9..881729da89c 100644
--- a/drivers/usb/otg/ab8500-usb.c
+++ b/drivers/usb/otg/ab8500-usb.c
@@ -391,10 +391,17 @@ static void ab8500_usb_delayed_work(struct work_struct *work)
static irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data)
{
struct ab8500_usb *ab = (struct ab8500_usb *) data;
+ enum usb_xceiv_events event;
/* Link status will not be updated till phy is disabled. */
- if (ab->mode == USB_HOST)
+ if (ab->mode == USB_HOST) {
+ event = USB_EVENT_NONE;
+ ab->otg.default_a = false;
+ ab->vbus_draw = 0;
+ atomic_notifier_call_chain(&ab->otg.notifier,
+ event, &ab->vbus_draw);
ab8500_usb_host_phy_dis(ab);
+ }
else if (ab->mode == USB_PERIPHERAL)
ab8500_usb_peri_phy_dis(ab);
else if (ab->mode == USB_DEDICATED_CHG && ab->rev == 0x20) {
@@ -478,23 +485,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;
}
@@ -509,22 +506,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;
}
@@ -536,11 +525,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,
@@ -570,39 +554,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;
}