Commit cef06913 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull gpio fixes from Bartosz Golaszewski:

 - fix a probe failure for Tegra241 GPIO controller in gpio-tegra186

 - revert changes that caused a regression in the sysfs user-space
   interface

 - correct the debounce time conversion in GPIO ACPI

 - statify a struct in gpio-sim and fix a typo

 - update registers in correct order (hardware quirk) in gpio-ts4900

* tag 'gpio-fixes-for-v5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  gpio: sim: fix a typo
  gpio: ts4900: Do not set DAT and OE together
  gpio: sim: Declare gpio_sim_hog_config_item_ops static
  gpiolib: acpi: Convert ACPI value of debounce to microseconds
  gpio: Revert regression in sysfs-gpio (gpiolib.c)
  gpio: tegra186: Add IRQ per bank for Tegra241
parents 9c674947 55d01c98
...@@ -547,7 +547,7 @@ struct gpio_sim_bank { ...@@ -547,7 +547,7 @@ struct gpio_sim_bank {
* *
* So we need to store the pointer to the parent struct here. We can * So we need to store the pointer to the parent struct here. We can
* dereference it anywhere we need with no checks and no locking as * dereference it anywhere we need with no checks and no locking as
* it's guaranteed to survive the childred and protected by configfs * it's guaranteed to survive the children and protected by configfs
* locks. * locks.
* *
* Same for other structures. * Same for other structures.
...@@ -1322,7 +1322,7 @@ static void gpio_sim_hog_config_item_release(struct config_item *item) ...@@ -1322,7 +1322,7 @@ static void gpio_sim_hog_config_item_release(struct config_item *item)
kfree(hog); kfree(hog);
} }
struct configfs_item_operations gpio_sim_hog_config_item_ops = { static struct configfs_item_operations gpio_sim_hog_config_item_ops = {
.release = gpio_sim_hog_config_item_release, .release = gpio_sim_hog_config_item_release,
}; };
......
...@@ -1075,6 +1075,7 @@ static const struct tegra_gpio_soc tegra241_main_soc = { ...@@ -1075,6 +1075,7 @@ static const struct tegra_gpio_soc tegra241_main_soc = {
.ports = tegra241_main_ports, .ports = tegra241_main_ports,
.name = "tegra241-gpio", .name = "tegra241-gpio",
.instance = 0, .instance = 0,
.num_irqs_per_bank = 8,
}; };
#define TEGRA241_AON_GPIO_PORT(_name, _bank, _port, _pins) \ #define TEGRA241_AON_GPIO_PORT(_name, _bank, _port, _pins) \
...@@ -1095,6 +1096,7 @@ static const struct tegra_gpio_soc tegra241_aon_soc = { ...@@ -1095,6 +1096,7 @@ static const struct tegra_gpio_soc tegra241_aon_soc = {
.ports = tegra241_aon_ports, .ports = tegra241_aon_ports,
.name = "tegra241-gpio-aon", .name = "tegra241-gpio-aon",
.instance = 1, .instance = 1,
.num_irqs_per_bank = 8,
}; };
static const struct of_device_id tegra186_gpio_of_match[] = { static const struct of_device_id tegra186_gpio_of_match[] = {
......
/* /*
* Digital I/O driver for Technologic Systems I2C FPGA Core * Digital I/O driver for Technologic Systems I2C FPGA Core
* *
* Copyright (C) 2015 Technologic Systems * Copyright (C) 2015, 2018 Technologic Systems
* Copyright (C) 2016 Savoir-Faire Linux * Copyright (C) 2016 Savoir-Faire Linux
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -55,19 +55,33 @@ static int ts4900_gpio_direction_input(struct gpio_chip *chip, ...@@ -55,19 +55,33 @@ static int ts4900_gpio_direction_input(struct gpio_chip *chip,
{ {
struct ts4900_gpio_priv *priv = gpiochip_get_data(chip); struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
/* /* Only clear the OE bit here, requires a RMW. Prevents potential issue
* This will clear the output enable bit, the other bits are * with OE and data getting to the physical pin at different times.
* dontcare when this is cleared
*/ */
return regmap_write(priv->regmap, offset, 0); return regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OE, 0);
} }
static int ts4900_gpio_direction_output(struct gpio_chip *chip, static int ts4900_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value) unsigned int offset, int value)
{ {
struct ts4900_gpio_priv *priv = gpiochip_get_data(chip); struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
unsigned int reg;
int ret; int ret;
/* If changing from an input to an output, we need to first set the
* proper data bit to what is requested and then set OE bit. This
* prevents a glitch that can occur on the IO line
*/
regmap_read(priv->regmap, offset, &reg);
if (!(reg & TS4900_GPIO_OE)) {
if (value)
reg = TS4900_GPIO_OUT;
else
reg &= ~TS4900_GPIO_OUT;
regmap_write(priv->regmap, offset, reg);
}
if (value) if (value)
ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE | ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE |
TS4900_GPIO_OUT); TS4900_GPIO_OUT);
......
...@@ -307,7 +307,8 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip, ...@@ -307,7 +307,8 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
if (IS_ERR(desc)) if (IS_ERR(desc))
return desc; return desc;
ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout); /* ACPI uses hundredths of milliseconds units */
ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout * 10);
if (ret) if (ret)
dev_warn(chip->parent, dev_warn(chip->parent,
"Failed to set debounce-timeout for pin 0x%04X, err %d\n", "Failed to set debounce-timeout for pin 0x%04X, err %d\n",
...@@ -1035,7 +1036,8 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind ...@@ -1035,7 +1036,8 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = gpio_set_debounce_timeout(desc, info.debounce); /* ACPI uses hundredths of milliseconds units */
ret = gpio_set_debounce_timeout(desc, info.debounce * 10);
if (ret) if (ret)
return ret; return ret;
......
...@@ -1701,11 +1701,6 @@ static inline void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gc) ...@@ -1701,11 +1701,6 @@ static inline void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gc)
*/ */
int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset) int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset)
{ {
#ifdef CONFIG_PINCTRL
if (list_empty(&gc->gpiodev->pin_ranges))
return 0;
#endif
return pinctrl_gpio_request(gc->gpiodev->base + offset); return pinctrl_gpio_request(gc->gpiodev->base + offset);
} }
EXPORT_SYMBOL_GPL(gpiochip_generic_request); EXPORT_SYMBOL_GPL(gpiochip_generic_request);
...@@ -1717,11 +1712,6 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_request); ...@@ -1717,11 +1712,6 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_request);
*/ */
void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset) void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset)
{ {
#ifdef CONFIG_PINCTRL
if (list_empty(&gc->gpiodev->pin_ranges))
return;
#endif
pinctrl_gpio_free(gc->gpiodev->base + offset); pinctrl_gpio_free(gc->gpiodev->base + offset);
} }
EXPORT_SYMBOL_GPL(gpiochip_generic_free); EXPORT_SYMBOL_GPL(gpiochip_generic_free);
...@@ -2227,6 +2217,16 @@ static int gpio_set_bias(struct gpio_desc *desc) ...@@ -2227,6 +2217,16 @@ static int gpio_set_bias(struct gpio_desc *desc)
return gpio_set_config_with_argument_optional(desc, bias, arg); return gpio_set_config_with_argument_optional(desc, bias, arg);
} }
/**
* gpio_set_debounce_timeout() - Set debounce timeout
* @desc: GPIO descriptor to set the debounce timeout
* @debounce: Debounce timeout in microseconds
*
* The function calls the certain GPIO driver to set debounce timeout
* in the hardware.
*
* Returns 0 on success, or negative error code otherwise.
*/
int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce) int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce)
{ {
return gpio_set_config_with_argument_optional(desc, return gpio_set_config_with_argument_optional(desc,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment