regmap: regmap-irq/gpio-max77620: add level-irq support
Add level active IRQ support to regmap-irq irqchip. Change breaks existing regmap-irq type setting. Convert the existing drivers which use regmap-irq with trigger type setting (gpio-max77620) to work with this new approach. So we do not magically support level-active IRQs on gpio-max77620 - but add support to the regmap-irq for chips which support them =) We do not support distinguishing situation where HW supports rising and falling edge detection but not both. Separating this would require inventing yet another flags for IRQ types. Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Этот коммит содержится в:

коммит произвёл
Mark Brown

родитель
84267d1b18
Коммит
1c2928e3e3
@@ -199,7 +199,7 @@ static void regmap_irq_enable(struct irq_data *data)
|
||||
const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
|
||||
unsigned int mask, type;
|
||||
|
||||
type = irq_data->type_falling_mask | irq_data->type_rising_mask;
|
||||
type = irq_data->type.type_falling_val | irq_data->type.type_rising_val;
|
||||
|
||||
/*
|
||||
* The type_in_mask flag means that the underlying hardware uses
|
||||
@@ -234,27 +234,42 @@ static int regmap_irq_set_type(struct irq_data *data, unsigned int type)
|
||||
struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
|
||||
struct regmap *map = d->map;
|
||||
const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
|
||||
int reg = irq_data->type_reg_offset / map->reg_stride;
|
||||
int reg;
|
||||
const struct regmap_irq_type *t = &irq_data->type;
|
||||
|
||||
if (!(irq_data->type_rising_mask | irq_data->type_falling_mask))
|
||||
return 0;
|
||||
if ((t->types_supported & type) != type)
|
||||
return -ENOTSUPP;
|
||||
|
||||
d->type_buf[reg] &= ~(irq_data->type_falling_mask |
|
||||
irq_data->type_rising_mask);
|
||||
reg = t->type_reg_offset / map->reg_stride;
|
||||
|
||||
if (t->type_reg_mask)
|
||||
d->type_buf[reg] &= ~t->type_reg_mask;
|
||||
else
|
||||
d->type_buf[reg] &= ~(t->type_falling_val |
|
||||
t->type_rising_val |
|
||||
t->type_level_low_val |
|
||||
t->type_level_high_val);
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
d->type_buf[reg] |= irq_data->type_falling_mask;
|
||||
d->type_buf[reg] |= t->type_falling_val;
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
d->type_buf[reg] |= irq_data->type_rising_mask;
|
||||
d->type_buf[reg] |= t->type_rising_val;
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
d->type_buf[reg] |= (irq_data->type_falling_mask |
|
||||
irq_data->type_rising_mask);
|
||||
d->type_buf[reg] |= (t->type_falling_val |
|
||||
t->type_rising_val);
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
d->type_buf[reg] |= t->type_level_high_val;
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
d->type_buf[reg] |= t->type_level_low_val;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
Ссылка в новой задаче
Block a user