static int __devinit dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) { struct resource res[2]; struct platform_device *dwc3; struct dwc3_pci *glue; int ret = -ENOMEM; int devid; struct device *dev = &pci->dev; glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(dev, "not enough memory\n"); return -ENOMEM; } glue->dev = dev; ret = pci_enable_device(pci); if (ret) { dev_err(dev, "failed to enable pci device\n"); return -ENODEV; } pci_set_power_state(pci, PCI_D0); pci_set_master(pci); devid = dwc3_get_device_id(); if (devid < 0) { ret = -ENOMEM; goto err1; } dwc3 = platform_device_alloc("dwc3", devid); if (!dwc3) { dev_err(dev, "couldn't allocate dwc3 device\n"); ret = -ENOMEM; goto err1; } memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); res[0].start = pci_resource_start(pci, 0); res[0].end = pci_resource_end(pci, 0); res[0].name = "dwc_usb3"; res[0].flags = IORESOURCE_MEM; res[1].start = pci->irq; res[1].name = "dwc_usb3"; res[1].flags = IORESOURCE_IRQ; ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); if (ret) { dev_err(dev, "couldn't add resources to dwc3 device\n"); goto err2; } pci_set_drvdata(pci, glue); dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); dwc3->dev.dma_mask = dev->dma_mask; dwc3->dev.dma_parms = dev->dma_parms; dwc3->dev.parent = dev; glue->dwc3 = dwc3; ret = platform_device_add(dwc3); if (ret) { dev_err(dev, "failed to register dwc3 device\n"); goto err3; } return 0; err3: pci_set_drvdata(pci, NULL); platform_device_put(dwc3); err2: dwc3_put_device_id(devid); err1: pci_disable_device(pci); return ret; }
static int __devinit dwc3_omap_probe(struct platform_device *pdev) { struct dwc3_omap_data *pdata = pdev->dev.platform_data; struct device_node *node = pdev->dev.of_node; struct platform_device *dwc3; struct dwc3_omap *omap; struct resource *res; struct device *dev = &pdev->dev; struct resource dwc3_res[2]; int devid; int size; int ret = -ENOMEM; int irq; const u32 *utmi_mode; u32 reg; void __iomem *base; void *context; omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL); if (!omap) { dev_err(dev, "not enough memory\n"); return -ENOMEM; } platform_set_drvdata(pdev, omap); irq = platform_get_irq(pdev, 1); if (irq < 0) { dev_err(dev, "missing IRQ resource\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing memory base resource\n"); return -EINVAL; } base = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!base) { dev_err(dev, "ioremap failed\n"); return -ENOMEM; } devid = dwc3_get_device_id(); if (devid < 0) return -ENODEV; omap->workqueue = create_singlethread_workqueue("omap_dwc3"); if (!omap->workqueue) { dev_err(dev, "unable to create workqueue for omap dwc3\n"); return -EINVAL; } dwc3 = platform_device_alloc("dwc3", devid); if (!dwc3) { dev_err(dev, "couldn't allocate dwc3 device\n"); goto err1; } context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL); if (!context) { dev_err(dev, "couldn't allocate dwc3 context memory\n"); goto err2; } spin_lock_init(&omap->lock); dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); dwc3->dev.parent = dev; dwc3->dev.dma_mask = dev->dma_mask; dwc3->dev.dma_parms = dev->dma_parms; omap->resource_size = resource_size(res); omap->context = context; omap->dev = dev; omap->irq = irq; omap->base = base; omap->dwc3 = dwc3; omap->status = OMAP_DWC3_UNKNOWN; INIT_DELAYED_WORK(&omap->omap_dwc3_mailbox_work, omap_dwc3_mailbox_work); /* * REVISIT if we ever have two instances of the wrapper, we will be * in big trouble */ _omap = omap; pm_runtime_enable(dev); pm_runtime_get_sync(dev); reg = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); utmi_mode = of_get_property(node, "utmi-mode", &size); if (utmi_mode && size == sizeof(*utmi_mode)) { reg |= *utmi_mode; } else { if (!pdata) { dev_dbg(dev, "missing platform data\n"); } else { switch (pdata->utmi_mode) { case DWC3_OMAP_UTMI_MODE_SW: reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; break; case DWC3_OMAP_UTMI_MODE_HW: reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; break; default: dev_dbg(dev, "UNKNOWN utmi mode %d\n", pdata->utmi_mode); } } } dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg); /* check the DMA Status */ reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE); ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0, "dwc3-omap", omap); if (ret) { dev_err(dev, "failed to request IRQ #%d --> %d\n", omap->irq, ret); goto err2; } dwc3_omap_enable_irqs(omap); pm_runtime_put_sync(dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res) { dev_err(&pdev->dev, "missing memory base resource for dwc3\n"); ret = -EINVAL; goto err2; } memset(dwc3_res, 0, sizeof(dwc3_res)); dwc3_res[0].start = res->start; dwc3_res[0].end = res->end; dwc3_res[0].flags = res->flags; dwc3_res[0].name = res->name; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "missing IRQ\n"); ret = -EINVAL; goto err2; } dwc3_res[1].start = irq; dwc3_res[1].flags = IORESOURCE_IRQ; dwc3_res[1].name = res->name; ret = platform_device_add_resources(dwc3, dwc3_res, ARRAY_SIZE(dwc3_res)); if (ret) { dev_err(dev, "couldn't add resources to dwc3 device\n"); goto err2; } ret = platform_device_add(dwc3); if (ret) { dev_err(dev, "failed to register dwc3 device\n"); goto err2; } pm_qos_add_request(&omap->pm_qos_request, PM_QOS_MEMORY_THROUGHPUT, PM_QOS_MEMORY_THROUGHPUT_DEFAULT_VALUE); wake_lock_init(&omap->dwc_wakelock, WAKE_LOCK_SUSPEND, "usb3_dwc"); return 0; err2: platform_device_put(dwc3); err1: dwc3_put_device_id(devid); return ret; }