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.
Unified · Split
| @@ -31,6 +31,7 @@ struct gpio_regmap { · 30 unmodified lines | |||
| 31 | unsigned int reg_clr_base; | 31 | unsigned int reg_clr_base; |
| 32 | unsigned int reg_dir_in_base; | 32 | unsigned int reg_dir_in_base; |
| 33 | unsigned int reg_dir_out_base; | 33 | unsigned int reg_dir_out_base; |
| 34 | unsigned long *fixed_direction_output; | ||
| 34 | 35 | ||
| 35 | #ifdef CONFIG_REGMAP_IRQ | 36 | #ifdef CONFIG_REGMAP_IRQ |
| 36 | int regmap_irq_line; | 37 | int regmap_irq_line; |
| @@ -134,6 +135,13 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip, · 97 unmodified lines | |||
| 134 | unsigned int base, val, reg, mask; | 135 | unsigned int base, val, reg, mask; |
| 135 | int invert, ret; | 136 | int invert, ret; |
| 136 | 137 | ||
| 138 | if (gpio->fixed_direction_output) { | ||
| 139 | if (test_bit(offset, gpio->fixed_direction_output)) | ||
| 140 | return GPIO_LINE_DIRECTION_OUT; | ||
| 141 | else | ||
| 142 | return GPIO_LINE_DIRECTION_IN; | ||
| 143 | } | ||
| 144 | |||
| 137 | if (gpio->reg_dat_base && !gpio->reg_set_base) | 145 | if (gpio->reg_dat_base && !gpio->reg_set_base) |
| 138 | return GPIO_LINE_DIRECTION_IN; | 146 | return GPIO_LINE_DIRECTION_IN; |
| 139 | if (gpio->reg_set_base && !gpio->reg_dat_base) | 147 | 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 · 144 unmodified lines | |||
| 284 | goto err_free_gpio; | 292 | goto err_free_gpio; |
| 285 | } | 293 | } |
| 286 | 294 | ||
| 295 | if (config->fixed_direction_output) { | ||
| 296 | gpio->fixed_direction_output = bitmap_alloc(chip->ngpio, | ||
| 297 | GFP_KERNEL); | ||
| 298 | if (!gpio->fixed_direction_output) { | ||
| 299 | ret = -ENOMEM; | ||
| 300 | goto err_free_gpio; | ||
| 301 | } | ||
| 302 | bitmap_copy(gpio->fixed_direction_output, | ||
| 303 | config->fixed_direction_output, chip->ngpio); | ||
| 304 | } | ||
| 305 | |||
| 287 | /* if not set, assume there is only one register */ | 306 | /* if not set, assume there is only one register */ |
| 288 | gpio->ngpio_per_reg = config->ngpio_per_reg; | 307 | gpio->ngpio_per_reg = config->ngpio_per_reg; |
| 289 | if (!gpio->ngpio_per_reg) | 308 | if (!gpio->ngpio_per_reg) |
| @@ -300,7 +319,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config · 10 unmodified lines | |||
| 300 | 319 | ||
| 301 | ret = gpiochip_add_data(chip, gpio); | 320 | ret = gpiochip_add_data(chip, gpio); |
| 302 | if (ret < 0) | 321 | if (ret < 0) |
| 303 | goto err_free_gpio; | 322 | goto err_free_bitmap; |
| 304 | 323 | ||
| 305 | #ifdef CONFIG_REGMAP_IRQ | 324 | #ifdef CONFIG_REGMAP_IRQ |
| 306 | if (config->regmap_irq_chip) { | 325 | if (config->regmap_irq_chip) { |
| @@ -309,7 +328,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config · 2 unmodified lines | |||
| 309 | config->regmap_irq_line, config->regmap_irq_flags, | 328 | config->regmap_irq_line, config->regmap_irq_flags, |
| 310 | 0, config->regmap_irq_chip, &gpio->irq_chip_data); | 329 | 0, config->regmap_irq_chip, &gpio->irq_chip_data); |
| 311 | if (ret) | 330 | if (ret) |
| 312 | goto err_free_gpio; | 331 | goto err_free_bitmap; |
| 313 | 332 | ||
| 314 | irq_domain = regmap_irq_get_domain(gpio->irq_chip_data); | 333 | irq_domain = regmap_irq_get_domain(gpio->irq_chip_data); |
| 315 | } else | 334 | } else |
| @@ -326,6 +345,8 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config · 10 unmodified lines | |||
| 326 | 345 | ||
| 327 | err_remove_gpiochip: | 346 | err_remove_gpiochip: |
| 328 | gpiochip_remove(chip); | 347 | gpiochip_remove(chip); |
| 348 | err_free_bitmap: | ||
| 349 | bitmap_free(gpio->fixed_direction_output); | ||
| 329 | err_free_gpio: | 350 | err_free_gpio: |
| 330 | kfree(gpio); | 351 | kfree(gpio); |
| 331 | return ERR_PTR(ret); | 352 | return ERR_PTR(ret); |
| @@ -344,6 +365,7 @@ void gpio_regmap_unregister(struct gpio_regmap *gpio) · 12 unmodified lines | |||
| 344 | #endif | 365 | #endif |
| 345 | 366 | ||
| 346 | gpiochip_remove(&gpio->gpio_chip); | 367 | gpiochip_remove(&gpio->gpio_chip); |
| 368 | bitmap_free(gpio->fixed_direction_output); | ||
| 347 | kfree(gpio); | 369 | kfree(gpio); |
| 348 | } | 370 | } |
| 349 | EXPORT_SYMBOL_GPL(gpio_regmap_unregister); | 371 | EXPORT_SYMBOL_GPL(gpio_regmap_unregister); |
| @@ -38,6 +38,10 @@ struct regmap; · 37 unmodified lines | |||
| 38 | * offset to a register/bitmask pair. If not | 38 | * offset to a register/bitmask pair. If not |
| 39 | * given the default gpio_regmap_simple_xlate() | 39 | * given the default gpio_regmap_simple_xlate() |
| 40 | * is used. | 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 | * @drvdata: (Optional) Pointer to driver specific data which is | 45 | * @drvdata: (Optional) Pointer to driver specific data which is |
| 42 | * not used by gpio-remap but is provided "as is" to the | 46 | * not used by gpio-remap but is provided "as is" to the |
| 43 | * driver callback(s). | 47 | * driver callback(s). |
| @@ -85,6 +89,7 @@ struct gpio_regmap_config { · 41 unmodified lines | |||
| 85 | int reg_stride; | 89 | int reg_stride; |
| 86 | int ngpio_per_reg; | 90 | int ngpio_per_reg; |
| 87 | struct irq_domain *irq_domain; | 91 | struct irq_domain *irq_domain; |
| 92 | unsigned long *fixed_direction_output; | ||
| 88 | 93 | ||
| 89 | #ifdef CONFIG_REGMAP_IRQ | 94 | #ifdef CONFIG_REGMAP_IRQ |
| 90 | struct regmap_irq_chip *regmap_irq_chip; | 95 | struct regmap_irq_chip *regmap_irq_chip; |