diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/regmap/regmap-irq.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 8b216b2e2c19..31d23c9a5ae7 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -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; + + reg = t->type_reg_offset / map->reg_stride; - d->type_buf[reg] &= ~(irq_data->type_falling_mask | - irq_data->type_rising_mask); + 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; } |