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:
commit
a091208308
@ -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
|
||||
|
@ -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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, gpio, MESON_REG_IN, ®, &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;
|
||||
|
||||
|
@ -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 }, \
|
||||
}, \
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user