This is the first round of GPIO fixes for v4.3:
- Return value checks and thus nicer errorpath for two drivers. - Make GPIO_RCAR arch neutral. - Propagate errors from GPIO chip ->get() vtable call. It turned out these can actually fail sometimes, especially on slowpath controllers doing I2C traffic and similar. - Update documentation to be in sync with the massive changes in the v4.3 merge window, phew. - Handle deferred probe properly in the OMAP driver. - Get rid of surplus MODULE_ALIAS() from sx150x. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJV+RcuAAoJEEEQszewGV1zMqwQALnqXAvtJGw7CaKOiShm3ywH JPm4jMh7iiUFI8H+k6TscwxRz7bPKrezsCZleUxz/BOu/sAA9bVarYU3Fcl5HwZD 0qVszWCQ3E44qMh708F/B2kuQWdMl3u0aY9AGcNm0e4uDZ+hxXQ/jw+B1N/W0KFL vkCCCG/uE5eoRsOkOlEtm0UI+DjHRSpzEkgZ/1HmFfBtZaQuvHOMc5ouzT72hMQn YOk9lKPqjivGzDZYiISfmb62uuDQ8YnwsWZvP5SEbNdEgSlVes5Njd59pnxJgjYg tSQO37Sm0kNafbIao71DHrTBWHRxvsNeLuaDRnfNj95W8QtcYjvWrqCd3kBIeAt5 ZgUlm6mKEeZuz2PW+biT4DC7hPpV0LXCwTjjHtJ6S5w7JuM3+2HpHDItbYfs5SiL 40VlXKuLPOlxt6f179+4YTRwtaotQ6Bw0Rcflh5Sa4qq7LmZFghwSwtCDsNsWhWq qnFRoqbDmcxXBbnOuTvhM4DVCv7bvyQpos3EoFVANGg/T2zJ+8TEfi1ClHd5CbFO WHbgVaYVwLsfGgYX5Hq5aF/dhl4NSSDpikUhcDCvX62HoeImGFcWrybzIjk+9QND dCFS2ldd2znVZsCszCVAvtKmv0+TACb2iUK8Anhte8aYc1PLnhYT95BqUSB9QiyI Df6Pj5FQiLEyAnxVIrEh =72G1 -----END PGP SIGNATURE----- Merge tag 'gpio-v4.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio Pull GPIO fixes from Linus Walleij: "This is the first round of GPIO fixes for v4.3. Quite a lot of patches, but the influx of new stuff in the merge window was equally big, so I'm not surprised. - Return value checks and thus nicer errorpath for two drivers. - Make GPIO_RCAR arch neutral. - Propagate errors from GPIO chip ->get() vtable call. It turned out these can actually fail sometimes, especially on slowpath controllers doing I2C traffic and similar. - Update documentation to be in sync with the massive changes in the v4.3 merge window, phew. - Handle deferred probe properly in the OMAP driver. - Get rid of surplus MODULE_ALIAS() from sx150x" * tag 'gpio-v4.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: gpio: omap: Fix GPIO numbering for deferred probe Documentation: gpio: Explain that <function>-gpio is also supported gpio: omap: Fix gpiochip_add() handling for deferred probe gpio: sx150x: Remove unnecessary MODULE_ALIAS() Documentation: gpio: board: describe the con_id parameter Documentation: gpio: board: add flags parameter to gpiod_get*() functions gpio: Propagate errors from chip->get() gpio: rcar: GPIO_RCAR doesn't relate to ARM gpio: mxs: need to check return value of irq_alloc_generic_chip gpio: mxc: need to check return value of irq_alloc_generic_chip
This commit is contained in:
commit
d1291ebd85
|
@ -21,8 +21,8 @@ exact way to do it depends on the GPIO controller providing the GPIOs, see the
|
|||
device tree bindings for your controller.
|
||||
|
||||
GPIOs mappings are defined in the consumer device's node, in a property named
|
||||
<function>-gpios, where <function> is the function the driver will request
|
||||
through gpiod_get(). For example:
|
||||
either <function>-gpios or <function>-gpio, where <function> is the function
|
||||
the driver will request through gpiod_get(). For example:
|
||||
|
||||
foo_device {
|
||||
compatible = "acme,foo";
|
||||
|
@ -31,7 +31,7 @@ through gpiod_get(). For example:
|
|||
<&gpio 16 GPIO_ACTIVE_HIGH>, /* green */
|
||||
<&gpio 17 GPIO_ACTIVE_HIGH>; /* blue */
|
||||
|
||||
power-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
|
||||
power-gpio = <&gpio 1 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
This property will make GPIOs 15, 16 and 17 available to the driver under the
|
||||
|
@ -39,15 +39,24 @@ This property will make GPIOs 15, 16 and 17 available to the driver under the
|
|||
|
||||
struct gpio_desc *red, *green, *blue, *power;
|
||||
|
||||
red = gpiod_get_index(dev, "led", 0);
|
||||
green = gpiod_get_index(dev, "led", 1);
|
||||
blue = gpiod_get_index(dev, "led", 2);
|
||||
red = gpiod_get_index(dev, "led", 0, GPIOD_OUT_HIGH);
|
||||
green = gpiod_get_index(dev, "led", 1, GPIOD_OUT_HIGH);
|
||||
blue = gpiod_get_index(dev, "led", 2, GPIOD_OUT_HIGH);
|
||||
|
||||
power = gpiod_get(dev, "power");
|
||||
power = gpiod_get(dev, "power", GPIOD_OUT_HIGH);
|
||||
|
||||
The led GPIOs will be active-high, while the power GPIO will be active-low (i.e.
|
||||
gpiod_is_active_low(power) will be true).
|
||||
|
||||
The second parameter of the gpiod_get() functions, the con_id string, has to be
|
||||
the <function>-prefix of the GPIO suffixes ("gpios" or "gpio", automatically
|
||||
looked up by the gpiod functions internally) used in the device tree. With above
|
||||
"led-gpios" example, use the prefix without the "-" as con_id parameter: "led".
|
||||
|
||||
Internally, the GPIO subsystem prefixes the GPIO suffix ("gpios" or "gpio")
|
||||
with the string passed in con_id to get the resulting string
|
||||
(snprintf(... "%s-%s", con_id, gpio_suffixes[]).
|
||||
|
||||
ACPI
|
||||
----
|
||||
ACPI also supports function names for GPIOs in a similar fashion to DT.
|
||||
|
@ -142,13 +151,14 @@ The driver controlling "foo.0" will then be able to obtain its GPIOs as follows:
|
|||
|
||||
struct gpio_desc *red, *green, *blue, *power;
|
||||
|
||||
red = gpiod_get_index(dev, "led", 0);
|
||||
green = gpiod_get_index(dev, "led", 1);
|
||||
blue = gpiod_get_index(dev, "led", 2);
|
||||
red = gpiod_get_index(dev, "led", 0, GPIOD_OUT_HIGH);
|
||||
green = gpiod_get_index(dev, "led", 1, GPIOD_OUT_HIGH);
|
||||
blue = gpiod_get_index(dev, "led", 2, GPIOD_OUT_HIGH);
|
||||
|
||||
power = gpiod_get(dev, "power");
|
||||
gpiod_direction_output(power, 1);
|
||||
power = gpiod_get(dev, "power", GPIOD_OUT_HIGH);
|
||||
|
||||
Since the "power" GPIO is mapped as active-low, its actual signal will be 0
|
||||
after this code. Contrary to the legacy integer GPIO interface, the active-low
|
||||
property is handled during mapping and is thus transparent to GPIO consumers.
|
||||
Since the "led" GPIOs are mapped as active-high, this example will switch their
|
||||
signals to 1, i.e. enabling the LEDs. And for the "power" GPIO, which is mapped
|
||||
as active-low, its actual signal will be 0 after this code. Contrary to the legacy
|
||||
integer GPIO interface, the active-low property is handled during mapping and is
|
||||
thus transparent to GPIO consumers.
|
||||
|
|
|
@ -39,6 +39,9 @@ device that displays digits), an additional index argument can be specified:
|
|||
const char *con_id, unsigned int idx,
|
||||
enum gpiod_flags flags)
|
||||
|
||||
For a more detailed description of the con_id parameter in the DeviceTree case
|
||||
see Documentation/gpio/board.txt
|
||||
|
||||
The flags parameter is used to optionally specify a direction and initial value
|
||||
for the GPIO. Values can be:
|
||||
|
||||
|
|
|
@ -356,7 +356,7 @@ config GPIO_PXA
|
|||
|
||||
config GPIO_RCAR
|
||||
tristate "Renesas R-Car GPIO"
|
||||
depends on ARM && (ARCH_SHMOBILE || COMPILE_TEST)
|
||||
depends on ARCH_SHMOBILE || COMPILE_TEST
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
Say yes here to support GPIO on Renesas R-Car SoCs.
|
||||
|
|
|
@ -339,13 +339,15 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
|
||||
static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
|
||||
{
|
||||
struct irq_chip_generic *gc;
|
||||
struct irq_chip_type *ct;
|
||||
|
||||
gc = irq_alloc_generic_chip("gpio-mxc", 1, irq_base,
|
||||
port->base, handle_level_irq);
|
||||
if (!gc)
|
||||
return -ENOMEM;
|
||||
gc->private = port;
|
||||
|
||||
ct = gc->chip_types;
|
||||
|
@ -360,6 +362,8 @@ static void mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
|
|||
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
|
||||
IRQ_NOREQUEST, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mxc_gpio_get_hw(struct platform_device *pdev)
|
||||
|
@ -477,12 +481,16 @@ static int mxc_gpio_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/* gpio-mxc can be a generic irq chip */
|
||||
mxc_gpio_init_gc(port, irq_base);
|
||||
err = mxc_gpio_init_gc(port, irq_base);
|
||||
if (err < 0)
|
||||
goto out_irqdomain_remove;
|
||||
|
||||
list_add_tail(&port->node, &mxc_gpio_ports);
|
||||
|
||||
return 0;
|
||||
|
||||
out_irqdomain_remove:
|
||||
irq_domain_remove(port->domain);
|
||||
out_irqdesc_free:
|
||||
irq_free_descs(irq_base, 32);
|
||||
out_gpiochip_remove:
|
||||
|
|
|
@ -196,13 +196,16 @@ static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
|
||||
static int __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
|
||||
{
|
||||
struct irq_chip_generic *gc;
|
||||
struct irq_chip_type *ct;
|
||||
|
||||
gc = irq_alloc_generic_chip("gpio-mxs", 1, irq_base,
|
||||
port->base, handle_level_irq);
|
||||
if (!gc)
|
||||
return -ENOMEM;
|
||||
|
||||
gc->private = port;
|
||||
|
||||
ct = gc->chip_types;
|
||||
|
@ -216,6 +219,8 @@ static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
|
|||
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
|
||||
IRQ_NOREQUEST, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
|
||||
|
@ -317,7 +322,9 @@ static int mxs_gpio_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/* gpio-mxs can be a generic irq chip */
|
||||
mxs_gpio_init_gc(port, irq_base);
|
||||
err = mxs_gpio_init_gc(port, irq_base);
|
||||
if (err < 0)
|
||||
goto out_irqdomain_remove;
|
||||
|
||||
/* setup one handler for each entry */
|
||||
irq_set_chained_handler_and_data(port->irq, mxs_gpio_irq_handler,
|
||||
|
@ -343,6 +350,8 @@ static int mxs_gpio_probe(struct platform_device *pdev)
|
|||
|
||||
out_bgpio_remove:
|
||||
bgpio_remove(&port->bgc);
|
||||
out_irqdomain_remove:
|
||||
irq_domain_remove(port->domain);
|
||||
out_irqdesc_free:
|
||||
irq_free_descs(irq_base, 32);
|
||||
return err;
|
||||
|
|
|
@ -1098,7 +1098,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
|||
} else {
|
||||
bank->chip.label = "gpio";
|
||||
bank->chip.base = gpio;
|
||||
gpio += bank->width;
|
||||
}
|
||||
bank->chip.ngpio = bank->width;
|
||||
|
||||
|
@ -1108,6 +1107,9 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!bank->is_mpuio)
|
||||
gpio += bank->width;
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1
|
||||
/*
|
||||
* REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
|
||||
|
@ -1253,8 +1255,11 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|||
omap_gpio_mod_init(bank);
|
||||
|
||||
ret = omap_gpio_chip_init(bank, irqc);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
pm_runtime_put_sync(bank->dev);
|
||||
pm_runtime_disable(bank->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
omap_gpio_show_rev(bank);
|
||||
|
||||
|
|
|
@ -706,4 +706,3 @@ module_exit(sx150x_exit);
|
|||
MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
|
||||
MODULE_DESCRIPTION("Driver for Semtech SX150X I2C GPIO Expanders");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("i2c:sx150x");
|
||||
|
|
|
@ -1174,15 +1174,16 @@ EXPORT_SYMBOL_GPL(gpiod_is_active_low);
|
|||
* that the GPIO was actually requested.
|
||||
*/
|
||||
|
||||
static bool _gpiod_get_raw_value(const struct gpio_desc *desc)
|
||||
static int _gpiod_get_raw_value(const struct gpio_desc *desc)
|
||||
{
|
||||
struct gpio_chip *chip;
|
||||
bool value;
|
||||
int offset;
|
||||
int value;
|
||||
|
||||
chip = desc->chip;
|
||||
offset = gpio_chip_hwgpio(desc);
|
||||
value = chip->get ? chip->get(chip, offset) : false;
|
||||
value = chip->get ? chip->get(chip, offset) : -EIO;
|
||||
value = value < 0 ? value : !!value;
|
||||
trace_gpio_value(desc_to_gpio(desc), 1, value);
|
||||
return value;
|
||||
}
|
||||
|
@ -1192,7 +1193,7 @@ static bool _gpiod_get_raw_value(const struct gpio_desc *desc)
|
|||
* @desc: gpio whose value will be returned
|
||||
*
|
||||
* Return the GPIO's raw value, i.e. the value of the physical line disregarding
|
||||
* its ACTIVE_LOW status.
|
||||
* its ACTIVE_LOW status, or negative errno on failure.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep, and will
|
||||
* complain if the GPIO chip functions potentially sleep.
|
||||
|
@ -1212,7 +1213,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_value);
|
|||
* @desc: gpio whose value will be returned
|
||||
*
|
||||
* Return the GPIO's logical value, i.e. taking the ACTIVE_LOW status into
|
||||
* account.
|
||||
* account, or negative errno on failure.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep, and will
|
||||
* complain if the GPIO chip functions potentially sleep.
|
||||
|
@ -1226,6 +1227,9 @@ int gpiod_get_value(const struct gpio_desc *desc)
|
|||
WARN_ON(desc->chip->can_sleep);
|
||||
|
||||
value = _gpiod_get_raw_value(desc);
|
||||
if (value < 0)
|
||||
return value;
|
||||
|
||||
if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
|
||||
value = !value;
|
||||
|
||||
|
@ -1548,7 +1552,7 @@ EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq);
|
|||
* @desc: gpio whose value will be returned
|
||||
*
|
||||
* Return the GPIO's raw value, i.e. the value of the physical line disregarding
|
||||
* its ACTIVE_LOW status.
|
||||
* its ACTIVE_LOW status, or negative errno on failure.
|
||||
*
|
||||
* This function is to be called from contexts that can sleep.
|
||||
*/
|
||||
|
@ -1566,7 +1570,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_value_cansleep);
|
|||
* @desc: gpio whose value will be returned
|
||||
*
|
||||
* Return the GPIO's logical value, i.e. taking the ACTIVE_LOW status into
|
||||
* account.
|
||||
* account, or negative errno on failure.
|
||||
*
|
||||
* This function is to be called from contexts that can sleep.
|
||||
*/
|
||||
|
@ -1579,6 +1583,9 @@ int gpiod_get_value_cansleep(const struct gpio_desc *desc)
|
|||
return 0;
|
||||
|
||||
value = _gpiod_get_raw_value(desc);
|
||||
if (value < 0)
|
||||
return value;
|
||||
|
||||
if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
|
||||
value = !value;
|
||||
|
||||
|
|
Loading…
Reference in New Issue