static int __devinit s5p_ehci_probe(struct platform_device *pdev) { struct s5p_ehci_platdata *pdata; struct s5p_ehci_hcd *s5p_ehci; struct usb_hcd *hcd; struct ehci_hcd *ehci; struct resource *res; int irq; int err; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No platform data defined\n"); return -EINVAL; } s5p_ehci = kzalloc(sizeof(struct s5p_ehci_hcd), GFP_KERNEL); if (!s5p_ehci) return -ENOMEM; s5p_ehci->dev = &pdev->dev; hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); err = -ENOMEM; goto fail_hcd; } s5p_ehci->hcd = hcd; s5p_ehci->clk = clk_get(&pdev->dev, "usbhost"); if (IS_ERR(s5p_ehci->clk)) { dev_err(&pdev->dev, "Failed to get usbhost clock\n"); err = PTR_ERR(s5p_ehci->clk); goto fail_clk; } err = clk_enable(s5p_ehci->clk); if (err) goto fail_clken; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Failed to get I/O memory\n"); err = -ENXIO; goto fail_io; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(res->start, resource_size(res)); if (!hcd->regs) { dev_err(&pdev->dev, "Failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "Failed to get IRQ\n"); err = -ENODEV; goto fail; } platform_set_drvdata(pdev, s5p_ehci); s5p_ehci_phy_init(pdev); ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = readl(&ehci->caps->hcs_params); err = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD\n"); goto fail; } create_ehci_sys_file(ehci); s5p_ehci->power_on = 1; #ifdef CONFIG_USB_SUSPEND pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); #endif #ifdef CONFIG_MDM_HSIC_PM /* halt controller before driving suspend on ths bus */ ehci->susp_sof_bug = 1; set_host_stat(hsic_pm_dev, POWER_ON); pm_runtime_allow(&pdev->dev); pm_runtime_set_autosuspend_delay(&hcd->self.root_hub->dev, 0); pm_runtime_forbid(&pdev->dev); enable_periodic(ehci); #endif #ifdef CONFIG_EHCI_IRQ_DISTRIBUTION if (num_possible_cpus() > 1) { s5p_ehci_irq_no = irq; s5p_ehci_irq_cpu = s5p_ehci_cpus[num_possible_cpus() - 1]; irq_set_affinity(s5p_ehci_irq_no, cpumask_of(s5p_ehci_irq_cpu)); register_cpu_notifier(&s5p_ehci_cpu_notifier); } #endif #if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) /* for cp enumeration */ pm_runtime_forbid(&pdev->dev); /*HSIC IPC control the ACTIVE_STATE*/ if (pdata && pdata->noti_host_states) pdata->noti_host_states(pdev, S5P_HOST_ON); #endif return 0; fail: iounmap(hcd->regs); fail_io: clk_disable(s5p_ehci->clk); fail_clken: clk_put(s5p_ehci->clk); fail_clk: usb_put_hcd(hcd); fail_hcd: kfree(s5p_ehci); return err; }
static int __devinit s5p_ehci_probe(struct platform_device *pdev) { struct s5p_ehci_platdata *pdata; struct s5p_ehci_hcd *s5p_ehci; struct usb_hcd *hcd; struct ehci_hcd *ehci; struct resource *res; int irq; int err; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No platform data defined\n"); return -EINVAL; } s5p_ehci = kzalloc(sizeof(struct s5p_ehci_hcd), GFP_KERNEL); if (!s5p_ehci) return -ENOMEM; s5p_ehci->dev = &pdev->dev; hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); err = -ENOMEM; goto fail_hcd; } s5p_ehci->hcd = hcd; s5p_ehci->clk = clk_get(&pdev->dev, "usbhost"); if (IS_ERR(s5p_ehci->clk)) { dev_err(&pdev->dev, "Failed to get usbhost clock\n"); err = PTR_ERR(s5p_ehci->clk); goto fail_clk; } err = clk_enable(s5p_ehci->clk); if (err) goto fail_clken; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Failed to get I/O memory\n"); err = -ENXIO; goto fail_io; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(res->start, resource_size(res)); if (!hcd->regs) { dev_err(&pdev->dev, "Failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "Failed to get IRQ\n"); err = -ENODEV; goto fail; } platform_set_drvdata(pdev, s5p_ehci); s5p_ehci_phy_init(pdev); ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = readl(&ehci->caps->hcs_params); err = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD\n"); goto fail; } /* * EHCI root hubs are expected to handle remote wakeup. * So, wakeup flag init defaults for root hubs. */ device_wakeup_enable(&hcd->self.root_hub->dev); create_ehci_sys_file(ehci); s5p_ehci->power_on = 1; #ifdef CONFIG_USB_SUSPEND pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_get(hcd->self.controller); #endif #ifdef CONFIG_MDM_HSIC_PM /* halt controller before driving suspend on ths bus */ ehci->susp_sof_bug = 1; set_host_stat(hsic_pm_dev, POWER_ON); /* pm_runtime_allow(&pdev->dev); */ pm_runtime_set_autosuspend_delay(&hcd->self.root_hub->dev, 0); pm_runtime_forbid(&pdev->dev); enable_periodic(ehci); #endif return 0; fail: iounmap(hcd->regs); fail_io: clk_disable(s5p_ehci->clk); fail_clken: clk_put(s5p_ehci->clk); fail_clk: usb_put_hcd(hcd); fail_hcd: kfree(s5p_ehci); return err; }