aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-03 08:48:58 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-03 08:48:58 -0800
commit7f5b09c15ab989ed5ce4adda0be42c1302df70b7 (patch)
tree9695b00983d1bd077ff91c463abcb136330cf344 /drivers/usb/host
parent94468080220162f74dc6ce5c3e95e5fec8022902 (diff)
parentcedf8a78421943441b9011ce7bcdab55f07d2ea6 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (220 commits) USB: backlight, appledisplay: fix incomplete registration failure handling USB: pl2303: remove unnecessary reset of usb_device in urbs USB: ftdi_sio: remove obsolete check in unthrottle USB: ftdi_sio: remove unused tx_bytes counter USB: qcaux: driver for auxiliary serial ports on Qualcomm devices USB: pl2303: initial TIOCGSERIAL support USB: option: add Longcheer/Longsung vendor ID USB: fix I2C API usage in ohci-pnx4008. USB: usbmon: mask seconds properly in text API USB: sisusbvga: no unnecessary GFP_ATOMIC USB: storage: onetouch: unnecessary GFP_ATOMIC USB: serial: ftdi: add CONTEC vendor and product id USB: remove references to port->port.count from the serial drivers USB: tty: Prune uses of tty_request_room in the USB layer USB: tty: Add a function to insert a string of characters with the same flag USB: don't read past config->interface[] if usb_control_msg() fails in usb_reset_configuration() USB: tty: kill request_room for USB ACM class USB: tty: sort out the request_room handling for whiteheat USB: storage: fix misplaced parenthesis USB: vstusb.c: removal of driver for Vernier Software & Technology, Inc., devices and spectrometers ...
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/Kconfig11
-rw-r--r--drivers/usb/host/Makefile2
-rw-r--r--drivers/usb/host/ehci-atmel.c2
-rw-r--r--drivers/usb/host/ehci-au1xxx.c6
-rw-r--r--drivers/usb/host/ehci-fsl.c97
-rw-r--r--drivers/usb/host/ehci-mxc.c23
-rw-r--r--drivers/usb/host/ehci-omap.c47
-rw-r--r--drivers/usb/host/ehci-orion.c8
-rw-r--r--drivers/usb/host/ehci-ppc-of.c14
-rw-r--r--drivers/usb/host/ehci-sched.c12
-rw-r--r--drivers/usb/host/ehci-xilinx-of.c8
-rw-r--r--drivers/usb/host/fhci-hcd.c4
-rw-r--r--drivers/usb/host/imx21-dbg.c527
-rw-r--r--drivers/usb/host/imx21-hcd.c1789
-rw-r--r--drivers/usb/host/imx21-hcd.h436
-rw-r--r--drivers/usb/host/isp1362-hcd.c15
-rw-r--r--drivers/usb/host/isp1760-hcd.c10
-rw-r--r--drivers/usb/host/isp1760-if.c2
-rw-r--r--drivers/usb/host/ohci-da8xx.c456
-rw-r--r--drivers/usb/host/ohci-dbg.c4
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/ohci-lh7a404.c11
-rw-r--r--drivers/usb/host/ohci-pnx4008.c6
-rw-r--r--drivers/usb/host/ohci-ppc-of.c10
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c8
-rw-r--r--drivers/usb/host/ohci-sa1111.c8
-rw-r--r--drivers/usb/host/sl811-hcd.c5
-rw-r--r--drivers/usb/host/uhci-hcd.c1
-rw-r--r--drivers/usb/host/xhci-dbg.c19
-rw-r--r--drivers/usb/host/xhci-ext-caps.h7
-rw-r--r--drivers/usb/host/xhci-hcd.c150
-rw-r--r--drivers/usb/host/xhci-hub.c65
-rw-r--r--drivers/usb/host/xhci-mem.c47
-rw-r--r--drivers/usb/host/xhci-pci.c1
-rw-r--r--drivers/usb/host/xhci-ring.c41
-rw-r--r--drivers/usb/host/xhci.h11
36 files changed, 3723 insertions, 145 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2678a1624fc..8d3df0397de 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -399,3 +399,14 @@ config USB_HWA_HCD
To compile this driver a module, choose M here: the module
will be called "hwa-hc".
+
+config USB_IMX21_HCD
+ tristate "iMX21 HCD support"
+ depends on USB && ARM && MACH_MX21
+ help
+ This driver enables support for the on-chip USB host in the
+ iMX21 processor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called "imx21-hcd".
+
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index f58b2494c44..4e0c67f1f51 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -32,3 +32,5 @@ obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
+obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
+
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 87c1b7c34c0..51bd0edf544 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -149,7 +149,7 @@ static int __init ehci_atmel_drv_probe(struct platform_device *pdev)
goto fail_request_resource;
}
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
index dbfb482a94e..e3a74e75e82 100644
--- a/drivers/usb/host/ehci-au1xxx.c
+++ b/drivers/usb/host/ehci-au1xxx.c
@@ -121,6 +121,7 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct ehci_hcd *ehci;
+ struct resource *res;
int ret;
if (usb_disabled())
@@ -144,8 +145,9 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
if (!hcd)
return -ENOMEM;
- hcd->rsrc_start = pdev->resource[0].start;
- hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
pr_debug("request_mem_region failed");
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 991174937db..0e26aa13f15 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2005 MontaVista Software
+ * Copyright 2005-2009 MontaVista Software, Inc.
+ * Copyright 2008 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -17,17 +18,20 @@
*
* Ported to 834x by Randy Vinson <rvinson@mvista.com> using code provided
* by Hunter Wu.
+ * Power Management support by Dave Liu <daveliu@freescale.com>,
+ * Jerry Huang <Chang-Ming.Huang@freescale.com> and
+ * Anton Vorontsov <avorontsov@ru.mvista.com>.
*/
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
#include "ehci-fsl.h"
-/* FIXME: Power Management is un-ported so temporarily disable it */
-#undef CONFIG_PM
-
-
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
@@ -40,8 +44,8 @@
* Allocates basic resources for this USB host controller.
*
*/
-int usb_hcd_fsl_probe(const struct hc_driver *driver,
- struct platform_device *pdev)
+static int usb_hcd_fsl_probe(const struct hc_driver *driver,
+ struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata;
struct usb_hcd *hcd;
@@ -147,7 +151,8 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver,
* Reverses the effect of usb_hcd_fsl_probe().
*
*/
-void usb_hcd_fsl_remove(struct usb_hcd *hcd, struct platform_device *pdev)
+static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
+ struct platform_device *pdev)
{
usb_remove_hcd(hcd);
iounmap(hcd->regs);
@@ -284,10 +289,81 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
return retval;
}
+struct ehci_fsl {
+ struct ehci_hcd ehci;
+
+#ifdef CONFIG_PM
+ /* Saved USB PHY settings, need to restore after deep sleep. */
+ u32 usb_ctrl;
+#endif
+};
+
+#ifdef CONFIG_PM
+
+static struct ehci_fsl *hcd_to_ehci_fsl(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+
+ return container_of(ehci, struct ehci_fsl, ehci);
+}
+
+static int ehci_fsl_drv_suspend(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
+ void __iomem *non_ehci = hcd->regs;
+
+ if (!fsl_deep_sleep())
+ return 0;
+
+ ehci_fsl->usb_ctrl = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+ return 0;
+}
+
+static int ehci_fsl_drv_resume(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ void __iomem *non_ehci = hcd->regs;
+
+ if (!fsl_deep_sleep())
+ return 0;
+
+ usb_root_hub_lost_power(hcd->self.root_hub);
+
+ /* Restore USB PHY settings and enable the controller. */
+ out_be32(non_ehci + FSL_SOC_USB_CTRL, ehci_fsl->usb_ctrl);
+
+ ehci_reset(ehci);
+ ehci_fsl_reinit(ehci);
+
+ return 0;
+}
+
+static int ehci_fsl_drv_restore(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+ usb_root_hub_lost_power(hcd->self.root_hub);
+ return 0;
+}
+
+static struct dev_pm_ops ehci_fsl_pm_ops = {
+ .suspend = ehci_fsl_drv_suspend,
+ .resume = ehci_fsl_drv_resume,
+ .restore = ehci_fsl_drv_restore,
+};
+
+#define EHCI_FSL_PM_OPS (&ehci_fsl_pm_ops)
+#else
+#define EHCI_FSL_PM_OPS NULL
+#endif /* CONFIG_PM */
+
static const struct hc_driver ehci_fsl_hc_driver = {
.description = hcd_name,
.product_desc = "Freescale On-Chip EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
+ .hcd_priv_size = sizeof(struct ehci_fsl),
/*
* generic hardware linkage
@@ -354,6 +430,7 @@ static struct platform_driver ehci_fsl_driver = {
.remove = ehci_fsl_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
- .name = "fsl-ehci",
+ .name = "fsl-ehci",
+ .pm = EHCI_FSL_PM_OPS,
},
};
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index 35c56f40bdb..23cd917088b 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -162,6 +162,17 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
goto err_ioremap;
}
+ /* call platform specific init function */
+ if (pdata->init) {
+ ret = pdata->init(pdev);
+ if (ret) {
+ dev_err(dev, "platform init failed\n");
+ goto err_init;
+ }
+ /* platforms need some time to settle changed IO settings */
+ mdelay(10);
+ }
+
/* enable clocks */
priv->usbclk = clk_get(dev, "usb");
if (IS_ERR(priv->usbclk)) {
@@ -192,18 +203,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
if (ret < 0)
goto err_init;
- /* call platform specific init function */
- if (pdata->init) {
- ret = pdata->init(pdev);
- if (ret) {
- dev_err(dev, "platform init failed\n");
- goto err_init;
- }
- }
-
- /* most platforms need some time to settle changed IO settings */
- mdelay(10);
-
/* Initialize the transceiver */
if (pdata->otg) {
pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 74d07f4e8b7..f0282d6bb7a 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -26,10 +26,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * TODO (last updated Feb 23rd, 2009):
+ * TODO (last updated Feb 12, 2010):
* - add kernel-doc
* - enable AUTOIDLE
- * - move DPLL5 programming to clock fw
* - add suspend/resume
* - move workarounds to board-files
*/
@@ -37,6 +36,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
#include <plat/usb.h>
/*
@@ -178,6 +178,11 @@ struct ehci_hcd_omap {
void __iomem *uhh_base;
void __iomem *tll_base;
void __iomem *ehci_base;
+
+ /* Regulators for USB PHYs.
+ * Each PHY can have a seperate regulator.
+ */
+ struct regulator *regulator[OMAP3_HS_USB_PORTS];
};
/*-------------------------------------------------------------------------*/
@@ -546,6 +551,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
int irq = platform_get_irq(pdev, 0);
int ret = -ENODEV;
+ int i;
+ char supply[7];
if (!pdata) {
dev_dbg(&pdev->dev, "missing platform_data\n");
@@ -613,6 +620,21 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
goto err_tll_ioremap;
}
+ /* get ehci regulator and enable */
+ for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
+ if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) {
+ omap->regulator[i] = NULL;
+ continue;
+ }
+ snprintf(supply, sizeof(supply), "hsusb%d", i);
+ omap->regulator[i] = regulator_get(omap->dev, supply);
+ if (IS_ERR(omap->regulator[i]))
+ dev_dbg(&pdev->dev,
+ "failed to get ehci port%d regulator\n", i);
+ else
+ regulator_enable(omap->regulator[i]);
+ }
+
ret = omap_start_ehc(omap, hcd);
if (ret) {
dev_dbg(&pdev->dev, "failed to start ehci\n");
@@ -622,13 +644,12 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
omap->ehci->regs = hcd->regs
+ HC_LENGTH(readl(&omap->ehci->caps->hc_capbase));
+ dbg_hcs_params(omap->ehci, "reset");
+ dbg_hcc_params(omap->ehci, "reset");
+
/* cache this readonly data; minimize chip reads */
omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params);
- /* SET 1 micro-frame Interrupt interval */
- writel(readl(&omap->ehci->regs->command) | (1 << 16),
- &omap->ehci->regs->command);
-
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
if (ret) {
dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
@@ -641,6 +662,12 @@ err_add_hcd:
omap_stop_ehc(omap, hcd);
err_start:
+ for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
+ if (omap->regulator[i]) {
+ regulator_disable(omap->regulator[i]);
+ regulator_put(omap->regulator[i]);
+ }
+ }
iounmap(omap->tll_base);
err_tll_ioremap:
@@ -674,13 +701,21 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
{
struct ehci_hcd_omap *omap = platform_get_drvdata(pdev);
struct usb_hcd *hcd = ehci_to_hcd(omap->ehci);
+ int i;
usb_remove_hcd(hcd);
omap_stop_ehc(omap, hcd);
iounmap(hcd->regs);
+ for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) {
+ if (omap->regulator[i]) {
+ regulator_disable(omap->regulator[i]);
+ regulator_put(omap->regulator[i]);
+ }
+ }
iounmap(omap->tll_base);
iounmap(omap->uhh_base);
usb_put_hcd(hcd);
+ kfree(omap);
return 0;
}
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 1d283e1b2b8..0f87dc72820 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -222,14 +222,14 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
goto err1;
}
- if (!request_mem_region(res->start, res->end - res->start + 1,
+ if (!request_mem_region(res->start, resource_size(res),
ehci_orion_hc_driver.description)) {
dev_dbg(&pdev->dev, "controller already in use\n");
err = -EBUSY;
goto err1;
}
- regs = ioremap(res->start, res->end - res->start + 1);
+ regs = ioremap(res->start, resource_size(res));
if (regs == NULL) {
dev_dbg(&pdev->dev, "error mapping memory\n");
err = -EFAULT;
@@ -244,7 +244,7 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
}
hcd->rsrc_start = res->start;
- hcd->rsrc_len = res->end - res->start + 1;
+ hcd->rsrc_len = resource_size(res);
hcd->regs = regs;
ehci = hcd_to_ehci(hcd);
@@ -287,7 +287,7 @@ err4:
err3:
iounmap(regs);
err2:
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, resource_size(res));
err1:
dev_err(&pdev->dev, "init %s fail, %d\n",
dev_name(&pdev->dev), err);
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
index 36f96da129f..8df33b8a634 100644
--- a/drivers/usb/host/ehci-ppc-of.c
+++ b/drivers/usb/host/ehci-ppc-of.c
@@ -134,21 +134,21 @@ ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
hcd->rsrc_len = res.end - res.start + 1;
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- printk(KERN_ERR __FILE__ ": request_mem_region failed\n");
+ printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
rv = -EBUSY;
goto err_rmr;
}
irq = irq_of_parse_and_map(dn, 0);
if (irq == NO_IRQ) {
- printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
+ printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
rv = -EBUSY;
goto err_irq;
}
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs) {
- printk(KERN_ERR __FILE__ ": ioremap failed\n");
+ printk(KERN_ERR "%s: ioremap failed\n", __FILE__);
rv = -ENOMEM;
goto err_ioremap;
}
@@ -161,9 +161,9 @@ ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
ehci->ohci_hcctrl_reg = ioremap(res.start +
OHCI_HCCTRL_OFFSET, OHCI_HCCTRL_LEN);
else
- pr_debug(__FILE__ ": no ohci offset in fdt\n");
+ pr_debug("%s: no ohci offset in fdt\n", __FILE__);
if (!ehci->ohci_hcctrl_reg) {
- pr_debug(__FILE__ ": ioremap for ohci hcctrl failed\n");
+ pr_debug("%s: ioremap for ohci hcctrl failed\n", __FILE__);
} else {
ehci->has_amcc_usb23 = 1;
}
@@ -241,7 +241,7 @@ static int ehci_hcd_ppc_of_remove(struct of_device *op)
else
release_mem_region(res.start, 0x4);
else
- pr_debug(__FILE__ ": no ohci offset in fdt\n");
+ pr_debug("%s: no ohci offset in fdt\n", __FILE__);
of_node_put(np);
}
@@ -264,7 +264,7 @@ static int ehci_hcd_ppc_of_shutdown(struct of_device *op)
}
-static struct of_device_id ehci_hcd_ppc_of_match[] = {
+static const struct of_device_id ehci_hcd_ppc_of_match[] = {
{
.compatible = "usb-ehci",
},
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 1e391e624c8..39340ae00ac 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -510,6 +510,8 @@ static int disable_periodic (struct ehci_hcd *ehci)
ehci_writel(ehci, cmd, &ehci->regs->command);
/* posted write ... */
+ free_cached_itd_list(ehci);
+
ehci->next_uframe = -1;
return 0;
}
@@ -2322,9 +2324,13 @@ restart:
* No need to check for activity unless the
* frame is current.
*/
- if (frame == clock_frame && live &&
- (q.sitd->hw_results &
- SITD_ACTIVE(ehci))) {
+ if (((frame == clock_frame) ||
+ (((frame + 1) % ehci->periodic_size)
+ == clock_frame))
+ && live
+ && (q.sitd->hw_results &
+ SITD_ACTIVE(ehci))) {
+
incomplete = true;
q_p = &q.sitd->sitd_next;
hw_p = &q.sitd->hw_next;
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c
index a5861531ad3..f603bb2c0a8 100644
--- a/drivers/usb/host/ehci-xilinx-of.c
+++ b/drivers/usb/host/ehci-xilinx-of.c
@@ -177,21 +177,21 @@ ehci_hcd_xilinx_of_probe(struct of_device *op, const struct of_device_id *match)
hcd->rsrc_len = res.end - res.start + 1;
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- printk(KERN_ERR __FILE__ ": request_mem_region failed\n");
+ printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
rv = -EBUSY;
goto err_rmr;
}
irq = irq_of_parse_and_map(dn, 0);
if (irq == NO_IRQ) {
- printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
+ printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
rv = -EBUSY;
goto err_irq;
}
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs) {
- printk(KERN_ERR __FILE__ ": ioremap failed\n");
+ printk(KERN_ERR "%s: ioremap failed\n", __FILE__);
rv = -ENOMEM;
goto err_ioremap;
}
@@ -281,7 +281,7 @@ static int ehci_hcd_xilinx_of_shutdown(struct of_device *op)
}
-static struct of_device_id ehci_hcd_xilinx_of_match[] = {
+static const struct of_device_id ehci_hcd_xilinx_of_match[] = {
{.compatible = "xlnx,xps-usb-host-1.00.a",},
{},
};
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
index 78e7c3cfcb7..5dcfb3de994 100644
--- a/drivers/usb/host/fhci-hcd.c
+++ b/drivers/usb/host/fhci-hcd.c
@@ -433,7 +433,7 @@ static int fhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
return -ENOMEM;
/* allocate the private part of the URB */
- urb_priv->tds = kzalloc(size * sizeof(struct td), mem_flags);
+ urb_priv->tds = kcalloc(size, sizeof(*urb_priv->tds), mem_flags);
if (!urb_priv->tds) {
kfree(urb_priv);
return -ENOMEM;
@@ -805,7 +805,7 @@ static int __devexit of_fhci_remove(struct of_device *ofdev)
return fhci_remove(&ofdev->dev);
}
-static struct of_device_id of_fhci_match[] = {
+static const struct of_device_id of_fhci_match[] = {
{ .compatible = "fsl,mpc8323-qe-usb", },
{},
};
diff --git a/drivers/usb/host/imx21-dbg.c b/drivers/usb/host/imx21-dbg.c
new file mode 100644
index 00000000000..512f647448c
--- /dev/null
+++ b/drivers/usb/host/imx21-dbg.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2009 by Martin Fuzzey
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* this file is part of imx21-hcd.c */
+
+#ifndef DEBUG
+
+static inline void create_debug_files(struct imx21 *imx21) { }
+static inline void remove_debug_files(struct imx21 *imx21) { }
+static inline void debug_urb_submitted(struct imx21 *imx21, struct urb *urb) {}
+static inline void debug_urb_completed(struct imx21 *imx21, struct urb *urb,
+ int status) {}
+static inline void debug_urb_unlinked(struct imx21 *imx21, struct urb *urb) {}
+static inline void debug_urb_queued_for_etd(struct imx21 *imx21,
+ struct urb *urb) {}
+static inline void debug_urb_queued_for_dmem(struct imx21 *imx21,
+ struct urb *urb) {}
+static inline void debug_etd_allocated(struct imx21 *imx21) {}
+static inline void debug_etd_freed(struct imx21 *imx21) {}
+static inline void debug_dmem_allocated(struct imx21 *imx21, int size) {}
+static inline void debug_dmem_freed(struct imx21 *imx21, int size) {}
+static inline void debug_isoc_submitted(struct imx21 *imx21,
+ int frame, struct td *td) {}
+static inline void debug_isoc_completed(struct imx21 *imx21,
+ int frame, struct td *td, int cc, int len) {}
+
+#else
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static const char *dir_labels[] = {
+ "TD 0",
+ "OUT",
+ "IN",
+ "TD 1"
+};
+
+static const char *speed_labels[] = {
+ "Full",
+ "Low"
+};
+
+static const char *format_labels[] = {
+ "Control",
+ "ISO",
+ "Bulk",
+ "Interrupt"
+};
+
+static inline struct debug_stats *stats_for_urb(struct imx21 *imx21,
+ struct urb *urb)
+{
+ return usb_pipeisoc(urb->pipe) ?
+ &imx21->isoc_stats : &imx21->nonisoc_stats;
+}
+
+static void debug_urb_submitted(struct imx21 *imx21, struct urb *urb)
+{
+ stats_for_urb(imx21, urb)->submitted++;
+}
+
+static void debug_urb_completed(struct imx21 *imx21, struct urb *urb, int st)
+{
+ if (st)
+ stats_for_urb(imx21, urb)->completed_failed++;
+ else
+ stats_for_urb(imx21, urb)->completed_ok++;
+}
+
+static void debug_urb_unlinked(struct imx21 *imx21, struct urb *urb)
+{
+ stats_for_urb(imx21, urb)->unlinked++;
+}
+
+static void debug_urb_queued_for_etd(struct imx21 *imx21, struct urb *urb)
+{
+ stats_for_urb(imx21, urb)->queue_etd++;
+}
+
+static void debug_urb_queued_for_dmem(struct imx21 *imx21, struct urb *urb)
+{
+ stats_for_urb(imx21, urb)->queue_dmem++;
+}
+
+static inline void debug_etd_allocated(struct imx21 *imx21)
+{
+ imx21->etd_usage.maximum = max(
+ ++(imx21->etd_usage.value),
+ imx21->etd_usage.maximum);
+}
+
+static inline void debug_etd_freed(struct imx21 *imx21)
+{
+ imx21->etd_usage.value--;
+}
+
+static inline void debug_dmem_allocated(struct imx21 *imx21, int size)
+{
+ imx21->dmem_usage.value += size;
+ imx21->dmem_usage.maximum = max(
+ imx21->dmem_usage.value,
+ imx21->dmem_usage.maximum);
+}
+
+static inline void debug_dmem_freed(struct imx21 *imx21, int size)
+{
+ imx21->dmem_usage.value -= size;
+}
+
+
+static void debug_isoc_submitted(struct imx21 *imx21,
+ int frame, struct td *td)
+{
+ struct debug_isoc_trace *trace = &imx21->isoc_trace[
+ imx21->isoc_trace_index++];
+
+ imx21->isoc_trace_index %= ARRAY_SIZE(imx21->isoc_trace);
+ trace->schedule_frame = td->frame;
+ trace->submit_frame = frame;
+ trace->request_len = td->len;
+ trace->td = td;
+}
+
+static inline void debug_isoc_completed(struct imx21 *imx21,
+ int frame, struct td *td, int cc, int len)
+{
+ struct debug_isoc_trace *trace, *trace_failed;
+ int i;
+ int found = 0;
+
+ trace = imx21->isoc_trace;
+ for (i = 0; i < ARRAY_SIZE(imx21->isoc_trace); i++, trace++) {
+ if (trace->td == td) {
+ trace->done_frame = frame;
+ trace->done_len = len;
+ trace->cc = cc;
+ trace->td = NULL;
+ found = 1;
+ break;
+ }
+ }
+
+ if (found && cc) {
+ trace_failed = &imx21->isoc_trace_failed[
+ imx21->isoc_trace_index_failed++];
+
+ imx21->isoc_trace_index_failed %= ARRAY_SIZE(
+ imx21->isoc_trace_failed);
+ *trace_failed = *trace;
+ }
+}
+
+
+static char *format_ep(struct usb_host_endpoint *ep, char *buf, int bufsize)
+{
+ if (ep)
+ snprintf(buf, bufsize, "ep_%02x (type:%02X kaddr:%p)",
+ ep->desc.bEndpointAddress,
+ usb_endpoint_type(&ep->desc),
+ ep);
+ else
+ snprintf(buf, bufsize, "none");
+ return buf;
+}
+
+static char *format_etd_dword0(u32 value, char *buf, int bufsize)