diff options
Diffstat (limited to 'drivers/usb/host/ohci-omap.c')
| -rw-r--r-- | drivers/usb/host/ohci-omap.c | 174 | 
1 files changed, 66 insertions, 108 deletions
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 31d3a12eb48..c923cafcaca 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -14,12 +14,21 @@   * 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> @@ -42,10 +51,7 @@  #define OMAP1510_LB_MMU_RAM_H	0xfffec234  #define OMAP1510_LB_MMU_RAM_L	0xfffec238 - -#ifndef CONFIG_ARCH_OMAP -#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined." -#endif +#define DRIVER_DESC "OHCI OMAP driver"  #ifdef CONFIG_TPS65010  #include <linux/i2c/tps65010.h> @@ -68,8 +74,9 @@ extern int ocpi_enable(void);  static struct clk *usb_host_ck;  static struct clk *usb_dc_ck; -static int host_enabled; -static int host_initialized; + +static const char hcd_name[] = "ohci-omap"; +static struct hc_driver __read_mostly ohci_omap_hc_driver;  static void omap_ohci_clock_power(int on)  { @@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)  /*-------------------------------------------------------------------------*/ -static int ohci_omap_init(struct usb_hcd *hcd) +static int ohci_omap_reset(struct usb_hcd *hcd)  {  	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);  	struct omap_usb_config	*config = dev_get_platdata(hcd->self.controller); @@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)  	dev_dbg(hcd->self.controller, "starting USB Controller\n");  	if (config->otg) { -		ohci_to_hcd(ohci)->self.otg_port = config->otg; +		hcd->self.otg_port = config->otg;  		/* default/minimum OTG power budget:  8 mA */ -		ohci_to_hcd(ohci)->power_budget = 8; +		hcd->power_budget = 8;  	}  	/* boards can use OTG transceivers in non-OTG modes */ @@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)  		omap_1510_local_bus_init();  	} -	if ((ret = ohci_init(ohci)) < 0) +	ret = ohci_setup(hcd); +	if (ret < 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); @@ -281,14 +294,6 @@ static int ohci_omap_init(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); -} - -  /*-------------------------------------------------------------------------*/  /** @@ -304,17 +309,16 @@ 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", +		dev_err(&pdev->dev, "invalid num_resources: %i\n",  		       pdev->num_resources);  		return -ENODEV;  	}  	if (pdev->resource[0].flags != IORESOURCE_MEM  			|| pdev->resource[1].flags != IORESOURCE_IRQ) { -		printk(KERN_ERR "hcd probe: invalid resource type\n"); +		dev_err(&pdev->dev, "invalid resource type\n");  		return -ENODEV;  	} @@ -354,12 +358,6 @@ 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; @@ -369,11 +367,7 @@ 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); - +	device_wakeup_enable(hcd->self.controller);  	return 0;  err3:  	iounmap(hcd->regs); @@ -402,7 +396,9 @@ 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); @@ -418,76 +414,6 @@ 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); @@ -506,16 +432,23 @@ static int ohci_hcd_omap_drv_remove(struct platform_device *dev)  #ifdef	CONFIG_PM -static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message) +static int ohci_omap_suspend(struct platform_device *pdev, pm_message_t message)  { -	struct ohci_hcd	*ohci = hcd_to_ohci(platform_get_drvdata(dev)); +	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;  	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 0; +	return ret;  }  static int ohci_omap_resume(struct platform_device *dev) @@ -553,4 +486,29 @@ 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");  | 
