On Thu, Jan 27, 2011 at 04:58:56PM +0530, Anoop P.A wrote: > From: Anoop P A <anoop.pa@xxxxxxxxx> > > Signed-off-by: Anoop P A <anoop.pa@xxxxxxxxx> > Tested-by: Shane McDonald <mcdonald.shane@xxxxxxxxx> Care to provide a "real" changelog comment for this patch? We need something here. > --- > drivers/usb/host/Kconfig | 15 +- > drivers/usb/host/ehci-hcd.c | 7 + > drivers/usb/host/ehci-pmcmsp.c | 552 ++++++++++++++++++++++++++++++++++++++++ > drivers/usb/host/ehci.h | 3 + > 4 files changed, 575 insertions(+), 2 deletions(-) > create mode 100644 drivers/usb/host/ehci-pmcmsp.c > > diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig > index 24046c0..1f73127 100644 > --- a/drivers/usb/host/Kconfig > +++ b/drivers/usb/host/Kconfig > @@ -91,17 +91,28 @@ config USB_EHCI_TT_NEWSCHED > > If unsure, say Y. > > +config USB_EHCI_HCD_PMC_MSP > + tristate "EHCI support for on-chip PMC MSP USB controller" > + depends on USB_EHCI_HCD && MSP_HAS_USB > + default y > + select USB_EHCI_BIG_ENDIAN_DESC > + select USB_EHCI_BIG_ENDIAN_MMIO > + ---help--- > + Enables support for the onchip USB controller on the PMC_MSP7100 Family SoC's. > + If unsure, say N. > + > config USB_EHCI_BIG_ENDIAN_MMIO > bool > depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \ > ARCH_IXP4XX || XPS_USB_HCD_XILINX || \ > - PPC_MPC512x || CPU_CAVIUM_OCTEON) > + PPC_MPC512x || CPU_CAVIUM_OCTEON || \ > + PMC_MSP) > default y > > config USB_EHCI_BIG_ENDIAN_DESC > bool > depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \ > - PPC_MPC512x) > + PPC_MPC512x || PMC_MSP) > default y > > config XPS_USB_HCD_XILINX > diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c > index 6fee3cd..a591890 100644 > --- a/drivers/usb/host/ehci-hcd.c > +++ b/drivers/usb/host/ehci-hcd.c > @@ -262,6 +262,8 @@ static void tdi_reset (struct ehci_hcd *ehci) > if (ehci_big_endian_mmio(ehci)) > tmp |= USBMODE_BE; > ehci_writel(ehci, tmp, reg_ptr); > + if (ehci->pmc_msp_tdi) > + usb_hcd_tdi_set_mode(ehci); > } > > /* reset a non-running (STS_HALT == 1) controller */ > @@ -1249,6 +1251,11 @@ MODULE_LICENSE ("GPL"); > #define PLATFORM_DRIVER ehci_msm_driver > #endif > > +#ifdef CONFIG_USB_EHCI_HCD_PMC_MSP > +#include "ehci-pmcmsp.c" > +#define PLATFORM_DRIVER ehci_hcd_msp_driver > +#endif > + > #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ > !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ > !defined(XILINX_OF_PLATFORM_DRIVER) > diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c > new file mode 100644 > index 0000000..28dd26c > --- /dev/null > +++ b/drivers/usb/host/ehci-pmcmsp.c > @@ -0,0 +1,552 @@ > +/* > + * PMC MSP EHCI (Host Controller Driver) for USB. > + * > + * (C) Copyright 2006-2010 PMC-Sierra 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 > + * Free Software Foundation; either version 2 of the License, or (at your > + * option) any later version. Are you sure about "any later version"? Is this acceptable to your company lawyers? > + * > + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED > + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN > + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF > + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON > + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + * > + * 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. These two paragraphs are not needed, please remove them. > + */ > + > +#include <linux/platform_device.h> > +#include <linux/gpio.h> > +#include <msp_usb.h> > + > +/* includes */ Um, includes for what? Are we writing comments for the previous lines? > +#define USB_CTRL_MODE_HOST 0x3 > + /* host mode */ > +#define USB_CTRL_MODE_BIG_ENDIAN 0x4 > + /* big endian */ > +#define USB_CTRL_MODE_STREAM_DISABLE 0x10 > + /* stream disable*/ > +#define USB_CTRL_FIFO_THRESH 0x00300000 > + /* thresh hold */ > +#define USB_EHCI_REG_USB_MODE 0x68 > + /* register offset for usb_mode */ > +#define USB_EHCI_REG_USB_FIFO 0x24 > + /* register offset for usb fifo */ > +#define USB_EHCI_REG_USB_STATUS 0x44 > + /* register offset for usb status */ > +#define USB_EHCI_REG_BIT_STAT_STS (1<<29) > + /* serial/parallel transceiver */ > +#define MSP_PIN_USB0_HOST_DEV 49 > + /* TWI USB0 host device pin */ > +#define MSP_PIN_USB1_HOST_DEV 50 > + /* TWI USB1 host device pin */ Ok, I see we are. That's horrible, please fix it up. > + > +extern int usb_disabled(void); Why is this in a .c file? externs should never be in a .c file. > + > +void usb_hcd_tdi_set_mode(struct ehci_hcd *ehci) > +{ > + u8 *base; > + u8 *statreg; > + u8 *fiforeg; > + u32 val; > + struct ehci_regs *reg_base = ehci->regs; > + > + /* get register base */ > + base = (u8 *)reg_base + USB_EHCI_REG_USB_MODE; > + statreg = (u8 *)reg_base + USB_EHCI_REG_USB_STATUS; > + fiforeg = (u8 *)reg_base + USB_EHCI_REG_USB_FIFO; > + > + /* set the controller to host mode and BIG ENDIAN */ > + ehci_writel(ehci, (USB_CTRL_MODE_HOST | USB_CTRL_MODE_BIG_ENDIAN > + | USB_CTRL_MODE_STREAM_DISABLE), (u32 *)base); > + > + /* clear STS to select parallel transceiver interface */ > + val = ehci_readl(ehci, (u32 *)statreg); > + val = val & ~USB_EHCI_REG_BIT_STAT_STS; > + ehci_writel(ehci, val, (u32 *)statreg); > + > + /* write to set the proper fifo threshold */ > + ehci_writel(ehci, USB_CTRL_FIFO_THRESH, (u32 *)fiforeg); > + > + /* set TWI GPIO USB_HOST_DEV pin high */ > + gpio_direction_output(MSP_PIN_USB0_HOST_DEV, 1); > +#ifdef CONFIG_MSP_HAS_DUAL_USB > + gpio_direction_output(MSP_PIN_USB1_HOST_DEV, 1); > +#endif Please don't put #defines in .c files. > +} > + > +/* called after powerup, by probe or system-pm "wakeup" */ > +static int ehci_msp_reinit(struct ehci_hcd *ehci) > +{ > + ehci_port_power(ehci, 0); > + > + return 0; > +} > + > +/* called during probe() after chip reset completes */ > +static int ehci_msp_setup(struct usb_hcd *hcd) > +{ > + struct ehci_hcd *ehci = hcd_to_ehci(hcd); > + u32 temp; > + int retval; > + ehci->big_endian_mmio = 1; > + ehci->big_endian_desc = 1; > + ehci->pmc_msp_tdi = 1; > + > + ehci->caps = hcd->regs; > + ehci->regs = hcd->regs + > + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); > + dbg_hcs_params(ehci, "reset"); > + dbg_hcc_params(ehci, "reset"); > + > + /* cache this readonly data; minimize chip reads */ > + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); > + hcd->has_tt = 1; > + tdi_reset(ehci); > + > + retval = ehci_halt(ehci); > + if (retval) > + return retval; > + > + ehci_reset(ehci); > + > + /* data structure init */ > + retval = ehci_init(hcd); > + if (retval) > + return retval; > + > + temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); > + temp &= 0x0f; > + if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { > + ehci_dbg(ehci, "bogus port configuration: " > + "cc=%d x pcc=%d < ports=%d\n", > + HCS_N_CC(ehci->hcs_params), > + HCS_N_PCC(ehci->hcs_params), > + HCS_N_PORTS(ehci->hcs_params)); > + } > + > + retval = ehci_msp_reinit(ehci); > + > + return retval; > +} > + > +/*-------------------------------------------------------------------------*/ > + > +static void msp_start_hc(struct platform_device *dev) > +{ > + printk(KERN_DEBUG __FILE__ > + ": starting PMC MSP EHCI USB Controller\n"); Why? Who really cares? And, if you _really_ want to do this, please use a dev_dbg() call instead, which ties it properly into the dynamic printk system _and_ properly identifies this deivce. > + > + /* > + * Now, carefully enable the USB clock, and take > + * the USB host controller out of reset. > + */ > + printk(KERN_DEBUG __FILE__ > + ": Clock to USB host has been enabled\n"); > +} You never enabled anything, yet you said you did? Somethings wrong here. > + > +static void msp_stop_hc(struct platform_device *dev) > +{ > + printk(KERN_DEBUG __FILE__ > + ": stopping PMC MSP EHCI USB Controller\n"); > +} Same for this printk, you didn't stop anything. Also fix it up and don't use printk, see above. > + > + > +/*-------------------------------------------------------------------------*/ > + > +/*-------------------------------------------------------------------------*/ > + > +#ifdef CONFIG_PM > + > +/* suspend/resume, section 4.3 */ > + > +/* These routines rely on the bus glue > + * to handle powerdown and wakeup, and currently also on > + * transceivers that don't need any software attention to set up > + * the right sort of wakeup. > + * Also they depend on separate root hub suspend/resume. > + */ > +static int ehci_msp_suspend(struct device *dev) > +{ > + struct usb_hcd *hcd = dev_get_drvdata(dev); > + struct ehci_hcd *ehci = hcd_to_ehci(hcd); > + unsigned long flags; > + int rc; > + > + return 0; > + rc = 0; > + > + if (time_before(jiffies, ehci->next_statechange)) > + msleep(10); Short sleep, why? > + > + /* Root hub was already suspended. Disable irq emission and > + * mark HW unaccessible. The PM and USB cores make sure that > + * the root hub is either suspended or stopped. > + */ > + spin_lock_irqsave(&ehci->lock, flags); > + ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev)); > + ehci_writel(ehci, 0, &ehci->regs->intr_enable); > + (void)ehci_readl(ehci, &ehci->regs->intr_enable); > + > + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); > + spin_unlock_irqrestore(&ehci->lock, flags); > + > + /* could save FLADJ in case of Vaux power loss > + ... we'd only use it to handle clock skew */ Huh? > + > + return rc; > +} > + > +static int ehci_msp_resume(struct device *dev) > +{ > + struct usb_hcd *hcd = dev_get_drvdata(dev); > + struct ehci_hcd *ehci = hcd_to_ehci(hcd); > + > + > + /* maybe restore FLADJ */ Don't you know? > + > + if (time_before(jiffies, ehci->next_statechange)) > + msleep(100); That's a long sleep, are you sure that's ok on the resume path? > + > + /* Mark hardware accessible again as we are out of D3 state by now */ > + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); > + > + /* If CF is still set, we maintained PCI Vaux power. > + * Just undo the effect of ehci_pci_suspend(). > + */ > + if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { > + int mask = INTR_MASK; > + > + ehci_prepare_ports_for_controller_resume(ehci); > + if (!hcd->self.root_hub->do_remote_wakeup) > + mask &= ~STS_PCD; > + ehci_writel(ehci, mask, &ehci->regs->intr_enable); > + ehci_readl(ehci, &ehci->regs->intr_enable); > + return 0; > + } > + > + ehci_dbg(ehci, "lost power, restarting\n"); > + usb_root_hub_lost_power(hcd->self.root_hub); > + > + /* Else reset, to cope with power loss or flush-to-storage > + * style "resume" having let BIOS kick in during reboot. > + */ > + (void) ehci_halt(ehci); > + (void) ehci_reset(ehci); > + (void) ehci_msp_reinit(ehci); > + > + /* emptying the schedule aborts any urbs */ > + spin_lock_irq(&ehci->lock); > + if (ehci->reclaim) > + end_unlink_async(ehci); > + ehci_work(ehci); > + spin_unlock_irq(&ehci->lock); > + > + ehci_writel(ehci, ehci->command, &ehci->regs->command); > + ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); > + ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ > + > + /* here we "know" root ports should always stay powered */ > + ehci_port_power(ehci, 1); > + > + hcd->state = HC_STATE_SUSPENDED; > + > + return 0; > +} > + > +static const struct dev_pm_ops ehci_msp_pmops = { > + .suspend = ehci_msp_suspend, > + .resume = ehci_msp_resume, > +}; > +#endif > + > + > +/* configure so an HC device and id are always provided */ > +/* always called with process context; sleeping is OK */ > + > +static int usb_hcd_msp_map_regs(struct mspusb_device *dev) > +{ > + struct resource *res; > + struct platform_device *pdev = &dev->dev; > + u32 res_len; > + int retval; > + > + /* MAB register space */ > + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); > + if (res == NULL) > + return -ENOMEM; > + res_len = res->end - res->start + 1; > + if (!request_mem_region(res->start, res_len, "mab regs")) > + return -EBUSY; > + > + dev->mab_regs = ioremap_nocache(res->start, res_len); > + if (dev->mab_regs == NULL) { > + retval = -ENOMEM; > + goto err1; > + } > + > + /* MSP USB register space */ > + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); > + if (res == NULL) { > + retval = -ENOMEM; > + goto err2; > + } > + res_len = res->end - res->start + 1; > + if (!request_mem_region(res->start, res_len, "usbid regs")) { > + retval = -EBUSY; > + goto err2; > + } > + dev->usbid_regs = ioremap_nocache(res->start, res_len); > + if (dev->usbid_regs == NULL) { > + retval = -ENOMEM; > + goto err3; > + } > + > + return 0; > +err3: > + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); > + res_len = res->end - res->start + 1; > + release_mem_region(res->start, res_len); > +err2: > + iounmap(dev->mab_regs); > +err1: > + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); > + res_len = res->end - res->start + 1; > + release_mem_region(res->start, res_len); > + dev_err(&pdev->dev, "Failed to map non-EHCI regs.\n"); > + return retval; > +} > + > +/** > + * usb_hcd_msp_probe - initialize PMC MSP-based HCDs > + * Context: !in_interrupt() > + * > + * Allocates basic resources for this USB host controller, and > + * then invokes the start() method for the HCD associated with it > + * through the hotplug entry's driver_data. > + * > + */ > +int usb_hcd_msp_probe(const struct hc_driver *driver, > + struct platform_device *dev) > +{ > + int retval; > + struct usb_hcd *hcd; > + struct resource *res; > + struct ehci_hcd *ehci ; > + > + hcd = usb_create_hcd(driver, &dev->dev, "pmcmsp"); > + if (!hcd) > + return -ENOMEM; > + > + res = platform_get_resource(dev, IORESOURCE_MEM, 0); > + if (res == NULL) { > + pr_debug("No IOMEM resource info for %s.\n", dev->name); > + retval = -ENOMEM; > + goto err1; > + } > + hcd->rsrc_start = res->start; > + hcd->rsrc_len = res->end - res->start + 1; > + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, dev->name)) { > + retval = -EBUSY; > + goto err1; > + } > + hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); > + if (!hcd->regs) { > + pr_debug("ioremap failed"); > + retval = -ENOMEM; > + goto err2; > + } > + msp_start_hc(dev); > + > + res = platform_get_resource(dev, IORESOURCE_IRQ, 0); > + if (res == NULL) { > + dev_err(&dev->dev, "No IRQ resource info for %s.\n", dev->name); > + retval = -ENOMEM; > + goto err3; > + } > + > + /* Map non-EHCI register spaces */ > + retval = usb_hcd_msp_map_regs(to_mspusb_device(dev)); > + if (retval != 0) > + goto err3; > + > + ehci = hcd_to_ehci(hcd); > + ehci->big_endian_mmio = 1; > + ehci->big_endian_desc = 1; > + > + > + retval = usb_add_hcd(hcd, res->start, IRQF_SHARED); > + if (retval == 0) > + return 0; > + > + usb_remove_hcd(hcd); > +err3: > + msp_stop_hc(dev); > + iounmap(hcd->regs); > +err2: > + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); > +err1: > + usb_put_hcd(hcd); > + > + return retval; > +} > + > + > +/* may be called without controller electrically present */ > +/* may be called with controller, bus, and devices active */ > + What may be called? > +/** > + * usb_hcd_msp_remove - shutdown processing for PMC MSP-based HCDs > + * @dev: USB Host Controller being removed > + * Context: !in_interrupt() > + * > + * Reverses the effect of usb_hcd_msp_probe(), first invoking > + * the HCD's stop() method. It is always called from a thread > + * context, normally "rmmod", "apmd", or something similar. > + * > + */ > +void usb_hcd_msp_remove(struct usb_hcd *hcd, struct platform_device *dev) > +{ > + usb_remove_hcd(hcd); > + msp_stop_hc(dev); > + iounmap(hcd->regs); > + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); > + usb_put_hcd(hcd); > +} > + > +#ifdef CONFIG_MSP_HAS_DUAL_USB > +/*-------------------------------------------------------------------------*/ > +/* > + * Wrapper around the main ehci_irq. Since both USB host controllers are > + * sharing the same IRQ, need to first determine whether we're the intended > + * recipient of this interrupt. > + */ > +static irqreturn_t ehci_msp_irq(struct usb_hcd *hcd) > +{ > + u32 int_src; > + struct device *dev = hcd->self.controller; > + struct platform_device *pdev; > + struct mspusb_device *mdev; > + struct ehci_hcd *ehci = hcd_to_ehci(hcd); > + > + /* need to reverse-map a couple of containers to get our device */ > + pdev = to_platform_device(dev); > + mdev = to_mspusb_device(pdev); > + > + /* Check to see if this interrupt is for this host controller */ > + int_src = ehci_readl(ehci, &mdev->mab_regs->int_stat); > + if (int_src & (1 << pdev->id)) > + return ehci_irq(hcd); > + > + /* Not for this device */ > + return IRQ_NONE; > +} > +/*-------------------------------------------------------------------------*/ > +#endif /* DUAL_USB */ > + > +static const struct hc_driver ehci_msp_hc_driver = { > + .description = hcd_name, > + .product_desc = "PMC MSP EHCI", > + .hcd_priv_size = sizeof(struct ehci_hcd), > + > + /* > + * generic hardware linkage > + */ > +#ifdef CONFIG_MSP_HAS_DUAL_USB > + .irq = ehci_msp_irq, > +#else > + .irq = ehci_irq, > +#endif > + .flags = HCD_MEMORY | HCD_USB2, > + > + /* > + * basic lifecycle operations > + */ > + .reset = ehci_msp_setup, > + .start = ehci_run, > + .shutdown = ehci_shutdown, > + .start = ehci_run, > + .stop = ehci_stop, > + > + /* > + * managing i/o requests and associated device resources > + */ > + .urb_enqueue = ehci_urb_enqueue, > + .urb_dequeue = ehci_urb_dequeue, > + .endpoint_disable = ehci_endpoint_disable, > + .endpoint_reset = ehci_endpoint_reset, > + > + /* > + * scheduling support > + */ > + .get_frame_number = ehci_get_frame, > + > + /* > + * root hub support > + */ > + .hub_status_data = ehci_hub_status_data, > + .hub_control = ehci_hub_control, > + .bus_suspend = ehci_bus_suspend, > + .bus_resume = ehci_bus_resume, > + .relinquish_port = ehci_relinquish_port, > + .port_handed_over = ehci_port_handed_over, > + > + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, > +}; > + > +static int ehci_hcd_msp_drv_probe(struct platform_device *pdev) > +{ > + int ret; > + > + pr_debug("In ehci_hcd_msp_drv_probe"); > + > + if (usb_disabled()) > + return -ENODEV; > + > + gpio_request(MSP_PIN_USB0_HOST_DEV, "USB0_HOST_DEV_GPIO"); > +#ifdef CONFIG_MSP_HAS_DUAL_USB > + gpio_request(MSP_PIN_USB1_HOST_DEV, "USB1_HOST_DEV_GPIO"); > +#endif > + > + ret = usb_hcd_msp_probe(&ehci_msp_hc_driver, pdev); > + > + return ret; > +} > + > +static int ehci_hcd_msp_drv_remove(struct platform_device *pdev) > +{ > + struct usb_hcd *hcd = platform_get_drvdata(pdev); > + > + usb_hcd_msp_remove(hcd, pdev); > + > + /* free TWI GPIO USB_HOST_DEV pin */ > + gpio_free(MSP_PIN_USB0_HOST_DEV); > +#ifdef CONFIG_MSP_HAS_DUAL_USB > + gpio_free(MSP_PIN_USB1_HOST_DEV); > +#endif > + > + return 0; > +} > + > +MODULE_ALIAS("pmcmsp-ehci"); > + > +static struct platform_driver ehci_hcd_msp_driver = { > + .probe = ehci_hcd_msp_drv_probe, > + .remove = ehci_hcd_msp_drv_remove, > + .driver = { > + .name = "pmcmsp-ehci", > + .owner = THIS_MODULE, > +#ifdef CONFIG_PM > + .pm = &ehci_msp_pmops, > +#endif > + }, > +}; > diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h > index 799ac16..1b71d6a 100644 > --- a/drivers/usb/host/ehci.h > +++ b/drivers/usb/host/ehci.h > @@ -134,6 +134,7 @@ struct ehci_hcd { /* one per controller */ > unsigned amd_l1_fix:1; > unsigned fs_i_thresh:1; /* Intel iso scheduling */ > unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ > + unsigned pmc_msp_tdi:1; /* PMC MSP tdi quirk*/ This part of the patch doesn't apply cleanly anymore, care to refresh it against linux-next, and make all of the other fixes and resend it? thanks, greg k-h