summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2022-05-05 00:15:21 +0300
committerLinus Walleij <linus.walleij@linaro.org>2022-05-05 00:15:21 +0300
commita0912083086d7b6bd7f0f1b4c2ffa6c8283a9f98 (patch)
tree1ba060676d3f7788f054e1681b36a6ec875ce90e
parentc954531bc5d84fc13e035204750c3761c5fc93b0 (diff)
parentedc5601db66411a8c9c6b08b3aacf7e154a34c6d (diff)
downloadlinux-a0912083086d7b6bd7f0f1b4c2ffa6c8283a9f98.tar.xz
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
-rw-r--r--drivers/pinctrl/meson/Kconfig2
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson.c52
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson.h28
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-37xx.c34
-rw-r--r--drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c142
-rw-r--r--drivers/pinctrl/renesas/pinctrl-rza1.c47
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.c8
-rw-r--r--drivers/pinctrl/samsung/pinctrl-s3c24xx.c2
-rw-r--r--drivers/pinctrl/samsung/pinctrl-s3c64xx.c4
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.c30
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.h2
-rw-r--r--drivers/pinctrl/stm32/pinctrl-stm32.c84
-rw-r--r--include/linux/gpio/driver.h28
13 files changed, 210 insertions, 253 deletions
diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig
index d1955c65b4b6..64fb9e074ac6 100644
--- a/drivers/pinctrl/meson/Kconfig
+++ b/drivers/pinctrl/meson/Kconfig
@@ -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
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 49851444a6e3..cc2cd73ff8f9 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -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;
diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h
index ff5372e0a475..b197827027bd 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.h
+++ b/drivers/pinctrl/meson/pinctrl-meson.h
@@ -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 }, \
}, \
}
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
index adccf03b3e5a..a140b6bfbfaa 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -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;
-
- /* 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");
+ unsigned int i, nr_irq_parent;
- 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);
diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
index 9557fac5d11c..3cf0f8a43c37 100644
--- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
@@ -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;
-
- 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;
- }
-
- 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++;
+ struct device *dev = pctrl->dev;
+ struct fwnode_reference_args args;
+ struct fwnode_handle *child;
+ int id = 0;
+
+ for_each_gpiochip_node(dev, child) {
+ struct device_node *np = to_of_node(child);
+
+ 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;
}
diff --git a/drivers/pinctrl/renesas/pinctrl-rza1.c b/drivers/pinctrl/renesas/pinctrl-rza1.c
index c1d6e9512c7a..529c0fc4ec06 100644
--- a/drivers/pinctrl/renesas/pinctrl-rza1.c
+++ b/drivers/pinctrl/renesas/pinctrl-rza1.c
@@ -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;
}
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index c1c4ffbae6e2..6d7ca1758292 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -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);
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
index ac1eba30cf40..625cb1065eaf 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
@@ -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");
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
index c5f95a1071ae..c5d92db4fdb1 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
@@ -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");
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index f610beab23a0..26d309d2516d 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -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;
}
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 5b32d3f30fcd..fc6f5199c548 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -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;
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index b308e7bb7487..aef1cda4934d 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -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;
}
- }
-
- 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;
- }
+ 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++;
+ }
- 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");
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 48d03eb4e5d8..f06236b2a34b 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -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 */