mirror of https://github.com/torvalds/linux.git
gpio: regmap: Allow to allocate regmap-irq device
GPIO controller often have support for IRQ: allow to easily allocate both gpio-regmap and regmap-irq in one operation. Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com> Link: https://lore.kernel.org/r/20250824-mdb-max7360-support-v14-5-435cfda2b1ea@bootlin.com Signed-off-by: Lee Jones <lee@kernel.org>
This commit is contained in:
parent
d93a75d94b
commit
553b75d4bf
|
|
@ -32,6 +32,11 @@ struct gpio_regmap {
|
||||||
unsigned int reg_dir_in_base;
|
unsigned int reg_dir_in_base;
|
||||||
unsigned int reg_dir_out_base;
|
unsigned int reg_dir_out_base;
|
||||||
|
|
||||||
|
#ifdef CONFIG_REGMAP_IRQ
|
||||||
|
int regmap_irq_line;
|
||||||
|
struct regmap_irq_chip_data *irq_chip_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
|
int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
|
||||||
unsigned int offset, unsigned int *reg,
|
unsigned int offset, unsigned int *reg,
|
||||||
unsigned int *mask);
|
unsigned int *mask);
|
||||||
|
|
@ -215,6 +220,7 @@ EXPORT_SYMBOL_GPL(gpio_regmap_get_drvdata);
|
||||||
*/
|
*/
|
||||||
struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config)
|
struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config)
|
||||||
{
|
{
|
||||||
|
struct irq_domain *irq_domain;
|
||||||
struct gpio_regmap *gpio;
|
struct gpio_regmap *gpio;
|
||||||
struct gpio_chip *chip;
|
struct gpio_chip *chip;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -295,8 +301,22 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_free_gpio;
|
goto err_free_gpio;
|
||||||
|
|
||||||
if (config->irq_domain) {
|
#ifdef CONFIG_REGMAP_IRQ
|
||||||
ret = gpiochip_irqchip_add_domain(chip, config->irq_domain);
|
if (config->regmap_irq_chip) {
|
||||||
|
gpio->regmap_irq_line = config->regmap_irq_line;
|
||||||
|
ret = regmap_add_irq_chip_fwnode(dev_fwnode(config->parent), config->regmap,
|
||||||
|
config->regmap_irq_line, config->regmap_irq_flags,
|
||||||
|
0, config->regmap_irq_chip, &gpio->irq_chip_data);
|
||||||
|
if (ret)
|
||||||
|
goto err_free_gpio;
|
||||||
|
|
||||||
|
irq_domain = regmap_irq_get_domain(gpio->irq_chip_data);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
irq_domain = config->irq_domain;
|
||||||
|
|
||||||
|
if (irq_domain) {
|
||||||
|
ret = gpiochip_irqchip_add_domain(chip, irq_domain);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_remove_gpiochip;
|
goto err_remove_gpiochip;
|
||||||
}
|
}
|
||||||
|
|
@ -317,6 +337,11 @@ EXPORT_SYMBOL_GPL(gpio_regmap_register);
|
||||||
*/
|
*/
|
||||||
void gpio_regmap_unregister(struct gpio_regmap *gpio)
|
void gpio_regmap_unregister(struct gpio_regmap *gpio)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_REGMAP_IRQ
|
||||||
|
if (gpio->irq_chip_data)
|
||||||
|
regmap_del_irq_chip(gpio->regmap_irq_line, gpio->irq_chip_data);
|
||||||
|
#endif
|
||||||
|
|
||||||
gpiochip_remove(&gpio->gpio_chip);
|
gpiochip_remove(&gpio->gpio_chip);
|
||||||
kfree(gpio);
|
kfree(gpio);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,11 @@ struct regmap;
|
||||||
* @drvdata: (Optional) Pointer to driver specific data which is
|
* @drvdata: (Optional) Pointer to driver specific data which is
|
||||||
* not used by gpio-remap but is provided "as is" to the
|
* not used by gpio-remap but is provided "as is" to the
|
||||||
* driver callback(s).
|
* driver callback(s).
|
||||||
|
* @regmap_irq_chip: (Optional) Pointer on an regmap_irq_chip structure. If
|
||||||
|
* set, a regmap-irq device will be created and the IRQ
|
||||||
|
* domain will be set accordingly.
|
||||||
|
* @regmap_irq_line (Optional) The IRQ the device uses to signal interrupts.
|
||||||
|
* @regmap_irq_flags (Optional) The IRQF_ flags to use for the interrupt.
|
||||||
*
|
*
|
||||||
* The ->reg_mask_xlate translates a given base address and GPIO offset to
|
* The ->reg_mask_xlate translates a given base address and GPIO offset to
|
||||||
* register and mask pair. The base address is one of the given register
|
* register and mask pair. The base address is one of the given register
|
||||||
|
|
@ -78,6 +83,12 @@ struct gpio_regmap_config {
|
||||||
int ngpio_per_reg;
|
int ngpio_per_reg;
|
||||||
struct irq_domain *irq_domain;
|
struct irq_domain *irq_domain;
|
||||||
|
|
||||||
|
#ifdef CONFIG_REGMAP_IRQ
|
||||||
|
struct regmap_irq_chip *regmap_irq_chip;
|
||||||
|
int regmap_irq_line;
|
||||||
|
unsigned long regmap_irq_flags;
|
||||||
|
#endif
|
||||||
|
|
||||||
int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
|
int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
|
||||||
unsigned int offset, unsigned int *reg,
|
unsigned int offset, unsigned int *reg,
|
||||||
unsigned int *mask);
|
unsigned int *mask);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue