Factor out common code for registering a FSL EHCI platform
device into new fsl_usb2_register_device() function. This
is done to avoid code duplication while adding code for
instantiating of MPC5121 dual role USB platform devices.
Then, the subsequent patch can use
for_each_compatible_node(np, NULL, "fsl,mpc5121-usb2-dr") {
        ...
        fsl_usb2_register_device();
}

Signed-off-by: Anatolij Gustschin <ag...@denx.de>
Cc: Grant Likely <grant.lik...@secretlab.ca>
---
Note to avoid confusion: this patch is new in this series
and is needed because for mpc5121 "fsl,mpc5121-usb2-dr" is
used as the compatible property as requested. "fsl-usb2-dr"
won't be used for mpc5121 any more.

 arch/powerpc/sysdev/fsl_soc.c |  219 ++++++++++++++++++-----------------------
 1 files changed, 98 insertions(+), 121 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index b91f7ac..7bd6436 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -209,6 +209,37 @@ static int __init of_add_fixed_phys(void)
 arch_initcall(of_add_fixed_phys);
 #endif /* CONFIG_FIXED_PHY */
 
+struct fsl_usb2_dev_data {
+       char *dr_mode;          /* controller mode */
+       char *drivers[2];       /* drivers to instantiate for this mode */
+       enum fsl_usb2_operating_modes op_mode;  /* operating mode */
+};
+
+struct fsl_usb2_dev_data dr_data[] __initdata = {
+       { "host",       { "fsl-ehci",   NULL,           }, FSL_USB2_DR_HOST,  },
+       { "otg",        { "fsl-ehci",   "fsl-usb2-udc", }, FSL_USB2_DR_OTG,   },
+       { "periferal",  { "fsl-usb2-udc", NULL,         }, FSL_USB2_DR_DEVICE,},
+};
+
+struct fsl_usb2_dev_data mph_data[] __initdata = {
+       { NULL,         { "fsl-ehci",   NULL,           }, FSL_USB2_MPH_HOST, },
+};
+
+struct fsl_usb2_dev_data * __init get_dr_data(struct device_node *np)
+{
+       const unsigned char *prop;
+       int i;
+
+       prop = of_get_property(np, "dr_mode", NULL);
+       if (prop) {
+               for (i = 0; i < ARRAY_SIZE(dr_data); i++) {
+                       if (!strcmp(prop, dr_data[i].dr_mode))
+                               return &dr_data[i];
+               }
+       }
+       return &dr_data[0]; /* mode not specified, use host */
+}
+
 static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
 {
        if (!phy_type)
@@ -225,151 +256,97 @@ static enum fsl_usb2_phy_modes determine_usb_phy(const 
char *phy_type)
        return FSL_USB2_PHY_NONE;
 }
 
-static int __init fsl_usb_of_init(void)
+int __init fsl_usb2_register_device(struct device_node *np,
+                       struct fsl_usb2_dev_data *dev_data,
+                       struct fsl_usb2_platform_data *pdata,
+                       unsigned int idx)
 {
-       struct device_node *np;
-       unsigned int i = 0;
-       struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL,
-               *usb_dev_dr_client = NULL;
+       struct platform_device *usb_dev;
+       const unsigned char *prop;
+       struct resource r[2];
+       int registered = 0;
        int ret;
+       int i;
+
+       if (!(dev_data && pdata))
+               return -EINVAL;
+
+       memset(&r, 0, sizeof(r));
+       ret = of_address_to_resource(np, 0, &r[0]);
+       if (ret)
+               return -ENODEV;
+
+       ret = of_irq_to_resource(np, 0, &r[1]);
+       if (ret == NO_IRQ)
+               return -ENODEV;
+
+       pdata->operating_mode = dev_data->op_mode;
+
+       prop = of_get_property(np, "phy_type", NULL);
+       pdata->phy_mode = determine_usb_phy(prop);
+       ret = 0;
+       for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
+               if (!dev_data->drivers[i])
+                       break;
+               usb_dev = platform_device_register_simple(
+                                       dev_data->drivers[i], idx, r, 2);
+               if (IS_ERR(usb_dev)) {
+                       ret = PTR_ERR(usb_dev);
+                       goto out;
+               }
 
-       for_each_compatible_node(np, NULL, "fsl-usb2-mph") {
-               struct resource r[2];
-               struct fsl_usb2_platform_data usb_data;
-               const unsigned char *prop = NULL;
-
-               memset(&r, 0, sizeof(r));
-               memset(&usb_data, 0, sizeof(usb_data));
-
-               ret = of_address_to_resource(np, 0, &r[0]);
+               usb_dev->dev.coherent_dma_mask = 0xffffffffUL;
+               usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask;
+               ret = platform_device_add_data(usb_dev, pdata,
+                               sizeof(struct fsl_usb2_platform_data));
                if (ret)
-                       goto err;
-
-               of_irq_to_resource(np, 0, &r[1]);
-
-               usb_dev_mph =
-                   platform_device_register_simple("fsl-ehci", i, r, 2);
-               if (IS_ERR(usb_dev_mph)) {
-                       ret = PTR_ERR(usb_dev_mph);
-                       goto err;
-               }
+                       platform_device_unregister(usb_dev);
+               else
+                       registered++;
+       }
+out:
+       if (!registered)
+               irq_dispose_mapping(r[1].end);
 
-               usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
-               usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
+       return ret;
+}
 
-               usb_data.operating_mode = FSL_USB2_MPH_HOST;
+static int __init fsl_usb_of_init(void)
+{
+       struct device_node *np;
+       const unsigned char *prop;
+       struct fsl_usb2_platform_data pdata;
+       unsigned int idx = 0;
+       int ret;
 
+       for_each_compatible_node(np, NULL, "fsl-usb2-mph") {
+               memset(&pdata, 0, sizeof(pdata));
                prop = of_get_property(np, "port0", NULL);
                if (prop)
-                       usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
+                       pdata.port_enables |= FSL_USB2_PORT0_ENABLED;
 
                prop = of_get_property(np, "port1", NULL);
                if (prop)
-                       usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
+                       pdata.port_enables |= FSL_USB2_PORT1_ENABLED;
 
-               prop = of_get_property(np, "phy_type", NULL);
-               usb_data.phy_mode = determine_usb_phy(prop);
-
-               ret =
-                   platform_device_add_data(usb_dev_mph, &usb_data,
-                                            sizeof(struct
-                                                   fsl_usb2_platform_data));
+               ret = fsl_usb2_register_device(np, mph_data, &pdata, idx++);
                if (ret)
-                       goto unreg_mph;
-               i++;
+                       return ret;
        }
 
        for_each_compatible_node(np, NULL, "fsl-usb2-dr") {
-               struct resource r[2];
-               struct fsl_usb2_platform_data usb_data;
-               const unsigned char *prop = NULL;
-
                if (!of_device_is_available(np))
                        continue;
 
-               memset(&r, 0, sizeof(r));
-               memset(&usb_data, 0, sizeof(usb_data));
-
-               ret = of_address_to_resource(np, 0, &r[0]);
+               memset(&pdata, 0, sizeof(pdata));
+               ret = fsl_usb2_register_device(np, get_dr_data(np),
+                                               &pdata, idx++);
                if (ret)
-                       goto unreg_mph;
-
-               of_irq_to_resource(np, 0, &r[1]);
-
-               prop = of_get_property(np, "dr_mode", NULL);
-
-               if (!prop || !strcmp(prop, "host")) {
-                       usb_data.operating_mode = FSL_USB2_DR_HOST;
-                       usb_dev_dr_host = platform_device_register_simple(
-                                       "fsl-ehci", i, r, 2);
-                       if (IS_ERR(usb_dev_dr_host)) {
-                               ret = PTR_ERR(usb_dev_dr_host);
-                               goto err;
-                       }
-               } else if (prop && !strcmp(prop, "peripheral")) {
-                       usb_data.operating_mode = FSL_USB2_DR_DEVICE;
-                       usb_dev_dr_client = platform_device_register_simple(
-                                       "fsl-usb2-udc", i, r, 2);
-                       if (IS_ERR(usb_dev_dr_client)) {
-                               ret = PTR_ERR(usb_dev_dr_client);
-                               goto err;
-                       }
-               } else if (prop && !strcmp(prop, "otg")) {
-                       usb_data.operating_mode = FSL_USB2_DR_OTG;
-                       usb_dev_dr_host = platform_device_register_simple(
-                                       "fsl-ehci", i, r, 2);
-                       if (IS_ERR(usb_dev_dr_host)) {
-                               ret = PTR_ERR(usb_dev_dr_host);
-                               goto err;
-                       }
-                       usb_dev_dr_client = platform_device_register_simple(
-                                       "fsl-usb2-udc", i, r, 2);
-                       if (IS_ERR(usb_dev_dr_client)) {
-                               ret = PTR_ERR(usb_dev_dr_client);
-                               goto err;
-                       }
-               } else {
-                       ret = -EINVAL;
-                       goto err;
-               }
-
-               prop = of_get_property(np, "phy_type", NULL);
-               usb_data.phy_mode = determine_usb_phy(prop);
-
-               if (usb_dev_dr_host) {
-                       usb_dev_dr_host->dev.coherent_dma_mask = 0xffffffffUL;
-                       usb_dev_dr_host->dev.dma_mask = &usb_dev_dr_host->
-                               dev.coherent_dma_mask;
-                       if ((ret = platform_device_add_data(usb_dev_dr_host,
-                                               &usb_data, sizeof(struct
-                                               fsl_usb2_platform_data))))
-                               goto unreg_dr;
-               }
-               if (usb_dev_dr_client) {
-                       usb_dev_dr_client->dev.coherent_dma_mask = 0xffffffffUL;
-                       usb_dev_dr_client->dev.dma_mask = &usb_dev_dr_client->
-                               dev.coherent_dma_mask;
-                       if ((ret = platform_device_add_data(usb_dev_dr_client,
-                                               &usb_data, sizeof(struct
-                                               fsl_usb2_platform_data))))
-                               goto unreg_dr;
-               }
-               i++;
+                       return ret;
        }
-       return 0;
 
-unreg_dr:
-       if (usb_dev_dr_host)
-               platform_device_unregister(usb_dev_dr_host);
-       if (usb_dev_dr_client)
-               platform_device_unregister(usb_dev_dr_client);
-unreg_mph:
-       if (usb_dev_mph)
-               platform_device_unregister(usb_dev_mph);
-err:
-       return ret;
+       return 0;
 }
-
 arch_initcall(fsl_usb_of_init);
 
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
-- 
1.6.3.3

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to