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