static int ehci_hsic_probe(struct pci_dev *pdev,
				const struct pci_device_id *id)
{
	struct hc_driver *driver;
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	int irq, retval;

	pr_debug("initializing Intel EHCI HSIC Host Controller\n");

	if (usb_disabled())
		return -ENODEV;

	if (!id)
		return -EINVAL;

	pci_dev = pdev;
	if (pci_enable_device(pdev) < 0)
		return -ENODEV;
	pdev->current_state = PCI_D0;

	wake_lock_init(&hsic.resume_wake_lock,
		WAKE_LOCK_SUSPEND, "hsic_aux2_wlock");
	wake_lock_init(&hsic.s3_wake_lock,
			WAKE_LOCK_SUSPEND, "hsic_s3_wlock");
	hsic.hsic_pm_nb.notifier_call = hsic_pm_notify;
	usb_register_notify(&hsic.hsic_pm_nb);
	hsic.hsic_s3_entry_nb.notifier_call = hsic_s3_entry_notify;
	register_pm_notifier(&hsic.hsic_s3_entry_nb);

	/* we need not call pci_enable_dev since otg transceiver already take
	 * the control of this device and this probe actaully gets called by
	 * otg transceiver driver with HNP protocol.
	 */
	irq = pdev->irq;
	if (!pdev->irq) {
		dev_dbg(&pdev->dev, "No IRQ.\n");
		retval = -ENODEV;
		goto disable_pci;
	}

	driver = (struct hc_driver *)id->driver_data;
	if (!driver)
		return -EINVAL;

	/* AUX GPIO init */
	retval = hsic_aux_gpio_init();
	if (retval < 0) {
		dev_err(&pdev->dev, "AUX GPIO init fail\n");
		retval = -ENODEV;
		goto disable_pci;
	}

	/* AUX GPIO init */
	retval = hsic_wakeup_gpio_init();
	if (retval < 0) {
		dev_err(&pdev->dev, "Wakeup GPIO init fail\n");
		retval = -ENODEV;
		goto disable_pci;
	}

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto disable_pci;
	}

	ehci = hcd_to_ehci(hcd);

	hcd->rsrc_start = pci_resource_start(pdev, 0);
	hcd->rsrc_len = pci_resource_len(pdev, 0);
	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
			driver->description)) {
		dev_dbg(&pdev->dev, "controller already in use\n");
		retval = -EBUSY;
		goto clear_companion;
	}

	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
	if (hcd->regs == NULL) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		retval = -EFAULT;
		goto release_mem_region;
	}

	pci_set_master(pdev);

	if (hsic.hsic_enable_created == 0) {
		retval = create_device_files();
		if (retval < 0) {
			dev_dbg(&pdev->dev, "error create device files\n");
			goto release_mem_region;
		}
		hsic.hsic_enable_created = 1;
	}

	if (hsic.hsic_mutex_init == 0) {
		mutex_init(&hsic.hsic_mutex);
		mutex_init(&hsic.wlock_mutex);
		hsic.hsic_mutex_init = 1;
	}

	if (hsic.aux_wq_init == 0) {
		init_waitqueue_head(&hsic.aux_wq);
		hsic.aux_wq_init = 1;
	}

	hsic.work_queue = create_singlethread_workqueue("hsic");
	INIT_DELAYED_WORK(&hsic.wakeup_work, wakeup_work);
	INIT_DELAYED_WORK(&(hsic.hsic_aux), hsic_aux_work);

	hcd->hsic_notify = hsic_notify;

	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED | IRQF_NO_SUSPEND);
	if (retval != 0)
		goto unmap_registers;
	dev_set_drvdata(&pdev->dev, hcd);
	/* Clear phy low power mode, enable phy clock */
	ehci_hsic_phy_power(ehci, 0);

	if (pci_dev_run_wake(pdev))
		pm_runtime_put_noidle(&pdev->dev);

	if (!enabling_disabling) {
		/* Check here to avoid to call pm_runtime_put_noidle() twice */
		if (!pci_dev_run_wake(pdev))
			pm_runtime_put_noidle(&pdev->dev);

		pm_runtime_allow(&pdev->dev);
	}
	hsic.hsic_stopped = 0;
	hsic_enable = 1;
	hsic.s3_rt_state = RESUMED;
	s3_wake_lock();
	hsic_debugfs_init(hcd);

	return retval;
unmap_registers:
	destroy_workqueue(hsic.work_queue);
	if (driver->flags & HCD_MEMORY) {
		iounmap(hcd->regs);
release_mem_region:
		release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	} else
		release_region(hcd->rsrc_start, hcd->rsrc_len);
clear_companion:
	dev_set_drvdata(&pdev->dev, NULL);
	usb_put_hcd(hcd);
disable_pci:
	pci_disable_device(pdev);
	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
	wake_lock_destroy(&(hsic.resume_wake_lock));
	wake_lock_destroy(&hsic.s3_wake_lock);
	return retval;
}
/*
 * We need to register our own PCI probe function (instead of the USB core's
 * function) in order to create a second roothub under xHCI.
 */
static int xhci_ush_pci_probe(struct pci_dev *dev,
		const struct pci_device_id *id)
{
	int retval;
	struct xhci_hcd *xhci;
	struct hc_driver *driver;
	struct usb_hcd *hcd;

	driver = (struct hc_driver *)id->driver_data;
	pci_dev = dev;

	/* AUX GPIO init */
	retval = hsic_aux_gpio_init();
	if (retval < 0) {
		dev_err(&dev->dev, "AUX GPIO init fail\n");
		retval = -ENODEV;
	}

	/* AUX GPIO init */
	retval = hsic_wakeup_gpio_init();
	if (retval < 0) {
		dev_err(&dev->dev, "Wakeup GPIO init fail\n");
		retval = -ENODEV;
	}

	/* 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);
	if (retval)
		return retval;

	/* USB 2.0 roothub is stored in the PCI device now. */
	hcd = dev_get_drvdata(&dev->dev);
	xhci = hcd_to_xhci(hcd);
	xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev,
				pci_name(dev), hcd);
	if (!xhci->shared_hcd) {
		retval = -ENOMEM;
		goto dealloc_usb2_hcd;
	}

	/* 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;

	if (hsic.hsic_enable_created == 0) {
		retval = create_device_files();
		if (retval < 0) {
			dev_dbg(&dev->dev, "error create device files\n");
			goto dealloc_usb2_hcd;
		}

		hsic.hsic_enable_created = 1;
	}

	if (hsic.hsic_mutex_init == 0) {
		mutex_init(&hsic.hsic_mutex);
		hsic.hsic_mutex_init = 1;
	}

	if (hsic.aux_wq_init == 0) {
		init_waitqueue_head(&hsic.aux_wq);
		hsic.aux_wq_init = 1;
	}

	hsic.work_queue = create_singlethread_workqueue("hsic");
	INIT_WORK(&hsic.wakeup_work, wakeup_work);
	INIT_DELAYED_WORK(&(hsic.hsic_aux), hsic_aux_work);

	retval = usb_add_hcd(xhci->shared_hcd, dev->irq,
			IRQF_SHARED);
	if (retval)
		goto put_usb3_hcd;
	/* Roothub already marked as USB 3.0 speed */

	/* Enable Controller wakeup capability */
	device_set_wakeup_enable(&dev->dev, true);

	/* Enable runtime pm ability */
	hcd->rpm_control = 1;
	hcd->rpm_resume = 0;
	pm_runtime_set_active(&dev->dev);

	/* Check here to avoid to call pm_runtime_put_noidle() twice */
	if (!pci_dev_run_wake(dev))
		pm_runtime_put_noidle(&dev->dev);

	pm_runtime_allow(&dev->dev);
	hsic.hsic_stopped = 0;
	hsic_enable = 1;
	return 0;

put_usb3_hcd:
	usb_put_hcd(xhci->shared_hcd);
dealloc_usb2_hcd:
	usb_hcd_pci_remove(dev);
	return retval;
}