[PATCH 14/20] usb: host: xhci: move the hc_driver to xhci.c

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

 



by doing that, we need to remove all accesses
to PCI bus from any xhci core function. For now,
we still have one PCI function which is exported
from the PCI glue layer to xhci core. All else,
is removed.

[bigeasy@linutronix: keep the pdev workaround in ->setup]

Signed-off-by: Felipe Balbi <balbi@xxxxxx>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
---
 drivers/usb/host/xhci-pci.c |  214 +-----------------------------------------
 drivers/usb/host/xhci.c     |  153 ++++++++++++++++++++++++++++++-
 drivers/usb/host/xhci.h     |    2 +
 3 files changed, 158 insertions(+), 211 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index b01c021..ce9182a 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -35,8 +35,12 @@
 
 
 /* called after powerup, by probe or system-pm "wakeup" */
-static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
+int xhci_reinit(struct xhci_hcd *xhci, struct device *dev)
 {
+	struct pci_dev		*pdev = to_pci_dev(dev->parent);
+
+	pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
+
 	/*
 	 * TODO: Implement finding debug ports later.
 	 * TODO: see if there are any quirks that need to be added to handle
@@ -50,112 +54,9 @@ static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
 	xhci_dbg(xhci, "Finished xhci_pci_reinit\n");
 	return 0;
 }
+EXPORT_SYMBOL_GPL(xhci_reinit);
 
 /* called during probe() after chip reset completes */
-static int xhci_pci_setup(struct usb_hcd *hcd)
-{
-	struct xhci_hcd		*xhci;
-	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;
-
-	if (usb_hcd_is_primary_hcd(hcd)) {
-		xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL);
-		if (!xhci)
-			return -ENOMEM;
-		*((struct xhci_hcd **) hcd->hcd_priv) = xhci;
-		xhci->main_hcd = hcd;
-		/* Mark the first roothub as being USB 2.0.
-		 * The xHCI driver will register the USB 3.0 roothub.
-		 */
-		hcd->speed = HCD_USB2;
-		hcd->self.root_hub->speed = USB_SPEED_HIGH;
-		/*
-		 * USB 2.0 roothub under xHCI has an integrated TT,
-		 * (rate matching hub) as opposed to having an OHCI/UHCI
-		 * companion controller.
-		 */
-		hcd->has_tt = 1;
-	} else {
-		/* xHCI private pointer was set in xhci_pci_probe for the second
-		 * registered roothub.
-		 */
-		xhci = hcd_to_xhci(hcd);
-		temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
-		if (HCC_64BIT_ADDR(temp)) {
-			xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
-			dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
-		} else {
-			dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
-		}
-		return 0;
-	}
-
-	xhci->cap_regs = hcd->regs;
-	xhci->op_regs = hcd->regs +
-		HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase));
-	xhci->run_regs = hcd->regs +
-		(xhci_readl(xhci, &xhci->cap_regs->run_regs_off) & RTSOFF_MASK);
-	/* Cache read-only capability registers */
-	xhci->hcs_params1 = xhci_readl(xhci, &xhci->cap_regs->hcs_params1);
-	xhci->hcs_params2 = xhci_readl(xhci, &xhci->cap_regs->hcs_params2);
-	xhci->hcs_params3 = xhci_readl(xhci, &xhci->cap_regs->hcs_params3);
-	xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hc_capbase);
-	xhci->hci_version = HC_VERSION(xhci->hcc_params);
-	xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
-	xhci_print_registers(xhci);
-
-	xhci->quirks = data->quirks;
-	xhci->limit_active_eps = data->limit_active_eps;
-
-	/* Make sure the HC is halted. */
-	retval = xhci_halt(xhci);
-	if (retval)
-		goto error;
-
-	xhci_dbg(xhci, "Resetting HCD\n");
-	/* Reset the internal HC memory state and registers. */
-	retval = xhci_reset(xhci);
-	if (retval)
-		goto error;
-	xhci_dbg(xhci, "Reset complete\n");
-
-	temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
-	if (HCC_64BIT_ADDR(temp)) {
-		xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
-		dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
-	} else {
-		dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
-	}
-
-	xhci_dbg(xhci, "Calling HCD init\n");
-	/* Initialize HCD and host controller data structures. */
-	retval = xhci_init(hcd);
-	if (retval)
-		goto error;
-	xhci_dbg(xhci, "Called HCD init\n");
-
-	pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
-	xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn);
-
-	/* Find any debug ports */
-	retval = xhci_pci_reinit(xhci, pdev);
-	if (!retval)
-		return retval;
-
-error:
-	kfree(xhci);
-	return retval;
-}
-
 #define XHCI_PCI_DEVS_POSSIBLE	32
 static DECLARE_BITMAP(xhci_pci_devs, XHCI_PCI_DEVS_POSSIBLE);
 
@@ -284,131 +185,28 @@ static void xhci_pci_remove(struct pci_dev *dev)
 	pci_disable_device(dev);
 }
 
-#ifdef CONFIG_PM
-static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
-{
-	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
-	int	retval = 0;
-
-	if (hcd->state != HC_STATE_SUSPENDED ||
-			xhci->shared_hcd->state != HC_STATE_SUSPENDED)
-		return -EINVAL;
-
-	retval = xhci_suspend(xhci);
-
-	return retval;
-}
-
-static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
-{
-	struct xhci_hcd		*xhci = hcd_to_xhci(hcd);
-	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
-	int			retval = 0;
-
-	/* The BIOS on systems with the Intel Panther Point chipset may or may
-	 * not support xHCI natively.  That means that during system resume, it
-	 * may switch the ports back to EHCI so that users can use their
-	 * keyboard to select a kernel from GRUB after resume from hibernate.
-	 *
-	 * The BIOS is supposed to remember whether the OS had xHCI ports
-	 * enabled before resume, and switch the ports back to xHCI when the
-	 * BIOS/OS semaphore is written, but we all know we can't trust BIOS
-	 * writers.
-	 *
-	 * Unconditionally switch the ports back to xHCI after a system resume.
-	 * We can't tell whether the EHCI or xHCI controller will be resumed
-	 * first, so we have to do the port switchover in both drivers.  Writing
-	 * a '1' to the port switchover registers should have no effect if the
-	 * port was already switched over.
-	 */
-	if (usb_is_intel_switchable_xhci(pdev))
-		usb_enable_xhci_ports(pdev);
-
-	retval = xhci_resume(xhci, hibernated);
-	return retval;
-}
-#endif /* CONFIG_PM */
-
-static const struct hc_driver xhci_pci_hc_driver = {
-	.description =		"xhci-pci",
-	.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_pci_setup,
-	.start =		xhci_run,
-#ifdef CONFIG_PM
-	.pci_suspend =          xhci_pci_suspend,
-	.pci_resume =           xhci_pci_resume,
-#endif
-	.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 DEFINE_XHCI_DATA(fresco_logic) = {
 	.quirks		= XHCI_BROKEN_MSI,
-	.driver		= &xhci_pci_hc_driver,
 };
 
 static DEFINE_XHCI_DATA(nec) = {
 	.quirks		= XHCI_NEC_HOST,
-	.driver		= &xhci_pci_hc_driver,
 };
 
 static DEFINE_XHCI_DATA(amd) = {
 	.quirks		= XHCI_AMD_PLL_FIX,
-	.driver		= &xhci_pci_hc_driver,
 };
 
 static DEFINE_XHCI_DATA(intel_pantherpoint) = {
 	.quirks		= (XHCI_SPURIOUS_SUCCESS
 			| XHCI_EP_LIMIT_QUIRK),
 	.limit_active_eps = 64,
-	.driver		= &xhci_pci_hc_driver,
 };
 
 static DEFINE_XHCI_DATA(etron) = {
 	.quirks		= XHCI_RESET_ON_RESUME,
-	.driver		= &xhci_pci_hc_driver,
 };
 
 /* PCI driver selection metadata; PCI hotplugging uses this */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 55a963c..c03b738 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3117,6 +3117,152 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_LICENSE("GPL");
 
+static int xhci_setup(struct usb_hcd *hcd)
+{
+	struct xhci_hcd		*xhci;
+	struct device		*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;
+
+	hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 2;
+
+	if (usb_hcd_is_primary_hcd(hcd)) {
+		xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL);
+		if (!xhci)
+			return -ENOMEM;
+		*((struct xhci_hcd **) hcd->hcd_priv) = xhci;
+		xhci->main_hcd = hcd;
+		/* Mark the first roothub as being USB 2.0.
+		 * The xHCI driver will register the USB 3.0 roothub.
+		 */
+		hcd->speed = HCD_USB2;
+		hcd->self.root_hub->speed = USB_SPEED_HIGH;
+		/*
+		 * USB 2.0 roothub under xHCI has an integrated TT,
+		 * (rate matching hub) as opposed to having an OHCI/UHCI
+		 * companion controller.
+		 */
+		hcd->has_tt = 1;
+	} else {
+		/* xHCI private pointer was set in xhci_pci_probe for the second
+		 * registered roothub.
+		 */
+		xhci = hcd_to_xhci(hcd);
+		temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
+		if (HCC_64BIT_ADDR(temp)) {
+			xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
+			dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
+		} else {
+			dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
+		}
+		return 0;
+	}
+
+	xhci->cap_regs = hcd->regs;
+	xhci->op_regs = hcd->regs +
+		HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase));
+	xhci->run_regs = hcd->regs +
+		(xhci_readl(xhci, &xhci->cap_regs->run_regs_off) & RTSOFF_MASK);
+	/* Cache read-only capability registers */
+	xhci->hcs_params1 = xhci_readl(xhci, &xhci->cap_regs->hcs_params1);
+	xhci->hcs_params2 = xhci_readl(xhci, &xhci->cap_regs->hcs_params2);
+	xhci->hcs_params3 = xhci_readl(xhci, &xhci->cap_regs->hcs_params3);
+	xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hc_capbase);
+	xhci->hci_version = HC_VERSION(xhci->hcc_params);
+	xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
+	xhci_print_registers(xhci);
+
+	xhci->quirks = data->quirks;
+	xhci->limit_active_eps = data->limit_active_eps;
+
+	/* Make sure the HC is halted. */
+	retval = xhci_halt(xhci);
+	if (retval)
+		goto error;
+
+	xhci_dbg(xhci, "Resetting HCD\n");
+	/* Reset the internal HC memory state and registers. */
+	retval = xhci_reset(xhci);
+	if (retval)
+		goto error;
+	xhci_dbg(xhci, "Reset complete\n");
+
+	temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
+	if (HCC_64BIT_ADDR(temp)) {
+		xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
+		dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
+	} else {
+		dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
+	}
+
+	xhci_dbg(xhci, "Calling HCD init\n");
+	/* Initialize HCD and host controller data structures. */
+	retval = xhci_init(hcd);
+	if (retval)
+		goto error;
+	xhci_dbg(xhci, "Called HCD init\n");
+
+	/* Find any debug ports */
+	retval = xhci_reinit(xhci, dev);
+
+	xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn);
+
+	if (!retval)
+		return retval;
+
+error:
+	kfree(xhci);
+	return retval;
+}
+
+static const struct hc_driver xhci_hc_driver = {
+	.description		= "xhci-hcd",
+	.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_setup,
+	.start			= xhci_run,
+	.stop			= xhci_stop,
+	.shutdown		= xhci_shutdown,
+
+	 /* i/o requests and associated 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 xhci_probe(struct platform_device *pdev)
 {
 	struct xhci_platform_data *data;
@@ -3139,7 +3285,8 @@ static int xhci_probe(struct platform_device *pdev)
 		goto err0;
 	}
 
-	hcd = usb_create_hcd(data->driver, &pdev->dev, dev_name(&pdev->dev));
+	hcd = usb_create_hcd(&xhci_hc_driver, &pdev->dev,
+			dev_name(&pdev->dev));
 	if (!hcd) {
 		ret = -ENOMEM;
 		goto err0;
@@ -3156,7 +3303,7 @@ static int xhci_probe(struct platform_device *pdev)
 	hcd->rsrc_len = resource_size(res);
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
-				data->driver->description)) {
+				xhci_hc_driver.description)) {
 		dev_err(&pdev->dev, "controller already in use\n");
 		ret = -EBUSY;
 		goto err1;
@@ -3176,7 +3323,7 @@ static int xhci_probe(struct platform_device *pdev)
 	}
 
 	xhci = hcd_to_xhci(hcd);
-	xhci->shared_hcd = usb_create_shared_hcd(data->driver, &pdev->dev,
+	xhci->shared_hcd = usb_create_shared_hcd(&xhci_hc_driver, &pdev->dev,
 			dev_name(&pdev->dev), hcd);
 	if (!xhci->shared_hcd) {
 		dev_err(&pdev->dev, "failed to create shared HCD\n");
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 3f82ad2..c8a3f12 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1415,6 +1415,8 @@ static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci)
 			(xhci->quirks & XHCI_LINK_TRB_QUIRK));
 }
 
+extern int xhci_reinit(struct xhci_hcd *xhci, struct device *dev);
+
 /* xHCI debugging */
 void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num);
 void xhci_print_registers(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