Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'gpio-updates-for-v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio updates from Bartosz Golaszewski:
"Relatively few updates for this release cycle. We have a single new
driver and some minor changes in drivers, more work on limiting the
usage of of_node in drivers and DT updates:

- new driver: gpio-en7523

- dt-bindings: convertion of faraday,ftgpio010 to YAML, new
compatible string in gpio-vf610 and a bugfix in an example

- gpiolib core: several improvements and some code shrink

- documentation: convert all public docs into kerneldoc format

- set IRQ bus token in gpio-crystalcove (addresses a debugfs issue)

- add a missing return value check for kstrdup() in gpio-merrifield

- allow gpio-tps68470 to be built as module

- more work on limiting usage of of_node in GPIO drivers

- several sysfs interface improvements

- use SDPX in gpio-ts4900"

* tag 'gpio-updates-for-v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
gpio: ts4900: Use SPDX header
gpiolib: Use list_first_entry()/list_last_entry()
gpiolib: sysfs: Simplify edge handling in the code
gpiolib: sysfs: Move kstrtox() calls outside of the mutex lock
gpiolib: sysfs: Move sysfs_emit() calls outside of the mutex lock
gpiolib: make struct comments into real kernel docs
dt-bindings: gpio: convert faraday,ftgpio01 to yaml
dt-bindings: gpio: gpio-vf610: Add imx93 compatible string
gpiolib: Simplify error path in gpiod_get_index() when requesting GPIO
gpiolib: Use short form of ternary operator in gpiod_get_index()
gpiolib: Introduce for_each_gpio_desc_with_flag() macro
gpio: Add support for Airoha EN7523 GPIO controller
dt-bindings: arm: airoha: Add binding for Airoha GPIO controller
dt-bindings: gpio: fix gpio-hog example
gpio: tps68470: Allow building as module
gpio: tegra: Get rid of duplicate of_node assignment
gpio: altera-a10sr: Switch to use fwnode instead of of_node
gpio: merrifield: check the return value of devm_kstrdup()
gpio: crystalcove: Set IRQ domain bus token to DOMAIN_BUS_WIRED

+422 -154
+66
Documentation/devicetree/bindings/gpio/airoha,en7523-gpio.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/gpio/airoha,en7523-gpio.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Airoha EN7523 GPIO controller 8 + 9 + maintainers: 10 + - John Crispin <john@phrozen.org> 11 + 12 + description: | 13 + Airoha's GPIO controller on their ARM EN7523 SoCs consists of two banks of 32 14 + GPIOs. 15 + 16 + properties: 17 + $nodename: 18 + pattern: "^gpio@[0-9a-f]+$" 19 + 20 + compatible: 21 + items: 22 + - const: airoha,en7523-gpio 23 + 24 + reg: 25 + description: | 26 + The first tuple points to the input register. 27 + The second and third tuple point to the direction registers 28 + The fourth tuple points to the output register 29 + maxItems: 4 30 + 31 + "#gpio-cells": 32 + const: 2 33 + 34 + gpio-controller: true 35 + 36 + required: 37 + - compatible 38 + - reg 39 + - "#gpio-cells" 40 + - gpio-controller 41 + 42 + additionalProperties: false 43 + 44 + examples: 45 + - | 46 + gpio0: gpio@1fbf0200 { 47 + compatible = "airoha,en7523-gpio"; 48 + reg = <0x1fbf0204 0x4>, 49 + <0x1fbf0200 0x4>, 50 + <0x1fbf0220 0x4>, 51 + <0x1fbf0214 0x4>; 52 + gpio-controller; 53 + #gpio-cells = <2>; 54 + }; 55 + 56 + gpio1: gpio@1fbf0270 { 57 + compatible = "airoha,en7523-gpio"; 58 + reg = <0x1fbf0270 0x4>, 59 + <0x1fbf0260 0x4>, 60 + <0x1fbf0264 0x4>, 61 + <0x1fbf0278 0x4>; 62 + gpio-controller; 63 + #gpio-cells = <2>; 64 + }; 65 + 66 + ...
-27
Documentation/devicetree/bindings/gpio/faraday,ftgpio010.txt
··· 1 - Faraday Technology FTGPIO010 GPIO Controller 2 - 3 - Required properties: 4 - 5 - - compatible : Should be one of 6 - "cortina,gemini-gpio", "faraday,ftgpio010" 7 - "moxa,moxart-gpio", "faraday,ftgpio010" 8 - "faraday,ftgpio010" 9 - - reg : Should contain registers location and length 10 - - interrupts : Should contain the interrupt line for the GPIO block 11 - - gpio-controller : marks this as a GPIO controller 12 - - #gpio-cells : Should be 2, see gpio/gpio.txt 13 - - interrupt-controller : marks this as an interrupt controller 14 - - #interrupt-cells : a standard two-cell interrupt flag, see 15 - interrupt-controller/interrupts.txt 16 - 17 - Example: 18 - 19 - gpio@4d000000 { 20 - compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; 21 - reg = <0x4d000000 0x100>; 22 - interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; 23 - gpio-controller; 24 - #gpio-cells = <2>; 25 - interrupt-controller; 26 - #interrupt-cells = <2>; 27 - };
+65
Documentation/devicetree/bindings/gpio/faraday,ftgpio010.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/gpio/faraday,ftgpio010.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Faraday Technology FTGPIO010 GPIO Controller 8 + 9 + maintainers: 10 + - Linus Walleij <linus.walleij@linaro.org> 11 + 12 + properties: 13 + compatible: 14 + oneOf: 15 + - items: 16 + - const: cortina,gemini-gpio 17 + - const: faraday,ftgpio010 18 + - items: 19 + - const: moxa,moxart-gpio 20 + - const: faraday,ftgpio010 21 + - const: faraday,ftgpio010 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + resets: 27 + maxItems: 1 28 + 29 + clocks: 30 + maxItems: 1 31 + 32 + interrupts: 33 + maxItems: 1 34 + description: Should contain the interrupt line for the GPIO block 35 + 36 + gpio-controller: true 37 + "#gpio-cells": 38 + const: 2 39 + 40 + interrupt-controller: true 41 + "#interrupt-cells": 42 + const: 2 43 + 44 + required: 45 + - compatible 46 + - reg 47 + - interrupts 48 + - "#gpio-cells" 49 + - interrupt-controller 50 + - "#interrupt-cells" 51 + 52 + additionalProperties: false 53 + 54 + examples: 55 + - | 56 + #include <dt-bindings/interrupt-controller/irq.h> 57 + gpio@4d000000 { 58 + compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; 59 + reg = <0x4d000000 0x100>; 60 + interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; 61 + gpio-controller; 62 + #gpio-cells = <2>; 63 + interrupt-controller; 64 + #interrupt-cells = <2>; 65 + };
+3 -1
Documentation/devicetree/bindings/gpio/gpio-vf610.yaml
··· 25 25 - const: fsl,imx7ulp-gpio 26 26 - const: fsl,vf610-gpio 27 27 - items: 28 - - const: fsl,imx8ulp-gpio 28 + - enum: 29 + - fsl,imx93-gpio 30 + - fsl,imx8ulp-gpio 29 31 - const: fsl,imx7ulp-gpio 30 32 31 33 reg:
+1 -1
Documentation/devicetree/bindings/gpio/gpio.txt
··· 213 213 gpio-controller; 214 214 #gpio-cells = <2>; 215 215 216 - line_b { 216 + line_b-hog { 217 217 gpio-hog; 218 218 gpios = <6 0>; 219 219 output-low;
+11 -5
drivers/gpio/Kconfig
··· 247 247 help 248 248 Say yes here to support GPIO on Renesas Emma Mobile SoCs. 249 249 250 + config GPIO_EN7523 251 + tristate "Airoha GPIO support" 252 + depends on ARCH_AIROHA 253 + default ARCH_AIROHA 254 + select GPIO_GENERIC 255 + select GPIOLIB_IRQCHIP 256 + help 257 + Say Y or M here to support the GPIO controller block on the 258 + Airoha EN7523 SoC. It supports two banks of 32 GPIOs. 259 + 250 260 config GPIO_EP93XX 251 261 def_bool y 252 262 depends on ARCH_EP93XX ··· 1390 1380 This driver supports TPS65912 GPIO chip. 1391 1381 1392 1382 config GPIO_TPS68470 1393 - bool "TPS68470 GPIO" 1383 + tristate "TPS68470 GPIO" 1394 1384 depends on INTEL_SKL_INT3472 1395 1385 help 1396 1386 Select this option to enable GPIO driver for the TPS68470 ··· 1399 1389 by the TPS68470. While the 7 GPIOs can be configured as 1400 1390 input or output as appropriate, the sensor related GPIOs 1401 1391 are "output only" GPIOs. 1402 - 1403 - This driver config is bool, as the GPIO functionality 1404 - of the TPS68470 must be available before dependent 1405 - drivers are loaded. 1406 1392 1407 1393 config GPIO_TQMX86 1408 1394 tristate "TQ-Systems QTMX86 GPIO"
+1
drivers/gpio/Makefile
··· 55 55 obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o 56 56 obj-$(CONFIG_GPIO_EIC_SPRD) += gpio-eic-sprd.o 57 57 obj-$(CONFIG_GPIO_EM) += gpio-em.o 58 + obj-$(CONFIG_GPIO_EN7523) += gpio-en7523.o 58 59 obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o 59 60 obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o 60 61 obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
+2 -1
drivers/gpio/gpio-altera-a10sr.c
··· 10 10 #include <linux/gpio/driver.h> 11 11 #include <linux/mfd/altera-a10sr.h> 12 12 #include <linux/module.h> 13 + #include <linux/property.h> 13 14 14 15 /** 15 16 * struct altr_a10sr_gpio - Altera Max5 GPIO device private data structure ··· 89 88 90 89 gpio->gp = altr_a10sr_gc; 91 90 gpio->gp.parent = pdev->dev.parent; 92 - gpio->gp.of_node = pdev->dev.of_node; 91 + gpio->gp.fwnode = dev_fwnode(&pdev->dev); 93 92 94 93 return devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio); 95 94 }
+8 -1
drivers/gpio/gpio-crystalcove.c
··· 370 370 return retval; 371 371 } 372 372 373 - return devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg); 373 + retval = devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg); 374 + if (retval) 375 + return retval; 376 + 377 + /* Distuingish IRQ domain from others sharing (MFD) the same fwnode */ 378 + irq_domain_update_bus_token(cg->chip.irq.domain, DOMAIN_BUS_WIRED); 379 + 380 + return 0; 374 381 } 375 382 376 383 static struct platform_driver crystalcove_gpio_driver = {
+137
drivers/gpio/gpio-en7523.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #include <linux/types.h> 4 + #include <linux/io.h> 5 + #include <linux/bits.h> 6 + #include <linux/gpio/driver.h> 7 + #include <linux/mod_devicetable.h> 8 + #include <linux/module.h> 9 + #include <linux/platform_device.h> 10 + #include <linux/property.h> 11 + 12 + #define AIROHA_GPIO_MAX 32 13 + 14 + /** 15 + * airoha_gpio_ctrl - Airoha GPIO driver data 16 + * @gc: Associated gpio_chip instance. 17 + * @data: The data register. 18 + * @dir0: The direction register for the lower 16 pins. 19 + * @dir1: The direction register for the higher 16 pins. 20 + * @output: The output enable register. 21 + */ 22 + struct airoha_gpio_ctrl { 23 + struct gpio_chip gc; 24 + void __iomem *data; 25 + void __iomem *dir[2]; 26 + void __iomem *output; 27 + }; 28 + 29 + static struct airoha_gpio_ctrl *gc_to_ctrl(struct gpio_chip *gc) 30 + { 31 + return container_of(gc, struct airoha_gpio_ctrl, gc); 32 + } 33 + 34 + static int airoha_dir_set(struct gpio_chip *gc, unsigned int gpio, 35 + int val, int out) 36 + { 37 + struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc); 38 + u32 dir = ioread32(ctrl->dir[gpio / 16]); 39 + u32 output = ioread32(ctrl->output); 40 + u32 mask = BIT((gpio % 16) * 2); 41 + 42 + if (out) { 43 + dir |= mask; 44 + output |= BIT(gpio); 45 + } else { 46 + dir &= ~mask; 47 + output &= ~BIT(gpio); 48 + } 49 + 50 + iowrite32(dir, ctrl->dir[gpio / 16]); 51 + 52 + if (out) 53 + gc->set(gc, gpio, val); 54 + 55 + iowrite32(output, ctrl->output); 56 + 57 + return 0; 58 + } 59 + 60 + static int airoha_dir_out(struct gpio_chip *gc, unsigned int gpio, 61 + int val) 62 + { 63 + return airoha_dir_set(gc, gpio, val, 1); 64 + } 65 + 66 + static int airoha_dir_in(struct gpio_chip *gc, unsigned int gpio) 67 + { 68 + return airoha_dir_set(gc, gpio, 0, 0); 69 + } 70 + 71 + static int airoha_get_dir(struct gpio_chip *gc, unsigned int gpio) 72 + { 73 + struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc); 74 + u32 dir = ioread32(ctrl->dir[gpio / 16]); 75 + u32 mask = BIT((gpio % 16) * 2); 76 + 77 + return (dir & mask) ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; 78 + } 79 + 80 + static int airoha_gpio_probe(struct platform_device *pdev) 81 + { 82 + struct device *dev = &pdev->dev; 83 + struct airoha_gpio_ctrl *ctrl; 84 + int err; 85 + 86 + ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); 87 + if (!ctrl) 88 + return -ENOMEM; 89 + 90 + ctrl->data = devm_platform_ioremap_resource(pdev, 0); 91 + if (IS_ERR(ctrl->data)) 92 + return PTR_ERR(ctrl->data); 93 + 94 + ctrl->dir[0] = devm_platform_ioremap_resource(pdev, 1); 95 + if (IS_ERR(ctrl->dir[0])) 96 + return PTR_ERR(ctrl->dir[0]); 97 + 98 + ctrl->dir[1] = devm_platform_ioremap_resource(pdev, 2); 99 + if (IS_ERR(ctrl->dir[1])) 100 + return PTR_ERR(ctrl->dir[1]); 101 + 102 + ctrl->output = devm_platform_ioremap_resource(pdev, 3); 103 + if (IS_ERR(ctrl->output)) 104 + return PTR_ERR(ctrl->output); 105 + 106 + err = bgpio_init(&ctrl->gc, dev, 4, ctrl->data, NULL, 107 + NULL, NULL, NULL, 0); 108 + if (err) 109 + return dev_err_probe(dev, err, "unable to init generic GPIO"); 110 + 111 + ctrl->gc.ngpio = AIROHA_GPIO_MAX; 112 + ctrl->gc.owner = THIS_MODULE; 113 + ctrl->gc.direction_output = airoha_dir_out; 114 + ctrl->gc.direction_input = airoha_dir_in; 115 + ctrl->gc.get_direction = airoha_get_dir; 116 + 117 + return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl); 118 + } 119 + 120 + static const struct of_device_id airoha_gpio_of_match[] = { 121 + { .compatible = "airoha,en7523-gpio" }, 122 + { } 123 + }; 124 + MODULE_DEVICE_TABLE(of, airoha_gpio_of_match); 125 + 126 + static struct platform_driver airoha_gpio_driver = { 127 + .driver = { 128 + .name = "airoha-gpio", 129 + .of_match_table = airoha_gpio_of_match, 130 + }, 131 + .probe = airoha_gpio_probe, 132 + }; 133 + module_platform_driver(airoha_gpio_driver); 134 + 135 + MODULE_DESCRIPTION("Airoha GPIO support"); 136 + MODULE_AUTHOR("John Crispin <john@phrozen.org>"); 137 + MODULE_LICENSE("GPL v2");
+3
drivers/gpio/gpio-merrifield.c
··· 409 409 int retval; 410 410 411 411 pinctrl_dev_name = mrfld_gpio_get_pinctrl_dev_name(priv); 412 + if (!pinctrl_dev_name) 413 + return -ENOMEM; 414 + 412 415 for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) { 413 416 range = &mrfld_gpio_ranges[i]; 414 417 retval = gpiochip_add_pin_range(&priv->chip, pinctrl_dev_name,
-1
drivers/gpio/gpio-tegra.c
··· 691 691 tgi->gc.base = 0; 692 692 tgi->gc.ngpio = tgi->bank_count * 32; 693 693 tgi->gc.parent = &pdev->dev; 694 - tgi->gc.of_node = pdev->dev.of_node; 695 694 696 695 tgi->ic.name = "GPIO"; 697 696 tgi->ic.irq_ack = tegra_gpio_irq_ack;
+4 -1
drivers/gpio/gpio-tps68470.c
··· 154 154 }, 155 155 .probe = tps68470_gpio_probe, 156 156 }; 157 + module_platform_driver(tps68470_gpio_driver); 157 158 158 - builtin_platform_driver(tps68470_gpio_driver) 159 + MODULE_ALIAS("platform:tps68470-gpio"); 160 + MODULE_DESCRIPTION("GPIO driver for TPS68470 PMIC"); 161 + MODULE_LICENSE("GPL v2");
+1 -9
drivers/gpio/gpio-ts4900.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Digital I/O driver for Technologic Systems I2C FPGA Core 3 4 * 4 5 * Copyright (C) 2015, 2018 Technologic Systems 5 6 * Copyright (C) 2016 Savoir-Faire Linux 6 - * 7 - * This program is free software; you can redistribute it and/or 8 - * modify it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 - * 11 - * This program is distributed "as is" WITHOUT ANY WARRANTY of any 12 - * kind, whether expressed or implied; without even the implied warranty 13 - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License version 2 for more details. 15 7 */ 16 8 17 9 #include <linux/gpio/driver.h>
+4 -6
drivers/gpio/gpiolib-of.c
··· 711 711 static void of_gpiochip_remove_hog(struct gpio_chip *chip, 712 712 struct device_node *hog) 713 713 { 714 - struct gpio_desc *descs = chip->gpiodev->descs; 714 + struct gpio_desc *desc; 715 715 unsigned int i; 716 716 717 - for (i = 0; i < chip->ngpio; i++) { 718 - if (test_bit(FLAG_IS_HOGGED, &descs[i].flags) && 719 - descs[i].hog == hog) 720 - gpiochip_free_own_desc(&descs[i]); 721 - } 717 + for_each_gpio_desc_with_flag(i, chip, desc, FLAG_IS_HOGGED) 718 + if (desc->hog == hog) 719 + gpiochip_free_own_desc(desc); 722 720 } 723 721 724 722 static int of_gpiochip_match_node(struct gpio_chip *chip, void *data)
+40 -60
drivers/gpio/gpiolib-sysfs.c
··· 13 13 #include "gpiolib.h" 14 14 #include "gpiolib-sysfs.h" 15 15 16 + #define GPIO_IRQF_TRIGGER_NONE 0 16 17 #define GPIO_IRQF_TRIGGER_FALLING BIT(0) 17 18 #define GPIO_IRQF_TRIGGER_RISING BIT(1) 18 19 #define GPIO_IRQF_TRIGGER_BOTH (GPIO_IRQF_TRIGGER_FALLING | \ ··· 62 61 { 63 62 struct gpiod_data *data = dev_get_drvdata(dev); 64 63 struct gpio_desc *desc = data->desc; 65 - ssize_t status; 64 + int value; 66 65 67 66 mutex_lock(&data->mutex); 68 67 69 68 gpiod_get_direction(desc); 70 - status = sysfs_emit(buf, "%s\n", 71 - test_bit(FLAG_IS_OUT, &desc->flags) ? "out" : "in"); 69 + value = !!test_bit(FLAG_IS_OUT, &desc->flags); 72 70 73 71 mutex_unlock(&data->mutex); 74 72 75 - return status; 73 + return sysfs_emit(buf, "%s\n", value ? "out" : "in"); 76 74 } 77 75 78 76 static ssize_t direction_store(struct device *dev, ··· 108 108 mutex_lock(&data->mutex); 109 109 110 110 status = gpiod_get_value_cansleep(desc); 111 - if (status >= 0) 112 - status = sysfs_emit(buf, "%zd\n", status); 113 111 114 112 mutex_unlock(&data->mutex); 115 113 116 - return status; 114 + if (status < 0) 115 + return status; 116 + 117 + return sysfs_emit(buf, "%zd\n", status); 117 118 } 118 119 119 120 static ssize_t value_store(struct device *dev, ··· 122 121 { 123 122 struct gpiod_data *data = dev_get_drvdata(dev); 124 123 struct gpio_desc *desc = data->desc; 125 - ssize_t status = 0; 124 + ssize_t status; 125 + long value; 126 + 127 + status = kstrtol(buf, 0, &value); 126 128 127 129 mutex_lock(&data->mutex); 128 130 129 131 if (!test_bit(FLAG_IS_OUT, &desc->flags)) { 130 132 status = -EPERM; 131 - } else { 132 - long value; 133 - 134 - if (size <= 2 && isdigit(buf[0]) && 135 - (size == 1 || buf[1] == '\n')) 136 - value = buf[0] - '0'; 137 - else 138 - status = kstrtol(buf, 0, &value); 139 - if (status == 0) { 140 - gpiod_set_value_cansleep(desc, value); 141 - status = size; 142 - } 133 + } else if (status == 0) { 134 + gpiod_set_value_cansleep(desc, value); 135 + status = size; 143 136 } 144 137 145 138 mutex_unlock(&data->mutex); ··· 219 224 sysfs_put(data->value_kn); 220 225 } 221 226 222 - static const struct { 223 - const char *name; 224 - unsigned char flags; 225 - } trigger_types[] = { 226 - { "none", 0 }, 227 - { "falling", GPIO_IRQF_TRIGGER_FALLING }, 228 - { "rising", GPIO_IRQF_TRIGGER_RISING }, 229 - { "both", GPIO_IRQF_TRIGGER_BOTH }, 227 + static const char * const trigger_names[] = { 228 + [GPIO_IRQF_TRIGGER_NONE] = "none", 229 + [GPIO_IRQF_TRIGGER_FALLING] = "falling", 230 + [GPIO_IRQF_TRIGGER_RISING] = "rising", 231 + [GPIO_IRQF_TRIGGER_BOTH] = "both", 230 232 }; 231 233 232 234 static ssize_t edge_show(struct device *dev, 233 235 struct device_attribute *attr, char *buf) 234 236 { 235 237 struct gpiod_data *data = dev_get_drvdata(dev); 236 - ssize_t status = 0; 237 - int i; 238 + int flags; 238 239 239 240 mutex_lock(&data->mutex); 240 241 241 - for (i = 0; i < ARRAY_SIZE(trigger_types); i++) { 242 - if (data->irq_flags == trigger_types[i].flags) 243 - break; 244 - } 245 - if (i < ARRAY_SIZE(trigger_types)) 246 - status = sysfs_emit(buf, "%s\n", trigger_types[i].name); 242 + flags = data->irq_flags; 247 243 248 244 mutex_unlock(&data->mutex); 249 245 250 - return status; 246 + if (flags >= ARRAY_SIZE(trigger_names)) 247 + return 0; 248 + 249 + return sysfs_emit(buf, "%s\n", trigger_names[flags]); 251 250 } 252 251 253 252 static ssize_t edge_store(struct device *dev, 254 253 struct device_attribute *attr, const char *buf, size_t size) 255 254 { 256 255 struct gpiod_data *data = dev_get_drvdata(dev); 257 - unsigned char flags; 258 256 ssize_t status = size; 259 - int i; 257 + int flags; 260 258 261 - for (i = 0; i < ARRAY_SIZE(trigger_types); i++) { 262 - if (sysfs_streq(trigger_types[i].name, buf)) 263 - break; 264 - } 265 - 266 - if (i == ARRAY_SIZE(trigger_types)) 267 - return -EINVAL; 268 - 269 - flags = trigger_types[i].flags; 259 + flags = sysfs_match_string(trigger_names, buf); 260 + if (flags < 0) 261 + return flags; 270 262 271 263 mutex_lock(&data->mutex); 272 264 ··· 306 324 { 307 325 struct gpiod_data *data = dev_get_drvdata(dev); 308 326 struct gpio_desc *desc = data->desc; 309 - ssize_t status; 327 + int value; 310 328 311 329 mutex_lock(&data->mutex); 312 330 313 - status = sysfs_emit(buf, "%d\n", 314 - !!test_bit(FLAG_ACTIVE_LOW, &desc->flags)); 331 + value = !!test_bit(FLAG_ACTIVE_LOW, &desc->flags); 315 332 316 333 mutex_unlock(&data->mutex); 317 334 318 - return status; 335 + return sysfs_emit(buf, "%d\n", value); 319 336 } 320 337 321 338 static ssize_t active_low_store(struct device *dev, ··· 324 343 ssize_t status; 325 344 long value; 326 345 346 + status = kstrtol(buf, 0, &value); 347 + if (status) 348 + return status; 349 + 327 350 mutex_lock(&data->mutex); 328 351 329 - status = kstrtol(buf, 0, &value); 330 - if (status == 0) 331 - status = gpio_sysfs_set_active_low(dev, value); 352 + status = gpio_sysfs_set_active_low(dev, value); 332 353 333 354 mutex_unlock(&data->mutex); 334 355 ··· 773 790 mutex_unlock(&sysfs_lock); 774 791 775 792 /* unregister gpiod class devices owned by sysfs */ 776 - for (i = 0; i < chip->ngpio; i++) { 777 - desc = &gdev->descs[i]; 778 - if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) 779 - gpiod_free(desc); 780 - } 793 + for_each_gpio_desc_with_flag(i, chip, desc, FLAG_SYSFS) 794 + gpiod_free(desc); 781 795 } 782 796 783 797 static int __init gpiolib_sysfs_init(void)
+19 -22
drivers/gpio/gpiolib.c
··· 262 262 return 0; 263 263 } 264 264 265 - next = list_entry(gpio_devices.next, struct gpio_device, list); 265 + next = list_first_entry(&gpio_devices, struct gpio_device, list); 266 266 if (gdev->base + gdev->ngpio <= next->base) { 267 267 /* add before first entry */ 268 268 list_add(&gdev->list, &gpio_devices); 269 269 return 0; 270 270 } 271 271 272 - prev = list_entry(gpio_devices.prev, struct gpio_device, list); 272 + prev = list_last_entry(&gpio_devices, struct gpio_device, list); 273 273 if (prev->base + prev->ngpio <= gdev->base) { 274 274 /* add behind last entry */ 275 275 list_add_tail(&gdev->list, &gpio_devices); ··· 3951 3951 * If a connection label was passed use that, else attempt to use 3952 3952 * the device name as label 3953 3953 */ 3954 - ret = gpiod_request(desc, con_id ? con_id : devname); 3954 + ret = gpiod_request(desc, con_id ?: devname); 3955 3955 if (ret) { 3956 - if (ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) { 3957 - /* 3958 - * This happens when there are several consumers for 3959 - * the same GPIO line: we just return here without 3960 - * further initialization. It is a bit if a hack. 3961 - * This is necessary to support fixed regulators. 3962 - * 3963 - * FIXME: Make this more sane and safe. 3964 - */ 3965 - dev_info(dev, "nonexclusive access to GPIO for %s\n", 3966 - con_id ? con_id : devname); 3967 - return desc; 3968 - } else { 3956 + if (!(ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE)) 3969 3957 return ERR_PTR(ret); 3970 - } 3958 + 3959 + /* 3960 + * This happens when there are several consumers for 3961 + * the same GPIO line: we just return here without 3962 + * further initialization. It is a bit of a hack. 3963 + * This is necessary to support fixed regulators. 3964 + * 3965 + * FIXME: Make this more sane and safe. 3966 + */ 3967 + dev_info(dev, "nonexclusive access to GPIO for %s\n", con_id ?: devname); 3968 + return desc; 3971 3969 } 3972 3970 3973 3971 ret = gpiod_configure_flags(desc, con_id, lookupflags, flags); ··· 4120 4122 */ 4121 4123 static void gpiochip_free_hogs(struct gpio_chip *gc) 4122 4124 { 4125 + struct gpio_desc *desc; 4123 4126 int id; 4124 4127 4125 - for (id = 0; id < gc->ngpio; id++) { 4126 - if (test_bit(FLAG_IS_HOGGED, &gc->gpiodev->descs[id].flags)) 4127 - gpiochip_free_own_desc(&gc->gpiodev->descs[id]); 4128 - } 4128 + for_each_gpio_desc_with_flag(id, gc, desc, FLAG_IS_HOGGED) 4129 + gpiochip_free_own_desc(desc); 4129 4130 } 4130 4131 4131 4132 /** ··· 4443 4446 if (list_is_last(&gdev->list, &gpio_devices)) 4444 4447 ret = NULL; 4445 4448 else 4446 - ret = list_entry(gdev->list.next, struct gpio_device, list); 4449 + ret = list_first_entry(&gdev->list, struct gpio_device, list); 4447 4450 spin_unlock_irqrestore(&gpio_lock, flags); 4448 4451 4449 4452 s->private = "\n";
+41
drivers/gpio/gpiolib.h
··· 37 37 * or name of the IP component in a System on Chip. 38 38 * @data: per-instance data assigned by the driver 39 39 * @list: links gpio_device:s together for traversal 40 + * @notifier: used to notify subscribers about lines being requested, released 41 + * or reconfigured 42 + * @pin_ranges: range of pins served by the GPIO driver 40 43 * 41 44 * This state container holds most of the runtime variable data 42 45 * for a GPIO device and can hold references and live on after the ··· 75 72 /* gpio suffixes used for ACPI and device tree lookup */ 76 73 static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" }; 77 74 75 + /** 76 + * struct gpio_array - Opaque descriptor for a structure of GPIO array attributes 77 + * 78 + * @desc: Array of pointers to the GPIO descriptors 79 + * @size: Number of elements in desc 80 + * @chip: Parent GPIO chip 81 + * @get_mask: Get mask used in fastpath 82 + * @set_mask: Set mask used in fastpath 83 + * @invert_mask: Invert mask used in fastpath 84 + * 85 + * This structure is attached to struct gpiod_descs obtained from 86 + * gpiod_get_array() and can be passed back to get/set array functions in order 87 + * to activate fast processing path if applicable. 88 + */ 78 89 struct gpio_array { 79 90 struct gpio_desc **desc; 80 91 unsigned int size; ··· 99 82 }; 100 83 101 84 struct gpio_desc *gpiochip_get_desc(struct gpio_chip *gc, unsigned int hwnum); 85 + 86 + #define for_each_gpio_desc_with_flag(i, gc, desc, flag) \ 87 + for (i = 0, desc = gpiochip_get_desc(gc, i); \ 88 + i < gc->ngpio; \ 89 + i++, desc = gpiochip_get_desc(gc, i)) \ 90 + if (!test_bit(flag, &desc->flags)) {} else 91 + 102 92 int gpiod_get_array_value_complex(bool raw, bool can_sleep, 103 93 unsigned int array_size, 104 94 struct gpio_desc **desc_array, ··· 120 96 extern spinlock_t gpio_lock; 121 97 extern struct list_head gpio_devices; 122 98 99 + 100 + /** 101 + * struct gpio_desc - Opaque descriptor for a GPIO 102 + * 103 + * @gdev: Pointer to the parent GPIO device 104 + * @flags: Binary descriptor flags 105 + * @label: Name of the consumer 106 + * @name: Line name 107 + * @hog: Pointer to the device node that hogs this line (if any) 108 + * @debounce_period_us: Debounce period in microseconds 109 + * 110 + * These are obtained using gpiod_get() and are preferable to the old 111 + * integer-based handles. 112 + * 113 + * Contrary to integers, a pointer to a &struct gpio_desc is guaranteed to be 114 + * valid until the GPIO is released. 115 + */ 123 116 struct gpio_desc { 124 117 struct gpio_device *gdev; 125 118 unsigned long flags;
+16 -19
include/linux/gpio/consumer.h
··· 8 8 #include <linux/err.h> 9 9 10 10 struct device; 11 - 12 - /** 13 - * Opaque descriptor for a GPIO. These are obtained using gpiod_get() and are 14 - * preferable to the old integer-based handles. 15 - * 16 - * Contrary to integers, a pointer to a gpio_desc is guaranteed to be valid 17 - * until the GPIO is released. 18 - */ 19 11 struct gpio_desc; 20 - 21 - /** 22 - * Opaque descriptor for a structure of GPIO array attributes. This structure 23 - * is attached to struct gpiod_descs obtained from gpiod_get_array() and can be 24 - * passed back to get/set array functions in order to activate fast processing 25 - * path if applicable. 26 - */ 27 12 struct gpio_array; 28 13 29 14 /** 30 - * Struct containing an array of descriptors that can be obtained using 31 - * gpiod_get_array(). 15 + * struct gpio_descs - Struct containing an array of descriptors that can be 16 + * obtained using gpiod_get_array() 17 + * 18 + * @info: Pointer to the opaque gpio_array structure 19 + * @ndescs: Number of held descriptors 20 + * @desc: Array of pointers to GPIO descriptors 32 21 */ 33 22 struct gpio_descs { 34 23 struct gpio_array *info; ··· 32 43 #define GPIOD_FLAGS_BIT_NONEXCLUSIVE BIT(4) 33 44 34 45 /** 35 - * Optional flags that can be passed to one of gpiod_* to configure direction 36 - * and output value. These values cannot be OR'd. 46 + * enum gpiod_flags - Optional flags that can be passed to one of gpiod_* to 47 + * configure direction and output value. These values 48 + * cannot be OR'd. 49 + * 50 + * @GPIOD_ASIS: Don't change anything 51 + * @GPIOD_IN: Set lines to input mode 52 + * @GPIOD_OUT_LOW: Set lines to output and drive them low 53 + * @GPIOD_OUT_HIGH: Set lines to output and drive them high 54 + * @GPIOD_OUT_LOW_OPEN_DRAIN: Set lines to open-drain output and drive them low 55 + * @GPIOD_OUT_HIGH_OPEN_DRAIN: Set lines to open-drain output and drive them high 37 56 */ 38 57 enum gpiod_flags { 39 58 GPIOD_ASIS = 0,