aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ehci-hcd.c16
-rw-r--r--drivers/usb/host/ehci-langwell-pci.c151
2 files changed, 119 insertions, 48 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 535a1aa8990..10ed7452b5b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -43,8 +43,6 @@
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/unaligned.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/langwell_otg.h>
/*-------------------------------------------------------------------------*/
@@ -1159,7 +1157,7 @@ MODULE_LICENSE ("GPL");
#define PCI_DRIVER ehci_pci_driver
#ifdef CONFIG_USB_LANGWELL_OTG
#include "ehci-langwell-pci.c"
-#define LNW_OTG_HOST_DRIVER ehci_otg_driver
+#define INTEL_MID_OTG_HOST_DRIVER ehci_otg_driver
#endif
#endif
@@ -1286,16 +1284,16 @@ static int __init ehci_hcd_init(void)
goto clean4;
#endif
-#ifdef LNW_OTG_HOST_DRIVER
- retval = langwell_register_host(&LNW_OTG_HOST_DRIVER);
+#ifdef INTEL_MID_OTG_HOST_DRIVER
+ retval = intel_mid_ehci_driver_register(&INTEL_MID_OTG_HOST_DRIVER);
if (retval < 0)
goto clean5;
#endif
return retval;
-#ifdef LNW_OTG_HOST_DRIVER
+#ifdef INTEL_MID_OTG_HOST_DRIVER
clean5:
- langwell_unregister_host(&LNW_OTG_HOST_DRIVER);
+ intel_mid_ehci_driver_unregister(&INTEL_MID_OTG_HOST_DRIVER);
#endif
#ifdef XILINX_OF_PLATFORM_DRIVER
/* of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); */
@@ -1329,8 +1327,8 @@ module_init(ehci_hcd_init);
static void __exit ehci_hcd_cleanup(void)
{
-#ifdef LNW_OTG_HOST_DRIVER
- langwell_unregister_host(&LNW_OTG_HOST_DRIVER);
+#ifdef INTEL_MID_OTG_HOST_DRIVER
+ intel_mid_ehci_driver_unregister(&INTEL_MID_OTG_HOST_DRIVER);
#endif
#ifdef XILINX_OF_PLATFORM_DRIVER
of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER);
diff --git a/drivers/usb/host/ehci-langwell-pci.c b/drivers/usb/host/ehci-langwell-pci.c
index 64ffd6020e3..46b09851175 100644
--- a/drivers/usb/host/ehci-langwell-pci.c
+++ b/drivers/usb/host/ehci-langwell-pci.c
@@ -1,7 +1,7 @@
/*
- * Intel Moorestown Platform Langwell OTG EHCI Controller PCI Bus Glue.
+ * Intel MID Platform Langwell/Penwell OTG EHCI Controller PCI Bus Glue.
*
- * Copyright (c) 2008 - 2009, Intel Corporation.
+ * Copyright (c) 2008 - 2010, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License 2 as published by the
@@ -17,23 +17,24 @@
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/usb/otg.h>
+#include <linux/usb/intel_mid_otg.h>
+
static int usb_otg_suspend(struct usb_hcd *hcd)
{
struct otg_transceiver *otg;
- struct langwell_otg *iotg;
+ struct intel_mid_otg_xceiv *iotg;
otg = otg_get_transceiver();
if (otg == NULL) {
printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__);
return -EINVAL;
}
- iotg = container_of(otg, struct langwell_otg, otg);
+ iotg = otg_to_mid_xceiv(otg);
printk(KERN_INFO "%s OTG HNP update suspend\n", __func__);
- if (iotg->otg.default_a)
- iotg->hsm.a_suspend_req = 1;
- else
- iotg->hsm.b_bus_req = 0;
- langwell_update_transceiver();
+
+ atomic_notifier_call_chain(&iotg->iotg_notifier,
+ MID_OTG_NOTIFY_HSUSPEND, iotg);
otg_put_transceiver(otg);
return 0;
}
@@ -41,19 +42,18 @@ static int usb_otg_suspend(struct usb_hcd *hcd)
static int usb_otg_resume(struct usb_hcd *hcd)
{
struct otg_transceiver *otg;
- struct langwell_otg *iotg;
+ struct intel_mid_otg_xceiv *iotg;
otg = otg_get_transceiver();
if (otg == NULL) {
printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__);
return -EINVAL;
}
- iotg = container_of(otg, struct langwell_otg, otg);
+ iotg = otg_to_mid_xceiv(otg);
printk(KERN_INFO "%s OTG HNP update resume\n", __func__);
- if (iotg->otg.default_a) {
- iotg->hsm.b_bus_resume = 1;
- langwell_update_transceiver();
- }
+
+ atomic_notifier_call_chain(&iotg->iotg_notifier,
+ MID_OTG_NOTIFY_HRESUME, iotg);
otg_put_transceiver(otg);
return 0;
}
@@ -62,54 +62,52 @@ static int usb_otg_resume(struct usb_hcd *hcd)
static void otg_notify(struct usb_device *udev, unsigned action)
{
struct otg_transceiver *otg;
- struct langwell_otg *iotg;
+ struct intel_mid_otg_xceiv *iotg;
+
+ /* Ignore root hub add/remove event */
+ if (!udev->parent) {
+ printk(KERN_INFO "%s Ignore root hub otg_notify\n", __func__);
+ return;
+ }
otg = otg_get_transceiver();
if (otg == NULL) {
printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__);
return;
}
- iotg = container_of(otg, struct langwell_otg, otg);
+ iotg = otg_to_mid_xceiv(otg);
switch (action) {
case USB_DEVICE_ADD:
pr_debug("Notify OTG HNP add device\n");
- if (iotg->otg.default_a == 1)
- iotg->hsm.b_conn = 1;
- else
- iotg->hsm.a_conn = 1;
+ atomic_notifier_call_chain(&iotg->iotg_notifier,
+ MID_OTG_NOTIFY_CONNECT, iotg);
break;
case USB_DEVICE_REMOVE:
pr_debug("Notify OTG HNP delete device\n");
- if (iotg->otg.default_a == 1)
- iotg->hsm.b_conn = 0;
- else
- iotg->hsm.a_conn = 0;
+ atomic_notifier_call_chain(&iotg->iotg_notifier,
+ MID_OTG_NOTIFY_DISCONN, iotg);
break;
default:
otg_put_transceiver(otg);
return ;
}
- if (spin_trylock(&iotg->wq_lock)) {
- langwell_update_transceiver();
- spin_unlock(&iotg->wq_lock);
- }
otg_put_transceiver(otg);
return;
}
-static int ehci_langwell_probe(struct pci_dev *pdev,
+static int ehci_mid_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct hc_driver *driver;
- struct langwell_otg *iotg;
struct otg_transceiver *otg;
+ struct intel_mid_otg_xceiv *iotg;
struct usb_hcd *hcd;
struct ehci_hcd *ehci;
int irq;
int retval;
- pr_debug("initializing Langwell USB OTG Host Controller\n");
+ pr_debug("initializing Intel MID USB OTG Host Controller\n");
/* we need not call pci_enable_dev since otg transceiver already take
* the control of this device and this probe actaully gets called by
@@ -142,8 +140,10 @@ static int ehci_langwell_probe(struct pci_dev *pdev,
retval = -EINVAL;
goto err1;
}
- iotg = container_of(otg, struct langwell_otg, otg);
- hcd->regs = iotg->regs;
+
+ iotg = otg_to_mid_xceiv(otg);
+ hcd->regs = iotg->base;
+
hcd->rsrc_start = pci_resource_start(pdev, 0);
hcd->rsrc_len = pci_resource_len(pdev, 0);
@@ -168,7 +168,7 @@ err1:
return retval;
}
-void ehci_langwell_remove(struct pci_dev *dev)
+void ehci_mid_remove(struct pci_dev *dev)
{
struct usb_hcd *hcd = pci_get_drvdata(dev);
@@ -178,13 +178,13 @@ void ehci_langwell_remove(struct pci_dev *dev)
usb_put_hcd(hcd);
}
-/* Langwell OTG EHCI driver */
+/* Intel MID OTG EHCI driver */
static struct pci_driver ehci_otg_driver = {
- .name = "ehci-langwell",
+ .name = "ehci-intel-mid",
.id_table = pci_ids,
- .probe = ehci_langwell_probe,
- .remove = ehci_langwell_remove,
+ .probe = ehci_mid_probe,
+ .remove = ehci_mid_remove,
#ifdef CONFIG_PM_SLEEP
.driver = {
@@ -193,3 +193,76 @@ static struct pci_driver ehci_otg_driver = {
#endif
.shutdown = usb_hcd_pci_shutdown,
};
+
+static int ehci_mid_start_host(struct intel_mid_otg_xceiv *iotg)
+{
+ struct pci_dev *pdev;
+ int retval;
+
+ if (iotg == NULL)
+ return -EINVAL;
+
+ pdev = to_pci_dev(iotg->otg.dev);
+
+ retval = ehci_mid_probe(pdev, ehci_otg_driver.id_table);
+ if (retval)
+ dev_dbg(iotg->otg.dev, "Failed to start host\n");
+
+ return retval;
+}
+
+static int ehci_mid_stop_host(struct intel_mid_otg_xceiv *iotg)
+{
+ struct pci_dev *pdev;
+
+ if (iotg == NULL)
+ return -EINVAL;
+
+ pdev = to_pci_dev(iotg->otg.dev);
+
+ ehci_mid_remove(pdev);
+
+ return 0;
+}
+
+static int intel_mid_ehci_driver_register(struct pci_driver *host_driver)
+{
+ struct otg_transceiver *otg;
+ struct intel_mid_otg_xceiv *iotg;
+
+ otg = otg_get_transceiver();
+ if (otg == NULL)
+ return -EINVAL;
+
+ iotg = otg_to_mid_xceiv(otg);
+ iotg->start_host = ehci_mid_start_host;
+ iotg->stop_host = ehci_mid_stop_host;
+
+ /* notify host driver is registered */
+ atomic_notifier_call_chain(&iotg->iotg_notifier,
+ MID_OTG_NOTIFY_HOSTADD, iotg);
+
+ otg_put_transceiver(otg);
+
+ return 0;
+}
+
+static void intel_mid_ehci_driver_unregister(struct pci_driver *host_driver)
+{
+ struct otg_transceiver *otg;
+ struct intel_mid_otg_xceiv *iotg;
+
+ otg = otg_get_transceiver();
+ if (otg == NULL)
+ return ;
+
+ iotg = otg_to_mid_xceiv(otg);
+ iotg->start_host = NULL;
+ iotg->stop_host = NULL;
+
+ /* notify host driver is unregistered */
+ atomic_notifier_call_chain(&iotg->iotg_notifier,
+ MID_OTG_NOTIFY_HOSTREMOVE, iotg);
+
+ otg_put_transceiver(otg);
+}