]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/usb/chipidea/ci_hdrc_imx.c
MLK-10088-4 usb: chipidea: imx: simplify the usbmisc callers
[karo-tx-linux.git] / drivers / usb / chipidea / ci_hdrc_imx.c
index c00f77257d3651ff3e99858b23e1396e2df921b3..5bdd49e2c08f9bd35f5d0e1f90c9cb5817cf6310 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
  * Copyright (C) 2012 Marek Vasut <marex@denx.de>
  * on behalf of DENX Software Engineering GmbH
  *
@@ -23,8 +23,6 @@
 #include "ci.h"
 #include "ci_hdrc_imx.h"
 
-#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
-
 struct ci_hdrc_imx_platform_flag {
        unsigned int flags;
 };
@@ -33,7 +31,7 @@ static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
 };
 
 static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
-       .flags = CI_HDRC_IMX_IMX28_WRITE_FIX,
+       .flags = CI_HDRC_IMX28_WRITE_FIX,
 };
 
 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
@@ -54,6 +52,7 @@ struct ci_hdrc_imx_data {
 
 static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
 {
+       struct platform_device *misc_pdev;
        struct device_node *np = dev->of_node;
        struct of_phandle_args args;
        struct imx_usbmisc_data *data;
@@ -79,8 +78,15 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
        }
 
        data->index = args.args[0];
+
+       misc_pdev = of_find_device_by_node(args.np);
        of_node_put(args.np);
 
+       if (!misc_pdev)
+               return ERR_PTR(-EPROBE_DEFER);
+
+       data->dev = &misc_pdev->dev;
+
        if (of_find_property(np, "disable-over-current", NULL))
                data->disable_oc = 1;
 
@@ -96,10 +102,9 @@ 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",
+               .name           = dev_name(&pdev->dev),
                .capoffset      = DEF_CAPOFFSET,
-               .flags          = CI_HDRC_REQUIRE_TRANSCEIVER |
-                                 CI_HDRC_DISABLE_STREAMING,
+               .flags          = CI_HDRC_DISABLE_STREAMING,
        };
        int ret;
        const struct of_device_id *of_id =
@@ -107,10 +112,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        const struct ci_hdrc_imx_platform_flag *imx_platform_flag = of_id->data;
 
        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-       if (!data) {
-               dev_err(&pdev->dev, "Failed to allocate ci_hdrc-imx data!\n");
+       if (!data)
                return -ENOMEM;
-       }
 
        data->usbmisc_data = usbmisc_get_init_data(&pdev->dev);
        if (IS_ERR(data->usbmisc_data))
@@ -133,25 +136,23 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0);
        if (IS_ERR(data->phy)) {
                ret = PTR_ERR(data->phy);
+               /* Return -EINVAL if no usbphy is available */
+               if (ret == -ENODEV)
+                       ret = -EINVAL;
                goto err_clk;
        }
 
-       pdata.phy = data->phy;
-
-       if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX)
-               pdata.flags |= CI_HDRC_IMX28_WRITE_FIX;
+       pdata.usb_phy = data->phy;
+       pdata.flags |= imx_platform_flag->flags;
 
        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;
-               }
+       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,
@@ -165,13 +166,10 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
                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;
-               }
+       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);
@@ -199,6 +197,41 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int imx_controller_suspend(struct device *dev)
+{
+       struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+
+       dev_dbg(dev, "at %s\n", __func__);
+
+       clk_disable_unprepare(data->clk);
+
+       return 0;
+}
+
+static int imx_controller_resume(struct device *dev)
+{
+       struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+
+       dev_dbg(dev, "at %s\n", __func__);
+
+       return clk_prepare_enable(data->clk);
+}
+
+static int ci_hdrc_imx_suspend(struct device *dev)
+{
+       return imx_controller_suspend(dev);
+}
+
+static int ci_hdrc_imx_resume(struct device *dev)
+{
+       return imx_controller_resume(dev);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
+};
 static struct platform_driver ci_hdrc_imx_driver = {
        .probe = ci_hdrc_imx_probe,
        .remove = ci_hdrc_imx_remove,
@@ -206,6 +239,7 @@ static struct platform_driver ci_hdrc_imx_driver = {
                .name = "imx_usb",
                .owner = THIS_MODULE,
                .of_match_table = ci_hdrc_imx_dt_ids,
+               .pm = &ci_hdrc_imx_pm_ops,
         },
 };