summaryrefslogtreecommitdiff
path: root/drivers/usb/host/ohci-omap.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/usb/host/ohci-omap.c
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/usb/host/ohci-omap.c')
-rw-r--r--drivers/usb/host/ohci-omap.c169
1 files changed, 106 insertions, 63 deletions
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index f253214..31d3a12 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,21 +14,12 @@
* This file is licenced under the GPL.
*/
+#include <linux/signal.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
#include <linux/clk.h>
-#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/usb/otg.h>
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-#include <linux/usb.h>
-#include <linux/usb/hcd.h>
-
-#include "ohci.h"
#include <asm/io.h>
#include <asm/mach-types.h>
@@ -51,7 +42,10 @@
#define OMAP1510_LB_MMU_RAM_H 0xfffec234
#define OMAP1510_LB_MMU_RAM_L 0xfffec238
-#define DRIVER_DESC "OHCI OMAP driver"
+
+#ifndef CONFIG_ARCH_OMAP
+#error "This file is OMAP bus glue. CONFIG_OMAP must be defined."
+#endif
#ifdef CONFIG_TPS65010
#include <linux/i2c/tps65010.h>
@@ -74,9 +68,8 @@ extern int ocpi_enable(void);
static struct clk *usb_host_ck;
static struct clk *usb_dc_ck;
-
-static const char hcd_name[] = "ohci-omap";
-static struct hc_driver __read_mostly ohci_omap_hc_driver;
+static int host_enabled;
+static int host_initialized;
static void omap_ohci_clock_power(int on)
{
@@ -195,7 +188,7 @@ static void start_hnp(struct ohci_hcd *ohci)
/*-------------------------------------------------------------------------*/
-static int ohci_omap_reset(struct usb_hcd *hcd)
+static int ohci_omap_init(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
struct omap_usb_config *config = dev_get_platdata(hcd->self.controller);
@@ -205,9 +198,9 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
dev_dbg(hcd->self.controller, "starting USB Controller\n");
if (config->otg) {
- hcd->self.otg_port = config->otg;
+ ohci_to_hcd(ohci)->self.otg_port = config->otg;
/* default/minimum OTG power budget: 8 mA */
- hcd->power_budget = 8;
+ ohci_to_hcd(ohci)->power_budget = 8;
}
/* boards can use OTG transceivers in non-OTG modes */
@@ -245,15 +238,9 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
omap_1510_local_bus_init();
}
- ret = ohci_setup(hcd);
- if (ret < 0)
+ if ((ret = ohci_init(ohci)) < 0)
return ret;
- if (config->otg || config->rwc) {
- ohci->hc_control = OHCI_CTRL_RWC;
- writel(OHCI_CTRL_RWC, &ohci->regs->control);
- }
-
/* board-specific power switching and overcurrent support */
if (machine_is_omap_osk() || machine_is_omap_innovator()) {
u32 rh = roothub_a (ohci);
@@ -294,6 +281,14 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
return 0;
}
+static void ohci_omap_stop(struct usb_hcd *hcd)
+{
+ dev_dbg(hcd->self.controller, "stopping USB Controller\n");
+ ohci_stop(hcd);
+ omap_ohci_clock_power(0);
+}
+
+
/*-------------------------------------------------------------------------*/
/**
@@ -309,6 +304,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
{
int retval, irq;
struct usb_hcd *hcd = 0;
+ struct ohci_hcd *ohci;
if (pdev->num_resources != 2) {
printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -358,6 +354,12 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
goto err2;
}
+ ohci = hcd_to_ohci(hcd);
+ ohci_hcd_init(ohci);
+
+ host_initialized = 0;
+ host_enabled = 1;
+
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
retval = -ENXIO;
@@ -367,6 +369,11 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
if (retval)
goto err3;
+ host_initialized = 1;
+
+ if (!host_enabled)
+ omap_ohci_clock_power(0);
+
return 0;
err3:
iounmap(hcd->regs);
@@ -395,9 +402,7 @@ err0:
static inline void
usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
{
- dev_dbg(hcd->self.controller, "stopping USB Controller\n");
usb_remove_hcd(hcd);
- omap_ohci_clock_power(0);
if (!IS_ERR_OR_NULL(hcd->phy)) {
(void) otg_set_host(hcd->phy->otg, 0);
usb_put_phy(hcd->phy);
@@ -413,6 +418,76 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
+static int
+ohci_omap_start (struct usb_hcd *hcd)
+{
+ struct omap_usb_config *config;
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ int ret;
+
+ if (!host_enabled)
+ return 0;
+ config = dev_get_platdata(hcd->self.controller);
+ if (config->otg || config->rwc) {
+ ohci->hc_control = OHCI_CTRL_RWC;
+ writel(OHCI_CTRL_RWC, &ohci->regs->control);
+ }
+
+ if ((ret = ohci_run (ohci)) < 0) {
+ dev_err(hcd->self.controller, "can't start\n");
+ ohci_stop (hcd);
+ return ret;
+ }
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static const struct hc_driver ohci_omap_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "OMAP OHCI",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+
+ /*
+ * generic hardware linkage
+ */
+ .irq = ohci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+
+ /*
+ * basic lifecycle operations
+ */
+ .reset = ohci_omap_init,
+ .start = ohci_omap_start,
+ .stop = ohci_omap_stop,
+ .shutdown = ohci_shutdown,
+
+ /*
+ * managing i/o requests and associated device resources
+ */
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
+
+ /*
+ * scheduling support
+ */
+ .get_frame_number = ohci_get_frame,
+
+ /*
+ * root hub support
+ */
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
+#endif
+ .start_port_reset = ohci_start_port_reset,
+};
+
+/*-------------------------------------------------------------------------*/
+
static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
{
return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -431,23 +506,16 @@ static int ohci_hcd_omap_drv_remove(struct platform_device *dev)
#ifdef CONFIG_PM
-static int ohci_omap_suspend(struct platform_device *pdev, pm_message_t message)
+static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message)
{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- bool do_wakeup = device_may_wakeup(&pdev->dev);
- int ret;
+ struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev));
if (time_before(jiffies, ohci->next_statechange))
msleep(5);
ohci->next_statechange = jiffies;
- ret = ohci_suspend(hcd, do_wakeup);
- if (ret)
- return ret;
-
omap_ohci_clock_power(0);
- return ret;
+ return 0;
}
static int ohci_omap_resume(struct platform_device *dev)
@@ -485,29 +553,4 @@ static struct platform_driver ohci_hcd_omap_driver = {
},
};
-static const struct ohci_driver_overrides omap_overrides __initconst = {
- .product_desc = "OMAP OHCI",
- .reset = ohci_omap_reset
-};
-
-static int __init ohci_omap_init(void)
-{
- if (usb_disabled())
- return -ENODEV;
-
- pr_info("%s: " DRIVER_DESC "\n", hcd_name);
-
- ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
- return platform_driver_register(&ohci_hcd_omap_driver);
-}
-module_init(ohci_omap_init);
-
-static void __exit ohci_omap_cleanup(void)
-{
- platform_driver_unregister(&ohci_hcd_omap_driver);
-}
-module_exit(ohci_omap_cleanup);
-
-MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_ALIAS("platform:ohci");
-MODULE_LICENSE("GPL");