Hi Lee,
Thanks for your patch, and some comments about the modification
#1 The re-try you put into set_host function, may still fail again, right?
Actually I suspect that it is caused by loading order of the drivers,
USB driver uses IPC driver to set VBUS, if IPC driver loaded (init) after USB
OTG driver, IPC driver interface will always return failure(not ready). It only
happens at boot time. If it is this case, it can be fixed by change the driver
loading order.
#2 Re-try them in langwell_otg_set_host / langwell_otg_set_peripheral does not
make sense.
Delay vbus operation may cause USB OTG Spec violation
Langwell_otg_set_peripheral may be invoked at anytime when user
inserted/removed USB Gadget module.
Hao
From: [email protected]
[mailto:[email protected]] On Behalf Of [email protected]
Sent: Wednesday, November 24, 2010 2:56 PM
To: [email protected]
Subject: [Meego-kernel] [RFC] langwell_otg: langwell otg set vbus again if ipc
command failed
Hi,
Request for comment.
Thanks.
Lee
[RFC] langwell_otg: langwell otg set vbus again if ipc command failed
If a device (for example, hub/HID/storage) is connected when booting, setting
vbus power will fail.
This problem is langwell otg driver does not handle the error status when
setting vbus off/on via ipc command.
Re-try it when langwell_otg_set_peripheral() or langwell_otg_set_host().
diff -ruN a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c
--- a/drivers/usb/otg/langwell_otg.c 2010-11-23 13:40:50.480748000 +0800
+++ b/drivers/usb/otg/langwell_otg.c 2010-11-24 14:13:49.972907000 +0800
@@ -60,6 +60,7 @@
static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
struct usb_gadget *gadget);
static int langwell_otg_start_srp(struct otg_transceiver *otg);
+static int langwell_otg_set_vbus(struct otg_transceiver *otg, bool enabled);
static const struct pci_device_id pci_ids[] = {{
.class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
@@ -155,7 +156,11 @@
static int langwell_otg_set_host(struct otg_transceiver *otg,
struct usb_bus *host)
{
+ struct langwell_otg *lnw = the_transceiver;
+
otg->host = host;
+ if (lnw->iotg.hsm.vbus_failed)
+ langwell_otg_set_vbus(otg, 1);
return 0;
}
@@ -163,7 +168,11 @@
static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
struct usb_gadget *gadget)
{
+ struct langwell_otg *lnw = the_transceiver;
+
otg->gadget = gadget;
+ if (lnw->iotg.hsm.vbus_failed)
+ langwell_otg_set_vbus(otg, 0);
return 0;
}
@@ -189,8 +198,10 @@
if (intel_scu_ipc_simple_command(0xef, sub_id)) {
dev_dbg(lnw->dev, "Failed to set Vbus via IPC commands\n");
- return -EBUSY;
+ lnw->iotg.hsm.vbus_failed = 1;
+ return -EFAULT;
}
+ lnw->iotg.hsm.vbus_failed = 0;
dev_dbg(lnw->dev, "%s --->\n", __func__);
diff -ruN a/include/linux/usb/intel_mid_otg.h
b/include/linux/usb/intel_mid_otg.h
--- a/include/linux/usb/intel_mid_otg.h 2010-11-23 13:40:51.140755000
+0800
+++ b/include/linux/usb/intel_mid_otg.h 2010-11-24 14:13:55.886488000 +0800
@@ -89,6 +89,7 @@
/* Others */
int vbus_srp_up;
+ int vbus_failed;
};
/* must provide ULPI access function to read/write registers implemented in
_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel