Commit cc4dac3f authored by Linus Walleij's avatar Linus Walleij

Merge tag 'intel-pinctrl-v5.17-2' of...

Merge tag 'intel-pinctrl-v5.17-2' of gitolite.kernel.org:pub/scm/linux/kernel/git/pinctrl/intel into devel

intel-pinctrl for v5.17-2

* Introduce new generic kasprintf_strarray() API
* Clean up and convert existing drivers to use the above

The API will be needed in the future for new comers, including Intel ones.

The following is an automated git shortlog grouped by driver:

armada-37xx:
 -  Switch to use devm_kasprintf_strarray()
 -  Convert to use dev_err_probe()
 -  Make use of the devm_platform_ioremap_resource()
 -  Use temporary variable for struct device
 -  Fix function name in the kernel doc

gpio:
 -  mockup: Switch to use kasprintf_strarray()

lib/string_helpers:
 -  Introduce managed variant of kasprintf_strarray()
 -  Introduce kasprintf_strarray()

pinctrl/rockchip:
 -  Switch to use devm_kasprintf_strarray()
 -  Convert to use dev_err_probe()
 -  Make use of the devm_platform_get_and_ioremap_resource()
 -  Use temporary variable for struct device
 -  Drop wrong kernel doc annotation

st:
 -  Switch to use devm_kasprintf_strarray()
 -  Convert to use dev_err_probe()
 -  Make use of the devm_platform_ioremap_resource_byname()
 -  Use temporary variable for struct device
 -  Drop wrong kernel doc annotations

zynqmp:
 -  Unify pin naming
parents fa55b7dc f7c151d8
......@@ -491,27 +491,6 @@ static void gpio_mockup_unregister_pdevs(void)
}
}
static __init char **gpio_mockup_make_line_names(const char *label,
unsigned int num_lines)
{
unsigned int i;
char **names;
names = kcalloc(num_lines + 1, sizeof(char *), GFP_KERNEL);
if (!names)
return NULL;
for (i = 0; i < num_lines; i++) {
names[i] = kasprintf(GFP_KERNEL, "%s-%u", label, i);
if (!names[i]) {
kfree_strarray(names, i);
return NULL;
}
}
return names;
}
static int __init gpio_mockup_register_chip(int idx)
{
struct property_entry properties[GPIO_MOCKUP_MAX_PROP];
......@@ -538,7 +517,7 @@ static int __init gpio_mockup_register_chip(int idx)
properties[prop++] = PROPERTY_ENTRY_U16("nr-gpios", ngpio);
if (gpio_mockup_named_lines) {
line_names = gpio_mockup_make_line_names(chip_label, ngpio);
line_names = kasprintf_strarray(GFP_KERNEL, chip_label, ngpio);
if (!line_names)
return -ENOMEM;
......
......@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/string_helpers.h>
#include "../pinctrl-utils.h"
......@@ -341,12 +342,12 @@ static int armada_37xx_pmx_set_by_name(struct pinctrl_dev *pctldev,
struct armada_37xx_pin_group *grp)
{
struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct device *dev = info->dev;
unsigned int reg = SELECTION;
unsigned int mask = grp->reg_mask;
int func, val;
dev_dbg(info->dev, "enable function %s group %s\n",
name, grp->name);
dev_dbg(dev, "enable function %s group %s\n", name, grp->name);
func = match_string(grp->funcs, NB_FUNCS, name);
if (func < 0)
......@@ -722,25 +723,22 @@ static unsigned int armada_37xx_irq_startup(struct irq_data *d)
static int armada_37xx_irqchip_register(struct platform_device *pdev,
struct armada_37xx_pinctrl *info)
{
struct device_node *np = info->dev->of_node;
struct gpio_chip *gc = &info->gpio_chip;
struct irq_chip *irqchip = &info->irq_chip;
struct gpio_irq_chip *girq = &gc->irq;
struct device *dev = &pdev->dev;
struct resource res;
struct device_node *np;
int ret = -ENODEV, i, nr_irq_parent;
/* Check if we have at least one gpio-controller child node */
for_each_child_of_node(info->dev->of_node, np) {
for_each_child_of_node(dev->of_node, np) {
if (of_property_read_bool(np, "gpio-controller")) {
ret = 0;
break;
}
}
if (ret) {
dev_err(dev, "no gpio-controller child node\n");
return ret;
}
if (ret)
return dev_err_probe(dev, ret, "no gpio-controller child node\n");
nr_irq_parent = of_irq_count(np);
spin_lock_init(&info->irq_lock);
......@@ -750,12 +748,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
return 0;
}
if (of_address_to_resource(info->dev->of_node, 1, &res)) {
dev_err(dev, "cannot find IO resource\n");
return -ENOENT;
}
info->base = devm_ioremap_resource(info->dev, &res);
info->base = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(info->base))
return PTR_ERR(info->base);
......@@ -774,8 +767,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
* the chained irq with all of them.
*/
girq->num_parents = nr_irq_parent;
girq->parents = devm_kcalloc(&pdev->dev, nr_irq_parent,
sizeof(*girq->parents), GFP_KERNEL);
girq->parents = devm_kcalloc(dev, nr_irq_parent, sizeof(*girq->parents), GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
for (i = 0; i < nr_irq_parent; i++) {
......@@ -794,11 +786,12 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
static int armada_37xx_gpiochip_register(struct platform_device *pdev,
struct armada_37xx_pinctrl *info)
{
struct device *dev = &pdev->dev;
struct device_node *np;
struct gpio_chip *gc;
int ret = -ENODEV;
for_each_child_of_node(info->dev->of_node, np) {
for_each_child_of_node(dev->of_node, np) {
if (of_find_property(np, "gpio-controller", NULL)) {
ret = 0;
break;
......@@ -811,19 +804,16 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
gc = &info->gpio_chip;
gc->ngpio = info->data->nr_pins;
gc->parent = &pdev->dev;
gc->parent = dev;
gc->base = -1;
gc->of_node = np;
gc->label = info->data->name;
ret = armada_37xx_irqchip_register(pdev, info);
if (ret)
return ret;
ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
if (ret)
return ret;
return 0;
return devm_gpiochip_add_data(dev, gc, info);
}
/**
......@@ -874,13 +864,13 @@ static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
{
int n, num = 0, funcsize = info->data->nr_pins;
struct device *dev = info->dev;
for (n = 0; n < info->ngroups; n++) {
struct armada_37xx_pin_group *grp = &info->groups[n];
int i, j, f;
grp->pins = devm_kcalloc(info->dev,
grp->npins + grp->extra_npins,
grp->pins = devm_kcalloc(dev, grp->npins + grp->extra_npins,
sizeof(*grp->pins),
GFP_KERNEL);
if (!grp->pins)
......@@ -898,8 +888,7 @@ static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
ret = armada_37xx_add_function(info->funcs, &funcsize,
grp->funcs[f]);
if (ret == -EOVERFLOW)
dev_err(info->dev,
"More functions than pins(%d)\n",
dev_err(dev, "More functions than pins(%d)\n",
info->data->nr_pins);
if (ret < 0)
continue;
......@@ -913,7 +902,7 @@ static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
}
/**
* armada_37xx_fill_funcs() - complete the funcs array
* armada_37xx_fill_func() - complete the funcs array
* @info: info driver instance
*
* Based on the data available from the armada_37xx_pin_group array
......@@ -925,6 +914,7 @@ static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
static int armada_37xx_fill_func(struct armada_37xx_pinctrl *info)
{
struct armada_37xx_pmx_func *funcs = info->funcs;
struct device *dev = info->dev;
int n;
for (n = 0; n < info->nfuncs; n++) {
......@@ -932,8 +922,7 @@ static int armada_37xx_fill_func(struct armada_37xx_pinctrl *info)
const char **groups;
int g;
funcs[n].groups = devm_kcalloc(info->dev,
funcs[n].ngroups,
funcs[n].groups = devm_kcalloc(dev, funcs[n].ngroups,
sizeof(*(funcs[n].groups)),
GFP_KERNEL);
if (!funcs[n].groups)
......@@ -962,6 +951,8 @@ static int armada_37xx_pinctrl_register(struct platform_device *pdev,
const struct armada_37xx_pin_data *pin_data = info->data;
struct pinctrl_desc *ctrldesc = &info->pctl;
struct pinctrl_pin_desc *pindesc, *pdesc;
struct device *dev = &pdev->dev;
char **pin_names;
int pin, ret;
info->groups = pin_data->groups;
......@@ -973,20 +964,21 @@ static int armada_37xx_pinctrl_register(struct platform_device *pdev,
ctrldesc->pmxops = &armada_37xx_pmx_ops;
ctrldesc->confops = &armada_37xx_pinconf_ops;
pindesc = devm_kcalloc(&pdev->dev,
pin_data->nr_pins, sizeof(*pindesc),
GFP_KERNEL);
pindesc = devm_kcalloc(dev, pin_data->nr_pins, sizeof(*pindesc), GFP_KERNEL);
if (!pindesc)
return -ENOMEM;
ctrldesc->pins = pindesc;
ctrldesc->npins = pin_data->nr_pins;
pin_names = devm_kasprintf_strarray(dev, pin_data->name, pin_data->nr_pins);
if (IS_ERR(pin_names))
return PTR_ERR(pin_names);
pdesc = pindesc;
for (pin = 0; pin < pin_data->nr_pins; pin++) {
pdesc->number = pin;
pdesc->name = kasprintf(GFP_KERNEL, "%s-%d",
pin_data->name, pin);
pdesc->name = pin_names[pin];
pdesc++;
}
......@@ -994,14 +986,10 @@ static int armada_37xx_pinctrl_register(struct platform_device *pdev,
* we allocate functions for number of pins and hope there are
* fewer unique functions than pins available
*/
info->funcs = devm_kcalloc(&pdev->dev,
pin_data->nr_pins,
sizeof(struct armada_37xx_pmx_func),
GFP_KERNEL);
info->funcs = devm_kcalloc(dev, pin_data->nr_pins, sizeof(*info->funcs), GFP_KERNEL);
if (!info->funcs)
return -ENOMEM;
ret = armada_37xx_fill_group(info);
if (ret)
return ret;
......@@ -1010,11 +998,9 @@ static int armada_37xx_pinctrl_register(struct platform_device *pdev,
if (ret)
return ret;
info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info);
if (IS_ERR(info->pctl_dev)) {
dev_err(&pdev->dev, "could not register pinctrl driver\n");
return PTR_ERR(info->pctl_dev);
}
info->pctl_dev = devm_pinctrl_register(dev, ctrldesc, info);
if (IS_ERR(info->pctl_dev))
return dev_err_probe(dev, PTR_ERR(info->pctl_dev), "could not register pinctrl driver\n");
return 0;
}
......@@ -1143,18 +1129,15 @@ static int __init armada_37xx_pinctrl_probe(struct platform_device *pdev)
struct regmap *regmap;
int ret;
info = devm_kzalloc(dev, sizeof(struct armada_37xx_pinctrl),
GFP_KERNEL);
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->dev = dev;
regmap = syscon_node_to_regmap(np);
if (IS_ERR(regmap)) {
dev_err(&pdev->dev, "cannot get regmap\n");
return PTR_ERR(regmap);
}
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "cannot get regmap\n");
info->regmap = regmap;
info->data = of_device_get_match_data(dev);
......
This diff is collapsed.
......@@ -55,7 +55,7 @@
#define ST_GPIO_DIRECTION_OUT 0x2
#define ST_GPIO_DIRECTION_IN 0x4
/**
/*
* Packed style retime configuration.
* There are two registers cfg0 and cfg1 in this style for each bank.
* Each field in this register is 8 bit corresponding to 8 pins in the bank.
......@@ -69,7 +69,7 @@
#define RT_P_CFG1_CLKNOTDATA_FIELD(reg) REG_FIELD(reg, 16, 23)
#define RT_P_CFG1_DOUBLE_EDGE_FIELD(reg) REG_FIELD(reg, 24, 31)
/**
/*
* Dedicated style retime Configuration register
* each register is dedicated per pin.
*/
......@@ -814,26 +814,25 @@ static int st_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
{
struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
const struct st_pctl_group *grp;
struct device *dev = info->dev;
struct pinctrl_map *new_map;
struct device_node *parent;
int map_num, i;
grp = st_pctl_find_group_by_name(info, np->name);
if (!grp) {
dev_err(info->dev, "unable to find group for node %pOFn\n",
np);
dev_err(dev, "unable to find group for node %pOFn\n", np);
return -EINVAL;
}
map_num = grp->npins + 1;
new_map = devm_kcalloc(pctldev->dev,
map_num, sizeof(*new_map), GFP_KERNEL);
new_map = devm_kcalloc(dev, map_num, sizeof(*new_map), GFP_KERNEL);
if (!new_map)
return -ENOMEM;
parent = of_get_parent(np);
if (!parent) {
devm_kfree(pctldev->dev, new_map);
devm_kfree(dev, new_map);
return -EINVAL;
}
......@@ -853,7 +852,7 @@ static int st_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
new_map[i].data.configs.configs = &grp->pin_conf[i].config;
new_map[i].data.configs.num_configs = 1;
}
dev_info(pctldev->dev, "maps: function %s group %s num %d\n",
dev_info(dev, "maps: function %s group %s num %d\n",
(*map)->data.mux.function, grp->name, map_num);
return 0;
......@@ -1173,6 +1172,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
/* bank pad direction val altfunction */
const __be32 *list;
struct property *pp;
struct device *dev = info->dev;
struct st_pinconf *conf;
struct device_node *pins;
int i = 0, npins = 0, nr_props, ret = 0;
......@@ -1197,9 +1197,8 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
grp->npins = npins;
grp->name = np->name;
grp->pins = devm_kcalloc(info->dev, npins, sizeof(u32), GFP_KERNEL);
grp->pin_conf = devm_kcalloc(info->dev,
npins, sizeof(*conf), GFP_KERNEL);
grp->pins = devm_kcalloc(dev, npins, sizeof(*grp->pins), GFP_KERNEL);
grp->pin_conf = devm_kcalloc(dev, npins, sizeof(*grp->pin_conf), GFP_KERNEL);
if (!grp->pins || !grp->pin_conf) {
ret = -ENOMEM;
......@@ -1247,6 +1246,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
static int st_pctl_parse_functions(struct device_node *np,
struct st_pinctrl *info, u32 index, int *grp_index)
{
struct device *dev = info->dev;
struct device_node *child;
struct st_pmx_func *func;
struct st_pctl_group *grp;
......@@ -1255,12 +1255,9 @@ static int st_pctl_parse_functions(struct device_node *np,
func = &info->functions[index];
func->name = np->name;
func->ngroups = of_get_child_count(np);
if (func->ngroups == 0) {
dev_err(info->dev, "No groups defined\n");
return -EINVAL;
}
func->groups = devm_kcalloc(info->dev,
func->ngroups, sizeof(char *), GFP_KERNEL);
if (func->ngroups == 0)
return dev_err_probe(dev, -EINVAL, "No groups defined\n");
func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL);
if (!func->groups)
return -ENOMEM;
......@@ -1275,8 +1272,7 @@ static int st_pctl_parse_functions(struct device_node *np,
return ret;
}
}
dev_info(info->dev, "Function[%d\t name:%s,\tgroups:%d]\n",
index, func->name, func->ngroups);
dev_info(dev, "Function[%d\t name:%s,\tgroups:%d]\n", index, func->name, func->ngroups);
return 0;
}
......@@ -1557,10 +1553,8 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info,
skip_irq:
err = gpiochip_add_data(&bank->gpio_chip, bank);
if (err) {
dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_num);
return err;
}
if (err)
return dev_err_probe(dev, err, "Failed to add gpiochip(%d)!\n", bank_num);
dev_info(dev, "%s bank added.\n", range->name);
return 0;
......@@ -1577,63 +1571,50 @@ static const struct of_device_id st_pctl_of_match[] = {
static int st_pctl_probe_dt(struct platform_device *pdev,
struct pinctrl_desc *pctl_desc, struct st_pinctrl *info)
{
struct device *dev = &pdev->dev;
int ret = 0;
int i = 0, j = 0, k = 0, bank;
struct pinctrl_pin_desc *pdesc;
struct device_node *np = pdev->dev.of_node;
struct device_node *np = dev->of_node;
struct device_node *child;
int grp_index = 0;
int irq = 0;
struct resource *res;
st_pctl_dt_child_count(info, np);
if (!info->nbanks) {
dev_err(&pdev->dev, "you need at least one gpio bank\n");
return -EINVAL;
}
if (!info->nbanks)
return dev_err_probe(dev, -EINVAL, "you need at least one gpio bank\n");
dev_info(&pdev->dev, "nbanks = %d\n", info->nbanks);
dev_info(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
dev_info(&pdev->dev, "ngroups = %d\n", info->ngroups);
dev_info(dev, "nbanks = %d\n", info->nbanks);
dev_info(dev, "nfunctions = %d\n", info->nfunctions);
dev_info(dev, "ngroups = %d\n", info->ngroups);
info->functions = devm_kcalloc(&pdev->dev,
info->nfunctions, sizeof(*info->functions), GFP_KERNEL);
info->functions = devm_kcalloc(dev, info->nfunctions, sizeof(*info->functions), GFP_KERNEL);
info->groups = devm_kcalloc(&pdev->dev,
info->ngroups, sizeof(*info->groups),
GFP_KERNEL);
info->groups = devm_kcalloc(dev, info->ngroups, sizeof(*info->groups), GFP_KERNEL);
info->banks = devm_kcalloc(&pdev->dev,
info->nbanks, sizeof(*info->banks), GFP_KERNEL);
info->banks = devm_kcalloc(dev, info->nbanks, sizeof(*info->banks), GFP_KERNEL);
if (!info->functions || !info->groups || !info->banks)
return -ENOMEM;
info->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
if (IS_ERR(info->regmap)) {
dev_err(info->dev, "No syscfg phandle specified\n");
return PTR_ERR(info->regmap);
}
if (IS_ERR(info->regmap))
return dev_err_probe(dev, PTR_ERR(info->regmap), "No syscfg phandle specified\n");
info->data = of_match_node(st_pctl_of_match, np)->data;
irq = platform_get_irq(pdev, 0);
if (irq > 0) {
res = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "irqmux");
info->irqmux_base = devm_ioremap_resource(&pdev->dev, res);
info->irqmux_base = devm_platform_ioremap_resource_byname(pdev, "irqmux");
if (IS_ERR(info->irqmux_base))
return PTR_ERR(info->irqmux_base);
irq_set_chained_handler_and_data(irq, st_gpio_irqmux_handler,
info);
}
pctl_desc->npins = info->nbanks * ST_GPIO_PINS_PER_BANK;
pdesc = devm_kcalloc(&pdev->dev,
pctl_desc->npins, sizeof(*pdesc), GFP_KERNEL);
pdesc = devm_kcalloc(dev, pctl_desc->npins, sizeof(*pdesc), GFP_KERNEL);
if (!pdesc)
return -ENOMEM;
......@@ -1643,6 +1624,8 @@ static int st_pctl_probe_dt(struct platform_device *pdev,
for_each_child_of_node(np, child) {
if (of_property_read_bool(child, "gpio-controller")) {
const char *bank_name = NULL;
char **pin_names;
ret = st_gpiolib_register_bank(info, bank, child);
if (ret) {
of_node_put(child);
......@@ -1651,10 +1634,16 @@ static int st_pctl_probe_dt(struct platform_device *pdev,
k = info->banks[bank].range.pin_base;
bank_name = info->banks[bank].range.name;
pin_names = devm_kasprintf_strarray(dev, bank_name, ST_GPIO_PINS_PER_BANK);
if (IS_ERR(pin_names)) {
of_node_put(child);
return PTR_ERR(pin_names);
}
for (j = 0; j < ST_GPIO_PINS_PER_BANK; j++, k++) {
pdesc->number = k;
pdesc->name = kasprintf(GFP_KERNEL, "%s[%d]",
bank_name, j);
pdesc->name = pin_names[j];
pdesc++;
}
st_parse_syscfgs(info, bank, child);
......@@ -1663,7 +1652,7 @@ static int st_pctl_probe_dt(struct platform_device *pdev,
ret = st_pctl_parse_functions(child, info,
i++, &grp_index);
if (ret) {
dev_err(&pdev->dev, "No functions found.\n");
dev_err(dev, "No functions found.\n");
of_node_put(child);
return ret;
}
......@@ -1675,24 +1664,25 @@ static int st_pctl_probe_dt(struct platform_device *pdev,
static int st_pctl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct st_pinctrl *info;
struct pinctrl_desc *pctl_desc;
int ret, i;
if (!pdev->dev.of_node) {
dev_err(&pdev->dev, "device node not found.\n");
if (!dev->of_node) {
dev_err(dev, "device node not found.\n");
return -EINVAL;
}
pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
pctl_desc = devm_kzalloc(dev, sizeof(*pctl_desc), GFP_KERNEL);
if (!pctl_desc)
return -ENOMEM;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->dev = &pdev->dev;
info->dev = dev;
platform_set_drvdata(pdev, info);
ret = st_pctl_probe_dt(pdev, pctl_desc, info);
if (ret)
......@@ -1702,13 +1692,11 @@ static int st_pctl_probe(struct platform_device *pdev)
pctl_desc->pctlops = &st_pctlops;
pctl_desc->pmxops = &st_pmxops;
pctl_desc->confops = &st_confops;
pctl_desc->name = dev_name(&pdev->dev);
pctl_desc->name = dev_name(dev);
info->pctl = devm_pinctrl_register(&pdev->dev, pctl_desc, info);
if (IS_ERR(info->pctl)) {
dev_err(&pdev->dev, "Failed pinctrl registration\n");
return PTR_ERR(info->pctl);
}
info->pctl = devm_pinctrl_register(dev, pctl_desc, info);
if (IS_ERR(info->pctl))
return dev_err_probe(dev, PTR_ERR(info->pctl), "Failed pinctrl registration\n");
for (i = 0; i < info->nbanks; i++)
pinctrl_add_gpio_range(info->pctl, &info->banks[i].range);
......
......@@ -809,6 +809,7 @@ static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev,
unsigned int *npins)
{
struct pinctrl_pin_desc *pins, *pin;
char **pin_names;
int ret;
int i;
......@@ -820,13 +821,14 @@ static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev,
if (!pins)
return -ENOMEM;
pin_names = devm_kasprintf_strarray(dev, ZYNQMP_PIN_PREFIX, *npins);
if (IS_ERR(pin_names))
return PTR_ERR(pin_names);
for (i = 0; i < *npins; i++) {
pin = &pins[i];
pin->number = i;
pin->name = devm_kasprintf(dev, GFP_KERNEL, "%s%d",
ZYNQMP_PIN_PREFIX, i);
if (!pin->name)
return -ENOMEM;
pin->name = pin_names[i];
}
*zynqmp_pins = pins;
......
......@@ -7,6 +7,7 @@
#include <linux/string.h>
#include <linux/types.h>
struct device;
struct file;
struct task_struct;
......@@ -100,6 +101,9 @@ char *kstrdup_quotable(const char *src, gfp_t gfp);
char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp);
char *kstrdup_quotable_file(struct file *file, gfp_t gfp);
char **kasprintf_strarray(gfp_t gfp, const char *prefix, size_t n);
void kfree_strarray(char **array, size_t n);
char **devm_kasprintf_strarray(struct device *dev, const char *prefix, size_t n);
#endif
......@@ -10,6 +10,7 @@
#include <linux/math64.h>
#include <linux/export.h>
#include <linux/ctype.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/limits.h>
......@@ -674,6 +675,39 @@ char *kstrdup_quotable_file(struct file *file, gfp_t gfp)
}
EXPORT_SYMBOL_GPL(kstrdup_quotable_file);
/**
* kasprintf_strarray - allocate and fill array of sequential strings
* @gfp: flags for the slab allocator
* @prefix: prefix to be used
* @n: amount of lines to be allocated and filled
*
* Allocates and fills @n strings using pattern "%s-%zu", where prefix
* is provided by caller. The caller is responsible to free them with
* kfree_strarray() after use.
*
* Returns array of strings or NULL when memory can't be allocated.
*/
char **kasprintf_strarray(gfp_t gfp, const char *prefix, size_t n)
{
char **names;
size_t i;
names = kcalloc(n + 1, sizeof(char *), gfp);
if (!names)
return NULL;
for (i = 0; i < n; i++) {
names[i] = kasprintf(gfp, "%s-%zu", prefix, i);
if (!names[i]) {
kfree_strarray(names, i);
return NULL;
}
}
return names;
}
EXPORT_SYMBOL_GPL(kasprintf_strarray);
/**
* kfree_strarray - free a number of dynamically allocated strings contained
* in an array and the array itself
......@@ -697,6 +731,36 @@ void kfree_strarray(char **array, size_t n)
}
EXPORT_SYMBOL_GPL(kfree_strarray);
struct strarray {
char **array;
size_t n;
};
static void devm_kfree_strarray(struct device *dev, void *res)
{
struct strarray *array = res;
kfree_strarray(array->array, array->n);
}
char **devm_kasprintf_strarray(struct device *dev, const char *prefix, size_t n)
{
struct strarray *ptr;
ptr = devres_alloc(devm_kfree_strarray, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
ptr->array = kasprintf_strarray(GFP_KERNEL, prefix, n);
if (!ptr->array) {
devres_free(ptr);
return ERR_PTR(-ENOMEM);
}
return ptr->array;
}
EXPORT_SYMBOL_GPL(devm_kasprintf_strarray);
/**
* strscpy_pad() - Copy a C-string into a sized buffer
* @dest: Where to copy the string to
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment