struct imx_pinctrl_soc_info *info;
 };
 
-static inline const struct imx_pin_group *imx_pinctrl_find_group_by_name(
-                               struct imx_pinctrl_soc_info *info,
+static inline const struct group_desc *imx_pinctrl_find_group_by_name(
+                               struct pinctrl_dev *pctldev,
                                const char *name)
 {
-       const struct imx_pin_group *grp = NULL;
+       const struct group_desc *grp = NULL;
        int i;
 
-       for (i = 0; i < info->ngroups; i++) {
-               grp = radix_tree_lookup(&info->pgtree, i);
+       for (i = 0; i < pctldev->num_groups; i++) {
+               grp = pinctrl_generic_get_group(pctldev, i);
                if (grp && !strcmp(grp->name, name))
                        break;
        }
        return grp;
 }
 
-static int imx_get_groups_count(struct pinctrl_dev *pctldev)
-{
-       struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
-       struct imx_pinctrl_soc_info *info = ipctl->info;
-
-       return info->ngroups;
-}
-
-static const char *imx_get_group_name(struct pinctrl_dev *pctldev,
-                                      unsigned selector)
-{
-       struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
-       struct imx_pinctrl_soc_info *info = ipctl->info;
-       struct imx_pin_group *grp = NULL;
-
-       grp = radix_tree_lookup(&info->pgtree, selector);
-       if (!grp)
-               return NULL;
-
-       return grp->name;
-}
-
-static int imx_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
-                              const unsigned **pins,
-                              unsigned *npins)
-{
-       struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
-       struct imx_pinctrl_soc_info *info = ipctl->info;
-       struct imx_pin_group *grp = NULL;
-
-       if (selector >= info->ngroups)
-               return -EINVAL;
-
-       grp = radix_tree_lookup(&info->pgtree, selector);
-       if (!grp)
-               return -EINVAL;
-
-       *pins = grp->pin_ids;
-       *npins = grp->npins;
-
-       return 0;
-}
-
 static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
                   unsigned offset)
 {
 {
        struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
        struct imx_pinctrl_soc_info *info = ipctl->info;
-       const struct imx_pin_group *grp;
+       const struct group_desc *grp;
        struct pinctrl_map *new_map;
        struct device_node *parent;
        int map_num = 1;
         * first find the group of this node and check if we need create
         * config maps for pins
         */
-       grp = imx_pinctrl_find_group_by_name(info, np->name);
+       grp = imx_pinctrl_find_group_by_name(pctldev, np->name);
        if (!grp) {
                dev_err(info->dev, "unable to find group for node %s\n",
                        np->name);
                return -EINVAL;
        }
 
-       for (i = 0; i < grp->npins; i++) {
-               if (!(grp->pins[i].config & IMX_NO_PAD_CTL))
+       for (i = 0; i < grp->num_pins; i++) {
+               struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
+
+               if (!(pin->config & IMX_NO_PAD_CTL))
                        map_num++;
        }
 
 
        /* create config map */
        new_map++;
-       for (i = j = 0; i < grp->npins; i++) {
-               if (!(grp->pins[i].config & IMX_NO_PAD_CTL)) {
+       for (i = j = 0; i < grp->num_pins; i++) {
+               struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
+
+               if (!(pin->config & IMX_NO_PAD_CTL)) {
                        new_map[j].type = PIN_MAP_TYPE_CONFIGS_PIN;
                        new_map[j].data.configs.group_or_pin =
-                                       pin_get_name(pctldev, grp->pins[i].pin);
-                       new_map[j].data.configs.configs = &grp->pins[i].config;
+                                       pin_get_name(pctldev, pin->pin);
+                       new_map[j].data.configs.configs = &pin->config;
                        new_map[j].data.configs.num_configs = 1;
                        j++;
                }
 }
 
 static const struct pinctrl_ops imx_pctrl_ops = {
-       .get_groups_count = imx_get_groups_count,
-       .get_group_name = imx_get_group_name,
-       .get_group_pins = imx_get_group_pins,
+       .get_groups_count = pinctrl_generic_get_group_count,
+       .get_group_name = pinctrl_generic_get_group_name,
+       .get_group_pins = pinctrl_generic_get_group_pins,
        .pin_dbg_show = imx_pin_dbg_show,
        .dt_node_to_map = imx_dt_node_to_map,
        .dt_free_map = imx_dt_free_map,
        const struct imx_pin_reg *pin_reg;
        unsigned int npins, pin_id;
        int i;
-       struct imx_pin_group *grp = NULL;
+       struct group_desc *grp = NULL;
        struct imx_pmx_func *func = NULL;
 
        /*
         * Configure the mux mode for each pin in the group for a specific
         * function.
         */
-       grp = radix_tree_lookup(&info->pgtree, group);
+       grp = pinctrl_generic_get_group(pctldev, group);
        if (!grp)
                return -EINVAL;
 
        if (!func)
                return -EINVAL;
 
-       npins = grp->npins;
+       npins = grp->num_pins;
 
        dev_dbg(ipctl->dev, "enable function %s group %s\n",
                func->name, grp->name);
 
        for (i = 0; i < npins; i++) {
-               struct imx_pin *pin = &grp->pins[i];
+               struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
+
                pin_id = pin->pin;
                pin_reg = &info->pin_regs[pin_id];
 
        struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
        struct imx_pinctrl_soc_info *info = ipctl->info;
        const struct imx_pin_reg *pin_reg;
-       struct imx_pin_group *grp;
+       struct group_desc *grp;
        struct imx_pin *imx_pin;
        unsigned int pin, group;
        u32 reg;
                return -EINVAL;
 
        /* Find the pinctrl config with GPIO mux mode for the requested pin */
-       for (group = 0; group < info->ngroups; group++) {
-               grp = radix_tree_lookup(&info->pgtree, group);
+       for (group = 0; group < pctldev->num_groups; group++) {
+               grp = pinctrl_generic_get_group(pctldev, group);
                if (!grp)
                        continue;
-               for (pin = 0; pin < grp->npins; pin++) {
-                       imx_pin = &grp->pins[pin];
+               for (pin = 0; pin < grp->num_pins; pin++) {
+                       imx_pin = &((struct imx_pin *)(grp->data))[pin];
                        if (imx_pin->pin == offset && !imx_pin->mux_mode)
                                goto mux_pin;
                }
 static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
                                         struct seq_file *s, unsigned group)
 {
-       struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
-       struct imx_pinctrl_soc_info *info = ipctl->info;
-       struct imx_pin_group *grp;
+       struct group_desc *grp;
        unsigned long config;
        const char *name;
        int i, ret;
 
-       if (group > info->ngroups)
+       if (group > pctldev->num_groups)
                return;
 
        seq_printf(s, "\n");
-       grp = radix_tree_lookup(&info->pgtree, group);
+       grp = pinctrl_generic_get_group(pctldev, group);
        if (!grp)
                return;
 
-       for (i = 0; i < grp->npins; i++) {
-               struct imx_pin *pin = &grp->pins[i];
+       for (i = 0; i < grp->num_pins; i++) {
+               struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
+
                name = pin_get_name(pctldev, pin->pin);
                ret = imx_pinconf_get(pctldev, pin->pin, &config);
                if (ret)
 #define SHARE_FSL_PIN_SIZE 20
 
 static int imx_pinctrl_parse_groups(struct device_node *np,
-                                   struct imx_pin_group *grp,
+                                   struct group_desc *grp,
                                    struct imx_pinctrl_soc_info *info,
                                    u32 index)
 {
                return -EINVAL;
        }
 
-       grp->npins = size / pin_size;
-       grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(struct imx_pin),
-                               GFP_KERNEL);
-       grp->pin_ids = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
-                               GFP_KERNEL);
-       if (!grp->pins || ! grp->pin_ids)
+       grp->num_pins = size / pin_size;
+       grp->data = devm_kzalloc(info->dev, grp->num_pins *
+                                sizeof(struct imx_pin), GFP_KERNEL);
+       grp->pins = devm_kzalloc(info->dev, grp->num_pins *
+                                sizeof(unsigned int), GFP_KERNEL);
+       if (!grp->pins || !grp->data)
                return -ENOMEM;
 
-       for (i = 0; i < grp->npins; i++) {
+       for (i = 0; i < grp->num_pins; i++) {
                u32 mux_reg = be32_to_cpu(*list++);
                u32 conf_reg;
                unsigned int pin_id;
                struct imx_pin_reg *pin_reg;
-               struct imx_pin *pin = &grp->pins[i];
+               struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i];
 
                if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg)
                        mux_reg = -1;
                pin_id = (mux_reg != -1) ? mux_reg / 4 : conf_reg / 4;
                pin_reg = &info->pin_regs[pin_id];
                pin->pin = pin_id;
-               grp->pin_ids[i] = pin_id;
+               grp->pins[i] = pin_id;
                pin_reg->mux_reg = mux_reg;
                pin_reg->conf_reg = conf_reg;
                pin->input_reg = be32_to_cpu(*list++);
 }
 
 static int imx_pinctrl_parse_functions(struct device_node *np,
-                                      struct imx_pinctrl_soc_info *info,
+                                      struct imx_pinctrl *ipctl,
                                       u32 index)
 {
+       struct pinctrl_dev *pctl = ipctl->pctl;
+       struct imx_pinctrl_soc_info *info = ipctl->info;
        struct device_node *child;
        struct imx_pmx_func *func;
-       struct imx_pin_group *grp;
+       struct group_desc *grp;
        u32 i = 0;
 
        dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
        for_each_child_of_node(np, child) {
                func->groups[i] = child->name;
 
-               grp = devm_kzalloc(info->dev, sizeof(struct imx_pin_group),
+               grp = devm_kzalloc(info->dev, sizeof(struct group_desc),
                                   GFP_KERNEL);
                if (!grp)
                        return -ENOMEM;
 
                mutex_lock(&info->mutex);
-               radix_tree_insert(&info->pgtree, info->group_index++, grp);
+               radix_tree_insert(&pctl->pin_group_tree,
+                                 info->group_index++, grp);
                mutex_unlock(&info->mutex);
 
                imx_pinctrl_parse_groups(child, grp, info, i++);
 }
 
 static int imx_pinctrl_probe_dt(struct platform_device *pdev,
-                               struct imx_pinctrl_soc_info *info)
+                               struct imx_pinctrl *ipctl)
 {
        struct device_node *np = pdev->dev.of_node;
        struct device_node *child;
+       struct pinctrl_dev *pctl = ipctl->pctl;
+       struct imx_pinctrl_soc_info *info = ipctl->info;
        u32 nfuncs = 0;
        u32 i = 0;
        bool flat_funcs;
 
        info->group_index = 0;
        if (flat_funcs) {
-               info->ngroups = of_get_child_count(np);
+               pctl->num_groups = of_get_child_count(np);
        } else {
-               info->ngroups = 0;
+               pctl->num_groups = 0;
                for_each_child_of_node(np, child)
-                       info->ngroups += of_get_child_count(child);
+                       pctl->num_groups += of_get_child_count(child);
        }
 
        if (flat_funcs) {
-               imx_pinctrl_parse_functions(np, info, 0);
+               imx_pinctrl_parse_functions(np, ipctl, 0);
        } else {
                i = 0;
                for_each_child_of_node(np, child)
-                       imx_pinctrl_parse_functions(child, info, i++);
+                       imx_pinctrl_parse_functions(child, ipctl, i++);
        }
 
        return 0;
        mutex_unlock(&info->mutex);
 }
 
-/*
- * imx_free_pingroups() - free memory used by pingroups
- * @info: info driver instance
- */
-static void imx_free_pingroups(struct imx_pinctrl_soc_info *info)
-{
-       int i;
-
-       mutex_lock(&info->mutex);
-       for (i = 0; i < info->ngroups; i++) {
-               struct imx_pin_group *pingroup;
-
-               pingroup = radix_tree_lookup(&info->pgtree, i);
-               if (!pingroup)
-                       continue;
-               radix_tree_delete(&info->pgtree, i);
-       }
-       mutex_unlock(&info->mutex);
-}
-
 /*
  * imx_free_resources() - free memory used by this driver
  * @info: info driver instance
                pinctrl_unregister(ipctl->pctl);
 
        imx_free_funcs(ipctl->info);
-       imx_free_pingroups(ipctl->info);
 }
 
 int imx_pinctrl_probe(struct platform_device *pdev,
 
        mutex_init(&info->mutex);
 
-       INIT_RADIX_TREE(&info->pgtree, GFP_KERNEL);
        INIT_RADIX_TREE(&info->ftree, GFP_KERNEL);
 
-       ret = imx_pinctrl_probe_dt(pdev, info);
-       if (ret) {
-               dev_err(&pdev->dev, "fail to probe dt properties\n");
-               goto free;
-       }
-
        ipctl->info = info;
        ipctl->dev = info->dev;
        platform_set_drvdata(pdev, ipctl);
                goto free;
        }
 
+       ret = imx_pinctrl_probe_dt(pdev, ipctl);
+       if (ret) {
+               dev_err(&pdev->dev, "fail to probe dt properties\n");
+               goto free;
+       }
+
        dev_info(&pdev->dev, "initialized IMX pinctrl driver\n");
 
        return 0;