Hi Felipe, I'm heading off to Prague for vacation before kernel summit, so I probably won't get around to reviewing this for a couple days at least. Sarah Sharp On Wed, Oct 12, 2011 at 02:17:09PM +0300, Felipe Balbi wrote: > SoCs will generally use the platform bus type, > in order to simplify re-use of xHCI driver by > SoCs, we introduce a generic file which is to > be re-used by anyone with an xHCI using the > platform bus_type. > > Also avoid always compiling xhci-pci.c, not > all architectures have PCI. > > Signed-off-by: Felipe Balbi <balbi@xxxxxx> > --- > drivers/usb/host/Kconfig | 4 + > drivers/usb/host/Makefile | 5 +- > drivers/usb/host/xhci-platform.c | 234 ++++++++++++++++++++++++++++++++++++++ > drivers/usb/host/xhci.c | 14 ++- > drivers/usb/host/xhci.h | 6 + > 5 files changed, 261 insertions(+), 2 deletions(-) > create mode 100644 drivers/usb/host/xhci-platform.c > > diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig > index ab085f1..f91619a 100644 > --- a/drivers/usb/host/Kconfig > +++ b/drivers/usb/host/Kconfig > @@ -27,6 +27,10 @@ config USB_XHCI_HCD > To compile this driver as a module, choose M here: the > module will be called xhci-hcd. > > +config USB_XHCI_PLATFORM > + bool > + depends on USB_XHCI_HCD > + > config USB_XHCI_HCD_DEBUGGING > bool "Debugging for the xHCI host controller" > depends on USB_XHCI_HCD > diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile > index 624a362..fd4f2ab 100644 > --- a/drivers/usb/host/Makefile > +++ b/drivers/usb/host/Makefile > @@ -11,9 +11,12 @@ fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o > > fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o > > -xhci-hcd-y := xhci.o xhci-mem.o xhci-pci.o > +xhci-hcd-y := xhci.o xhci-mem.o > xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o > > +xhci-hcd-$(CONFIG_PCI) += xhci-pci.o > +xhci-hcd-$(CONFIG_USB_XHCI_PLATFORM) += xhci-platform.o > + > obj-$(CONFIG_USB_WHCI_HCD) += whci/ > > obj-$(CONFIG_PCI) += pci-quirks.o > diff --git a/drivers/usb/host/xhci-platform.c b/drivers/usb/host/xhci-platform.c > new file mode 100644 > index 0000000..7a6e7f8 > --- /dev/null > +++ b/drivers/usb/host/xhci-platform.c > @@ -0,0 +1,234 @@ > +/** > + * xhci-platform.c - XHCI Platform Driver Glue > + * > + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com > + * > + * Authors: Felipe Balbi <balbi@xxxxxx>, > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions, and the following disclaimer, > + * without modification. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. The names of the above-listed copyright holders may not be used > + * to endorse or promote products derived from this software without > + * specific prior written permission. > + * > + * ALTERNATIVELY, this software may be distributed under the terms of the > + * GNU General Public License ("GPL") version 2, as published by the Free > + * Software Foundation. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR > + * CONTRIBUTORS 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. > + */ > + > +#include <linux/module.h> > +#include <linux/kernel.h> > +#include <linux/slab.h> > +#include <linux/platform_device.h> > +#include <linux/pm_runtime.h> > +#include <linux/interrupt.h> > +#include <linux/ioport.h> > +#include <linux/io.h> > +#include <linux/dma-mapping.h> > +#include <linux/usb.h> > + > +#include <linux/usb/hcd.h> > + > +#include "xhci.h" > + > +static const char hcd_name[] = "xhci_hcd"; > + > +static int xhci_platform_setup(struct usb_hcd *hcd) > +{ > + return 0; > +} > + > +static const struct hc_driver xhci_platform_hc_driver= { > + .description = hcd_name, > + .product_desc = "xHCI Host Controller", > + .hcd_priv_size = sizeof(struct xhci_hcd *), > + > + /* generic hardware linkage */ > + .irq = xhci_irq, > + .flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED, > + > + /* basic lifecycle operations */ > + .reset = xhci_platform_setup, > + .start = xhci_run, > + .stop = xhci_stop, > + .shutdown = xhci_shutdown, > + > + /* managing i/o requests and associated device resources */ > + .urb_enqueue = xhci_urb_enqueue, > + .urb_dequeue = xhci_urb_dequeue, > + .alloc_dev = xhci_alloc_dev, > + .free_dev = xhci_free_dev, > + .alloc_streams = xhci_alloc_streams, > + .free_streams = xhci_free_streams, > + .add_endpoint = xhci_add_endpoint, > + .drop_endpoint = xhci_drop_endpoint, > + .endpoint_reset = xhci_endpoint_reset, > + .check_bandwidth = xhci_check_bandwidth, > + .reset_bandwidth = xhci_reset_bandwidth, > + .address_device = xhci_address_device, > + .update_hub_device = xhci_update_hub_device, > + .reset_device = xhci_discover_or_reset_device, > + > + /* scheduling support */ > + .get_frame_number = xhci_get_frame, > + > + /* Root hub support */ > + .hub_control = xhci_hub_control, > + .hub_status_data = xhci_hub_status_data, > + .bus_suspend = xhci_bus_suspend, > + .bus_resume = xhci_bus_resume, > +}; > + > +static int __devinit xhci_platform_probe(struct platform_device *pdev) > +{ > + const struct hc_driver *driver = &xhci_platform_hc_driver; > + struct xhci_hcd *xhci; > + struct usb_hcd *hcd; > + struct resource *res; > + int ret; > + int irq; > + > + if (usb_disabled()) > + return -ENODEV; > + > + irq = platform_get_irq(pdev, 0); > + if (irq <= 0) { > + dev_err(&pdev->dev, "found HC with no IRQ\n"); > + ret = -ENODEV; > + goto err0; > + } > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!res) { > + dev_err(&pdev->dev, "missing memory address\n"); > + ret = -ENXIO; > + goto err0; > + } > + > + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); > + if (!hcd) { > + dev_err(&pdev->dev, "can't create HCD\n"); > + ret = -ENOMEM; > + goto err0; > + } > + > + hcd->rsrc_start = res->start; > + hcd->rsrc_len = resource_size(res); > + platform_set_drvdata(pdev, hcd); > + > + res = request_mem_region(res->start, resource_size(res), > + driver->description); > + if (!res) { > + dev_err(&pdev->dev, "controller in use\n"); > + ret = -EBUSY; > + goto err1; > + } > + > + hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); > + if (!hcd->regs) { > + dev_err(&pdev->dev, "failed mapping memory\n"); > + ret = -EFAULT; > + goto err2; > + } > + > + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); > + if (ret) { > + dev_err(&pdev->dev, "failed adding HCD\n"); > + goto err3; > + } > + > + xhci = hcd_to_xhci(hcd); > + xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, > + dev_name(&pdev->dev), hcd); > + if (!xhci->shared_hcd) { > + ret = -ENOMEM; > + goto err4; > + } > + > + *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; > + > + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); > + if (ret) { > + dev_err(&pdev->dev, "failed adding Shared HCD\n"); > + goto err5; > + } > + > + return 0; > + > +err5: > + usb_put_hcd(xhci->shared_hcd); > + > +err4: > + usb_remove_hcd(hcd); > + > +err3: > + iounmap(hcd->regs); > + > +err2: > + release_mem_region(res->start, resource_size(res)); > + > +err1: > + usb_put_hcd(hcd); > + > +err0: > + return ret; > +} > + > +static int __devexit xhci_platform_remove(struct platform_device *pdev) > +{ > + struct usb_hcd *hcd = platform_get_drvdata(pdev); > + struct xhci_hcd *xhci = hcd_to_xhci(hcd); > + > + usb_remove_hcd(xhci->shared_hcd); > + usb_put_hcd(xhci->shared_hcd); > + > + usb_remove_hcd(hcd); > + > + iounmap(hcd->regs); > + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); > + > + usb_put_hcd(hcd); > + > + return 0; > +} > + > +static struct platform_driver xhci_platform_driver = { > + .probe = xhci_platform_probe, > + .remove = __devexit_p(xhci_platform_remove), > + .driver = { > + .name = "xhci", > + }, > +}; > + > +MODULE_AUTHOR("Felipe Balbi <balbi@xxxxxx>"); > +MODULE_LICENSE("GPL v2"); > +MODULE_DESCRIPTION("XHCI Platform Glue Driver"); > + > +int __init xhci_register_platform(void) > +{ > + return platform_driver_register(&xhci_platform_driver); > +} > + > +void __exit xhci_unregister_platform(void) > +{ > + platform_driver_unregister(&xhci_platform_driver); > +} > diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c > index f647d91..ae1c4d4 100644 > --- a/drivers/usb/host/xhci.c > +++ b/drivers/usb/host/xhci.c > @@ -3057,9 +3057,9 @@ MODULE_LICENSE("GPL"); > > static int __init xhci_hcd_init(void) > { > -#ifdef CONFIG_PCI > int retval = 0; > > +#ifdef CONFIG_PCI > retval = xhci_register_pci(); > > if (retval < 0) { > @@ -3067,6 +3067,14 @@ static int __init xhci_hcd_init(void) > return retval; > } > #endif > + > +#ifdef CONFIG_USB_XHCI_PLATFORM > + retval = xhci_register_platform(); > + if (retval) { > + printk(KERN_DEBUG "Problem registering Platform driver.\n"); > + return retval; > + } > +#endif > /* > * Check the compiler generated sizes of structures that must be laid > * out in specific ways for hardware access. > @@ -3094,5 +3102,9 @@ static void __exit xhci_hcd_cleanup(void) > #ifdef CONFIG_PCI > xhci_unregister_pci(); > #endif > + > +#ifdef CONFIG_USB_XHCI_PLATFORM > + xhci_unregister_platform(); > +#endif > } > module_exit(xhci_hcd_cleanup); > diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h > index cae8e23..78637ce 100644 > --- a/drivers/usb/host/xhci.h > +++ b/drivers/usb/host/xhci.h > @@ -1485,6 +1485,12 @@ int xhci_register_pci(void); > void xhci_unregister_pci(void); > #endif > > +#ifdef CONFIG_USB_XHCI_PLATFORM > +/* xHCI Platform glue */ > +int xhci_register_platform(void); > +void xhci_unregister_platform(void); > +#endif > + > /* xHCI host controller glue */ > void xhci_quiesce(struct xhci_hcd *xhci); > int xhci_halt(struct xhci_hcd *xhci); > -- > 1.7.6.396.ge0613 > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html