static int init_sunxi_hci(struct sunxi_hci_hcd *sunxi_hci, u32 usbc_no, u32 ohci, const char *hci_name) { s32 ret = 0; memset(sunxi_hci, 0, sizeof(struct sunxi_hci_hcd)); sunxi_hci->usbc_no = usbc_no; sunxi_hci->usbc_type = ohci ? SUNXI_USB_OHCI : SUNXI_USB_EHCI; if(ohci){ sunxi_hci->irq_no = ohci_irq_no[sunxi_hci->usbc_no]; }else{ sunxi_hci->irq_no = ehci_irq_no[sunxi_hci->usbc_no]; } sprintf(sunxi_hci->hci_name, "%s%d", hci_name, sunxi_hci->usbc_no); sunxi_hci->usb_vbase = (void __iomem *)usbc_base[sunxi_hci->usbc_no]; sunxi_hci->sram_vbase = (void __iomem *)SUNXI_SRAMCTRL_VBASE; sunxi_hci->clock_vbase = (void __iomem *)SUNXI_CCM_VBASE; sunxi_hci->gpio_vbase = (void __iomem *)SUNXI_PIO_VBASE; sunxi_hci->sdram_vbase = (void __iomem *)SUNXI_SDMMC1_VBASE; get_usb_cfg(sunxi_hci); request_usb_regulator_io(sunxi_hci); sunxi_hci->open_clock = open_clock; sunxi_hci->close_clock = close_clock; sunxi_hci->set_power = sunxi_set_vbus; sunxi_hci->usb_passby = usb_passby; sunxi_hci->port_configure = hci_port_configure; #ifdef CONFIG_USB_SUNXI_HSIC u32 reg_value = 0; reg_value = USBC_Readl(sunxi_hci->sram_vbase+ SUNXI_USB_PMU_IRQ_ENABLE); reg_value |= (1 << 1); reg_value |= (1 << 20); reg_value |= (1 << 17); USBC_Writel(reg_value, (sunxi_hci->sram_vbase+ SUNXI_USB_PMU_IRQ_ENABLE)); #endif #ifndef CONFIG_ARCH_SUN9IW1 #ifdef SUNXI_USB_FPGA fpga_config_use_hci((__u32 __force)sunxi_hci->sram_vbase); #endif #endif ret = clock_init(sunxi_hci, ohci); if(ret != 0){ DMSG_PANIC("ERR: clock_init failed\n"); goto failed1; } print_sunxi_hci(sunxi_hci); return 0; failed1: return -1; }
static int __devinit sunxi_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct resource *res; struct sunxi_otgc *otgc; struct device *dev = &pdev->dev; int ret = -ENOMEM; int irq; void __iomem *regs; void *mem; mem = devm_kzalloc(dev, sizeof(*otgc) + SUNXI_ALIGN_MASK, GFP_KERNEL); if (!mem) { dev_err(dev, "not enough memory\n"); return -ENOMEM; } otgc = PTR_ALIGN(mem, SUNXI_ALIGN_MASK + 1); otgc->mem = mem; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing resource\n"); return -ENODEV; } otgc->res = res; res = devm_request_mem_region(dev, res->start, resource_size(res), dev_name(dev)); if (!res) { dev_err(dev, "can't request mem region\n"); return -ENOMEM; } regs = devm_ioremap(dev, res->start, resource_size(res)); if (!regs) { dev_err(dev, "ioremap failed\n"); return -ENOMEM; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "missing IRQ\n"); return -ENODEV; } spin_lock_init(&otgc ->lock); otgc->regs = regs; otgc->regs_size = resource_size(res); otgc->dev = dev; otgc->irq = irq; if (!strncmp("super", maximum_speed, 5)) otgc->maximum_speed = SUNXI_DCFG_SUPERSPEED; else if (!strncmp("high", maximum_speed, 4)) otgc->maximum_speed = SUNXI_DCFG_HIGHSPEED; else if (!strncmp("full", maximum_speed, 4)) otgc->maximum_speed = SUNXI_DCFG_FULLSPEED1; else if (!strncmp("low", maximum_speed, 3)) otgc->maximum_speed = SUNXI_DCFG_LOWSPEED; else otgc->maximum_speed = SUNXI_DCFG_SUPERSPEED; if (of_get_property(node, "tx-fifo-resize", NULL)) otgc->needs_fifo_resize = true; pm_runtime_enable(dev); pm_runtime_get_sync(dev); pm_runtime_forbid(dev); sunxi_open_usb_clock(otgc); #ifndef SUNXI_USB_FPGA sunxi_pin_init(otgc); request_usb_regulator_io(otgc); #endif ret = sunxi_core_init(otgc); if (ret) { dev_err(dev, "failed to initialize core\n"); return ret; } sunxi_set_mode(otgc , SUNXI_GCTL_PRTCAP_DEVICE); sunxi_gadget_init(otgc ); ret = sunxi_debugfs_init(otgc); if (ret) { dev_err(dev, "failed to initialize debugfs\n"); goto err1; } pm_runtime_allow(dev); platform_set_drvdata(pdev, otgc); sunxi_otg_pdev = pdev; sunxi_usb_device_disable(); return 0; err1: sunxi_core_exit(otgc); return ret; }