diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/usb/host/ohci-omap.c | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-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.c | 169 |
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"); |