[PATCH 13/20] usb: host: xhci: convert xhci-pci.c into a parent device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch starts decoupling xhci core from PCI.
Although we still have a lot to do, this shows
how things will look like after the conversion is
finished.

[bigeasy@xxxxxxxxxxxxx: - add module license, use bitmap for unique ids,
	tmp pdev workaround]

Signed-off-by: Felipe Balbi <balbi@xxxxxx>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
---
 drivers/usb/host/Makefile   |    7 +-
 drivers/usb/host/xhci-mem.c |   20 ++--
 drivers/usb/host/xhci-pci.c |  225 +++++++++++++++++++++++++------------------
 drivers/usb/host/xhci.c     |   85 ++++++++++------
 drivers/usb/host/xhci.h     |    6 -
 5 files changed, 200 insertions(+), 143 deletions(-)

diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 624a362..92357af 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -11,7 +11,7 @@ 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
 
 obj-$(CONFIG_USB_WHCI_HCD)	+= whci/
@@ -26,6 +26,11 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
 obj-$(CONFIG_USB_XHCI_HCD)	+= xhci-hcd.o
+
+ifneq ($(CONFIG_PCI),)
+	obj-$(CONFIG_USB_XHCI_HCD)	+= xhci-pci.o
+endif
+
 obj-$(CONFIG_USB_SL811_HCD)	+= sl811-hcd.o
 obj-$(CONFIG_USB_SL811_CS)	+= sl811_cs.o
 obj-$(CONFIG_USB_U132_HCD)	+= u132-hcd.o
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 586aac7..c9ff110 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -312,10 +312,10 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci,
 		unsigned int num_stream_ctxs,
 		struct xhci_stream_ctx *stream_ctx, dma_addr_t dma)
 {
-	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	struct device *dev = xhci_to_hcd(xhci)->self.controller;
 
 	if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE)
-		dma_free_coherent(&pdev->dev,
+		dma_free_coherent(dev,
 				sizeof(struct xhci_stream_ctx)*num_stream_ctxs,
 				stream_ctx, dma);
 	else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE)
@@ -340,10 +340,10 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci,
 		unsigned int num_stream_ctxs, dma_addr_t *dma,
 		gfp_t mem_flags)
 {
-	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	struct device *dev = xhci_to_hcd(xhci)->self.controller;
 
 	if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE)
-		return dma_alloc_coherent(&pdev->dev,
+		return dma_alloc_coherent(dev,
 				sizeof(struct xhci_stream_ctx)*num_stream_ctxs,
 				dma, mem_flags);
 	else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE)
@@ -1403,7 +1403,7 @@ static void scratchpad_free(struct xhci_hcd *xhci)
 {
 	int num_sp;
 	int i;
-	struct pci_dev	*pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	struct device *dev = xhci_to_hcd(xhci)->self.controller;
 
 	if (!xhci->scratchpad)
 		return;
@@ -1411,13 +1411,13 @@ static void scratchpad_free(struct xhci_hcd *xhci)
 	num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);
 
 	for (i = 0; i < num_sp; i++) {
-		dma_free_coherent(&pdev->dev, xhci->page_size,
+		dma_free_coherent(dev, xhci->page_size,
 				    xhci->scratchpad->sp_buffers[i],
 				    xhci->scratchpad->sp_dma_buffers[i]);
 	}
 	kfree(xhci->scratchpad->sp_dma_buffers);
 	kfree(xhci->scratchpad->sp_buffers);
-	dma_free_coherent(&pdev->dev, num_sp * sizeof(u64),
+	dma_free_coherent(dev, num_sp * sizeof(u64),
 			    xhci->scratchpad->sp_array,
 			    xhci->scratchpad->sp_dma);
 	kfree(xhci->scratchpad);
@@ -1487,7 +1487,7 @@ void xhci_free_command(struct xhci_hcd *xhci,
 
 void xhci_mem_cleanup(struct xhci_hcd *xhci)
 {
-	struct pci_dev	*pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	struct device *dev = xhci_to_hcd(xhci)->self.controller;
 	int size;
 	int i;
 
@@ -1499,7 +1499,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 	}
 	size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
 	if (xhci->erst.entries)
-		dma_free_coherent(&pdev->dev, size,
+		dma_free_coherent(dev, size,
 				xhci->erst.entries, xhci->erst.erst_dma_addr);
 	xhci->erst.entries = NULL;
 	xhci_dbg(xhci, "Freed ERST\n");
@@ -1539,7 +1539,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 
 	xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr);
 	if (xhci->dcbaa)
-		dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa),
+		dma_free_coherent(dev, sizeof(*xhci->dcbaa),
 				xhci->dcbaa, xhci->dcbaa->dma);
 	xhci->dcbaa = NULL;
 
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 7006600..b01c021 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -22,6 +22,7 @@
 
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/platform_device.h>
 
 #include "xhci.h"
 
@@ -32,7 +33,6 @@
 #define PCI_VENDOR_ID_ETRON		0x1b6f
 #define PCI_DEVICE_ID_ASROCK_P67	0x7023
 
-static const char hcd_name[] = "xhci_hcd";
 
 /* called after powerup, by probe or system-pm "wakeup" */
 static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
@@ -58,6 +58,12 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
 	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
 	int			retval;
 	u32			temp;
+	struct platform_device	*plat_dev;
+	struct xhci_platform_data	*data;
+
+	plat_dev = to_platform_device(hcd->self.controller);
+	data = plat_dev->dev.platform_data;
+	pdev = to_pci_dev(plat_dev->dev.parent);
 
 	hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 2;
 
@@ -107,41 +113,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
 	xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
 	xhci_print_registers(xhci);
 
-	/* Look for vendor-specific quirks */
-	if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
-			pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) {
-		if (pdev->revision == 0x0) {
-			xhci->quirks |= XHCI_RESET_EP_QUIRK;
-			xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
-					" endpoint cmd after reset endpoint\n");
-		}
-		/* Fresco Logic confirms: all revisions of this chip do not
-		 * support MSI, even though some of them claim to in their PCI
-		 * capabilities.
-		 */
-		xhci->quirks |= XHCI_BROKEN_MSI;
-		xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u "
-				"has broken MSI implementation\n",
-				pdev->revision);
-	}
-
-	if (pdev->vendor == PCI_VENDOR_ID_NEC)
-		xhci->quirks |= XHCI_NEC_HOST;
-
-	/* AMD PLL quirk */
-	if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info())
-		xhci->quirks |= XHCI_AMD_PLL_FIX;
-	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
-			pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) {
-		xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
-		xhci->quirks |= XHCI_EP_LIMIT_QUIRK;
-		xhci->limit_active_eps = 64;
-	}
-	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
-			pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
-		xhci->quirks |= XHCI_RESET_ON_RESUME;
-		xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
-	}
+	xhci->quirks = data->quirks;
+	xhci->limit_active_eps = data->limit_active_eps;
 
 	/* Make sure the HC is halted. */
 	retval = xhci_halt(xhci);
@@ -183,79 +156,132 @@ error:
 	return retval;
 }
 
-static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+#define XHCI_PCI_DEVS_POSSIBLE	32
+static DECLARE_BITMAP(xhci_pci_devs, XHCI_PCI_DEVS_POSSIBLE);
+
+static int xhci_get_unique_id(void)
 {
-	int retval;
-	struct xhci_hcd *xhci;
-	const struct hc_driver *driver;
-	struct usb_hcd *hcd;
-	struct xhci_platform_data *data;
+	int id;
+again:
+	id = find_first_zero_bit(xhci_pci_devs, XHCI_PCI_DEVS_POSSIBLE);
+	if (id < XHCI_PCI_DEVS_POSSIBLE) {
+		int old;
+
+		old = test_and_set_bit(id, xhci_pci_devs);
+		if (old)
+			goto again;
+	} else {
+		id = -ENOMEM;
+	}
+	return id;
+}
 
-	data = (struct xhci_platform_data *) id->driver_data;
-	driver = data->driver;
+static void xhci_put_unique_id(int id)
+{
+	if (id < 0)
+		return;
+	WARN_ON(!test_bit(id, xhci_pci_devs));
+	clear_bit(id, xhci_pci_devs);
+}
 
-	/* Register the USB 2.0 roothub.
-	 * FIXME: USB core must know to register the USB 2.0 roothub first.
-	 * This is sort of silly, because we could just set the HCD driver flags
-	 * to say USB 2.0, but I'm not sure what the implications would be in
-	 * the other parts of the HCD code.
-	 */
-	retval = usb_hcd_pci_probe(dev, id);
+static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct xhci_platform_data	*data;
+	struct platform_device		*xhci_pdev;
+	struct resource			res[2];
+	int				dev_id;
+	int				ret;
 
-	if (retval)
-		return retval;
+	data = (struct xhci_platform_data *) id->driver_data;
 
-	/* USB 2.0 roothub is stored in the PCI device now. */
-	hcd = dev_get_drvdata(&dev->dev);
-	xhci = hcd_to_xhci(hcd);
+	ret = pci_enable_device(dev);
+	if (ret) {
+		dev_err(&dev->dev, "failed to enable pci device\n");
+		goto err1;
+	}
 
 	/* Quirk on revision 0 of Fresco Logic's PDK */
 	if (dev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
 			dev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) {
-		if (dev->revision == 0x0) {
+		if (dev->revision == 0x0)
 			data->quirks |= XHCI_RESET_EP_QUIRK;
-			xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
-					" endpoint cmd after reset endpoint\n");
-		}
 	}
 
-	xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev,
-				pci_name(dev), hcd);
-	if (!xhci->shared_hcd) {
-		retval = -ENOMEM;
-		goto dealloc_usb2_hcd;
+	pci_set_power_state(dev, PCI_D0);
+	pci_set_master(dev);
+
+	dev_id = xhci_get_unique_id();
+	if (dev_id < 0) {
+		dev_err(&dev->dev, "Too many xhci controller in system\n");
+		goto err2;
+	}
+	xhci_pdev = platform_device_alloc("usb-xhci-pci", dev_id);
+	if (!xhci_pdev) {
+		dev_err(&dev->dev, "couldn't allocate xhci device\n");
+		goto err2_5;
 	}
 
-	/* Set the xHCI pointer before xhci_pci_setup() (aka hcd_driver.reset)
-	 * is called by usb_add_hcd().
-	 */
-	*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;
+	pci_set_drvdata(dev, xhci_pdev);
+
+	memset(res, 0x00, sizeof(res));
+
+	res[0].start	= pci_resource_start(dev, 0);
+	res[0].end	= pci_resource_end(dev, 0);
+	res[0].name	= "xhci";
+	res[0].flags	= IORESOURCE_MEM;
+	res[1].start	= dev->irq;
+	res[1].name	= "xhci";
+	res[1].flags	= IORESOURCE_IRQ;
+
+	ret = platform_device_add_resources(xhci_pdev, res, ARRAY_SIZE(res));
+	if (ret) {
+		dev_err(&dev->dev, "couldn't add resources to xhci device\n");
+		goto err3;
+	}
+
+	dma_set_coherent_mask(&xhci_pdev->dev, dev->dev.coherent_dma_mask);
+
+	xhci_pdev->dev.dma_mask	= dev->dev.dma_mask;
+	xhci_pdev->dev.dma_parms = dev->dev.dma_parms;
+	xhci_pdev->dev.parent = &dev->dev;
+
+	ret = platform_device_add_data(xhci_pdev, data, sizeof(*data));
+	if (ret) {
+		dev_err(&dev->dev, "failed to add platform data\n");
+		goto err3;
+	}
+
+	ret = platform_device_add(xhci_pdev);
+	if (ret) {
+		dev_err(&dev->dev, "failed to register xhci device\n");
+		goto err3;
+	}
 
-	retval = usb_add_hcd(xhci->shared_hcd, dev->irq,
-			IRQF_DISABLED | IRQF_SHARED);
-	if (retval)
-		goto put_usb3_hcd;
-	/* Roothub already marked as USB 3.0 speed */
 	return 0;
 
-put_usb3_hcd:
-	usb_put_hcd(xhci->shared_hcd);
-dealloc_usb2_hcd:
-	usb_hcd_pci_remove(dev);
-	return retval;
+err3:
+	pci_set_drvdata(dev, NULL);
+	platform_device_put(xhci_pdev);
+
+err2_5:
+	xhci_put_unique_id(dev_id);
+err2:
+	pci_disable_device(dev);
+
+err1:
+	return ret;
 }
 
 static void xhci_pci_remove(struct pci_dev *dev)
 {
-	struct xhci_hcd *xhci;
-
-	xhci = hcd_to_xhci(pci_get_drvdata(dev));
-	if (xhci->shared_hcd) {
-		usb_remove_hcd(xhci->shared_hcd);
-		usb_put_hcd(xhci->shared_hcd);
-	}
-	usb_hcd_pci_remove(dev);
-	kfree(xhci);
+	struct platform_device	*xhci_pdev = pci_get_drvdata(dev);
+	int id;
+
+	id = xhci_pdev->id;
+	pci_set_drvdata(dev, NULL);
+	platform_device_unregister(xhci_pdev);
+	xhci_put_unique_id(id);
+	pci_disable_device(dev);
 }
 
 #ifdef CONFIG_PM
@@ -304,7 +330,7 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
 #endif /* CONFIG_PM */
 
 static const struct hc_driver xhci_pci_hc_driver = {
-	.description =		hcd_name,
+	.description =		"xhci-pci",
 	.product_desc =		"xHCI Host Controller",
 	.hcd_priv_size =	sizeof(struct xhci_hcd *),
 
@@ -424,29 +450,38 @@ static DEFINE_PCI_DEVICE_TABLE(pci_ids) = {
 };
 MODULE_DEVICE_TABLE(pci, pci_ids);
 
+static void usb_xhci_pci_shutdown(struct pci_dev *dev)
+{
+	pci_disable_device(dev);
+}
+
 /* pci driver glue; this is a "new style" PCI driver module */
 static struct pci_driver xhci_pci_driver = {
-	.name =		(char *) hcd_name,
+	.name =		"xhci-pci",
 	.id_table =	pci_ids,
 
 	.probe =	xhci_pci_probe,
-	.remove =	xhci_pci_remove,
+	.remove =	__devexit_p(xhci_pci_remove),
 	/* suspend and resume implemented later */
 
-	.shutdown = 	usb_hcd_pci_shutdown,
+	.shutdown =	usb_xhci_pci_shutdown,
 #ifdef CONFIG_PM_SLEEP
 	.driver = {
-		.pm = &usb_hcd_pci_pm_ops
+		.pm = &usb_hcd_plat_pci_pm_ops,
 	},
 #endif
 };
 
-int xhci_register_pci(void)
+static int xhci_register_pci(void)
 {
 	return pci_register_driver(&xhci_pci_driver);
 }
+module_init(xhci_register_pci);
 
-void xhci_unregister_pci(void)
+static void xhci_unregister_pci(void)
 {
 	pci_unregister_driver(&xhci_pci_driver);
 }
+module_exit(xhci_unregister_pci);
+MODULE_DESCRIPTION("PCI glue code for the XHCI controller");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 203114d..55a963c 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -198,20 +198,24 @@ static int xhci_free_msi(struct xhci_hcd *xhci)
  */
 static int xhci_setup_msi(struct xhci_hcd *xhci)
 {
-	int ret;
-	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	struct platform_device  *plat_dev;
+	struct pci_dev		*pci_dev;
+	int			ret;
+
+	plat_dev = to_platform_device(xhci_to_hcd(xhci)->self.controller);
+	pci_dev = to_pci_dev(plat_dev->dev.parent);
 
-	ret = pci_enable_msi(pdev);
+	ret = pci_enable_msi(pci_dev);
 	if (ret) {
 		xhci_err(xhci, "failed to allocate MSI entry\n");
 		return ret;
 	}
 
-	ret = request_irq(pdev->irq, (irq_handler_t)xhci_msi_irq,
+	ret = request_irq(pci_dev->irq, (irq_handler_t)xhci_msi_irq,
 				0, "xhci_hcd", xhci_to_hcd(xhci));
 	if (ret) {
 		xhci_err(xhci, "disable MSI interrupt\n");
-		pci_disable_msi(pdev);
+		pci_disable_msi(pci_dev);
 	}
 
 	return ret;
@@ -223,9 +227,12 @@ static int xhci_setup_msi(struct xhci_hcd *xhci)
  */
 static void xhci_free_irq(struct xhci_hcd *xhci)
 {
-	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
-	int ret;
+	struct platform_device  *plat_dev;
+	struct pci_dev		*pci_dev;
+	int			ret;
 
+	plat_dev = to_platform_device(xhci_to_hcd(xhci)->self.controller);
+	pci_dev = to_pci_dev(plat_dev->dev.parent);
 	/* return if using legacy interrupt */
 	if (xhci_to_hcd(xhci)->irq >= 0)
 		return;
@@ -233,8 +240,8 @@ static void xhci_free_irq(struct xhci_hcd *xhci)
 	ret = xhci_free_msi(xhci);
 	if (!ret)
 		return;
-	if (pdev->irq >= 0)
-		free_irq(pdev->irq, xhci_to_hcd(xhci));
+	if (pci_dev->irq >= 0)
+		free_irq(pci_dev->irq, xhci_to_hcd(xhci));
 
 	return;
 }
@@ -246,7 +253,11 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
 {
 	int i, ret = 0;
 	struct usb_hcd *hcd = xhci_to_hcd(xhci);
-	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+	struct platform_device  *plat_dev;
+	struct pci_dev		*pci_dev;
+
+	plat_dev = to_platform_device(hcd->self.controller);
+	pci_dev = to_pci_dev(plat_dev->dev.parent);
 
 	/*
 	 * calculate number of msi-x vectors supported.
@@ -271,7 +282,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
 		xhci->msix_entries[i].vector = 0;
 	}
 
-	ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count);
+	ret = pci_enable_msix(pci_dev, xhci->msix_entries, xhci->msix_count);
 	if (ret) {
 		xhci_err(xhci, "Failed to enable MSI-X\n");
 		goto free_entries;
@@ -291,7 +302,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
 disable_msix:
 	xhci_err(xhci, "disable MSI-X interrupt\n");
 	xhci_free_irq(xhci);
-	pci_disable_msix(pdev);
+	pci_disable_msix(pci_dev);
 free_entries:
 	kfree(xhci->msix_entries);
 	xhci->msix_entries = NULL;
@@ -302,16 +313,20 @@ free_entries:
 static void xhci_cleanup_msix(struct xhci_hcd *xhci)
 {
 	struct usb_hcd *hcd = xhci_to_hcd(xhci);
-	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+	struct platform_device  *plat_dev;
+	struct pci_dev		*pci_dev;
+
+	plat_dev = to_platform_device(hcd->self.controller);
+	pci_dev = to_pci_dev(plat_dev->dev.parent);
 
 	xhci_free_irq(xhci);
 
 	if (xhci->msix_entries) {
-		pci_disable_msix(pdev);
+		pci_disable_msix(pci_dev);
 		kfree(xhci->msix_entries);
 		xhci->msix_entries = NULL;
 	} else {
-		pci_disable_msi(pdev);
+		pci_disable_msi(pci_dev);
 	}
 
 	hcd->msix_enabled = 0;
@@ -3130,8 +3145,6 @@ static int xhci_probe(struct platform_device *pdev)
 		goto err0;
 	}
 
-	platform_set_drvdata(pdev, hcd);
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "missing memory resource\n");
@@ -3211,29 +3224,42 @@ static int __devexit xhci_remove(struct platform_device *pdev)
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
+	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
+static void xhci_plat_shutdown(struct platform_device *pdev)
+{
+	struct usb_hcd		*hcd = platform_get_drvdata(pdev);
+
+	if (!hcd)
+		return;
+	if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) &&
+			hcd->driver->shutdown)
+		hcd->driver->shutdown(hcd);
+}
+
+static const struct platform_device_id xhci_id_table[] __devinitconst = {
+	{
+		.name   = "usb-xhci-pci",
+	},
+	{  },   /* Terminating Entry */
+};
+MODULE_DEVICE_TABLE(platform, xhci_id_table);
+
 static struct platform_driver xhci_driver = {
 	.probe		= xhci_probe,
 	.remove		= __devexit_p(xhci_remove),
+	.shutdown	= xhci_plat_shutdown,
 	.driver		= {
-		.name	= "xhci",
+		.name	= "xhci-core",
+		.owner	= THIS_MODULE,
 	},
+	.id_table	= xhci_id_table,
 };
 
 static int __init xhci_hcd_init(void)
 {
-#ifdef CONFIG_PCI
-	int retval = 0;
-
-	retval = xhci_register_pci();
-
-	if (retval < 0) {
-		printk(KERN_DEBUG "Problem registering PCI driver.");
-		return retval;
-	}
-#endif
 	/*
 	 * Check the compiler generated sizes of structures that must be laid
 	 * out in specific ways for hardware access.
@@ -3259,9 +3285,6 @@ module_init(xhci_hcd_init);
 
 static void __exit xhci_hcd_cleanup(void)
 {
-#ifdef CONFIG_PCI
-	xhci_unregister_pci();
-#endif
 	platform_driver_unregister(&xhci_driver);
 }
 module_exit(xhci_hcd_cleanup);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 1f0021c..3f82ad2 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1488,12 +1488,6 @@ void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv);
 void xhci_free_command(struct xhci_hcd *xhci,
 		struct xhci_command *command);
 
-#ifdef CONFIG_PCI
-/* xHCI PCI glue */
-int xhci_register_pci(void);
-void xhci_unregister_pci(void);
-#endif
-
 /* xHCI host controller glue */
 void xhci_quiesce(struct xhci_hcd *xhci);
 int xhci_halt(struct xhci_hcd *xhci);
-- 
1.7.4.4

--
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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux