static struct usbmisc_usb_device *get_usbdev(struct device *dev) { int i, ret; for (i = 0; i < USB_DEV_MAX; i++) { if (usbmisc->usbdev[i].dev == dev) return &usbmisc->usbdev[i]; else if (!usbmisc->usbdev[i].dev) break; } if (i >= USB_DEV_MAX) return ERR_PTR(-EBUSY); ret = usbmisc_get_init_data(dev, &usbmisc->usbdev[i]); if (ret) return ERR_PTR(ret); return &usbmisc->usbdev[i]; }
static int ci_hdrc_imx_probe(struct platform_device *pdev) { struct ci_hdrc_imx_data *data; struct ci_hdrc_platform_data pdata = { .name = "ci_hdrc_imx", .capoffset = DEF_CAPOFFSET, .flags = CI_HDRC_REQUIRE_TRANSCEIVER | CI_HDRC_DISABLE_STREAMING, }; int ret; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) { dev_err(&pdev->dev, "Failed to allocate ci_hdrc-imx data!\n"); return -ENOMEM; } data->usbmisc_data = usbmisc_get_init_data(&pdev->dev); if (IS_ERR(data->usbmisc_data)) return PTR_ERR(data->usbmisc_data); data->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(data->clk)) { dev_err(&pdev->dev, "Failed to get clock, err=%ld\n", PTR_ERR(data->clk)); return PTR_ERR(data->clk); } ret = clk_prepare_enable(data->clk); if (ret) { dev_err(&pdev->dev, "Failed to prepare or enable clock, err=%d\n", ret); return ret; } data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0); if (IS_ERR(data->phy)) { ret = PTR_ERR(data->phy); goto err_clk; } pdata.phy = data->phy; ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (ret) goto err_clk; if (data->usbmisc_data) { ret = imx_usbmisc_init(data->usbmisc_data); if (ret) { dev_err(&pdev->dev, "usbmisc init failed, ret=%d\n", ret); goto err_clk; } } data->ci_pdev = ci_hdrc_add_device(&pdev->dev, pdev->resource, pdev->num_resources, &pdata); if (IS_ERR(data->ci_pdev)) { ret = PTR_ERR(data->ci_pdev); dev_err(&pdev->dev, "Can't register ci_hdrc platform device, err=%d\n", ret); goto err_clk; } if (data->usbmisc_data) { ret = imx_usbmisc_init_post(data->usbmisc_data); if (ret) { dev_err(&pdev->dev, "usbmisc post failed, ret=%d\n", ret); goto disable_device; } } platform_set_drvdata(pdev, data); pm_runtime_no_callbacks(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; disable_device: ci_hdrc_remove_device(data->ci_pdev); err_clk: clk_disable_unprepare(data->clk); return ret; } static int ci_hdrc_imx_remove(struct platform_device *pdev) { struct ci_hdrc_imx_data *data = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); ci_hdrc_remove_device(data->ci_pdev); clk_disable_unprepare(data->clk); return 0; } static const struct of_device_id ci_hdrc_imx_dt_ids[] = { { .compatible = "fsl,imx27-usb", }, { /* sentinel */ } };