Commit c1a1c0d3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'gpio-fixes-for-v6.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:

 - fix regressions in regmap cache initialization in gpio-104-idio-16
   and gpio-pci-idio-16

 - configure first 16 GPIO lines of the IDIO-16 as fixed outputs

 - fix duplicated IRQ mapping that can lead to an RCU stall in gpio-ljca

 - fix printf formatters passed to dev_err() and make failure to set
   debounce period non fatal

* tag 'gpio-fixes-for-v6.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  gpio: ljca: Fix duplicated IRQ mapping
  gpiolib: acpi: Use %pe when passing an error pointer to dev_err()
  gpiolib: acpi: Make set debounce errors non fatal
  gpio: idio-16: Define fixed direction of the GPIO lines
  gpio: regmap: add the .fixed_direction_output configuration parameter
  gpio: pci-idio-16: Define maximum valid register address offset
  gpio: 104-idio-16: Define maximum valid register address offset
parents 6fab32bb 4c4e6ea4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ static const struct regmap_config idio_16_regmap_config = {
	.reg_stride = 1,
	.val_bits = 8,
	.io_port = true,
	.max_register = 0x5,
	.wr_table = &idio_16_wr_table,
	.rd_table = &idio_16_rd_table,
	.volatile_table = &idio_16_rd_table,
+5 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@

#define DEFAULT_SYMBOL_NAMESPACE "GPIO_IDIO_16"

#include <linux/bitmap.h>
#include <linux/bits.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -107,6 +108,7 @@ int devm_idio_16_regmap_register(struct device *const dev,
	struct idio_16_data *data;
	struct regmap_irq_chip *chip;
	struct regmap_irq_chip_data *chip_data;
	DECLARE_BITMAP(fixed_direction_output, IDIO_16_NGPIO);

	if (!config->parent)
		return -EINVAL;
@@ -164,6 +166,9 @@ int devm_idio_16_regmap_register(struct device *const dev,
	gpio_config.irq_domain = regmap_irq_get_domain(chip_data);
	gpio_config.reg_mask_xlate = idio_16_reg_mask_xlate;

	bitmap_from_u64(fixed_direction_output, GENMASK_U64(15, 0));
	gpio_config.fixed_direction_output = fixed_direction_output;

	return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpio_config));
}
EXPORT_SYMBOL_GPL(devm_idio_16_regmap_register);
+3 −11
Original line number Diff line number Diff line
@@ -286,22 +286,14 @@ static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data,
{
	const struct ljca_gpio_packet *packet = evt_data;
	struct ljca_gpio_dev *ljca_gpio = context;
	int i, irq;
	int i;

	if (cmd != LJCA_GPIO_INT_EVENT)
		return;

	for (i = 0; i < packet->num; i++) {
		irq = irq_find_mapping(ljca_gpio->gc.irq.domain,
		generic_handle_domain_irq(ljca_gpio->gc.irq.domain,
					packet->item[i].index);
		if (!irq) {
			dev_err(ljca_gpio->gc.parent,
				"gpio_id %u does not mapped to IRQ yet\n",
				packet->item[i].index);
			return;
		}

		generic_handle_domain_irq(ljca_gpio->gc.irq.domain, irq);
		set_bit(packet->item[i].index, ljca_gpio->reenable_irqs);
	}

+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ static const struct regmap_config idio_16_regmap_config = {
	.reg_stride = 1,
	.val_bits = 8,
	.io_port = true,
	.max_register = 0x7,
	.wr_table = &idio_16_wr_table,
	.rd_table = &idio_16_rd_table,
	.volatile_table = &idio_16_rd_table,
+24 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct gpio_regmap {
	unsigned int reg_clr_base;
	unsigned int reg_dir_in_base;
	unsigned int reg_dir_out_base;
	unsigned long *fixed_direction_output;

#ifdef CONFIG_REGMAP_IRQ
	int regmap_irq_line;
@@ -134,6 +135,13 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip,
	unsigned int base, val, reg, mask;
	int invert, ret;

	if (gpio->fixed_direction_output) {
		if (test_bit(offset, gpio->fixed_direction_output))
			return GPIO_LINE_DIRECTION_OUT;
		else
			return GPIO_LINE_DIRECTION_IN;
	}

	if (gpio->reg_dat_base && !gpio->reg_set_base)
		return GPIO_LINE_DIRECTION_IN;
	if (gpio->reg_set_base && !gpio->reg_dat_base)
@@ -284,6 +292,17 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
			goto err_free_gpio;
	}

	if (config->fixed_direction_output) {
		gpio->fixed_direction_output = bitmap_alloc(chip->ngpio,
							    GFP_KERNEL);
		if (!gpio->fixed_direction_output) {
			ret = -ENOMEM;
			goto err_free_gpio;
		}
		bitmap_copy(gpio->fixed_direction_output,
			    config->fixed_direction_output, chip->ngpio);
	}

	/* if not set, assume there is only one register */
	gpio->ngpio_per_reg = config->ngpio_per_reg;
	if (!gpio->ngpio_per_reg)
@@ -300,7 +319,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config

	ret = gpiochip_add_data(chip, gpio);
	if (ret < 0)
		goto err_free_gpio;
		goto err_free_bitmap;

#ifdef CONFIG_REGMAP_IRQ
	if (config->regmap_irq_chip) {
@@ -309,7 +328,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
						 config->regmap_irq_line, config->regmap_irq_flags,
						 0, config->regmap_irq_chip, &gpio->irq_chip_data);
		if (ret)
			goto err_free_gpio;
			goto err_free_bitmap;

		irq_domain = regmap_irq_get_domain(gpio->irq_chip_data);
	} else
@@ -326,6 +345,8 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config

err_remove_gpiochip:
	gpiochip_remove(chip);
err_free_bitmap:
	bitmap_free(gpio->fixed_direction_output);
err_free_gpio:
	kfree(gpio);
	return ERR_PTR(ret);
@@ -344,6 +365,7 @@ void gpio_regmap_unregister(struct gpio_regmap *gpio)
#endif

	gpiochip_remove(&gpio->gpio_chip);
	bitmap_free(gpio->fixed_direction_output);
	kfree(gpio);
}
EXPORT_SYMBOL_GPL(gpio_regmap_unregister);
Loading