pinctrl: imx: use generic pinmux helpers for managing functions
Now using function_desc structure instead of imx_pmx_func. Also leveraging generic functions to retrieve functions count/name/groups. The imx_free_funcs function can be removed since it is now handled by the core driver during unregister. Signed-off-by: Gary Bisson <gary.bisson@boundarydevices.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:

committed by
Linus Walleij

parent
e566fc11ea
commit
3fd6d6ad73
@@ -1,7 +1,7 @@
|
|||||||
config PINCTRL_IMX
|
config PINCTRL_IMX
|
||||||
bool
|
bool
|
||||||
select GENERIC_PINCTRL_GROUPS
|
select GENERIC_PINCTRL_GROUPS
|
||||||
select PINMUX
|
select GENERIC_PINMUX_FUNCTIONS
|
||||||
select PINCONF
|
select PINCONF
|
||||||
select REGMAP
|
select REGMAP
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
|
|
||||||
#include "../core.h"
|
#include "../core.h"
|
||||||
|
#include "../pinmux.h"
|
||||||
#include "pinctrl-imx.h"
|
#include "pinctrl-imx.h"
|
||||||
|
|
||||||
/* The bits in CONFIG cell defined in binding doc*/
|
/* The bits in CONFIG cell defined in binding doc*/
|
||||||
@@ -161,7 +162,7 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
|
|||||||
unsigned int npins, pin_id;
|
unsigned int npins, pin_id;
|
||||||
int i;
|
int i;
|
||||||
struct group_desc *grp = NULL;
|
struct group_desc *grp = NULL;
|
||||||
struct imx_pmx_func *func = NULL;
|
struct function_desc *func = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure the mux mode for each pin in the group for a specific
|
* Configure the mux mode for each pin in the group for a specific
|
||||||
@@ -171,7 +172,7 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
|
|||||||
if (!grp)
|
if (!grp)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
func = radix_tree_lookup(&info->ftree, selector);
|
func = pinmux_generic_get_function(pctldev, selector);
|
||||||
if (!func)
|
if (!func)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@@ -251,46 +252,6 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int imx_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
|
|
||||||
{
|
|
||||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
|
||||||
struct imx_pinctrl_soc_info *info = ipctl->info;
|
|
||||||
|
|
||||||
return info->nfunctions;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *imx_pmx_get_func_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_pmx_func *func = NULL;
|
|
||||||
|
|
||||||
func = radix_tree_lookup(&info->ftree, selector);
|
|
||||||
if (!func)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return func->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
|
|
||||||
const char * const **groups,
|
|
||||||
unsigned * const num_groups)
|
|
||||||
{
|
|
||||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
|
||||||
struct imx_pinctrl_soc_info *info = ipctl->info;
|
|
||||||
struct imx_pmx_func *func = NULL;
|
|
||||||
|
|
||||||
func = radix_tree_lookup(&info->ftree, selector);
|
|
||||||
if (!func)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
*groups = func->groups;
|
|
||||||
*num_groups = func->num_groups;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int imx_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
|
static int imx_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||||
struct pinctrl_gpio_range *range, unsigned offset)
|
struct pinctrl_gpio_range *range, unsigned offset)
|
||||||
{
|
{
|
||||||
@@ -389,9 +350,9 @@ static int imx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct pinmux_ops imx_pmx_ops = {
|
static const struct pinmux_ops imx_pmx_ops = {
|
||||||
.get_functions_count = imx_pmx_get_funcs_count,
|
.get_functions_count = pinmux_generic_get_function_count,
|
||||||
.get_function_name = imx_pmx_get_func_name,
|
.get_function_name = pinmux_generic_get_function_name,
|
||||||
.get_function_groups = imx_pmx_get_groups,
|
.get_function_groups = pinmux_generic_get_function_groups,
|
||||||
.set_mux = imx_pmx_set,
|
.set_mux = imx_pmx_set,
|
||||||
.gpio_request_enable = imx_pmx_gpio_request_enable,
|
.gpio_request_enable = imx_pmx_gpio_request_enable,
|
||||||
.gpio_disable_free = imx_pmx_gpio_disable_free,
|
.gpio_disable_free = imx_pmx_gpio_disable_free,
|
||||||
@@ -603,28 +564,29 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
|
|||||||
struct pinctrl_dev *pctl = ipctl->pctl;
|
struct pinctrl_dev *pctl = ipctl->pctl;
|
||||||
struct imx_pinctrl_soc_info *info = ipctl->info;
|
struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||||
struct device_node *child;
|
struct device_node *child;
|
||||||
struct imx_pmx_func *func;
|
struct function_desc *func;
|
||||||
struct group_desc *grp;
|
struct group_desc *grp;
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
|
|
||||||
dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
|
dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
|
||||||
|
|
||||||
func = radix_tree_lookup(&info->ftree, index);
|
func = pinmux_generic_get_function(pctl, index);
|
||||||
if (!func)
|
if (!func)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Initialise function */
|
/* Initialise function */
|
||||||
func->name = np->name;
|
func->name = np->name;
|
||||||
func->num_groups = of_get_child_count(np);
|
func->num_group_names = of_get_child_count(np);
|
||||||
if (func->num_groups == 0) {
|
if (func->num_group_names == 0) {
|
||||||
dev_err(info->dev, "no groups defined in %s\n", np->full_name);
|
dev_err(info->dev, "no groups defined in %s\n", np->full_name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
func->groups = devm_kzalloc(info->dev,
|
func->group_names = devm_kzalloc(info->dev,
|
||||||
func->num_groups * sizeof(char *), GFP_KERNEL);
|
func->num_group_names *
|
||||||
|
sizeof(char *), GFP_KERNEL);
|
||||||
|
|
||||||
for_each_child_of_node(np, child) {
|
for_each_child_of_node(np, child) {
|
||||||
func->groups[i] = child->name;
|
func->group_names[i] = child->name;
|
||||||
|
|
||||||
grp = devm_kzalloc(info->dev, sizeof(struct group_desc),
|
grp = devm_kzalloc(info->dev, sizeof(struct group_desc),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@@ -691,7 +653,7 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < nfuncs; i++) {
|
for (i = 0; i < nfuncs; i++) {
|
||||||
struct imx_pmx_func *function;
|
struct function_desc *function;
|
||||||
|
|
||||||
function = devm_kzalloc(&pdev->dev, sizeof(*function),
|
function = devm_kzalloc(&pdev->dev, sizeof(*function),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@@ -699,10 +661,10 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
mutex_lock(&info->mutex);
|
mutex_lock(&info->mutex);
|
||||||
radix_tree_insert(&info->ftree, i, function);
|
radix_tree_insert(&pctl->pin_function_tree, i, function);
|
||||||
mutex_unlock(&info->mutex);
|
mutex_unlock(&info->mutex);
|
||||||
}
|
}
|
||||||
info->nfunctions = nfuncs;
|
pctl->num_functions = nfuncs;
|
||||||
|
|
||||||
info->group_index = 0;
|
info->group_index = 0;
|
||||||
if (flat_funcs) {
|
if (flat_funcs) {
|
||||||
@@ -724,26 +686,6 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* imx_free_funcs() - free memory used by functions
|
|
||||||
* @info: info driver instance
|
|
||||||
*/
|
|
||||||
static void imx_free_funcs(struct imx_pinctrl_soc_info *info)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
mutex_lock(&info->mutex);
|
|
||||||
for (i = 0; i < info->nfunctions; i++) {
|
|
||||||
struct imx_pmx_func *func;
|
|
||||||
|
|
||||||
func = radix_tree_lookup(&info->ftree, i);
|
|
||||||
if (!func)
|
|
||||||
continue;
|
|
||||||
radix_tree_delete(&info->ftree, i);
|
|
||||||
}
|
|
||||||
mutex_unlock(&info->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* imx_free_resources() - free memory used by this driver
|
* imx_free_resources() - free memory used by this driver
|
||||||
* @info: info driver instance
|
* @info: info driver instance
|
||||||
@@ -752,8 +694,6 @@ static void imx_free_resources(struct imx_pinctrl *ipctl)
|
|||||||
{
|
{
|
||||||
if (ipctl->pctl)
|
if (ipctl->pctl)
|
||||||
pinctrl_unregister(ipctl->pctl);
|
pinctrl_unregister(ipctl->pctl);
|
||||||
|
|
||||||
imx_free_funcs(ipctl->info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int imx_pinctrl_probe(struct platform_device *pdev,
|
int imx_pinctrl_probe(struct platform_device *pdev,
|
||||||
@@ -831,8 +771,6 @@ int imx_pinctrl_probe(struct platform_device *pdev,
|
|||||||
|
|
||||||
mutex_init(&info->mutex);
|
mutex_init(&info->mutex);
|
||||||
|
|
||||||
INIT_RADIX_TREE(&info->ftree, GFP_KERNEL);
|
|
||||||
|
|
||||||
ipctl->info = info;
|
ipctl->info = info;
|
||||||
ipctl->dev = info->dev;
|
ipctl->dev = info->dev;
|
||||||
platform_set_drvdata(pdev, ipctl);
|
platform_set_drvdata(pdev, ipctl);
|
||||||
|
@@ -34,18 +34,6 @@ struct imx_pin {
|
|||||||
unsigned long config;
|
unsigned long config;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct imx_pmx_func - describes IMX pinmux functions
|
|
||||||
* @name: the name of this specific function
|
|
||||||
* @groups: corresponding pin groups
|
|
||||||
* @num_groups: the number of groups
|
|
||||||
*/
|
|
||||||
struct imx_pmx_func {
|
|
||||||
const char *name;
|
|
||||||
const char **groups;
|
|
||||||
unsigned num_groups;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct imx_pin_reg - describe a pin reg map
|
* struct imx_pin_reg - describe a pin reg map
|
||||||
* @mux_reg: mux register offset
|
* @mux_reg: mux register offset
|
||||||
@@ -62,10 +50,8 @@ struct imx_pinctrl_soc_info {
|
|||||||
unsigned int npins;
|
unsigned int npins;
|
||||||
struct imx_pin_reg *pin_regs;
|
struct imx_pin_reg *pin_regs;
|
||||||
unsigned int group_index;
|
unsigned int group_index;
|
||||||
unsigned int nfunctions;
|
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
const char *gpr_compatible;
|
const char *gpr_compatible;
|
||||||
struct radix_tree_root ftree;
|
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user