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
Unified · Split
| @@ -0,0 +1,66 @@ | |||
| 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 | ... | ||
| @@ -1,27 +0,0 @@ | |||
| 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 | }; | ||
| @@ -0,0 +1,65 @@ | |||
| 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 | }; | ||
| @@ -25,7 +25,9 @@ properties: · 24 unmodified lines | |||
| 25 | - const: fsl,imx7ulp-gpio | 25 | - const: fsl,imx7ulp-gpio |
| 26 | - const: fsl,vf610-gpio | 26 | - const: fsl,vf610-gpio |
| 27 | - items: | 27 | - items: |
| 28 | - const: fsl,imx8ulp-gpio | 28 | - enum: |
| 29 | - fsl,imx93-gpio | ||
| 30 | - fsl,imx8ulp-gpio | ||
| 29 | - const: fsl,imx7ulp-gpio | 31 | - const: fsl,imx7ulp-gpio |
| 30 | 32 | ||
| 31 | reg: | 33 | reg: |
| @@ -213,7 +213,7 @@ Example of two SOC GPIO banks defined as gpio-controller nodes: · 212 unmodified lines | |||
| 213 | gpio-controller; | 213 | gpio-controller; |
| 214 | #gpio-cells = <2>; | 214 | #gpio-cells = <2>; |
| 215 | 215 | ||
| 216 | line_b { | 216 | line_b-hog { |
| 217 | gpio-hog; | 217 | gpio-hog; |
| 218 | gpios = <6 0>; | 218 | gpios = <6 0>; |
| 219 | output-low; | 219 | output-low; |
| @@ -247,6 +247,16 @@ config GPIO_EM · 246 unmodified lines | |||
| 247 | help | 247 | help |
| 248 | Say yes here to support GPIO on Renesas Emma Mobile SoCs. | 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 | config GPIO_EP93XX | 260 | config GPIO_EP93XX |
| 251 | def_bool y | 261 | def_bool y |
| 252 | depends on ARCH_EP93XX | 262 | depends on ARCH_EP93XX |
| @@ -1380,7 +1390,7 @@ config GPIO_TPS65912 · 1127 unmodified lines | |||
| 1380 | This driver supports TPS65912 GPIO chip. | 1390 | This driver supports TPS65912 GPIO chip. |
| 1381 | 1391 | ||
| 1382 | config GPIO_TPS68470 | 1392 | config GPIO_TPS68470 |
| 1383 | bool "TPS68470 GPIO" | 1393 | tristate "TPS68470 GPIO" |
| 1384 | depends on INTEL_SKL_INT3472 | 1394 | depends on INTEL_SKL_INT3472 |
| 1385 | help | 1395 | help |
| 1386 | Select this option to enable GPIO driver for the TPS68470 | 1396 | Select this option to enable GPIO driver for the TPS68470 |
| @@ -1390,10 +1400,6 @@ config GPIO_TPS68470 · 3 unmodified lines | |||
| 1390 | input or output as appropriate, the sensor related GPIOs | 1400 | input or output as appropriate, the sensor related GPIOs |
| 1391 | are "output only" GPIOs. | 1401 | are "output only" GPIOs. |
| 1392 | 1402 | ||
| 1393 | This driver config is bool, as the GPIO functionality | ||
| 1394 | of the TPS68470 must be available before dependent | ||
| 1395 | drivers are loaded. | ||
| 1396 | |||
| 1397 | config GPIO_TQMX86 | 1403 | config GPIO_TQMX86 |
| 1398 | tristate "TQ-Systems QTMX86 GPIO" | 1404 | tristate "TQ-Systems QTMX86 GPIO" |
| 1399 | depends on MFD_TQMX86 || COMPILE_TEST | 1405 | depends on MFD_TQMX86 || COMPILE_TEST |
| @@ -55,6 +55,7 @@ obj-$(CONFIG_GPIO_DLN2) += gpio-dln2.o · 54 unmodified lines | |||
| 55 | obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o | 55 | obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o |
| 56 | obj-$(CONFIG_GPIO_EIC_SPRD) += gpio-eic-sprd.o | 56 | obj-$(CONFIG_GPIO_EIC_SPRD) += gpio-eic-sprd.o |
| 57 | obj-$(CONFIG_GPIO_EM) += gpio-em.o | 57 | obj-$(CONFIG_GPIO_EM) += gpio-em.o |
| 58 | obj-$(CONFIG_GPIO_EN7523) += gpio-en7523.o | ||
| 58 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 59 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
| 59 | obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o | 60 | obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o |
| 60 | obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o | 61 | obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | #include <linux/gpio/driver.h> | 10 | #include <linux/gpio/driver.h> |
| 11 | #include <linux/mfd/altera-a10sr.h> | 11 | #include <linux/mfd/altera-a10sr.h> |
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/property.h> | ||
| 13 | 14 | ||
| 14 | /** | 15 | /** |
| 15 | * struct altr_a10sr_gpio - Altera Max5 GPIO device private data structure | 16 | * struct altr_a10sr_gpio - Altera Max5 GPIO device private data structure |
| @@ -88,7 +89,7 @@ static int altr_a10sr_gpio_probe(struct platform_device *pdev) · 72 unmodified lines | |||
| 88 | 89 | ||
| 89 | gpio->gp = altr_a10sr_gc; | 90 | gpio->gp = altr_a10sr_gc; |
| 90 | gpio->gp.parent = pdev->dev.parent; | 91 | gpio->gp.parent = pdev->dev.parent; |
| 91 | gpio->gp.of_node = pdev->dev.of_node; | 92 | gpio->gp.fwnode = dev_fwnode(&pdev->dev); |
| 92 | 93 | ||
| 93 | return devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio); | 94 | return devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio); |
| 94 | } | 95 | } |
| @@ -370,7 +370,14 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) · 369 unmodified lines | |||
| 370 | return retval; | 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 | static struct platform_driver crystalcove_gpio_driver = { | 383 | static struct platform_driver crystalcove_gpio_driver = { |
| @@ -0,0 +1,137 @@ | |||
| 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"); | ||
| @@ -409,6 +409,9 @@ static int mrfld_gpio_add_pin_ranges(struct gpio_chip *chip) · 408 unmodified lines | |||
| 409 | int retval; | 409 | int retval; |
| 410 | 410 | ||
| 411 | pinctrl_dev_name = mrfld_gpio_get_pinctrl_dev_name(priv); | 411 | pinctrl_dev_name = mrfld_gpio_get_pinctrl_dev_name(priv); |
| 412 | if (!pinctrl_dev_name) | ||
| 413 | return -ENOMEM; | ||
| 414 | |||
| 412 | for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) { | 415 | for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) { |
| 413 | range = &mrfld_gpio_ranges[i]; | 416 | range = &mrfld_gpio_ranges[i]; |
| 414 | retval = gpiochip_add_pin_range(&priv->chip, pinctrl_dev_name, | 417 | retval = gpiochip_add_pin_range(&priv->chip, pinctrl_dev_name, |
| @@ -691,7 +691,6 @@ static int tegra_gpio_probe(struct platform_device *pdev) · 690 unmodified lines | |||
| 691 | tgi->gc.base = 0; | 691 | tgi->gc.base = 0; |
| 692 | tgi->gc.ngpio = tgi->bank_count * 32; | 692 | tgi->gc.ngpio = tgi->bank_count * 32; |
| 693 | tgi->gc.parent = &pdev->dev; | 693 | tgi->gc.parent = &pdev->dev; |
| 694 | tgi->gc.of_node = pdev->dev.of_node; | ||
| 695 | 694 | ||
| 696 | tgi->ic.name = "GPIO"; | 695 | tgi->ic.name = "GPIO"; |
| 697 | tgi->ic.irq_ack = tegra_gpio_irq_ack; | 696 | tgi->ic.irq_ack = tegra_gpio_irq_ack; |
| @@ -154,5 +154,8 @@ static struct platform_driver tps68470_gpio_driver = { · 153 unmodified lines | |||
| 154 | }, | 154 | }, |
| 155 | .probe = tps68470_gpio_probe, | 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,17 +1,9 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Digital I/O driver for Technologic Systems I2C FPGA Core | 3 | * Digital I/O driver for Technologic Systems I2C FPGA Core |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2015, 2018 Technologic Systems | 5 | * Copyright (C) 2015, 2018 Technologic Systems |
| 5 | * Copyright (C) 2016 Savoir-Faire Linux | 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 | #include <linux/gpio/driver.h> | 9 | #include <linux/gpio/driver.h> |
| @@ -711,14 +711,12 @@ static int of_gpiochip_scan_gpios(struct gpio_chip *chip) · 710 unmodified lines | |||
| 711 | static void of_gpiochip_remove_hog(struct gpio_chip *chip, | 711 | static void of_gpiochip_remove_hog(struct gpio_chip *chip, |
| 712 | struct device_node *hog) | 712 | struct device_node *hog) |
| 713 | { | 713 | { |
| 714 | struct gpio_desc *descs = chip->gpiodev->descs; | 714 | struct gpio_desc *desc; |
| 715 | unsigned int i; | 715 | unsigned int i; |
| 716 | 716 | ||
| 717 | for (i = 0; i < chip->ngpio; i++) { | 717 | for_each_gpio_desc_with_flag(i, chip, desc, FLAG_IS_HOGGED) |
| 718 | if (test_bit(FLAG_IS_HOGGED, &descs[i].flags) && | 718 | if (desc->hog == hog) |
| 719 | descs[i].hog == hog) | 719 | gpiochip_free_own_desc(desc); |
| 720 | gpiochip_free_own_desc(&descs[i]); | ||
| 721 | } | ||
| 722 | } | 720 | } |
| 723 | 721 | ||
| 724 | static int of_gpiochip_match_node(struct gpio_chip *chip, void *data) | 722 | static int of_gpiochip_match_node(struct gpio_chip *chip, void *data) |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include "gpiolib.h" | 13 | #include "gpiolib.h" |
| 14 | #include "gpiolib-sysfs.h" | 14 | #include "gpiolib-sysfs.h" |
| 15 | 15 | ||
| 16 | #define GPIO_IRQF_TRIGGER_NONE 0 | ||
| 16 | #define GPIO_IRQF_TRIGGER_FALLING BIT(0) | 17 | #define GPIO_IRQF_TRIGGER_FALLING BIT(0) |
| 17 | #define GPIO_IRQF_TRIGGER_RISING BIT(1) | 18 | #define GPIO_IRQF_TRIGGER_RISING BIT(1) |
| 18 | #define GPIO_IRQF_TRIGGER_BOTH (GPIO_IRQF_TRIGGER_FALLING | \ | 19 | #define GPIO_IRQF_TRIGGER_BOTH (GPIO_IRQF_TRIGGER_FALLING | \ |
| @@ -61,17 +62,16 @@ static ssize_t direction_show(struct device *dev, · 42 unmodified lines | |||
| 61 | { | 62 | { |
| 62 | struct gpiod_data *data = dev_get_drvdata(dev); | 63 | struct gpiod_data *data = dev_get_drvdata(dev); |
| 63 | struct gpio_desc *desc = data->desc; | 64 | struct gpio_desc *desc = data->desc; |
| 64 | ssize_t status; | 65 | int value; |
| 65 | 66 | ||
| 66 | mutex_lock(&data->mutex); | 67 | mutex_lock(&data->mutex); |
| 67 | 68 | ||
| 68 | gpiod_get_direction(desc); | 69 | gpiod_get_direction(desc); |
| 69 | status = sysfs_emit(buf, "%s\n", | 70 | value = !!test_bit(FLAG_IS_OUT, &desc->flags); |
| 70 | test_bit(FLAG_IS_OUT, &desc->flags) ? "out" : "in"); | ||
| 71 | 71 | ||
| 72 | mutex_unlock(&data->mutex); | 72 | mutex_unlock(&data->mutex); |
| 73 | 73 | ||
| 74 | return status; | 74 | return sysfs_emit(buf, "%s\n", value ? "out" : "in"); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | static ssize_t direction_store(struct device *dev, | 77 | static ssize_t direction_store(struct device *dev, |
| @@ -108,12 +108,13 @@ static ssize_t value_show(struct device *dev, · 30 unmodified lines | |||
| 108 | mutex_lock(&data->mutex); | 108 | mutex_lock(&data->mutex); |
| 109 | 109 | ||
| 110 | status = gpiod_get_value_cansleep(desc); | 110 | status = gpiod_get_value_cansleep(desc); |
| 111 | if (status >= 0) | ||
| 112 | status = sysfs_emit(buf, "%zd\n", status); | ||
| 113 | 111 | ||
| 114 | mutex_unlock(&data->mutex); | 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 | static ssize_t value_store(struct device *dev, | 120 | static ssize_t value_store(struct device *dev, |
| @@ -121,24 +122,18 @@ static ssize_t value_store(struct device *dev, · 1 unmodified line | |||
| 121 | { | 122 | { |
| 122 | struct gpiod_data *data = dev_get_drvdata(dev); | 123 | struct gpiod_data *data = dev_get_drvdata(dev); |
| 123 | struct gpio_desc *desc = data->desc; | 124 | struct gpio_desc *desc = data->desc; |
| 124 | ssize_t status = 0; | 125 | ssize_t status; |
| 126 | long value; | ||
| 127 | |||
| 128 | status = kstrtol(buf, 0, &value); | ||
| 125 | 129 | ||
| 126 | mutex_lock(&data->mutex); | 130 | mutex_lock(&data->mutex); |
| 127 | 131 | ||
| 128 | if (!test_bit(FLAG_IS_OUT, &desc->flags)) { | 132 | if (!test_bit(FLAG_IS_OUT, &desc->flags)) { |
| 129 | status = -EPERM; | 133 | status = -EPERM; |
| 130 | } else { | 134 | } else if (status == 0) { |
| 131 | long value; | 135 | gpiod_set_value_cansleep(desc, value); |
| 132 | 136 | status = size; | |
| 133 | if (size <= 2 && isdigit(buf[0]) && | ||
| 134 | (size == 1 || buf[1] == '\n')) | ||
| 135 | value = buf[0] - '0'; | ||
| 136 | else | ||
| 137 | status = kstrtol(buf, 0, &value); | ||
| 138 | if (status == 0) { | ||
| 139 | gpiod_set_value_cansleep(desc, value); | ||
| 140 | status = size; | ||
| 141 | } | ||
| 142 | } | 137 | } |
| 143 | 138 | ||
| 144 | mutex_unlock(&data->mutex); | 139 | mutex_unlock(&data->mutex); |
| @@ -224,54 +219,41 @@ static void gpio_sysfs_free_irq(struct device *dev) · 79 unmodified lines | |||
| 224 | sysfs_put(data->value_kn); | 219 | sysfs_put(data->value_kn); |
| 225 | } | 220 | } |
| 226 | 221 | ||
| 227 | static const struct { | 222 | static const char * const trigger_names[] = { |
| 228 | const char *name; | 223 | [GPIO_IRQF_TRIGGER_NONE] = "none", |
| 229 | unsigned char flags; | 224 | [GPIO_IRQF_TRIGGER_FALLING] = "falling", |
| 230 | } trigger_types[] = { | 225 | [GPIO_IRQF_TRIGGER_RISING] = "rising", |
| 231 | { "none", 0 }, | 226 | [GPIO_IRQF_TRIGGER_BOTH] = "both", |
| 232 | { "falling", GPIO_IRQF_TRIGGER_FALLING }, | ||
| 233 | { "rising", GPIO_IRQF_TRIGGER_RISING }, | ||
| 234 | { "both", GPIO_IRQF_TRIGGER_BOTH }, | ||
| 235 | }; | 227 | }; |
| 236 | 228 | ||
| 237 | static ssize_t edge_show(struct device *dev, | 229 | static ssize_t edge_show(struct device *dev, |
| 238 | struct device_attribute *attr, char *buf) | 230 | struct device_attribute *attr, char *buf) |
| 239 | { | 231 | { |
| 240 | struct gpiod_data *data = dev_get_drvdata(dev); | 232 | struct gpiod_data *data = dev_get_drvdata(dev); |
| 241 | ssize_t status = 0; | 233 | int flags; |
| 242 | int i; | ||
| 243 | 234 | ||
| 244 | mutex_lock(&data->mutex); | 235 | mutex_lock(&data->mutex); |
| 245 | 236 | ||
| 246 | for (i = 0; i < ARRAY_SIZE(trigger_types); i++) { | 237 | flags = data->irq_flags; |
| 247 | if (data->irq_flags == trigger_types[i].flags) | ||
| 248 | break; | ||
| 249 | } | ||
| 250 | if (i < ARRAY_SIZE(trigger_types)) | ||
| 251 | status = sysfs_emit(buf, "%s\n", trigger_types[i].name); | ||
| 252 | 238 | ||
| 253 | mutex_unlock(&data->mutex); | 239 | mutex_unlock(&data->mutex); |
| 254 | 240 | ||
| 255 | return status; | 241 | if (flags >= ARRAY_SIZE(trigger_names)) |
| 242 | return 0; | ||
| 243 | |||
| 244 | return sysfs_emit(buf, "%s\n", trigger_names[flags]); | ||
| 256 | } | 245 | } |
| 257 | 246 | ||
| 258 | static ssize_t edge_store(struct device *dev, | 247 | static ssize_t edge_store(struct device *dev, |
| 259 | struct device_attribute *attr, const char *buf, size_t size) | 248 | struct device_attribute *attr, const char *buf, size_t size) |
| 260 | { | 249 | { |
| 261 | struct gpiod_data *data = dev_get_drvdata(dev); | 250 | struct gpiod_data *data = dev_get_drvdata(dev); |
| 262 | unsigned char flags; | ||
| 263 | ssize_t status = size; | 251 | ssize_t status = size; |
| 264 | int i; | 252 | int flags; |
| 265 | |||
| 266 | for (i = 0; i < ARRAY_SIZE(trigger_types); i++) { | ||
| 267 | if (sysfs_streq(trigger_types[i].name, buf)) | ||
| 268 | break; | ||
| 269 | } | ||
| 270 | |||
| 271 | if (i == ARRAY_SIZE(trigger_types)) | ||
| 272 | return -EINVAL; | ||
| 273 | 253 | ||
| 274 | flags = trigger_types[i].flags; | 254 | flags = sysfs_match_string(trigger_names, buf); |
| 255 | if (flags < 0) | ||
| 256 | return flags; | ||
| 275 | 257 | ||
| 276 | mutex_lock(&data->mutex); | 258 | mutex_lock(&data->mutex); |
| 277 | 259 | ||
| @@ -324,16 +306,15 @@ static ssize_t active_low_show(struct device *dev, · 46 unmodified lines | |||
| 324 | { | 306 | { |
| 325 | struct gpiod_data *data = dev_get_drvdata(dev); | 307 | struct gpiod_data *data = dev_get_drvdata(dev); |
| 326 | struct gpio_desc *desc = data->desc; | 308 | struct gpio_desc *desc = data->desc; |
| 327 | ssize_t status; | 309 | int value; |
| 328 | 310 | ||
| 329 | mutex_lock(&data->mutex); | 311 | mutex_lock(&data->mutex); |
| 330 | 312 | ||
| 331 | status = sysfs_emit(buf, "%d\n", | 313 | value = !!test_bit(FLAG_ACTIVE_LOW, &desc->flags); |
| 332 | !!test_bit(FLAG_ACTIVE_LOW, &desc->flags)); | ||
| 333 | 314 | ||
| 334 | mutex_unlock(&data->mutex); | 315 | mutex_unlock(&data->mutex); |
| 335 | 316 | ||
| 336 | return status; | 317 | return sysfs_emit(buf, "%d\n", value); |
| 337 | } | 318 | } |
| 338 | 319 | ||
| 339 | static ssize_t active_low_store(struct device *dev, | 320 | static ssize_t active_low_store(struct device *dev, |
| @@ -343,11 +324,13 @@ static ssize_t active_low_store(struct device *dev, · 3 unmodified lines | |||
| 343 | ssize_t status; | 324 | ssize_t status; |
| 344 | long value; | 325 | long value; |
| 345 | 326 | ||
| 327 | status = kstrtol(buf, 0, &value); | ||
| 328 | if (status) | ||
| 329 | return status; | ||
| 330 | |||
| 346 | mutex_lock(&data->mutex); | 331 | mutex_lock(&data->mutex); |
| 347 | 332 | ||
| 348 | status = kstrtol(buf, 0, &value); | 333 | status = gpio_sysfs_set_active_low(dev, value); |
| 349 | if (status == 0) | ||
| 350 | status = gpio_sysfs_set_active_low(dev, value); | ||
| 351 | 334 | ||
| 352 | mutex_unlock(&data->mutex); | 335 | mutex_unlock(&data->mutex); |
| 353 | 336 | ||
| @@ -790,11 +773,8 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev) · 436 unmodified lines | |||
| 790 | mutex_unlock(&sysfs_lock); | 773 | mutex_unlock(&sysfs_lock); |
| 791 | 774 | ||
| 792 | /* unregister gpiod class devices owned by sysfs */ | 775 | /* unregister gpiod class devices owned by sysfs */ |
| 793 | for (i = 0; i < chip->ngpio; i++) { | 776 | for_each_gpio_desc_with_flag(i, chip, desc, FLAG_SYSFS) |
| 794 | desc = &gdev->descs[i]; | 777 | gpiod_free(desc); |
| 795 | if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) | ||
| 796 | gpiod_free(desc); | ||
| 797 | } | ||
| 798 | } | 778 | } |
| 799 | 779 | ||
| 800 | static int __init gpiolib_sysfs_init(void) | 780 | static int __init gpiolib_sysfs_init(void) |
| @@ -262,14 +262,14 @@ static int gpiodev_add_to_list(struct gpio_device *gdev) · 261 unmodified lines | |||
| 262 | return 0; | 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 | if (gdev->base + gdev->ngpio <= next->base) { | 266 | if (gdev->base + gdev->ngpio <= next->base) { |
| 267 | /* add before first entry */ | 267 | /* add before first entry */ |
| 268 | list_add(&gdev->list, &gpio_devices); | 268 | list_add(&gdev->list, &gpio_devices); |
| 269 | return 0; | 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 | if (prev->base + prev->ngpio <= gdev->base) { | 273 | if (prev->base + prev->ngpio <= gdev->base) { |
| 274 | /* add behind last entry */ | 274 | /* add behind last entry */ |
| 275 | list_add_tail(&gdev->list, &gpio_devices); | 275 | list_add_tail(&gdev->list, &gpio_devices); |
| @@ -3951,23 +3951,21 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, · 3675 unmodified lines | |||
| 3951 | * If a connection label was passed use that, else attempt to use | 3951 | * If a connection label was passed use that, else attempt to use |
| 3952 | * the device name as label | 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 | if (ret) { | 3955 | if (ret) { |
| 3956 | if (ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) { | 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 { | ||
| 3969 | return ERR_PTR(ret); | 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 | ret = gpiod_configure_flags(desc, con_id, lookupflags, flags); | 3971 | ret = gpiod_configure_flags(desc, con_id, lookupflags, flags); |
| @@ -4122,12 +4120,11 @@ int gpiod_hog(struct gpio_desc *desc, const char *name, · 148 unmodified lines | |||
| 4122 | */ | 4120 | */ |
| 4123 | static void gpiochip_free_hogs(struct gpio_chip *gc) | 4121 | static void gpiochip_free_hogs(struct gpio_chip *gc) |
| 4124 | { | 4122 | { |
| 4123 | struct gpio_desc *desc; | ||
| 4125 | int id; | 4124 | int id; |
| 4126 | 4125 | ||
| 4127 | for (id = 0; id < gc->ngpio; id++) { | 4126 | for_each_gpio_desc_with_flag(id, gc, desc, FLAG_IS_HOGGED) |
| 4128 | if (test_bit(FLAG_IS_HOGGED, &gc->gpiodev->descs[id].flags)) | 4127 | gpiochip_free_own_desc(desc); |
| 4129 | gpiochip_free_own_desc(&gc->gpiodev->descs[id]); | ||
| 4130 | } | ||
| 4131 | } | 4128 | } |
| 4132 | 4129 | ||
| 4133 | /** | 4130 | /** |
| @@ -4446,7 +4443,7 @@ static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos) · 312 unmodified lines | |||
| 4446 | if (list_is_last(&gdev->list, &gpio_devices)) | 4443 | if (list_is_last(&gdev->list, &gpio_devices)) |
| 4447 | ret = NULL; | 4444 | ret = NULL; |
| 4448 | else | 4445 | else |
| 4449 | ret = list_entry(gdev->list.next, struct gpio_device, list); | 4446 | ret = list_first_entry(&gdev->list, struct gpio_device, list); |
| 4450 | spin_unlock_irqrestore(&gpio_lock, flags); | 4447 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 4451 | 4448 | ||
| 4452 | s->private = "\n"; | 4449 | s->private = "\n"; |
| @@ -37,6 +37,9 @@ · 36 unmodified lines | |||
| 37 | * or name of the IP component in a System on Chip. | 37 | * or name of the IP component in a System on Chip. |
| 38 | * @data: per-instance data assigned by the driver | 38 | * @data: per-instance data assigned by the driver |
| 39 | * @list: links gpio_device:s together for traversal | 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 | * This state container holds most of the runtime variable data | 44 | * This state container holds most of the runtime variable data |
| 42 | * for a GPIO device and can hold references and live on after the | 45 | * for a GPIO device and can hold references and live on after the |
| @@ -72,6 +75,20 @@ struct gpio_device { · 29 unmodified lines | |||
| 72 | /* gpio suffixes used for ACPI and device tree lookup */ | 75 | /* gpio suffixes used for ACPI and device tree lookup */ |
| 73 | static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" }; | 76 | static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" }; |
| 74 | 77 | ||
| 78 | /** | ||
| 79 | * struct gpio_array - Opaque descriptor for a structure of GPIO array attributes | ||
| 80 | * | ||
| 81 | * @desc: Array of pointers to the GPIO descriptors | ||
| 82 | * @size: Number of elements in desc | ||
| 83 | * @chip: Parent GPIO chip | ||
| 84 | * @get_mask: Get mask used in fastpath | ||
| 85 | * @set_mask: Set mask used in fastpath | ||
| 86 | * @invert_mask: Invert mask used in fastpath | ||
| 87 | * | ||
| 88 | * This structure is attached to struct gpiod_descs obtained from | ||
| 89 | * gpiod_get_array() and can be passed back to get/set array functions in order | ||
| 90 | * to activate fast processing path if applicable. | ||
| 91 | */ | ||
| 75 | struct gpio_array { | 92 | struct gpio_array { |
| 76 | struct gpio_desc **desc; | 93 | struct gpio_desc **desc; |
| 77 | unsigned int size; | 94 | unsigned int size; |
| @@ -82,6 +99,13 @@ struct gpio_array { · 4 unmodified lines | |||
| 82 | }; | 99 | }; |
| 83 | 100 | ||
| 84 | struct gpio_desc *gpiochip_get_desc(struct gpio_chip *gc, unsigned int hwnum); | 101 | struct gpio_desc *gpiochip_get_desc(struct gpio_chip *gc, unsigned int hwnum); |
| 102 | |||
| 103 | #define for_each_gpio_desc_with_flag(i, gc, desc, flag) \ | ||
| 104 | for (i = 0, desc = gpiochip_get_desc(gc, i); \ | ||
| 105 | i < gc->ngpio; \ | ||
| 106 | i++, desc = gpiochip_get_desc(gc, i)) \ | ||
| 107 | if (!test_bit(flag, &desc->flags)) {} else | ||
| 108 | |||
| 85 | int gpiod_get_array_value_complex(bool raw, bool can_sleep, | 109 | int gpiod_get_array_value_complex(bool raw, bool can_sleep, |
| 86 | unsigned int array_size, | 110 | unsigned int array_size, |
| 87 | struct gpio_desc **desc_array, | 111 | struct gpio_desc **desc_array, |
| @@ -96,6 +120,23 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, · 8 unmodified lines | |||
| 96 | extern spinlock_t gpio_lock; | 120 | extern spinlock_t gpio_lock; |
| 97 | extern struct list_head gpio_devices; | 121 | extern struct list_head gpio_devices; |
| 98 | 122 | ||
| 123 | |||
| 124 | /** | ||
| 125 | * struct gpio_desc - Opaque descriptor for a GPIO | ||
| 126 | * | ||
| 127 | * @gdev: Pointer to the parent GPIO device | ||
| 128 | * @flags: Binary descriptor flags | ||
| 129 | * @label: Name of the consumer | ||
| 130 | * @name: Line name | ||
| 131 | * @hog: Pointer to the device node that hogs this line (if any) | ||
| 132 | * @debounce_period_us: Debounce period in microseconds | ||
| 133 | * | ||
| 134 | * These are obtained using gpiod_get() and are preferable to the old | ||
| 135 | * integer-based handles. | ||
| 136 | * | ||
| 137 | * Contrary to integers, a pointer to a &struct gpio_desc is guaranteed to be | ||
| 138 | * valid until the GPIO is released. | ||
| 139 | */ | ||
| 99 | struct gpio_desc { | 140 | struct gpio_desc { |
| 100 | struct gpio_device *gdev; | 141 | struct gpio_device *gdev; |
| 101 | unsigned long flags; | 142 | unsigned long flags; |
| @@ -8,27 +8,16 @@ · 7 unmodified lines | |||
| 8 | #include <linux/err.h> | 8 | #include <linux/err.h> |
| 9 | 9 | ||
| 10 | struct device; | 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 | struct gpio_desc; | 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 | struct gpio_array; | 12 | struct gpio_array; |
| 28 | 13 | ||
| 29 | /** | 14 | /** |
| 30 | * Struct containing an array of descriptors that can be obtained using | 15 | * struct gpio_descs - Struct containing an array of descriptors that can be |
| 31 | * gpiod_get_array(). | 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 | struct gpio_descs { | 22 | struct gpio_descs { |
| 34 | struct gpio_array *info; | 23 | struct gpio_array *info; |
| @@ -43,8 +32,16 @@ struct gpio_descs { · 8 unmodified lines | |||
| 43 | #define GPIOD_FLAGS_BIT_NONEXCLUSIVE BIT(4) | 32 | #define GPIOD_FLAGS_BIT_NONEXCLUSIVE BIT(4) |
| 44 | 33 | ||
| 45 | /** | 34 | /** |
| 46 | * Optional flags that can be passed to one of gpiod_* to configure direction | 35 | * enum gpiod_flags - Optional flags that can be passed to one of gpiod_* to |
| 47 | * and output value. These values cannot be OR'd. | 36 | * configure direction and output value. These values |
| 37 | * cannot be OR'd. | ||
| 38 | * | ||
| 39 | * @GPIOD_ASIS: Don't change anything | ||
| 40 | * @GPIOD_IN: Set lines to input mode | ||
| 41 | * @GPIOD_OUT_LOW: Set lines to output and drive them low | ||
| 42 | * @GPIOD_OUT_HIGH: Set lines to output and drive them high | ||
| 43 | * @GPIOD_OUT_LOW_OPEN_DRAIN: Set lines to open-drain output and drive them low | ||
| 44 | * @GPIOD_OUT_HIGH_OPEN_DRAIN: Set lines to open-drain output and drive them high | ||
| 48 | */ | 45 | */ |
| 49 | enum gpiod_flags { | 46 | enum gpiod_flags { |
| 50 | GPIOD_ASIS = 0, | 47 | GPIOD_ASIS = 0, |