Пример #1
0
/*****************************************************************
 *
 * Function Name: hc_found_hci
 *
 * This function request IO memory regions, request IRQ, and
 * allocate all other resources. 
 *
 * Input: addr = first IO address
 *        addr2 = second IO address
 *        irq = interrupt number 
 *
 * Return: 0 = success or error condition 
 *                
 *****************************************************************/
static int __devinit hc_found_hci (int addr, int addr2, int irq)
{
	hci_t *hci;
	hcipriv_t *hp;

	DBGFUNC ("Enter hc_found_hci\n");
	hci = hc_alloc_hci ();
	if (!hci) {
		return -ENOMEM;
	}

	init_irq ();
	hp = &hci->hp;

	if (!request_region (addr, 256, "SL811 USB HOST")) {
		DBGERR ("request address %d failed", addr);
		hc_release_hci (hci);
		return -EBUSY;
	}
	hp->hcport = addr;
	if (!hp->hcport) {
		DBGERR ("Error mapping SL811 Memory 0x%x", hp->hcport);
	}

	if (!request_region (addr2, 256, "SL811 USB HOST")) {
		DBGERR ("request address %d failed", addr2);
		hc_release_hci (hci);
		return -EBUSY;
	}
	hp->hcport2 = addr2;
	if (!hp->hcport2) {
		DBGERR ("Error mapping SL811 Memory 0x%x", hp->hcport2);
	}

	if (hc_alloc_trans_buffer (hci)) {
		hc_release_hci (hci);
		return -ENOMEM;
	}

	usb_register_bus (hci->bus);

	if (request_irq (irq, hc_interrupt, 0, "SL811", hci) != 0) {
		DBGERR ("request interrupt %d failed", irq);
		hc_release_hci (hci);
		return -EBUSY;
	}
	hp->irq = irq;

	printk (KERN_INFO __FILE__ ": USB SL811 at %x, addr2 = %x, IRQ %d\n",
		addr, addr2, irq);
	hc_reset (hci);

	if (hc_start (hci) < 0) {
		DBGERR ("can't start usb-%x", addr);
		hc_release_hci (hci);
		return -EBUSY;
	}

	return 0;
}
Пример #2
0
int usb_hcd_superh_probe(const struct hc_driver *driver,
			 struct usb_hcd **hcd_out, struct platform_device *dev)
{
	int retval;
	struct usb_hcd *hcd = 0;

	if (!request_mem_region
	    (SH_OHCI_REGS_BASE, sizeof(struct ohci_regs), hcd_name)) {
		dbg("controller already in use");
		return -EBUSY;
	}

	superh_start_hc(dev);

	hcd = usb_create_hcd(driver);
	if (hcd == NULL) {
		dbg("hcd_alloc failed");
		retval = -ENOMEM;
		goto err1;
	}
	ohci_hcd_init(hcd_to_ohci(hcd));

	hcd->driver = (struct hc_driver *)driver;
	hcd->irq = SH_OHCI_IRQ;
	hcd->regs = (void *)SH_OHCI_REGS_BASE;
	dev->dev.dma_mask = &superh_dmamask;
	hcd->self.controller = &dev->dev;

	retval = hcd_buffer_create(hcd);
	if (retval != 0) {
		dbg("pool alloc fail");
		goto err1;
	}

	retval = request_irq(hcd->irq, usb_hcd_superh_hcim_irq, SA_INTERRUPT,
			     hcd->driver->description, hcd);
	if (retval != 0) {
		dbg("request_irq failed");
		retval = -EBUSY;
		goto err2;
	}

	info("%s (SuperH USB) at 0x%p, irq %d\n",
	     hcd->driver->description, hcd->regs, hcd->irq);

	hcd->self.bus_name = "superh";

	usb_register_bus(&hcd->self);

	if ((retval = driver->start(hcd)) < 0) {
		usb_hcd_superh_remove(hcd, dev);
		return retval;
	}
	*hcd_out = hcd;
	return 0;

      err2:
	hcd_buffer_destroy(hcd);
      err1:
	kfree(hcd);
	superh_stop_hc(dev);
	release_mem_region((unsigned long)hcd->regs, sizeof(struct ohci_regs));
	return retval;
}
Пример #3
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;
}
Пример #4
0
int usb_hcd_amba_probe (struct amba_device *dev, void *vid)
{
	int			retval = 0;
	char			buf [8], *bufp = buf;
	struct usb_bus		*bus = NULL;
	struct usb_hcd 		*hcd = NULL;
	void 			*device_base = NULL;
	struct amba_id *id 	= (struct amba_id *)vid;
	struct hc_driver	*driver = (struct hc_driver *)id->data;

#if defined (CONFIG_USB_EHCI_PNX0106) && defined (GPIO_USB_POWER_FAULT)
	init_timer (&timer_check_usb_power_fault);
	timer_check_usb_power_fault.function = check_usb_power_fault_func;
	timer_check_usb_power_fault.data = 0;
#endif
	proc_vbus_init();

	usb2ip_init (dev);

	if (driver->flags & HCD_MEMORY) {	// EHCI, OHCI
		/* map the address (already requested by amba_device) */
		device_base = ioremap_nocache( dev->res.start, dev->res.end - dev->res.start + 1 ) ;
		if ( !device_base ) {
			printk( KERN_ERR "%s: failed to remap the amba registers\n", __FUNCTION__) ;
			return -1 ;
		}
	} else {
		printk (KERN_ERR "%s: tried to allocate i/o memory for UHCI\n", __FUNCTION__);
	}


	hcd = driver->hcd_alloc ();
	if (hcd == NULL) {
		printk(KERN_DEBUG "%s: hcd alloc fail\n", __FUNCTION__);
		retval = -ENOMEM;
clean_1:
		if (driver->flags & HCD_MEMORY) {
			iounmap (device_base);
			device_base = 0;
		}
		printk(KERN_DEBUG "hcd-amba::init usb_amba fail, %d\n", retval);
		goto done;
	}
	// hcd zeroed everything
	hcd->regs = device_base;

	//amba_set_drvdata (dev, hcd);
	hcd->pdev = dev;
	hcd->driver = driver;
	hcd->description = driver->description;

	if (hcd->product_desc == NULL)
		hcd->product_desc = "USB EHCI 1.0 Host Controller (amba)";

	hcd->state = USB_STATE_HALT;

#ifndef __sparc__
	sprintf (buf, "%d", dev->irq[0]);
#else
	bufp = __irq_itoa(dev->irq[0]);
#endif

	/* request the irq (there should be one) */
	retval = request_irq (dev->irq[0], hcd_irq, 0/*SA_SHIRQ*/, "usb_ehci", hcd);
	if (retval) {
		printk(KERN_ERR	"hcd-amba.c :: request interrupt %s failed\n", bufp);
		retval = -EBUSY;
		goto clean_1;
	}
	hcd->irq = dev->irq[0];

	bus = usb_alloc_bus (&hcd_operations);
	if (bus == NULL) {
		printk(KERN_ERR "usb_alloc_bus fail\n");
		retval = -ENOMEM;
		free_irq (dev->irq, hcd);
		goto clean_1;
	}

	hcd->bus = bus;
	strcpy(dev->slot_name, "1");
	bus->bus_name = dev->slot_name;
	bus->hcpriv = (void *) hcd;

	INIT_LIST_HEAD (&hcd->dev_list);
	INIT_LIST_HEAD (&hcd->hcd_list);

	down (&hcd_list_lock);
	list_add (&hcd->hcd_list, &hcd_list);
	up (&hcd_list_lock);

	usb_register_bus (bus);

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

done:
	return retval;
}
Пример #5
0
/**
 * usb_hcd_pxa27x_probe - initialize pxa27x-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic 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.
 *
 */
int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
			  struct usb_hcd **hcd_out,
			  struct platform_device *dev)
{
	int retval;
	struct usb_hcd *hcd = 0;

	unsigned int *addr = NULL;

	if (!request_mem_region(dev->resource[0].start,
				dev->resource[0].end
				- dev->resource[0].start + 1, hcd_name)) {
		pr_debug("request_mem_region failed");
		return -EBUSY;
	}

	pxa27x_start_hc(dev);

	/* Select Power Management Mode */
	pxa27x_ohci_select_pmm( PMM_PERPORT_MODE );

	/* If choosing PMM_PERPORT_MODE, we should set the port power before we use it. */
	if (pxa27x_ohci_set_port_power(1) < 0)
		printk(KERN_ERR "Setting port 1 power failed.\n");

	if (pxa27x_ohci_clear_port_power(2) < 0)
		printk(KERN_ERR "Setting port 2 power failed.\n");

	if (pxa27x_ohci_clear_port_power(3) < 0)
		printk(KERN_ERR "Setting port 3 power failed.\n");

	addr = ioremap(dev->resource[0].start,
		       dev->resource[0].end - dev->resource[0].start + 1);
	if (!addr) {
		pr_debug("ioremap failed");
		retval = -ENOMEM;
		goto err1;
	}

	hcd = driver->hcd_alloc ();
	if (hcd == NULL){
		pr_debug ("hcd_alloc failed");
		retval = -ENOMEM;
		goto err1;
	}

	if(dev->resource[1].flags != IORESOURCE_IRQ){
		pr_debug ("resource[1] is not IORESOURCE_IRQ");
		retval = -ENOMEM;
		goto err1;
	}

	hcd->driver = (struct hc_driver *) driver;
	hcd->description = driver->description;
	hcd->irq = dev->resource[1].start;
	hcd->regs = addr;
	hcd->self.controller = &dev->dev;

	retval = hcd_buffer_create (hcd);
	if (retval != 0) {
		pr_debug ("pool alloc fail");
		goto err1;
	}

	retval = request_irq (hcd->irq, usb_hcd_irq, SA_INTERRUPT,
			      hcd->description, hcd);
	if (retval != 0) {
		pr_debug("request_irq(%d) failed with retval %d\n",hcd->irq,retval);
		retval = -EBUSY;
		goto err2;
	}

	pr_debug ("%s (pxa27x) at 0x%p, irq %d",
	     hcd->description, hcd->regs, hcd->irq);

	usb_bus_init (&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.hcpriv = (void *) hcd;
	hcd->self.bus_name = "pxa27x";
	hcd->product_desc = "PXA27x OHCI";

	INIT_LIST_HEAD (&hcd->dev_list);

	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0) {
		usb_hcd_pxa27x_remove(hcd, dev);
		return retval;
	}

	*hcd_out = hcd;
	return 0;

 err2:
	hcd_buffer_destroy (hcd);
	if (hcd)
		driver->hcd_free(hcd);
 err1:
	pxa27x_stop_hc(dev);
	release_mem_region(dev->resource[0].start,
				dev->resource[0].end
			   - dev->resource[0].start + 1);
	return retval;
}
Пример #6
0
static int __devinit
hc_found_ohci (struct pci_dev *dev, int irq,
	void *mem_base, const struct pci_device_id *id)
{
	ohci_t * ohci;
	char buf[8], *bufp = buf;
	int ret;

#ifndef __sparc__
	sprintf(buf, "%d", irq);
#else
	bufp = __irq_itoa(irq);
#endif
	printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n",
		(unsigned long)	mem_base, bufp);
	printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
    
	ohci = hc_alloc_ohci (dev, mem_base);
	if (!ohci) {
		return -ENOMEM;
	}
	if ((ret = ohci_mem_init (ohci)) < 0) {
		hc_release_ohci (ohci);
		return ret;
	}
	ohci->flags = id->driver_data;

	/* Check for NSC87560. We have to look at the bridge (fn1) to identify
	   the USB (fn2). This quirk might apply to more or even all NSC stuff
	   I don't know.. */
	   
	if(dev->vendor == PCI_VENDOR_ID_NS)
	{
		struct pci_dev *fn1  = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 1));
		if(fn1 && fn1->vendor == PCI_VENDOR_ID_NS && fn1->device == PCI_DEVICE_ID_NS_87560_LIO)
			ohci->flags |= OHCI_QUIRK_SUCKYIO;
		
	}
	
	if (ohci->flags & OHCI_QUIRK_SUCKYIO)
		printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
	if (ohci->flags & OHCI_QUIRK_AMD756)
		printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
	if (hc_reset (ohci) < 0) {
		hc_release_ohci (ohci);
		return -ENODEV;
	}

	/* FIXME this is a second HC reset; why?? */
	writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control);
	wait_ms (10);

	usb_register_bus (ohci->bus);
	
	if (request_irq (irq, hc_interrupt, SA_SHIRQ,
			ohci_pci_driver.name, ohci) != 0) {
		err ("request interrupt %s failed", bufp);
		hc_release_ohci (ohci);
		return -EBUSY;
	}
	ohci->irq = irq;     

	if (hc_start (ohci) < 0) {
		err ("can't start usb-%s", dev->slot_name);
		hc_release_ohci (ohci);
		return -EBUSY;
	}

#ifdef	DEBUG
	ohci_dump (ohci, 1);
#endif
	return 0;
}
Пример #7
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			*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;
} 
Пример #8
0
/**
 * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
static int usb_hcd_ppc_soc_probe(struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd;
	struct ehci_hcd	*ehci;
	struct resource *res;
	unsigned long res_len;
	int irq;

	pr_debug("Initializing PPC-SOC EHCI USB Controller\n");

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		pr_debug(__FILE__ ": no irq\n");
		return -ENODEV;
	}
	irq = res->start;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		pr_debug(__FILE__ ": no reg addr\n");
		return -ENODEV;
	}
	hcd = driver->hcd_alloc();
	if (!hcd)
		return -ENOMEM;

	ehci = hcd_to_ehci(hcd);
	ehci->big_endian = 1;

	res_len = res->end - res->start + 1;
	if (!request_mem_region(res->start, res_len, hcd_name)) {
		pr_debug(__FILE__ ": request_mem_region failed\n");
		retval = -EBUSY;
		goto err1;
	}

	hcd->regs = ioremap64(res->start, res_len);
	if (!hcd->regs) {
		pr_debug(__FILE__ ": ioremap failed\n");
		retval = -ENOMEM;
		goto err2;
	}

	dev_set_drvdata(&pdev->dev, hcd);
	hcd->driver = driver;
	hcd->description = driver->description;
	hcd->self.bus_name = pdev->dev.bus_id;
	hcd->product_desc = "PPC-SOC EHCI USB";
	hcd->self.controller = &pdev->dev;

	if ((retval = hcd_buffer_create(hcd)) != 0) {
		pr_debug(__FILE__ ": hcd_buffer_create failed\n");
		retval = -ENOMEM;
		goto err3;
	}

	hcd->state = USB_STATE_HALT;

	retval = request_irq(irq, usb_hcd_irq, SA_SHIRQ,
				hcd->description, hcd);
	if (retval != 0) {
		pr_debug(__FILE__ ": request_irq failed\n");
		retval = -ENODEV;
		goto err4;
	}

	hcd->irq = irq;
	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_ppc_soc_remove(pdev);
	}
	return retval;

err4:
	hcd_buffer_destroy(hcd);
err3:
	iounmap(hcd->regs);
err2:
	release_mem_region(res->start, res_len);
err1:
	kfree(hcd);
	return retval;
}
/**
 * usb_add_hcd - finish generic HCD structure initialization and register
 * @hcd: the usb_hcd structure to initialize
 * @irqnum: Interrupt line to allocate
 * @irqflags: Interrupt type flags
 *
 * Finish the remaining parts of generic HCD initialization: allocate the
 * buffers of consistent memory, register the bus, request the IRQ line,
 * and call the driver's reset() and start() routines.
 */
int mtk_usb_add_hcd(struct usb_hcd *hcd,
		unsigned int irqnum, unsigned long irqflags)
{
	int retval;
	struct usb_device *rhdev;
	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);

	hcd->authorized_default = hcd->wireless? 0 : 1;
	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

	/* HC is in reset state, but accessible.  Now do the one-time init,
	 * bottom up so that hcds can customize the root hubs before khubd
	 * starts talking to them.  (Note, bus id is assigned early too.)
	 */
	if ((retval = hcd_buffer_create(hcd)) != 0) {
		dev_dbg(hcd->self.controller, "pool alloc failed\n");
		return retval;
	}
	
	if ((rhdev = mtk_usb_alloc_rhdev(NULL, &hcd->self, 0)) == NULL) {
		dev_err(hcd->self.controller, "unable to allocate root hub\n");
		retval = -ENOMEM;
		goto err_allocate_root_hub;
	}
	hcd->self.root_hub = rhdev;
#if 0
	if ((retval = usb_register_bus(&hcd->self)) < 0)
		goto err_register_bus;

	if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
		dev_err(hcd->self.controller, "unable to allocate root hub\n");
		retval = -ENOMEM;
		goto err_allocate_root_hub;
	}

	switch (hcd->driver->flags & HCD_MASK) {
	case HCD_USB11:
		rhdev->speed = USB_SPEED_FULL;
		break;
	case HCD_USB2:
		rhdev->speed = USB_SPEED_HIGH;
		break;
	case HCD_USB3:
		rhdev->speed = USB_SPEED_SUPER;
		break;
	default:
		goto err_allocate_root_hub;
	}
	hcd->self.root_hub = rhdev;

	/* wakeup flag init defaults to "everything works" for root hubs,
	 * but drivers can override it in reset() if needed, along with
	 * recording the overall controller's system wakeup capability.
	 */
	device_init_wakeup(&rhdev->dev, 1);
#endif

	/* "reset" is misnamed; its role is now one-time init. the controller
	 * should already have been reset (and boot firmware kicked off etc).
	 */
	printk(KERN_DEBUG "call xhci_mtk_setup\n");
	if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
		dev_err(hcd->self.controller, "can't setup\n");
		goto err_hcd_driver_setup;
	}
#if 0
	/* NOTE: root hub and controller capabilities may not be the same */
	if (device_can_wakeup(hcd->self.controller)
			&& device_can_wakeup(&hcd->self.root_hub->dev))
		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
#endif
	/* enable irqs just before we start the controller */
	if (hcd->driver->irq) {

		/* IRQF_DISABLED doesn't work as advertised when used together
		 * with IRQF_SHARED. As usb_hcd_irq() will always disable
		 * interrupts we can remove it here.
		 */
		if (irqflags & IRQF_SHARED)
			irqflags &= ~IRQF_DISABLED;

		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
				hcd->driver->description, hcd->self.busnum);
		if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
				hcd->irq_descr, hcd)) != 0) {
			dev_err(hcd->self.controller,
					"request interrupt %d failed\n", irqnum);
			goto err_request_irq;
		}
		hcd->irq = irqnum;
		dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum,
				(hcd->driver->flags & HCD_MEMORY) ?
					"io mem" : "io base",
					(unsigned long long)hcd->rsrc_start);
	} else {
		hcd->irq = -1;
		if (hcd->rsrc_start)
			dev_info(hcd->self.controller, "%s 0x%08llx\n",
					(hcd->driver->flags & HCD_MEMORY) ?
					"io mem" : "io base",
					(unsigned long long)hcd->rsrc_start);
	}

	if ((retval = hcd->driver->start(hcd)) < 0) {
		dev_err(hcd->self.controller, "startup error %d\n", retval);
		goto err_hcd_driver_start;
	}
#if 0
	/* starting here, usbcore will pay attention to this root hub */
	rhdev->bus_mA = min(500u, hcd->power_budget);
	if ((retval = register_root_hub(hcd)) != 0)
		goto err_register_root_hub;

	retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);
	if (retval < 0) {
		printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",
		       retval);
		goto error_create_attr_group;
	}
	if (hcd->uses_new_polling && hcd->poll_rh)
		usb_hcd_poll_rh_status(hcd);
#endif
	return retval;

error_create_attr_group:
	mutex_lock(&usb_bus_list_lock);
	usb_disconnect(&hcd->self.root_hub);
	mutex_unlock(&usb_bus_list_lock);
err_register_root_hub:
	hcd->driver->stop(hcd);
err_hcd_driver_start:
	if (hcd->irq >= 0)
		free_irq(irqnum, hcd);
err_request_irq:
err_hcd_driver_setup:
	hcd->self.root_hub = NULL;
	usb_put_dev(rhdev);
#if 1
err_allocate_root_hub:
	hcd->driver->stop(hcd);
#endif
err_register_bus:
	hcd_buffer_destroy(hcd);
	return retval;
} 
Пример #10
0
/**
 * usb_hcd_omap_probe - initialize OMAP-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic 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.
 */
int usb_hcd_omap_probe (const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;

	if (pdev->num_resources != 2) {
		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n", 
		       pdev->num_resources);
		return -ENODEV;
	}

	if (pdev->resource[0].flags != IORESOURCE_MEM 
	    || pdev->resource[1].flags != IORESOURCE_IRQ) {
		printk(KERN_ERR "hcd probe: invalid resource type\n");
		return -ENODEV;
	}

	if (!request_mem_region(pdev->resource[0].start, 
				pdev->resource[0].end - pdev->resource[0].start + 1, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		return -EBUSY;
	}

	hcd = driver->hcd_alloc ();
	if (hcd == NULL){
		dev_dbg(&pdev->dev, "hcd_alloc failed\n");
		retval = -ENOMEM;
		goto err1;
	}
	dev_set_drvdata(&pdev->dev, hcd);
	ohci = hcd_to_ohci(hcd);

	hcd->driver = (struct hc_driver *) driver;
	hcd->description = driver->description;
	hcd->irq = pdev->resource[1].start;
	hcd->regs = (void *)pdev->resource[0].start;
	hcd->self.controller = &pdev->dev;

	retval = omap_start_hc(ohci, pdev);
	if (retval < 0)
		goto err1;

	retval = hcd_buffer_create (hcd);
	if (retval != 0) {
		dev_dbg(&pdev->dev, "pool alloc fail\n");
		goto err1;
	}

	retval = request_irq (hcd->irq, usb_hcd_irq, 
#ifdef CONFIG_PREEMPT_HARDIRQS
			      0, hcd->description, hcd);
#else
			      SA_INTERRUPT, hcd->description, hcd);
#endif
	if (retval != 0) {
		dev_dbg(&pdev->dev, "request_irq failed\n");
		retval = -EBUSY;
		goto err2;
	}

	dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);

	usb_bus_init (&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.release = &usb_hcd_release;
	hcd->self.hcpriv = (void *) hcd;
	hcd->self.bus_name = pdev->dev.bus_id;
	hcd->product_desc = "OMAP OHCI";

	INIT_LIST_HEAD (&hcd->dev_list);
	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0) 
	{
		usb_hcd_omap_remove(hcd, pdev);
		return retval;
	}

	return 0;

 err2:
	hcd_buffer_destroy (hcd);
 err1:
	kfree(hcd);
	omap_stop_hc(pdev);

	release_mem_region(pdev->resource[0].start, 
			   pdev->resource[0].end - pdev->resource[0].start + 1);

	dev_set_drvdata(&pdev->dev, 0);
	return retval;
}
Пример #11
0
/**
 * usb_hcd_omap_probe - initialize OMAP-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic 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.
 */
int usb_hcd_omap_probe (const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;

	if (pdev->num_resources != 2) {
		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n", 
		       pdev->num_resources);
		return -ENODEV;
	}

	if (pdev->resource[0].flags != IORESOURCE_MEM 
	    || pdev->resource[1].flags != IORESOURCE_IRQ) {
		printk(KERN_ERR "hcd probe: invalid resource type\n");
		return -ENODEV;
	}

	if (!request_mem_region(pdev->resource[0].start, 
				pdev->resource[0].end - pdev->resource[0].start + 1, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		return -EBUSY;
	}

	hcd = usb_create_hcd (driver);
	if (hcd == NULL){
		dev_dbg(&pdev->dev, "hcd_alloc failed\n");
		retval = -ENOMEM;
		goto err1;
	}
	dev_set_drvdata(&pdev->dev, hcd);
	ohci = hcd_to_ohci(hcd);
	ohci_hcd_init(ohci);

	hcd->irq = pdev->resource[1].start;
	hcd->regs = (void *)pdev->resource[0].start;
	hcd->self.controller = &pdev->dev;

	retval = omap_start_hc(ohci, pdev);
	if (retval < 0)
		goto err2;

	retval = hcd_buffer_create (hcd);
	if (retval != 0) {
		dev_dbg(&pdev->dev, "pool alloc fail\n");
		goto err2;
	}

	retval = request_irq (hcd->irq, usb_hcd_irq, 
			      SA_INTERRUPT, hcd->driver->description, hcd);
	if (retval != 0) {
		dev_dbg(&pdev->dev, "request_irq failed\n");
		retval = -EBUSY;
		goto err3;
	}

	dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);

	hcd->self.bus_name = pdev->dev.bus_id;
	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0) 
	{
		usb_hcd_omap_remove(hcd, pdev);
		return retval;
	}

	return 0;

 err3:
	hcd_buffer_destroy (hcd);
 err2:
	dev_set_drvdata(&pdev->dev, NULL);
	usb_put_hcd(hcd);
 err1:
	omap_stop_hc(pdev);

	release_mem_region(pdev->resource[0].start, 
			   pdev->resource[0].end - pdev->resource[0].start + 1);

	return retval;
}
Пример #12
0
static int __init arc_ehci_probe(struct device *dev)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	int retval;
	struct arc_usb_config *config;
	struct platform_device *pdev = to_platform_device(dev);

	config = (struct arc_usb_config *)dev->platform_data;
	dbg("\n%s  dev=0x%p  config=0x%p  name=%s\n",
	    __FUNCTION__, dev, config, config->name);

	if (pdev->resource[0].flags != 0
	    || pdev->resource[1].flags != IORESOURCE_IRQ) {
		return -ENODEV;
	}

	dbg("ehci_driver.description=%s  platform_device.name=%s\n",
	    ehci_driver.description, pdev->name);

	/*
	 * do platform specific init: check the clock, grab/config pins, etc.
	 */
	if (config->platform_init() != 0) {
		retval = -EINVAL;
		goto err1;
	}

	hcd = usb_create_hcd(&ehci_driver);
	if (!hcd) {
		retval = 0;
		goto err1;
	}

	ehci = hcd_to_ehci(hcd);
	dev_set_drvdata(dev, ehci);

	dbg("%s: hcd=0x%p  ehci=0x%p\n", __FUNCTION__, hcd, ehci);

	hcd->regs = (void *)pdev->resource[0].start;
	hcd->irq = pdev->resource[1].start;

	hcd->self.controller = dev;
	hcd->self.bus_name = dev->bus_id;
	hcd->product_desc = "Freescale ARC_OTG";

	retval = hcd_buffer_create(hcd);
	if (retval != 0) {
		dev_dbg(dev, "pool alloc failed\n");
		goto err2;
	}

	INIT_LIST_HEAD(&hcd->dev_list);

	retval =
	    request_irq(hcd->irq, usb_hcd_irq, SA_INTERRUPT, pdev->name, hcd);
	if (retval != 0)
		goto err2;

	retval = usb_register_bus(&hcd->self);
	if (retval < 0)
		goto err3;

	retval = ehci_hc_reset(hcd);

	if (retval < 0)
		goto err4;

	if ((retval = ehci_start(hcd)) < 0) {
		goto err4;
	}

	return 0;
      err4:
	usb_deregister_bus(&hcd->self);
      err3:
	free_irq(hcd->irq, hcd);
      err2:
	usb_put_hcd(hcd);
      err1:
	printk("init error, %d\n", retval);
	return retval;
}
/**
 * usb_hcd_omap_probe - initialize OMAP-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic 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_omap_probe (const struct hc_driver *driver,
			  struct usb_hcd **hcd_out,
			  struct omap_dev *dev)
{
	int retval;
	struct usb_hcd *hcd = 0;

	if (!request_mem_region(dev->res.start, 
				dev->res.end - dev->res.start + 1, hcd_name)) {
		dbg("request_mem_region failed");
		return -EBUSY;
	}

	omap_start_hc(dev);

	hcd = driver->hcd_alloc ();
	if (hcd == NULL){
		dbg ("hcd_alloc failed");
		retval = -ENOMEM;
		goto err1;
	}

	hcd->driver = (struct hc_driver *) driver;
	hcd->description = driver->description;
	hcd->irq = dev->irq[0];
	hcd->regs = dev->mapbase;
	hcd->self.controller = &dev->dev;

	retval = hcd_buffer_create (hcd);
	if (retval != 0) {
		dbg ("pool alloc fail");
		goto err1;
	}

	retval = request_irq (hcd->irq, 
			      usb_hcd_omap_hcim_irq, 
			      SA_INTERRUPT, hcd->description, hcd);
	if (retval != 0) {
		dbg("request_irq failed");
		retval = -EBUSY;
		goto err2;
	}

	info ("%s (OMAP) at 0x%p, irq %d\n",
	      hcd->description, hcd->regs, hcd->irq);

	usb_bus_init (&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.hcpriv = (void *) hcd;
	hcd->self.bus_name = "omap";
	hcd->product_desc = "OMAP OHCI";

	INIT_LIST_HEAD (&hcd->dev_list);
	usb_register_bus (&hcd->self);

	if ((retval = driver->start (hcd)) < 0) 
	{
		usb_hcd_omap_remove(hcd, dev);
		return retval;
	}

	*hcd_out = hcd;
	return 0;

 err2:
	hcd_buffer_destroy (hcd);
	if (hcd)
		driver->hcd_free(hcd);
 err1:
	omap_stop_hc(dev);

	release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1);

	return retval;
}
Пример #14
0
/**
 * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller.
 *
 * Store this function in the HCD's struct pci_driver as probe().
 */
static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
			  struct usb_hcd **hcd_out,
			  struct platform_device *pdev)
{
	int retval;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd	*ohci;
	struct resource *res;
	int irq;

	pr_debug("initializing PPC-SOC USB Controller\n");

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		pr_debug(__FILE__ ": no irq\n");
		return -ENODEV;
	}
	irq = res->start;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		pr_debug(__FILE__ ": no reg addr\n");
		return -ENODEV;
	}
	if (!request_mem_region(res->start, res->end - res->start + 1,
					hcd_name)) {
		pr_debug(__FILE__ ": request_mem_region failed\n");
		return -EBUSY;
	}

	hcd = driver->hcd_alloc ();
	if (!hcd){
		pr_debug(__FILE__ ": hcd_alloc failed\n");
		retval = -ENOMEM;
		goto err1;
	}

	ohci = hcd_to_ohci(hcd);

	ohci->flags |= OHCI_BIG_ENDIAN;

	hcd->driver = (struct hc_driver *) driver;
	hcd->description = driver->description;
	hcd->irq = irq;
	hcd->regs = (struct ohci_regs *) ioremap(res->start,
						res->end - res->start + 1);
	if (!hcd->regs) {
		pr_debug(__FILE__ ": ioremap failed\n");
		retval = -ENOMEM;
		goto err2;
	}

	hcd->self.controller = &pdev->dev;

	retval = hcd_buffer_create(hcd);
	if (retval) {
		pr_debug(__FILE__ ": pool alloc fail\n");
		goto err3;
	}

	retval = request_irq(hcd->irq, usb_hcd_irq, SA_INTERRUPT,
				hcd_name, hcd);
	if (retval) {
		pr_debug(__FILE__ ": request_irq failed, returned %d\n",
								retval);
		retval = -EBUSY;
		goto err4;
	}

	info("%s (PPC-SOC) at 0x%p, irq %d\n",
	      hcd_name, hcd->regs, hcd->irq);

	usb_bus_init(&hcd->self);
	hcd->self.op = &usb_hcd_operations;
	hcd->self.release = & usb_hcd_release;
	hcd->self.hcpriv = (void *) hcd;
	hcd->self.bus_name = "PPC-SOC USB";
	hcd->product_desc = "PPC-SOC OHCI";

	INIT_LIST_HEAD(&hcd->dev_list);

	usb_register_bus(&hcd->self);

	if ((retval = driver->start(hcd)) < 0) {
		usb_hcd_ppc_soc_remove(hcd, pdev);
		return retval;
	}

	*hcd_out = hcd;
	return 0;

 err4:
	hcd_buffer_destroy(hcd);
 err3:
	iounmap(hcd->regs);
 err2:
	dev_set_drvdata(&pdev->dev, NULL);
 err1:
	pr_debug("Removing PPC-SOC USB Controller\n");
	release_mem_region(res->start, res->end - res->start + 1);
	return retval;
}