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

Configure Feed

Select the types of activity you want to include in your feed.

gpio: regmap: add the .fixed_direction_output configuration parameter

There are GPIO controllers such as the one present in the LX2160ARDB
QIXIS FPGA which have fixed-direction input and output GPIO lines mixed
together in a single register. This cannot be modeled using the
gpio-regmap as-is since there is no way to present the true direction of
a GPIO line.

In order to make this use case possible, add a new configuration
parameter - fixed_direction_output - into the gpio_regmap_config
structure. This will enable user drivers to provide a bitmap that
represents the fixed direction of the GPIO lines.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Michael Walle <mwalle@kernel.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

authored by

Ioana Ciornei and committed by
Bartosz Golaszewski
00aaae60 d3762313

+29 -2
+24 -2
drivers/gpio/gpio-regmap.c
··· 31 31 unsigned int reg_clr_base; 32 32 unsigned int reg_dir_in_base; 33 33 unsigned int reg_dir_out_base; 34 + unsigned long *fixed_direction_output; 34 35 35 36 #ifdef CONFIG_REGMAP_IRQ 36 37 int regmap_irq_line; ··· 134 133 struct gpio_regmap *gpio = gpiochip_get_data(chip); 135 134 unsigned int base, val, reg, mask; 136 135 int invert, ret; 136 + 137 + if (gpio->fixed_direction_output) { 138 + if (test_bit(offset, gpio->fixed_direction_output)) 139 + return GPIO_LINE_DIRECTION_OUT; 140 + else 141 + return GPIO_LINE_DIRECTION_IN; 142 + } 137 143 138 144 if (gpio->reg_dat_base && !gpio->reg_set_base) 139 145 return GPIO_LINE_DIRECTION_IN; ··· 292 284 goto err_free_gpio; 293 285 } 294 286 287 + if (config->fixed_direction_output) { 288 + gpio->fixed_direction_output = bitmap_alloc(chip->ngpio, 289 + GFP_KERNEL); 290 + if (!gpio->fixed_direction_output) { 291 + ret = -ENOMEM; 292 + goto err_free_gpio; 293 + } 294 + bitmap_copy(gpio->fixed_direction_output, 295 + config->fixed_direction_output, chip->ngpio); 296 + } 297 + 295 298 /* if not set, assume there is only one register */ 296 299 gpio->ngpio_per_reg = config->ngpio_per_reg; 297 300 if (!gpio->ngpio_per_reg) ··· 319 300 320 301 ret = gpiochip_add_data(chip, gpio); 321 302 if (ret < 0) 322 - goto err_free_gpio; 303 + goto err_free_bitmap; 323 304 324 305 #ifdef CONFIG_REGMAP_IRQ 325 306 if (config->regmap_irq_chip) { ··· 328 309 config->regmap_irq_line, config->regmap_irq_flags, 329 310 0, config->regmap_irq_chip, &gpio->irq_chip_data); 330 311 if (ret) 331 - goto err_free_gpio; 312 + goto err_free_bitmap; 332 313 333 314 irq_domain = regmap_irq_get_domain(gpio->irq_chip_data); 334 315 } else ··· 345 326 346 327 err_remove_gpiochip: 347 328 gpiochip_remove(chip); 329 + err_free_bitmap: 330 + bitmap_free(gpio->fixed_direction_output); 348 331 err_free_gpio: 349 332 kfree(gpio); 350 333 return ERR_PTR(ret); ··· 365 344 #endif 366 345 367 346 gpiochip_remove(&gpio->gpio_chip); 347 + bitmap_free(gpio->fixed_direction_output); 368 348 kfree(gpio); 369 349 } 370 350 EXPORT_SYMBOL_GPL(gpio_regmap_unregister);
+5
include/linux/gpio/regmap.h
··· 38 38 * offset to a register/bitmask pair. If not 39 39 * given the default gpio_regmap_simple_xlate() 40 40 * is used. 41 + * @fixed_direction_output: 42 + * (Optional) Bitmap representing the fixed direction of 43 + * the GPIO lines. Useful when there are GPIO lines with a 44 + * fixed direction mixed together in the same register. 41 45 * @drvdata: (Optional) Pointer to driver specific data which is 42 46 * not used by gpio-remap but is provided "as is" to the 43 47 * driver callback(s). ··· 89 85 int reg_stride; 90 86 int ngpio_per_reg; 91 87 struct irq_domain *irq_domain; 88 + unsigned long *fixed_direction_output; 92 89 93 90 #ifdef CONFIG_REGMAP_IRQ 94 91 struct regmap_irq_chip *regmap_irq_chip;