regmap: irq: Add mask invert flag for enable register
authorXiaofan Tian <tianxf@marvell.com>
Thu, 30 Aug 2012 09:03:35 +0000 (17:03 +0800)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Thu, 30 Aug 2012 18:13:41 +0000 (11:13 -0700)
Currently, regmap will write 1 to mask_base to mask
an interrupt and write 0 to unmask it.

But some chips do not have an interrupt mask register,
and only have interrupt enable register.
Then we should write 0 to disable interrupt and 1 to enable.

So add an mask_invert flag to handle this.
If it is not set, behavior is same as previous.
If set it to 1, the mask value will be inverted
before written to mask_base

Signed-off-by: Xiaofan Tian <tianxf@marvell.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
drivers/base/regmap/regmap-irq.c
include/linux/regmap.h

index bb5e103..094f998 100644 (file)
@@ -78,7 +78,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
        for (i = 0; i < d->chip->num_regs; i++) {
                reg = d->chip->mask_base +
                        (i * map->reg_stride * d->irq_reg_stride);
-               ret = regmap_update_bits(d->map, reg,
+               if (d->chip->mask_invert)
+                       ret = regmap_update_bits(d->map, reg,
+                                        d->mask_buf_def[i], ~d->mask_buf[i]);
+               else
+                       ret = regmap_update_bits(d->map, reg,
                                         d->mask_buf_def[i], d->mask_buf[i]);
                if (ret != 0)
                        dev_err(d->map->dev, "Failed to sync masks in %x\n",
@@ -338,7 +342,11 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
                d->mask_buf[i] = d->mask_buf_def[i];
                reg = chip->mask_base +
                        (i * map->reg_stride * d->irq_reg_stride);
-               ret = regmap_update_bits(map, reg,
+               if (chip->mask_invert)
+                       ret = regmap_update_bits(map, reg,
+                                        d->mask_buf[i], ~d->mask_buf[i]);
+               else
+                       ret = regmap_update_bits(map, reg,
                                         d->mask_buf[i], d->mask_buf[i]);
                if (ret != 0) {
                        dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
index 9c4c9c6..e3bcc3f 100644 (file)
@@ -300,6 +300,7 @@ struct regmap_irq_chip {
        unsigned int ack_base;
        unsigned int wake_base;
        unsigned int irq_reg_stride;
+       unsigned int mask_invert;
        bool runtime_pm;
 
        int num_regs;