static void xhci_ush_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);
	}

	if (!pci_dev_run_wake(dev))
		pm_runtime_get_noresume(&dev->dev);

	pm_runtime_forbid(&dev->dev);

	usb_hcd_pci_remove(dev);

	/* Free the aux irq */
	hsic_aux_irq_free();
	hsic_wakeup_irq_free();
	gpio_free(hsic.aux_gpio);
	gpio_free(hsic.wakeup_gpio);

	hsic.port_disconnect = 1;
	hsic_enable = 0;
	wake_lock_destroy(&(hsic.resume_wake_lock));
	wake_lock_destroy(&hsic.s3_wake_lock);
	usb_unregister_notify(&hsic.hsic_pm_nb);
	unregister_pm_notifier(&hsic.hsic_s3_entry_nb);

	kfree(xhci);
}
static void xhci_ush_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);
	}

	if (!pci_dev_run_wake(dev))
		pm_runtime_get_noresume(&dev->dev);

	pm_runtime_forbid(&dev->dev);

	usb_hcd_pci_remove(dev);

	/* Free the aux irq */
	hsic_aux_irq_free();
	hsic_wakeup_irq_free();
	gpio_free(hsic.aux_gpio);
	gpio_free(hsic.wakeup_gpio);

	hsic.hsic_stopped = 1;
	hsic_enable = 0;

	kfree(xhci);
}
Ejemplo n.º 3
0
/*
 * 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_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;

	/* Prevent runtime suspending between USB-2 and USB-3 initialization */
	pm_runtime_get_noresume(&dev->dev);

	/* 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)
		goto put_runtime_pm;

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

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

	if (!(xhci->quirks & XHCI_BROKEN_STREAMS) &&
			HCC_MAX_PSA(xhci->hcc_params) >= 4)
		xhci->shared_hcd->can_do_streams = 1;

	if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
		xhci_pme_acpi_rtd3_enable(dev);

	/* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */
	pm_runtime_put_noidle(&dev->dev);

	return 0;

put_usb3_hcd:
	usb_put_hcd(xhci->shared_hcd);
dealloc_usb2_hcd:
	usb_hcd_pci_remove(dev);
put_runtime_pm:
	pm_runtime_put_noidle(&dev->dev);
	return retval;
}
Ejemplo n.º 4
0
/*
 * 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_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;

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

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

    /* We know the LPM timeout algorithms for this host, let the USB core
     * enable and disable LPM for devices under the USB 3.0 roothub.
     */
    if (xhci->quirks & XHCI_LPM_SUPPORT)
        hcd_to_bus(xhci->shared_hcd)->root_hub->lpm_capable = 1;

    return 0;

put_usb3_hcd:
    usb_put_hcd(xhci->shared_hcd);
dealloc_usb2_hcd:
    usb_hcd_pci_remove(dev);
    return retval;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
/*
 * 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_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;
	/* 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;
	}
	if (pdev->vendor == PCI_VENDOR_ID_VIA)
		xhci->quirks |= XHCI_RESET_ON_RESUME;

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

	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;
}
Ejemplo n.º 7
0
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);

    /* Workaround for spurious wakeups at shutdown with HSW */
    if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
        pci_set_power_state(dev, PCI_D3hot);
}
Ejemplo n.º 8
0
/*------------------------------------------------------------------------*/ 
void BootStopUSB(void)
{
	int n;
        
    XPADRemove();
	XRemoteRemove();
	UsbKeyBoardRemove();
	UsbMouseRemove();
	
	for(n=0;n<100;n++)
	{
		USBGetEvents();
		wait_ms(1);
	}	

	module_exit_usb_exit();
	usb_hcd_pci_remove(&xx_ohci_dev);
	
}	
/*
 * 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;
}
Ejemplo n.º 10
0
/**
 * usb_hcd_pci_probe - initialize PCI-based HCDs
 * @dev: USB Host Controller being probed
 * @id: pci hotplug id connecting controller to HCD framework
 * Context: !in_interrupt()
 *
 * Allocates basic PCI resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
    struct hc_driver	*driver;
    unsigned long		resource, len;
    void __iomem		*base;
    struct usb_hcd		*hcd;
    int			retval, region;
    char			buf [8], *bufp = buf;

    if (usb_disabled())
        return -ENODEV;

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

    if (pci_enable_device (dev) < 0)
        return -ENODEV;
    dev->current_state = 0;
    dev->dev.power.power_state = 0;

    if (!dev->irq) {
        dev_err (&dev->dev,
                 "Found HC with no IRQ.  Check BIOS/PCI %s setup!\n",
                 pci_name(dev));
        retval = -ENODEV;
        goto done;
    }

    if (driver->flags & HCD_MEMORY) {	// EHCI, OHCI
        region = 0;
        resource = pci_resource_start (dev, 0);
        len = pci_resource_len (dev, 0);
        if (!request_mem_region (resource, len, driver->description)) {
            dev_dbg (&dev->dev, "controller already in use\n");
            retval = -EBUSY;
            goto done;
        }
        base = ioremap_nocache (resource, len);
        if (base == NULL) {
            dev_dbg (&dev->dev, "error mapping memory\n");
            retval = -EFAULT;
clean_1:
            release_mem_region (resource, len);
            dev_err (&dev->dev, "init %s fail, %d\n",
                     pci_name(dev), retval);
            goto done;
        }

    } else { 				// UHCI
        resource = len = 0;
        for (region = 0; region < PCI_ROM_RESOURCE; region++) {
            if (!(pci_resource_flags (dev, region) & IORESOURCE_IO))
                continue;

            resource = pci_resource_start (dev, region);
            len = pci_resource_len (dev, region);
            if (request_region (resource, len,
                                driver->description))
                break;
        }
        if (region == PCI_ROM_RESOURCE) {
            dev_dbg (&dev->dev, "no i/o regions available\n");
            retval = -EBUSY;
            goto done;
        }
        base = (void __iomem *) resource;
    }

    // driver->reset(), later on, will transfer device from
    // control by SMM/BIOS to control by Linux (if needed)

    hcd = driver->hcd_alloc ();
    if (hcd == NULL) {
        dev_dbg (&dev->dev, "hcd alloc fail\n");
        retval = -ENOMEM;
clean_2:
        if (driver->flags & HCD_MEMORY) {
            iounmap (base);
            goto clean_1;
        } else {
            release_region (resource, len);
            dev_err (&dev->dev, "init %s fail, %d\n",
                     pci_name(dev), retval);
            goto done;
        }
    }
    // hcd zeroed everything
    hcd->regs = base;
    hcd->region = region;

    pci_set_drvdata (dev, hcd);
    hcd->driver = driver;
    hcd->description = driver->description;
    hcd->self.bus_name = pci_name(dev);
#ifdef CONFIG_PCI_NAMES
    hcd->product_desc = dev->pretty_name;
#else
    if (hcd->product_desc == NULL)
        hcd->product_desc = "USB Host Controller";
#endif
    hcd->self.controller = &dev->dev;

    if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
        kfree (hcd);
        goto clean_2;
    }

    dev_info (hcd->self.controller, "%s\n", hcd->product_desc);

    /* till now HC has been in an indeterminate state ... */
    if (driver->reset && (retval = driver->reset (hcd)) < 0) {
        dev_err (hcd->self.controller, "can't reset\n");
        goto clean_3;
    }
    hcd->state = USB_STATE_HALT;

    pci_set_master (dev);
#ifndef __sparc__
    sprintf (buf, "%d", dev->irq);
#else
    bufp = __irq_itoa(dev->irq);
#endif
    retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ,
                          hcd->description, hcd);
    if (retval != 0) {
        dev_err (hcd->self.controller,
                 "request interrupt %s failed\n", bufp);
        goto clean_3;
    }
    hcd->irq = dev->irq;

    dev_info (hcd->self.controller, "irq %s, %s 0x%lx\n", bufp,
              (driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
              resource);

    usb_bus_init (&hcd->self);
    hcd->self.op = &usb_hcd_operations;
    hcd->self.release = &usb_hcd_release;
    hcd->self.hcpriv = (void *) hcd;
    init_timer (&hcd->rh_timer);

    INIT_LIST_HEAD (&hcd->dev_list);

    usb_register_bus (&hcd->self);

    if ((retval = driver->start (hcd)) < 0) {
        dev_err (hcd->self.controller, "init error %d\n", retval);
        usb_hcd_pci_remove (dev);
    }

done:
    if (retval != 0)
        pci_disable_device (dev);
    return retval;
}
Ejemplo n.º 11
0
Archivo: hcd-pci.c Proyecto: kidoz/cxbx
/**
 * usb_hcd_pci_probe - initialize PCI-based HCDs
 * @dev: USB Host Controller being probed
 * @id: pci hotplug id connecting controller to HCD framework
 * Context: !in_interrupt()
 *
 * Allocates basic PCI resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
	struct hc_driver	*driver;
	unsigned long		resource, len;
	void			*base;
	struct usb_hcd		*hcd;
	int			retval, region;
	char			buf [8], *bufp = buf;

	if (usb_disabled())
		return -ENODEV;

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

	if (pci_enable_device (dev) < 0)
		return -ENODEV;

        if (!dev->irq) {
        	err ("Found HC with no IRQ.  Check BIOS/PCI %s setup!",
			dev->slot_name);
   	        return -ENODEV;
        }

	if (driver->flags & HCD_MEMORY) {	// EHCI, OHCI
		region = 0;
		resource = pci_resource_start (dev, 0);
		len = pci_resource_len (dev, 0);
		if (!request_mem_region (resource, len, driver->description)) {
			dbg ("controller already in use");
			return -EBUSY;
		}
		base = ioremap_nocache (resource, len);
		if (base == NULL) {
			dbg ("error mapping memory");
			retval = -EFAULT;
clean_1:
			release_mem_region (resource, len);
			err ("init %s fail, %d", dev->slot_name, retval);
			return retval;
		}

	} else { 				// UHCI
		resource = len = 0;
		for (region = 0; region < PCI_ROM_RESOURCE; region++) {
			if (!(pci_resource_flags (dev, region) & IORESOURCE_IO))
				continue;

			resource = pci_resource_start (dev, region);
			len = pci_resource_len (dev, region);
			if (request_region (resource, len,
					driver->description))
				break;
		}
		if (region == PCI_ROM_RESOURCE) {
			dbg ("no i/o regions available");
			return -EBUSY;
		}
		base = (void *) resource;
	}

	// driver->start(), later on, will transfer device from
	// control by SMM/BIOS to control by Linux (if needed)

	pci_set_master (dev);

	hcd = driver->hcd_alloc ();
	if (hcd == NULL){
		dbg ("hcd alloc fail");
		retval = -ENOMEM;
clean_2:
		if (driver->flags & HCD_MEMORY) {
			iounmap (base);
			goto clean_1;
		} else {
			release_region (resource, len);
			err ("init %s fail, %d", dev->slot_name, retval);
			return retval;
		}
	}
	pci_set_drvdata (dev, hcd);
	hcd->driver = driver;
	hcd->description = driver->description;
	hcd->pdev = dev;
	hcd->self.bus_name = dev->slot_name;
	hcd->product_desc = dev->dev.name;
	hcd->self.controller = &dev->dev;
	hcd->controller = hcd->self.controller;

	if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
		driver->hcd_free (hcd);
		goto clean_2;
	}

	dev_info (hcd->controller, "%s\n", hcd->product_desc);

#ifndef __sparc__
	sprintf (buf, "%d", dev->irq);
#else
	bufp = __irq_itoa(dev->irq);
#endif
	if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd)
			!= 0) {
		dev_err (hcd->controller,
				"request interrupt %s failed\n", bufp);
		retval = -EBUSY;
		goto clean_3;
	}
	hcd->irq = dev->irq;

	hcd->regs = base;
	hcd->region = region;
	dev_info (hcd->controller, "irq %s, %s %p\n", bufp,
		(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
		base);

	usb_bus_init (&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.hcpriv = (void *) hcd;

	INIT_LIST_HEAD (&hcd->dev_list);

	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0)
		usb_hcd_pci_remove (dev);

	return retval;
}