intel-gpio for v5.19-1

* Introduce helpers to iterate over GPIO chip nodes and covert some drivers
 
 The following is an automated git shortlog grouped by driver:
 
 gpiolib:
  -  Introduce a helper to get first GPIO controller node
  -  Introduce gpiochip_node_count() helper
  -  Introduce for_each_gpiochip_node() loop helper
 
 pinctrl:
  -  meson: Replace custom code by gpiochip_node_count() call
  -  meson: Enable COMPILE_TEST
  -  meson: Rename REG_* to MESON_REG_*
  -  armada-37xx: Reuse GPIO fwnode in armada_37xx_irqchip_register()
  -  armada-37xx: Switch to use fwnode instead of of_node
  -  samsung: Switch to use for_each_gpiochip_node() helper
  -  samsung: Drop redundant node parameter in samsung_banks_of_node_get()
  -  npcm7xx: Switch to use for_each_gpiochip_node() helper
  -  renesas: rza1: Switch to use for_each_gpiochip_node() helper
  -  renesas: rza1: Replace custom code by gpiochip_node_count() call
  -  stm32: Switch to use for_each_gpiochip_node() helper
  -  stm32: Replace custom code by gpiochip_node_count() call
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQSu93Raj3rZDNXzGZv7cr9lmVa5zAUCYmwsmgAKCRD7cr9lmVa5
 zEYPAP4q31AbTJHk6Fs1A79esVSo+DZSkZSzbk/n8Vr3oYG56gD/dVu5EmLNKPHU
 6o5+BvdXqjHrymihHasdyD9YqI30zwM=
 =MIEU
 -----END PGP SIGNATURE-----

Merge tag 'intel-gpio-v5.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel into devel

intel-gpio for v5.19-1

* Introduce helpers to iterate over GPIO chip nodes and covert some drivers

The following is an automated git shortlog grouped by driver:

gpiolib:
 -  Introduce a helper to get first GPIO controller node
 -  Introduce gpiochip_node_count() helper
 -  Introduce for_each_gpiochip_node() loop helper

pinctrl:
 -  meson: Replace custom code by gpiochip_node_count() call
 -  meson: Enable COMPILE_TEST
 -  meson: Rename REG_* to MESON_REG_*
 -  armada-37xx: Reuse GPIO fwnode in armada_37xx_irqchip_register()
 -  armada-37xx: Switch to use fwnode instead of of_node
 -  samsung: Switch to use for_each_gpiochip_node() helper
 -  samsung: Drop redundant node parameter in samsung_banks_of_node_get()
 -  npcm7xx: Switch to use for_each_gpiochip_node() helper
 -  renesas: rza1: Switch to use for_each_gpiochip_node() helper
 -  renesas: rza1: Replace custom code by gpiochip_node_count() call
 -  stm32: Switch to use for_each_gpiochip_node() helper
 -  stm32: Replace custom code by gpiochip_node_count() call
This commit is contained in:
Linus Walleij 2022-05-04 23:15:21 +02:00
commit a091208308
13 changed files with 208 additions and 251 deletions

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig PINCTRL_MESON
tristate "Amlogic SoC pinctrl drivers"
depends on ARCH_MESON
depends on ARCH_MESON || COMPILE_TEST
depends on OF
default y
select PINMUX

View File

@ -49,6 +49,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/seq_file.h>
@ -218,13 +219,13 @@ static int meson_pinconf_set_output(struct meson_pinctrl *pc,
unsigned int pin,
bool out)
{
return meson_pinconf_set_gpio_bit(pc, pin, REG_DIR, !out);
return meson_pinconf_set_gpio_bit(pc, pin, MESON_REG_DIR, !out);
}
static int meson_pinconf_get_output(struct meson_pinctrl *pc,
unsigned int pin)
{
int ret = meson_pinconf_get_gpio_bit(pc, pin, REG_DIR);
int ret = meson_pinconf_get_gpio_bit(pc, pin, MESON_REG_DIR);
if (ret < 0)
return ret;
@ -236,13 +237,13 @@ static int meson_pinconf_set_drive(struct meson_pinctrl *pc,
unsigned int pin,
bool high)
{
return meson_pinconf_set_gpio_bit(pc, pin, REG_OUT, high);
return meson_pinconf_set_gpio_bit(pc, pin, MESON_REG_OUT, high);
}
static int meson_pinconf_get_drive(struct meson_pinctrl *pc,
unsigned int pin)
{
return meson_pinconf_get_gpio_bit(pc, pin, REG_OUT);
return meson_pinconf_get_gpio_bit(pc, pin, MESON_REG_OUT);
}
static int meson_pinconf_set_output_drive(struct meson_pinctrl *pc,
@ -269,7 +270,7 @@ static int meson_pinconf_disable_bias(struct meson_pinctrl *pc,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, &reg, &bit);
ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), 0);
if (ret)
return ret;
@ -288,7 +289,7 @@ static int meson_pinconf_enable_bias(struct meson_pinctrl *pc, unsigned int pin,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, &reg, &bit);
if (pull_up)
val = BIT(bit);
@ -296,7 +297,7 @@ static int meson_pinconf_enable_bias(struct meson_pinctrl *pc, unsigned int pin,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, &reg, &bit);
ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), BIT(bit));
if (ret)
return ret;
@ -321,7 +322,7 @@ static int meson_pinconf_set_drive_strength(struct meson_pinctrl *pc,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, &reg, &bit);
if (drive_strength_ua <= 500) {
ds_val = MESON_PINCONF_DRV_500UA;
@ -407,7 +408,7 @@ static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, &reg, &bit);
ret = regmap_read(pc->reg_pullen, reg, &val);
if (ret)
@ -416,7 +417,7 @@ static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
if (!(val & BIT(bit))) {
conf = PIN_CONFIG_BIAS_DISABLE;
} else {
meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, &reg, &bit);
ret = regmap_read(pc->reg_pull, reg, &val);
if (ret)
@ -447,7 +448,7 @@ static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, &reg, &bit);
ret = regmap_read(pc->reg_ds, reg, &val);
if (ret)
@ -595,7 +596,7 @@ static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
if (ret)
return ret;
meson_calc_reg_and_bit(bank, gpio, REG_IN, &reg, &bit);
meson_calc_reg_and_bit(bank, gpio, MESON_REG_IN, &reg, &bit);
regmap_read(pc->reg_gpio, reg, &val);
return !!(val & BIT(bit));
@ -662,27 +663,22 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config);
}
static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
struct device_node *node)
static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc)
{
struct device_node *np, *gpio_np = NULL;
struct device_node *gpio_np;
unsigned int chips;
for_each_child_of_node(node, np) {
if (!of_find_property(np, "gpio-controller", NULL))
continue;
if (gpio_np) {
dev_err(pc->dev, "multiple gpio nodes\n");
of_node_put(np);
return -EINVAL;
}
gpio_np = np;
}
if (!gpio_np) {
chips = gpiochip_node_count(pc->dev);
if (!chips) {
dev_err(pc->dev, "no gpio node found\n");
return -EINVAL;
}
if (chips > 1) {
dev_err(pc->dev, "multiple gpio nodes\n");
return -EINVAL;
}
gpio_np = to_of_node(gpiochip_node_get_first(pc->dev));
pc->of_node = gpio_np;
pc->reg_mux = meson_map_resource(pc, gpio_np, "mux");
@ -751,7 +747,7 @@ int meson_pinctrl_probe(struct platform_device *pdev)
pc->dev = dev;
pc->data = (struct meson_pinctrl_data *) of_device_get_match_data(dev);
ret = meson_pinctrl_parse_dt(pc, dev->of_node);
ret = meson_pinctrl_parse_dt(pc);
if (ret)
return ret;

View File

@ -63,13 +63,13 @@ struct meson_reg_desc {
* enum meson_reg_type - type of registers encoded in @meson_reg_desc
*/
enum meson_reg_type {
REG_PULLEN,
REG_PULL,
REG_DIR,
REG_OUT,
REG_IN,
REG_DS,
NUM_REG,
MESON_REG_PULLEN,
MESON_REG_PULL,
MESON_REG_DIR,
MESON_REG_OUT,
MESON_REG_IN,
MESON_REG_DS,
MESON_NUM_REG,
};
/**
@ -102,7 +102,7 @@ struct meson_bank {
unsigned int last;
int irq_first;
int irq_last;
struct meson_reg_desc regs[NUM_REG];
struct meson_reg_desc regs[MESON_NUM_REG];
};
struct meson_pinctrl_data {
@ -150,12 +150,12 @@ struct meson_pinctrl {
.irq_first = fi, \
.irq_last = li, \
.regs = { \
[REG_PULLEN] = { per, peb }, \
[REG_PULL] = { pr, pb }, \
[REG_DIR] = { dr, db }, \
[REG_OUT] = { or, ob }, \
[REG_IN] = { ir, ib }, \
[REG_DS] = { dsr, dsb }, \
[MESON_REG_PULLEN] = { per, peb }, \
[MESON_REG_PULL] = { pr, pb }, \
[MESON_REG_DIR] = { dr, db }, \
[MESON_REG_OUT] = { or, ob }, \
[MESON_REG_IN] = { ir, ib }, \
[MESON_REG_DS] = { dsr, dsb }, \
}, \
}

View File

@ -21,6 +21,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/string_helpers.h>
@ -726,23 +727,13 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
struct gpio_chip *gc = &info->gpio_chip;
struct irq_chip *irqchip = &info->irq_chip;
struct gpio_irq_chip *girq = &gc->irq;
struct device_node *np = to_of_node(gc->fwnode);
struct device *dev = &pdev->dev;
struct device_node *np;
int ret = -ENODEV, i, nr_irq_parent;
unsigned int i, nr_irq_parent;
/* Check if we have at least one gpio-controller child node */
for_each_child_of_node(dev->of_node, np) {
if (of_property_read_bool(np, "gpio-controller")) {
ret = 0;
break;
}
}
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);
nr_irq_parent = of_irq_count(np);
if (!nr_irq_parent) {
dev_err(dev, "invalid or no IRQ\n");
return 0;
@ -787,18 +778,13 @@ 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 fwnode_handle *fwnode;
struct gpio_chip *gc;
int ret = -ENODEV;
int ret;
for_each_child_of_node(dev->of_node, np) {
if (of_find_property(np, "gpio-controller", NULL)) {
ret = 0;
break;
}
}
if (ret)
return ret;
fwnode = gpiochip_node_get_first(dev);
if (!fwnode)
return -ENODEV;
info->gpio_chip = armada_37xx_gpiolib_chip;
@ -806,7 +792,7 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
gc->ngpio = info->data->nr_pins;
gc->parent = dev;
gc->base = -1;
gc->of_node = np;
gc->fwnode = fwnode;
gc->label = info->data->name;
ret = armada_37xx_irqchip_register(pdev, info);

View File

@ -17,6 +17,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
/* GCR registers */
@ -1862,88 +1863,69 @@ static int npcm7xx_gpio_of(struct npcm7xx_pinctrl *pctrl)
{
int ret = -ENXIO;
struct resource res;
int id = 0, irq;
struct device_node *np;
struct of_phandle_args pinspec;
struct device *dev = pctrl->dev;
struct fwnode_reference_args args;
struct fwnode_handle *child;
int id = 0;
for_each_available_child_of_node(pctrl->dev->of_node, np)
if (of_find_property(np, "gpio-controller", NULL)) {
ret = of_address_to_resource(np, 0, &res);
if (ret < 0) {
dev_err(pctrl->dev,
"Resource fail for GPIO bank %u\n", id);
return ret;
}
for_each_gpiochip_node(dev, child) {
struct device_node *np = to_of_node(child);
pctrl->gpio_bank[id].base =
ioremap(res.start, resource_size(&res));
irq = irq_of_parse_and_map(np, 0);
if (irq < 0) {
dev_err(pctrl->dev,
"No IRQ for GPIO bank %u\n", id);
ret = irq;
return ret;
}
ret = bgpio_init(&pctrl->gpio_bank[id].gc,
pctrl->dev, 4,
pctrl->gpio_bank[id].base +
NPCM7XX_GP_N_DIN,
pctrl->gpio_bank[id].base +
NPCM7XX_GP_N_DOUT,
NULL,
NULL,
pctrl->gpio_bank[id].base +
NPCM7XX_GP_N_IEM,
BGPIOF_READ_OUTPUT_REG_SET);
if (ret) {
dev_err(pctrl->dev, "bgpio_init() failed\n");
return ret;
}
ret = of_parse_phandle_with_fixed_args(np,
"gpio-ranges", 3,
0, &pinspec);
if (ret < 0) {
dev_err(pctrl->dev,
"gpio-ranges fail for GPIO bank %u\n",
id);
return ret;
}
pctrl->gpio_bank[id].irq = irq;
pctrl->gpio_bank[id].irq_chip = npcmgpio_irqchip;
pctrl->gpio_bank[id].gc.parent = pctrl->dev;
pctrl->gpio_bank[id].irqbase =
id * NPCM7XX_GPIO_PER_BANK;
pctrl->gpio_bank[id].pinctrl_id = pinspec.args[0];
pctrl->gpio_bank[id].gc.base = pinspec.args[1];
pctrl->gpio_bank[id].gc.ngpio = pinspec.args[2];
pctrl->gpio_bank[id].gc.owner = THIS_MODULE;
pctrl->gpio_bank[id].gc.label =
devm_kasprintf(pctrl->dev, GFP_KERNEL, "%pOF",
np);
if (pctrl->gpio_bank[id].gc.label == NULL)
return -ENOMEM;
pctrl->gpio_bank[id].gc.dbg_show = npcmgpio_dbg_show;
pctrl->gpio_bank[id].direction_input =
pctrl->gpio_bank[id].gc.direction_input;
pctrl->gpio_bank[id].gc.direction_input =
npcmgpio_direction_input;
pctrl->gpio_bank[id].direction_output =
pctrl->gpio_bank[id].gc.direction_output;
pctrl->gpio_bank[id].gc.direction_output =
npcmgpio_direction_output;
pctrl->gpio_bank[id].request =
pctrl->gpio_bank[id].gc.request;
pctrl->gpio_bank[id].gc.request = npcmgpio_gpio_request;
pctrl->gpio_bank[id].gc.free = npcmgpio_gpio_free;
pctrl->gpio_bank[id].gc.of_node = np;
id++;
ret = of_address_to_resource(np, 0, &res);
if (ret < 0) {
dev_err(dev, "Resource fail for GPIO bank %u\n", id);
return ret;
}
pctrl->gpio_bank[id].base = ioremap(res.start, resource_size(&res));
ret = bgpio_init(&pctrl->gpio_bank[id].gc, dev, 4,
pctrl->gpio_bank[id].base + NPCM7XX_GP_N_DIN,
pctrl->gpio_bank[id].base + NPCM7XX_GP_N_DOUT,
NULL,
NULL,
pctrl->gpio_bank[id].base + NPCM7XX_GP_N_IEM,
BGPIOF_READ_OUTPUT_REG_SET);
if (ret) {
dev_err(dev, "bgpio_init() failed\n");
return ret;
}
ret = fwnode_property_get_reference_args(child, "gpio-ranges", NULL, 3, 0, &args);
if (ret < 0) {
dev_err(dev, "gpio-ranges fail for GPIO bank %u\n", id);
return ret;
}
ret = irq_of_parse_and_map(np, 0);
if (ret < 0) {
dev_err(dev, "No IRQ for GPIO bank %u\n", id);
return ret;
}
pctrl->gpio_bank[id].irq = ret;
pctrl->gpio_bank[id].irq_chip = npcmgpio_irqchip;
pctrl->gpio_bank[id].irqbase = id * NPCM7XX_GPIO_PER_BANK;
pctrl->gpio_bank[id].pinctrl_id = args.args[0];
pctrl->gpio_bank[id].gc.base = args.args[1];
pctrl->gpio_bank[id].gc.ngpio = args.args[2];
pctrl->gpio_bank[id].gc.owner = THIS_MODULE;
pctrl->gpio_bank[id].gc.parent = dev;
pctrl->gpio_bank[id].gc.fwnode = child;
pctrl->gpio_bank[id].gc.label = devm_kasprintf(dev, GFP_KERNEL, "%pfw", child);
if (pctrl->gpio_bank[id].gc.label == NULL)
return -ENOMEM;
pctrl->gpio_bank[id].gc.dbg_show = npcmgpio_dbg_show;
pctrl->gpio_bank[id].direction_input = pctrl->gpio_bank[id].gc.direction_input;
pctrl->gpio_bank[id].gc.direction_input = npcmgpio_direction_input;
pctrl->gpio_bank[id].direction_output = pctrl->gpio_bank[id].gc.direction_output;
pctrl->gpio_bank[id].gc.direction_output = npcmgpio_direction_output;
pctrl->gpio_bank[id].request = pctrl->gpio_bank[id].gc.request;
pctrl->gpio_bank[id].gc.request = npcmgpio_gpio_request;
pctrl->gpio_bank[id].gc.free = npcmgpio_gpio_free;
id++;
}
pctrl->bank_num = id;
return ret;
}

View File

@ -24,6 +24,7 @@
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/property.h>
#include <linux/slab.h>
#include "../core.h"
@ -1154,21 +1155,6 @@ static const struct pinmux_ops rza1_pinmux_ops = {
* RZ/A1 pin controller driver operations
*/
static unsigned int rza1_count_gpio_chips(struct device_node *np)
{
struct device_node *child;
unsigned int count = 0;
for_each_child_of_node(np, child) {
if (!of_property_read_bool(child, "gpio-controller"))
continue;
count++;
}
return count;
}
/**
* rza1_parse_gpiochip() - parse and register a gpio chip and pin range
*
@ -1176,22 +1162,22 @@ static unsigned int rza1_count_gpio_chips(struct device_node *np)
* defined by gpio device tree binding documentation.
*
* @rza1_pctl: RZ/A1 pin controller device
* @np: of gpio-controller node
* @fwnode: gpio-controller firmware node
* @chip: gpio chip to register to gpiolib
* @range: pin range to register to pinctrl core
*/
static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
struct device_node *np,
struct fwnode_handle *fwnode,
struct gpio_chip *chip,
struct pinctrl_gpio_range *range)
{
const char *list_name = "gpio-ranges";
struct of_phandle_args of_args;
struct fwnode_reference_args args;
unsigned int gpioport;
u32 pinctrl_base;
int ret;
ret = of_parse_phandle_with_fixed_args(np, list_name, 3, 0, &of_args);
ret = fwnode_property_get_reference_args(fwnode, list_name, NULL, 3, 0, &args);
if (ret) {
dev_err(rza1_pctl->dev, "Unable to parse %s list property\n",
list_name);
@ -1202,7 +1188,7 @@ static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
* Find out on which port this gpio-chip maps to by inspecting the
* second argument of the "gpio-ranges" property.
*/
pinctrl_base = of_args.args[1];
pinctrl_base = args.args[1];
gpioport = RZA1_PIN_ID_TO_PORT(pinctrl_base);
if (gpioport >= RZA1_NPORTS) {
dev_err(rza1_pctl->dev,
@ -1212,19 +1198,18 @@ static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
*chip = rza1_gpiochip_template;
chip->base = -1;
chip->label = devm_kasprintf(rza1_pctl->dev, GFP_KERNEL, "%pOFn",
np);
chip->ngpio = args.args[2];
chip->label = devm_kasprintf(rza1_pctl->dev, GFP_KERNEL, "%pfwP", fwnode);
if (!chip->label)
return -ENOMEM;
chip->ngpio = of_args.args[2];
chip->of_node = np;
chip->fwnode = fwnode;
chip->parent = rza1_pctl->dev;
range->id = gpioport;
range->name = chip->label;
range->pin_base = range->base = pinctrl_base;
range->npins = of_args.args[2];
range->npins = args.args[2];
range->gc = chip;
ret = devm_gpiochip_add_data(rza1_pctl->dev, chip,
@ -1247,15 +1232,14 @@ static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
*/
static int rza1_gpio_register(struct rza1_pinctrl *rza1_pctl)
{
struct device_node *np = rza1_pctl->dev->of_node;
struct pinctrl_gpio_range *gpio_ranges;
struct gpio_chip *gpio_chips;
struct device_node *child;
struct fwnode_handle *child;
unsigned int ngpiochips;
unsigned int i;
int ret;
ngpiochips = rza1_count_gpio_chips(np);
ngpiochips = gpiochip_node_count(rza1_pctl->dev);
if (ngpiochips == 0) {
dev_dbg(rza1_pctl->dev, "No gpiochip registered\n");
return 0;
@ -1269,14 +1253,11 @@ static int rza1_gpio_register(struct rza1_pinctrl *rza1_pctl)
return -ENOMEM;
i = 0;
for_each_child_of_node(np, child) {
if (!of_property_read_bool(child, "gpio-controller"))
continue;
for_each_gpiochip_node(rza1_pctl->dev, child) {
ret = rza1_parse_gpiochip(rza1_pctl, child, &gpio_chips[i],
&gpio_ranges[i]);
if (ret) {
of_node_put(child);
fwnode_handle_put(child);
return ret;
}

View File

@ -307,7 +307,7 @@ __init int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
}
bank->irq_chip->chip.name = bank->name;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
bank->nr_pins, &exynos_eint_irqd_ops, bank);
if (!bank->irq_domain) {
dev_err(dev, "gpio irq domain add failed\n");
@ -565,7 +565,7 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
}
bank->irq_chip->chip.name = bank->name;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
bank->nr_pins, &exynos_eint_irqd_ops, bank);
if (!bank->irq_domain) {
dev_err(dev, "wkup irq domain add failed\n");
@ -573,7 +573,7 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
return -ENXIO;
}
if (!of_find_property(bank->of_node, "interrupts", NULL)) {
if (!fwnode_property_present(bank->fwnode, "interrupts")) {
bank->eint_type = EINT_TYPE_WKUP_MUX;
++muxed_banks;
continue;
@ -588,7 +588,7 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
}
for (idx = 0; idx < bank->nr_pins; ++idx) {
irq = irq_of_parse_and_map(bank->of_node, idx);
irq = irq_of_parse_and_map(to_of_node(bank->fwnode), idx);
if (!irq) {
dev_err(dev, "irq number for eint-%s-%d not found\n",
bank->name, idx);

View File

@ -525,7 +525,7 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops
: &s3c24xx_gpg_irq_ops;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
bank->nr_pins, ops, ddata);
if (!bank->irq_domain) {
dev_err(dev, "wkup irq domain add failed\n");

View File

@ -471,7 +471,7 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
mask = bank->eint_mask;
nr_eints = fls(mask);
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
nr_eints, &s3c64xx_gpio_irqd_ops, bank);
if (!bank->irq_domain) {
dev_err(dev, "gpio irq domain add failed\n");
@ -743,7 +743,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
return -ENOMEM;
ddata->bank = bank;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
nr_eints, &s3c64xx_eint0_irqd_ops, ddata);
if (!bank->irq_domain) {
dev_err(dev, "wkup irq domain add failed\n");

View File

@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
@ -966,7 +967,7 @@ static int samsung_gpiolib_register(struct platform_device *pdev,
gc->base = bank->grange.base;
gc->ngpio = bank->nr_pins;
gc->parent = &pdev->dev;
gc->of_node = bank->of_node;
gc->fwnode = bank->fwnode;
gc->label = bank->name;
ret = devm_gpiochip_add_data(&pdev->dev, gc, bank);
@ -1002,27 +1003,25 @@ samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
return &(of_data->ctrl[id]);
}
static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
static void samsung_banks_node_put(struct samsung_pinctrl_drv_data *d)
{
struct samsung_pin_bank *bank;
unsigned int i;
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank)
of_node_put(bank->of_node);
fwnode_handle_put(bank->fwnode);
}
/*
* Iterate over all driver pin banks to find one matching the name of node,
* skipping optional "-gpio" node suffix. When found, assign node to the bank.
*/
static void samsung_banks_of_node_get(struct device *dev,
struct samsung_pinctrl_drv_data *d,
struct device_node *node)
static void samsung_banks_node_get(struct device *dev, struct samsung_pinctrl_drv_data *d)
{
const char *suffix = "-gpio-bank";
struct samsung_pin_bank *bank;
struct device_node *child;
struct fwnode_handle *child;
/* Pin bank names are up to 4 characters */
char node_name[20];
unsigned int i;
@ -1038,17 +1037,17 @@ static void samsung_banks_of_node_get(struct device *dev,
continue;
}
for_each_child_of_node(node, child) {
if (!of_find_property(child, "gpio-controller", NULL))
continue;
if (of_node_name_eq(child, node_name))
for_each_gpiochip_node(dev, child) {
struct device_node *np = to_of_node(child);
if (of_node_name_eq(np, node_name))
break;
else if (of_node_name_eq(child, bank->name))
if (of_node_name_eq(np, bank->name))
break;
}
if (child)
bank->of_node = child;
bank->fwnode = child;
else
dev_warn(dev, "Missing node for bank %s - invalid DTB\n",
bank->name);
@ -1061,7 +1060,6 @@ static const struct samsung_pin_ctrl *
samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
const struct samsung_pin_bank_data *bdata;
const struct samsung_pin_ctrl *ctrl;
struct samsung_pin_bank *bank;
@ -1125,7 +1123,7 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
*/
d->virt_base = virt_base[0];
samsung_banks_of_node_get(&pdev->dev, d, node);
samsung_banks_node_get(&pdev->dev, d);
d->pin_base = pin_base;
pin_base += d->nr_pins;
@ -1186,7 +1184,7 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
err_unregister:
samsung_pinctrl_unregister(pdev, drvdata);
err_put_banks:
samsung_banks_of_node_put(drvdata);
samsung_banks_node_put(drvdata);
return ret;
}

View File

@ -165,7 +165,7 @@ struct samsung_pin_bank {
u32 pin_base;
void *soc_priv;
struct device_node *of_node;
struct fwnode_handle *fwnode;
struct samsung_pinctrl_drv_data *drvdata;
struct irq_domain *irq_domain;
struct gpio_chip gpio_chip;

View File

@ -24,6 +24,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
@ -1190,13 +1191,12 @@ static const struct pinconf_ops stm32_pconf_ops = {
.pin_config_dbg_show = stm32_pconf_dbg_show,
};
static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
struct device_node *np)
static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode_handle *fwnode)
{
struct stm32_gpio_bank *bank = &pctl->banks[pctl->nbanks];
int bank_ioport_nr;
struct pinctrl_gpio_range *range = &bank->range;
struct of_phandle_args args;
struct fwnode_reference_args args;
struct device *dev = pctl->dev;
struct resource res;
int npins = STM32_GPIO_PINS_PER_BANK;
@ -1205,7 +1205,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
if (!IS_ERR(bank->rstc))
reset_control_deassert(bank->rstc);
if (of_address_to_resource(np, 0, &res))
if (of_address_to_resource(to_of_node(fwnode), 0, &res))
return -ENODEV;
bank->base = devm_ioremap_resource(dev, &res);
@ -1220,15 +1220,15 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
bank->gpio_chip = stm32_gpio_template;
of_property_read_string(np, "st,bank-name", &bank->gpio_chip.label);
fwnode_property_read_string(fwnode, "st,bank-name", &bank->gpio_chip.label);
if (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, i, &args)) {
if (!fwnode_property_get_reference_args(fwnode, "gpio-ranges", NULL, 3, i, &args)) {
bank_nr = args.args[1] / STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip.base = args.args[1];
/* get the last defined gpio line (offset + nb of pins) */
npins = args.args[0] + args.args[2];
while (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, ++i, &args))
while (!fwnode_property_get_reference_args(fwnode, "gpio-ranges", NULL, 3, ++i, &args))
npins = max(npins, (int)(args.args[0] + args.args[2]));
} else {
bank_nr = pctl->nbanks;
@ -1243,20 +1243,20 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
&pctl->banks[bank_nr].range);
}
if (of_property_read_u32(np, "st,bank-ioport", &bank_ioport_nr))
if (fwnode_property_read_u32(fwnode, "st,bank-ioport", &bank_ioport_nr))
bank_ioport_nr = bank_nr;
bank->gpio_chip.base = bank_nr * STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip.ngpio = npins;
bank->gpio_chip.of_node = np;
bank->gpio_chip.fwnode = fwnode;
bank->gpio_chip.parent = dev;
bank->bank_nr = bank_nr;
bank->bank_ioport_nr = bank_ioport_nr;
spin_lock_init(&bank->lock);
/* create irq hierarchical domain */
bank->fwnode = of_node_to_fwnode(np);
bank->fwnode = fwnode;
bank->domain = irq_domain_create_hierarchy(pctl->domain, 0,
STM32_GPIO_IRQ_LINE, bank->fwnode,
@ -1399,12 +1399,13 @@ static int stm32_pctrl_create_pins_tab(struct stm32_pinctrl *pctl,
int stm32_pctl_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
struct fwnode_handle *child;
const struct of_device_id *match;
struct device *dev = &pdev->dev;
struct stm32_pinctrl *pctl;
struct pinctrl_pin_desc *pins;
int i, ret, hwlock_id, banks = 0;
int i, ret, hwlock_id;
unsigned int banks;
if (!np)
return -EINVAL;
@ -1494,10 +1495,7 @@ int stm32_pctl_probe(struct platform_device *pdev)
return PTR_ERR(pctl->pctl_dev);
}
for_each_available_child_of_node(np, child)
if (of_property_read_bool(child, "gpio-controller"))
banks++;
banks = gpiochip_node_count(dev);
if (!banks) {
dev_err(dev, "at least one GPIO bank is required\n");
return -EINVAL;
@ -1508,44 +1506,34 @@ int stm32_pctl_probe(struct platform_device *pdev)
return -ENOMEM;
i = 0;
for_each_available_child_of_node(np, child) {
for_each_gpiochip_node(dev, child) {
struct stm32_gpio_bank *bank = &pctl->banks[i];
struct device_node *np = to_of_node(child);
if (of_property_read_bool(child, "gpio-controller")) {
bank->rstc = of_reset_control_get_exclusive(child,
NULL);
if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) {
of_node_put(child);
return -EPROBE_DEFER;
}
bank->clk = of_clk_get_by_name(child, NULL);
if (IS_ERR(bank->clk)) {
if (PTR_ERR(bank->clk) != -EPROBE_DEFER)
dev_err(dev,
"failed to get clk (%ld)\n",
PTR_ERR(bank->clk));
of_node_put(child);
return PTR_ERR(bank->clk);
}
i++;
bank->rstc = of_reset_control_get_exclusive(np, NULL);
if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) {
fwnode_handle_put(child);
return -EPROBE_DEFER;
}
bank->clk = of_clk_get_by_name(np, NULL);
if (IS_ERR(bank->clk)) {
if (PTR_ERR(bank->clk) != -EPROBE_DEFER)
dev_err(dev, "failed to get clk (%ld)\n", PTR_ERR(bank->clk));
fwnode_handle_put(child);
return PTR_ERR(bank->clk);
}
i++;
}
for_each_available_child_of_node(np, child) {
if (of_property_read_bool(child, "gpio-controller")) {
ret = stm32_gpiolib_register_bank(pctl, child);
if (ret) {
of_node_put(child);
for (i = 0; i < pctl->nbanks; i++)
clk_disable_unprepare(pctl->banks[i].clk);
return ret;
}
pctl->nbanks++;
for_each_gpiochip_node(dev, child) {
ret = stm32_gpiolib_register_bank(pctl, child);
if (ret) {
fwnode_handle_put(child);
return ret;
}
pctl->nbanks++;
}
dev_info(dev, "Pinctrl STM32 initialized\n");

View File

@ -3,13 +3,14 @@
#define __LINUX_GPIO_DRIVER_H
#include <linux/device.h>
#include <linux/types.h>
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/lockdep.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/property.h>
#include <linux/types.h>
struct gpio_desc;
struct of_phandle_args;
@ -771,4 +772,29 @@ static inline void gpiochip_unlock_as_irq(struct gpio_chip *gc,
}
#endif /* CONFIG_GPIOLIB */
#define for_each_gpiochip_node(dev, child) \
device_for_each_child_node(dev, child) \
if (!fwnode_property_present(child, "gpio-controller")) {} else
static inline unsigned int gpiochip_node_count(struct device *dev)
{
struct fwnode_handle *child;
unsigned int count = 0;
for_each_gpiochip_node(dev, child)
count++;
return count;
}
static inline struct fwnode_handle *gpiochip_node_get_first(struct device *dev)
{
struct fwnode_handle *fwnode;
for_each_gpiochip_node(dev, fwnode)
return fwnode;
return NULL;
}
#endif /* __LINUX_GPIO_DRIVER_H */