};
 
 
-static int foo_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
+static int foo_get_groups_count(struct pinctrl_dev *pctldev)
 {
-       if (selector >= ARRAY_SIZE(foo_groups))
-               return -EINVAL;
-       return 0;
+       return ARRAY_SIZE(foo_groups);
 }
 
 static const char *foo_get_group_name(struct pinctrl_dev *pctldev,
 }
 
 static struct pinctrl_ops foo_pctrl_ops = {
-       .list_groups = foo_list_groups,
+       .get_groups_count = foo_get_groups_count,
        .get_group_name = foo_get_group_name,
        .get_group_pins = foo_get_group_pins,
 };
        .pctlops = &foo_pctrl_ops,
 };
 
-The pin control subsystem will call the .list_groups() function repeatedly
-beginning on 0 until it returns non-zero to determine legal selectors, then
-it will call the other functions to retrieve the name and pins of the group.
-Maintaining the data structure of the groups is up to the driver, this is
-just a simple example - in practice you may need more entries in your group
-structure, for example specific register ranges associated with each group
-and so on.
+The pin control subsystem will call the .get_groups_count() function to
+determine total number of legal selectors, then it will call the other functions
+to retrieve the name and pins of the group. Maintaining the data structure of
+the groups is up to the driver, this is just a simple example - in practice you
+may need more entries in your group structure, for example specific register
+ranges associated with each group and so on.
 
 
 Pin configuration
 };
 
 
-static int foo_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
+static int foo_get_groups_count(struct pinctrl_dev *pctldev)
 {
-       if (selector >= ARRAY_SIZE(foo_groups))
-               return -EINVAL;
-       return 0;
+       return ARRAY_SIZE(foo_groups);
 }
 
 static const char *foo_get_group_name(struct pinctrl_dev *pctldev,
 }
 
 static struct pinctrl_ops foo_pctrl_ops = {
-       .list_groups = foo_list_groups,
+       .get_groups_count = foo_get_groups_count,
        .get_group_name = foo_get_group_name,
        .get_group_pins = foo_get_group_pins,
 };
        },
 };
 
-int foo_list_funcs(struct pinctrl_dev *pctldev, unsigned selector)
+int foo_get_functions_count(struct pinctrl_dev *pctldev)
 {
-       if (selector >= ARRAY_SIZE(foo_functions))
-               return -EINVAL;
-       return 0;
+       return ARRAY_SIZE(foo_functions);
 }
 
 const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector)
 }
 
 struct pinmux_ops foo_pmxops = {
-       .list_functions = foo_list_funcs,
+       .get_functions_count = foo_get_functions_count,
        .get_function_name = foo_get_fname,
        .get_function_groups = foo_get_groups,
        .enable = foo_enable,
 
                               const char *pin_group)
 {
        const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
+       unsigned ngroups = pctlops->get_groups_count(pctldev);
        unsigned group_selector = 0;
 
-       while (pctlops->list_groups(pctldev, group_selector) >= 0) {
+       while (group_selector < ngroups) {
                const char *gname = pctlops->get_group_name(pctldev,
                                                            group_selector);
                if (!strcmp(gname, pin_group)) {
 {
        struct pinctrl_dev *pctldev = s->private;
        const struct pinctrl_ops *ops = pctldev->desc->pctlops;
-       unsigned selector = 0;
+       unsigned ngroups, selector = 0;
 
+       ngroups = ops->get_groups_count(pctldev);
        mutex_lock(&pinctrl_mutex);
 
        seq_puts(s, "registered pin groups:\n");
-       while (ops->list_groups(pctldev, selector) >= 0) {
+       while (selector < ngroups) {
                const unsigned *pins;
                unsigned num_pins;
                const char *gname = ops->get_group_name(pctldev, selector);
        const struct pinctrl_ops *ops = pctldev->desc->pctlops;
 
        if (!ops ||
-           !ops->list_groups ||
+           !ops->get_groups_count ||
            !ops->get_group_name ||
            !ops->get_group_pins)
                return -EINVAL;
 
        struct pinctrl_dev *pctldev = s->private;
        const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
        const struct pinconf_ops *ops = pctldev->desc->confops;
+       unsigned ngroups = pctlops->get_groups_count(pctldev);
        unsigned selector = 0;
 
        if (!ops || !ops->pin_config_group_get)
 
        mutex_lock(&pinctrl_mutex);
 
-       while (pctlops->list_groups(pctldev, selector) >= 0) {
+       while (selector < ngroups) {
                const char *gname = pctlops->get_group_name(pctldev, selector);
 
                seq_printf(s, "%u (%s):", selector, gname);
 
        .pin_base       = 0,
 };
 
-static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
+static int pxa3xx_get_groups_count(struct pinctrl_dev *pctrldev)
 {
        struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
-       if (selector >= info->num_grps)
-               return -EINVAL;
-       return 0;
+
+       return info->num_grps;
 }
 
 static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
                                         unsigned selector)
 {
        struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
-       if (selector >= info->num_grps)
-               return NULL;
+
        return info->grps[selector].name;
 }
 
                                 unsigned *num_pins)
 {
        struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
-       if (selector >= info->num_grps)
-               return -EINVAL;
+
        *pins = info->grps[selector].pins;
        *num_pins = info->grps[selector].npins;
        return 0;
 }
 
 static struct pinctrl_ops pxa3xx_pctrl_ops = {
-       .list_groups    = pxa3xx_list_groups,
+       .get_groups_count = pxa3xx_get_groups_count,
        .get_group_name = pxa3xx_get_group_name,
        .get_group_pins = pxa3xx_get_group_pins,
 };
 
-static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
+static int pxa3xx_pmx_get_funcs_count(struct pinctrl_dev *pctrldev)
 {
        struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
-       if (func >= info->num_funcs)
-               return -EINVAL;
-       return 0;
+
+       return info->num_funcs;
 }
 
 static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
 }
 
 static struct pinmux_ops pxa3xx_pmx_ops = {
-       .list_functions         = pxa3xx_pmx_list_func,
+       .get_functions_count    = pxa3xx_pmx_get_funcs_count,
        .get_function_name      = pxa3xx_pmx_get_func_name,
        .get_function_groups    = pxa3xx_pmx_get_groups,
        .enable                 = pxa3xx_pmx_enable,
 
        SIRFSOC_PIN_GROUP("gpsgrp", gps_pins),
 };
 
-static int sirfsoc_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
+static int sirfsoc_get_groups_count(struct pinctrl_dev *pctldev)
 {
-       if (selector >= ARRAY_SIZE(sirfsoc_pin_groups))
-               return -EINVAL;
-       return 0;
+       return ARRAY_SIZE(sirfsoc_pin_groups);
 }
 
 static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev,
                                       unsigned selector)
 {
-       if (selector >= ARRAY_SIZE(sirfsoc_pin_groups))
-               return NULL;
        return sirfsoc_pin_groups[selector].name;
 }
 
                               const unsigned **pins,
                               unsigned *num_pins)
 {
-       if (selector >= ARRAY_SIZE(sirfsoc_pin_groups))
-               return -EINVAL;
        *pins = sirfsoc_pin_groups[selector].pins;
        *num_pins = sirfsoc_pin_groups[selector].num_pins;
        return 0;
 }
 
 static struct pinctrl_ops sirfsoc_pctrl_ops = {
-       .list_groups = sirfsoc_list_groups,
+       .get_groups_count = sirfsoc_get_groups_count,
        .get_group_name = sirfsoc_get_group_name,
        .get_group_pins = sirfsoc_get_group_pins,
        .pin_dbg_show = sirfsoc_pin_dbg_show,
        sirfsoc_pinmux_endisable(spmx, selector, false);
 }
 
-static int sirfsoc_pinmux_list_funcs(struct pinctrl_dev *pmxdev, unsigned selector)
+static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
 {
-       if (selector >= ARRAY_SIZE(sirfsoc_pmx_functions))
-               return -EINVAL;
-       return 0;
+       return ARRAY_SIZE(sirfsoc_pmx_functions);
 }
 
 static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev,
 }
 
 static struct pinmux_ops sirfsoc_pinmux_ops = {
-       .list_functions = sirfsoc_pinmux_list_funcs,
        .enable = sirfsoc_pinmux_enable,
        .disable = sirfsoc_pinmux_disable,
+       .get_functions_count = sirfsoc_pinmux_get_funcs_count,
        .get_function_name = sirfsoc_pinmux_get_func_name,
        .get_function_groups = sirfsoc_pinmux_get_groups,
        .gpio_request_enable = sirfsoc_pinmux_request_gpio,
 
        writel(val, pmx->regs[bank] + reg);
 }
 
-static int tegra_pinctrl_list_groups(struct pinctrl_dev *pctldev,
-                                    unsigned group)
+static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
 {
        struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 
-       if (group >= pmx->soc->ngroups)
-               return -EINVAL;
-
-       return 0;
+       return pmx->soc->ngroups;
 }
 
 static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
 {
        struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 
-       if (group >= pmx->soc->ngroups)
-               return NULL;
-
        return pmx->soc->groups[group].name;
 }
 
 {
        struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 
-       if (group >= pmx->soc->ngroups)
-               return -EINVAL;
-
        *pins = pmx->soc->groups[group].pins;
        *num_pins = pmx->soc->groups[group].npins;
 
 }
 
 static struct pinctrl_ops tegra_pinctrl_ops = {
-       .list_groups = tegra_pinctrl_list_groups,
+       .get_groups_count = tegra_pinctrl_get_groups_count,
        .get_group_name = tegra_pinctrl_get_group_name,
        .get_group_pins = tegra_pinctrl_get_group_pins,
        .pin_dbg_show = tegra_pinctrl_pin_dbg_show,
 };
 
-static int tegra_pinctrl_list_funcs(struct pinctrl_dev *pctldev,
-                                   unsigned function)
+static int tegra_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
 {
        struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 
-       if (function >= pmx->soc->nfunctions)
-               return -EINVAL;
-
-       return 0;
+       return pmx->soc->nfunctions;
 }
 
 static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
 {
        struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 
-       if (function >= pmx->soc->nfunctions)
-               return NULL;
-
        return pmx->soc->functions[function].name;
 }
 
 {
        struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 
-       if (function >= pmx->soc->nfunctions)
-               return -EINVAL;
-
        *groups = pmx->soc->functions[function].groups;
        *num_groups = pmx->soc->functions[function].ngroups;
 
        int i;
        u32 val;
 
-       if (group >= pmx->soc->ngroups)
-               return -EINVAL;
        g = &pmx->soc->groups[group];
 
        if (g->mux_reg < 0)
        const struct tegra_pingroup *g;
        u32 val;
 
-       if (group >= pmx->soc->ngroups)
-               return;
        g = &pmx->soc->groups[group];
 
        if (g->mux_reg < 0)
 }
 
 static struct pinmux_ops tegra_pinmux_ops = {
-       .list_functions = tegra_pinctrl_list_funcs,
+       .get_functions_count = tegra_pinctrl_get_funcs_count,
        .get_function_name = tegra_pinctrl_get_func_name,
        .get_function_groups = tegra_pinctrl_get_func_groups,
        .enable = tegra_pinctrl_enable,
        s16 reg;
        u32 val, mask;
 
-       if (group >= pmx->soc->ngroups)
-               return -EINVAL;
        g = &pmx->soc->groups[group];
 
        ret = tegra_pinconf_reg(pmx, g, param, &bank, ®, &bit, &width);
        s16 reg;
        u32 val, mask;
 
-       if (group >= pmx->soc->ngroups)
-               return -EINVAL;
        g = &pmx->soc->groups[group];
 
        ret = tegra_pinconf_reg(pmx, g, param, &bank, ®, &bit, &width);
 
        },
 };
 
-static int u300_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
+static int u300_get_groups_count(struct pinctrl_dev *pctldev)
 {
-       if (selector >= ARRAY_SIZE(u300_pin_groups))
-               return -EINVAL;
-       return 0;
+       return ARRAY_SIZE(u300_pin_groups);
 }
 
 static const char *u300_get_group_name(struct pinctrl_dev *pctldev,
                                       unsigned selector)
 {
-       if (selector >= ARRAY_SIZE(u300_pin_groups))
-               return NULL;
        return u300_pin_groups[selector].name;
 }
 
                               const unsigned **pins,
                               unsigned *num_pins)
 {
-       if (selector >= ARRAY_SIZE(u300_pin_groups))
-               return -EINVAL;
        *pins = u300_pin_groups[selector].pins;
        *num_pins = u300_pin_groups[selector].num_pins;
        return 0;
 }
 
 static struct pinctrl_ops u300_pctrl_ops = {
-       .list_groups = u300_list_groups,
+       .get_groups_count = u300_get_groups_count,
        .get_group_name = u300_get_group_name,
        .get_group_pins = u300_get_group_pins,
        .pin_dbg_show = u300_pin_dbg_show,
        u300_pmx_endisable(upmx, selector, false);
 }
 
-static int u300_pmx_list_funcs(struct pinctrl_dev *pctldev, unsigned selector)
+static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
 {
-       if (selector >= ARRAY_SIZE(u300_pmx_functions))
-               return -EINVAL;
-       return 0;
+       return ARRAY_SIZE(u300_pmx_functions);
 }
 
 static const char *u300_pmx_get_func_name(struct pinctrl_dev *pctldev,
 }
 
 static struct pinmux_ops u300_pmx_ops = {
-       .list_functions = u300_pmx_list_funcs,
+       .get_functions_count = u300_pmx_get_funcs_count,
        .get_function_name = u300_pmx_get_func_name,
        .get_function_groups = u300_pmx_get_groups,
        .enable = u300_pmx_enable,
 
 int pinmux_check_ops(struct pinctrl_dev *pctldev)
 {
        const struct pinmux_ops *ops = pctldev->desc->pmxops;
+       unsigned nfuncs = ops->get_functions_count(pctldev);
        unsigned selector = 0;
 
        /* Check that we implement required operations */
-       if (!ops->list_functions ||
+       if (!ops->get_functions_count ||
            !ops->get_function_name ||
            !ops->get_function_groups ||
            !ops->enable ||
                return -EINVAL;
 
        /* Check that all functions registered have names */
-       while (ops->list_functions(pctldev, selector) >= 0) {
+       while (selector < nfuncs) {
                const char *fname = ops->get_function_name(pctldev,
                                                           selector);
                if (!fname) {
                                        const char *function)
 {
        const struct pinmux_ops *ops = pctldev->desc->pmxops;
+       unsigned nfuncs = ops->get_functions_count(pctldev);
        unsigned selector = 0;
 
        /* See if this pctldev has this function */
-       while (ops->list_functions(pctldev, selector) >= 0) {
+       while (selector < nfuncs) {
                const char *fname = ops->get_function_name(pctldev,
                                                           selector);
 
 {
        struct pinctrl_dev *pctldev = s->private;
        const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
+       unsigned nfuncs = pmxops->get_functions_count(pctldev);
        unsigned func_selector = 0;
 
        mutex_lock(&pinctrl_mutex);
 
-       while (pmxops->list_functions(pctldev, func_selector) >= 0) {
+       while (func_selector < nfuncs) {
                const char *func = pmxops->get_function_name(pctldev,
                                                          func_selector);
                const char * const *groups;
 
 /**
  * struct pinctrl_ops - global pin control operations, to be implemented by
  * pin controller drivers.
- * @list_groups: list the number of selectable named groups available
- *     in this pinmux driver, the core will begin on 0 and call this
- *     repeatedly as long as it returns >= 0 to enumerate the groups
+ * @get_groups_count: Returns the count of total number of groups registered.
  * @get_group_name: return the group name of the pin group
  * @get_group_pins: return an array of pins corresponding to a certain
  *     group selector @pins, and the size of the array in @num_pins
  *     info for a certain pin in debugfs
  */
 struct pinctrl_ops {
-       int (*list_groups) (struct pinctrl_dev *pctldev, unsigned selector);
+       int (*get_groups_count) (struct pinctrl_dev *pctldev);
        const char *(*get_group_name) (struct pinctrl_dev *pctldev,
                                       unsigned selector);
        int (*get_group_pins) (struct pinctrl_dev *pctldev,
 
  *     is allowed to answer "no" by returning a negative error code
  * @free: the reverse function of the request() callback, frees a pin after
  *     being requested
- * @list_functions: list the number of selectable named functions available
- *     in this pinmux driver, the core will begin on 0 and call this
- *     repeatedly as long as it returns >= 0 to enumerate mux settings
+ * @get_functions_count: returns number of selectable named functions available
+ *     in this pinmux driver
  * @get_function_name: return the function name of the muxing selector,
  *     called by the core to figure out which mux setting it shall map a
  *     certain device to
 struct pinmux_ops {
        int (*request) (struct pinctrl_dev *pctldev, unsigned offset);
        int (*free) (struct pinctrl_dev *pctldev, unsigned offset);
-       int (*list_functions) (struct pinctrl_dev *pctldev, unsigned selector);
+       int (*get_functions_count) (struct pinctrl_dev *pctldev);
        const char *(*get_function_name) (struct pinctrl_dev *pctldev,
                                          unsigned selector);
        int (*get_function_groups) (struct pinctrl_dev *pctldev,