[RFC][PATCH] USB: hcd-pci: apply driver probe deferral mechanism to uhci/ohci companion

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

 



From: Ming Lei <ming.lei@xxxxxxxxxxxxx>

This patch tries to apply the new driver probe deferral mechanism to
uhci/ohci companion driver so that ehci driver can be probed before
uhci/ohci companion driver.

Cc: Grant Likely <grant.likely@xxxxxxxxxxxx>
Cc: Manjunath GKondaiah <manjunath.gkondaiah@xxxxxxxxxx>
Cc: Mark Brown <broonie@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
Cc: Arnd Bergmann <arnd@xxxxxxxx>
Cc: Dilan Lee <dilee@xxxxxxxxxx>
Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxxxxx>
---
 drivers/usb/core/hcd-pci.c |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index ce22f4a..f64575e 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -53,6 +53,26 @@ enum companion_action {
 	SET_HS_COMPANION, CLEAR_HS_COMPANION, WAIT_FOR_COMPANIONS
 };
 
+static int has_ehci_companion(struct pci_dev *pdev,
+		struct pci_dev		**ehci_comp)
+{
+	struct pci_dev		*companion = NULL;
+	unsigned int		slot = PCI_SLOT(pdev->devfn);
+
+	for_each_pci_dev(companion) {
+		if (companion->bus != pdev->bus ||
+				PCI_SLOT(companion->devfn) != slot)
+			continue;
+
+		if ((pdev->class == CL_OHCI || pdev->class == CL_UHCI) &&
+				companion->class == CL_EHCI) {
+			*ehci_comp = companion;
+			return 1;
+		}
+	}
+	return 0;
+}
+
 static void companion_common(struct pci_dev *pdev, struct usb_hcd *hcd,
 		enum companion_action action)
 {
@@ -172,6 +192,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	struct hc_driver	*driver;
 	struct usb_hcd		*hcd;
+	struct pci_dev 		*ehci_comp;
 	int			retval;
 
 	if (usb_disabled())
@@ -183,6 +204,11 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	if (!driver)
 		return -EINVAL;
 
+	if (has_ehci_companion(dev, &ehci_comp)) {
+		if (!dev_get_drvdata(&ehci_comp->dev))
+			return -EPROBE_DEFER;
+	}
+
 	if (pci_enable_device(dev) < 0)
 		return -ENODEV;
 	dev->current_state = PCI_D0;
-- 
1.7.5.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