forked from Minki/linux
pinctrl: single: Use generic pinctrl helpers for managing groups
We can now drop the driver specific code for managing groups. Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
a76edc89b1
commit
caeb774ea3
@ -166,8 +166,8 @@ config PINCTRL_ROCKCHIP
|
||||
config PINCTRL_SINGLE
|
||||
tristate "One-register-per-pin type device tree based pinctrl driver"
|
||||
depends on OF
|
||||
select GENERIC_PINCTRL_GROUPS
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select GENERIC_PINCONF
|
||||
help
|
||||
This selects the device tree based generic pinctrl driver.
|
||||
|
@ -37,22 +37,6 @@
|
||||
#define DRIVER_NAME "pinctrl-single"
|
||||
#define PCS_OFF_DISABLED ~0U
|
||||
|
||||
/**
|
||||
* struct pcs_pingroup - pingroups for a function
|
||||
* @np: pingroup device node pointer
|
||||
* @name: pingroup name
|
||||
* @gpins: array of the pins in the group
|
||||
* @ngpins: number of pins in the group
|
||||
* @node: list node
|
||||
*/
|
||||
struct pcs_pingroup {
|
||||
struct device_node *np;
|
||||
const char *name;
|
||||
int *gpins;
|
||||
int ngpins;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pcs_func_vals - mux function register offset and value pair
|
||||
* @reg: register virtual address
|
||||
@ -176,15 +160,12 @@ struct pcs_soc_data {
|
||||
* @bits_per_mux: number of bits per mux
|
||||
* @bits_per_pin: number of bits per pin
|
||||
* @pins: physical pins on the SoC
|
||||
* @pgtree: pingroup index radix tree
|
||||
* @ftree: function index radix tree
|
||||
* @pingroups: list of pingroups
|
||||
* @functions: list of functions
|
||||
* @gpiofuncs: list of gpio functions
|
||||
* @irqs: list of interrupt registers
|
||||
* @chip: chip container for this instance
|
||||
* @domain: IRQ domain for this instance
|
||||
* @ngroups: number of pingroups
|
||||
* @nfuncs: number of functions
|
||||
* @desc: pin controller descriptor
|
||||
* @read: register read function to use
|
||||
@ -213,15 +194,12 @@ struct pcs_device {
|
||||
bool bits_per_mux;
|
||||
unsigned bits_per_pin;
|
||||
struct pcs_data pins;
|
||||
struct radix_tree_root pgtree;
|
||||
struct radix_tree_root ftree;
|
||||
struct list_head pingroups;
|
||||
struct list_head functions;
|
||||
struct list_head gpiofuncs;
|
||||
struct list_head irqs;
|
||||
struct irq_chip chip;
|
||||
struct irq_domain *domain;
|
||||
unsigned ngroups;
|
||||
unsigned nfuncs;
|
||||
struct pinctrl_desc desc;
|
||||
unsigned (*read)(void __iomem *reg);
|
||||
@ -288,54 +266,6 @@ static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg)
|
||||
writel(val, reg);
|
||||
}
|
||||
|
||||
static int pcs_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct pcs_device *pcs;
|
||||
|
||||
pcs = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pcs->ngroups;
|
||||
}
|
||||
|
||||
static const char *pcs_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned gselector)
|
||||
{
|
||||
struct pcs_device *pcs;
|
||||
struct pcs_pingroup *group;
|
||||
|
||||
pcs = pinctrl_dev_get_drvdata(pctldev);
|
||||
group = radix_tree_lookup(&pcs->pgtree, gselector);
|
||||
if (!group) {
|
||||
dev_err(pcs->dev, "%s could not find pingroup%i\n",
|
||||
__func__, gselector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return group->name;
|
||||
}
|
||||
|
||||
static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
|
||||
unsigned gselector,
|
||||
const unsigned **pins,
|
||||
unsigned *npins)
|
||||
{
|
||||
struct pcs_device *pcs;
|
||||
struct pcs_pingroup *group;
|
||||
|
||||
pcs = pinctrl_dev_get_drvdata(pctldev);
|
||||
group = radix_tree_lookup(&pcs->pgtree, gselector);
|
||||
if (!group) {
|
||||
dev_err(pcs->dev, "%s could not find pingroup%i\n",
|
||||
__func__, gselector);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*pins = group->gpins;
|
||||
*npins = group->ngpins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
|
||||
struct seq_file *s,
|
||||
unsigned pin)
|
||||
@ -369,9 +299,9 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map **map, unsigned *num_maps);
|
||||
|
||||
static const struct pinctrl_ops pcs_pinctrl_ops = {
|
||||
.get_groups_count = pcs_get_groups_count,
|
||||
.get_group_name = pcs_get_group_name,
|
||||
.get_group_pins = pcs_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 = pcs_pin_dbg_show,
|
||||
.dt_node_to_map = pcs_dt_node_to_map,
|
||||
.dt_free_map = pcs_dt_free_map,
|
||||
@ -685,7 +615,7 @@ static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
|
||||
unsigned npins, old = 0;
|
||||
int i, ret;
|
||||
|
||||
ret = pcs_get_group_pins(pctldev, group, &pins, &npins);
|
||||
ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (i = 0; i < npins; i++) {
|
||||
@ -707,7 +637,7 @@ static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
|
||||
unsigned npins;
|
||||
int i, ret;
|
||||
|
||||
ret = pcs_get_group_pins(pctldev, group, &pins, &npins);
|
||||
ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (i = 0; i < npins; i++) {
|
||||
@ -896,40 +826,6 @@ static void pcs_remove_function(struct pcs_device *pcs,
|
||||
mutex_unlock(&pcs->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* pcs_add_pingroup() - add a pingroup to the pingroup list
|
||||
* @pcs: pcs driver instance
|
||||
* @np: device node of the mux entry
|
||||
* @name: name of the pingroup
|
||||
* @gpins: array of the pins that belong to the group
|
||||
* @ngpins: number of pins in the group
|
||||
*/
|
||||
static int pcs_add_pingroup(struct pcs_device *pcs,
|
||||
struct device_node *np,
|
||||
const char *name,
|
||||
int *gpins,
|
||||
int ngpins)
|
||||
{
|
||||
struct pcs_pingroup *pingroup;
|
||||
|
||||
pingroup = devm_kzalloc(pcs->dev, sizeof(*pingroup), GFP_KERNEL);
|
||||
if (!pingroup)
|
||||
return -ENOMEM;
|
||||
|
||||
pingroup->name = name;
|
||||
pingroup->np = np;
|
||||
pingroup->gpins = gpins;
|
||||
pingroup->ngpins = ngpins;
|
||||
|
||||
mutex_lock(&pcs->mutex);
|
||||
list_add_tail(&pingroup->node, &pcs->pingroups);
|
||||
radix_tree_insert(&pcs->pgtree, pcs->ngroups, pingroup);
|
||||
pcs->ngroups++;
|
||||
mutex_unlock(&pcs->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pcs_get_pin_by_offset() - get a pin index based on the register offset
|
||||
* @pcs: pcs driver instance
|
||||
@ -1100,10 +996,9 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcs_free_pingroups(struct pcs_device *pcs);
|
||||
|
||||
/**
|
||||
* smux_parse_one_pinctrl_entry() - parses a device tree mux entry
|
||||
* @pctldev: pin controller device
|
||||
* @pcs: pinctrl driver instance
|
||||
* @np: device node of the mux entry
|
||||
* @map: map entry
|
||||
@ -1186,7 +1081,7 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
|
||||
goto free_pins;
|
||||
}
|
||||
|
||||
res = pcs_add_pingroup(pcs, np, np->name, pins, found);
|
||||
res = pinctrl_generic_add_group(pcs->pctl, np->name, pins, found, pcs);
|
||||
if (res < 0)
|
||||
goto free_function;
|
||||
|
||||
@ -1205,7 +1100,7 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
|
||||
return 0;
|
||||
|
||||
free_pingroups:
|
||||
pcs_free_pingroups(pcs);
|
||||
pinctrl_generic_remove_last_group(pcs->pctl);
|
||||
*num_maps = 1;
|
||||
free_function:
|
||||
pcs_remove_function(pcs, function);
|
||||
@ -1320,7 +1215,7 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
|
||||
goto free_pins;
|
||||
}
|
||||
|
||||
res = pcs_add_pingroup(pcs, np, np->name, pins, found);
|
||||
res = pinctrl_generic_add_group(pcs->pctl, np->name, pins, found, pcs);
|
||||
if (res < 0)
|
||||
goto free_function;
|
||||
|
||||
@ -1337,7 +1232,7 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
|
||||
return 0;
|
||||
|
||||
free_pingroups:
|
||||
pcs_free_pingroups(pcs);
|
||||
pinctrl_generic_remove_last_group(pcs->pctl);
|
||||
*num_maps = 1;
|
||||
free_function:
|
||||
pcs_remove_function(pcs, function);
|
||||
@ -1435,33 +1330,6 @@ static void pcs_free_funcs(struct pcs_device *pcs)
|
||||
mutex_unlock(&pcs->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* pcs_free_pingroups() - free memory used by pingroups
|
||||
* @pcs: pcs driver instance
|
||||
*/
|
||||
static void pcs_free_pingroups(struct pcs_device *pcs)
|
||||
{
|
||||
struct list_head *pos, *tmp;
|
||||
int i;
|
||||
|
||||
mutex_lock(&pcs->mutex);
|
||||
for (i = 0; i < pcs->ngroups; i++) {
|
||||
struct pcs_pingroup *pingroup;
|
||||
|
||||
pingroup = radix_tree_lookup(&pcs->pgtree, i);
|
||||
if (!pingroup)
|
||||
continue;
|
||||
radix_tree_delete(&pcs->pgtree, i);
|
||||
}
|
||||
list_for_each_safe(pos, tmp, &pcs->pingroups) {
|
||||
struct pcs_pingroup *pingroup;
|
||||
|
||||
pingroup = list_entry(pos, struct pcs_pingroup, node);
|
||||
list_del(&pingroup->node);
|
||||
}
|
||||
mutex_unlock(&pcs->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* pcs_irq_free() - free interrupt
|
||||
* @pcs: pcs driver instance
|
||||
@ -1491,7 +1359,7 @@ static void pcs_free_resources(struct pcs_device *pcs)
|
||||
pcs_irq_free(pcs);
|
||||
pinctrl_unregister(pcs->pctl);
|
||||
pcs_free_funcs(pcs);
|
||||
pcs_free_pingroups(pcs);
|
||||
|
||||
#if IS_BUILTIN(CONFIG_PINCTRL_SINGLE)
|
||||
if (pcs->missing_nr_pinctrl_cells)
|
||||
of_remove_property(pcs->np, pcs->missing_nr_pinctrl_cells);
|
||||
@ -1885,7 +1753,6 @@ static int pcs_probe(struct platform_device *pdev)
|
||||
pcs->np = np;
|
||||
raw_spin_lock_init(&pcs->lock);
|
||||
mutex_init(&pcs->mutex);
|
||||
INIT_LIST_HEAD(&pcs->pingroups);
|
||||
INIT_LIST_HEAD(&pcs->functions);
|
||||
INIT_LIST_HEAD(&pcs->gpiofuncs);
|
||||
soc = match->data;
|
||||
@ -1947,7 +1814,6 @@ static int pcs_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
INIT_RADIX_TREE(&pcs->pgtree, GFP_KERNEL);
|
||||
INIT_RADIX_TREE(&pcs->ftree, GFP_KERNEL);
|
||||
platform_set_drvdata(pdev, pcs);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user