Skip to content

Commit 69af4bc

Browse files
William Breathitt Graybroonie
authored andcommitted
regmap-irq: Add handle_mask_sync() callback
Provide a public callback handle_mask_sync() that drivers can use when they have more complex IRQ masking logic. The default implementation is regmap_irq_handle_mask_sync(), used if the chip doesn't provide its own callback. Cc: Mark Brown <[email protected]> Signed-off-by: William Breathitt Gray <[email protected]> Link: https://lore.kernel.org/r/e083474b3d467a86e6cb53da8072de4515bd6276.1669100542.git.william.gray@linaro.org Signed-off-by: Mark Brown <[email protected]>
1 parent acdce7a commit 69af4bc

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

drivers/base/regmap/regmap-irq.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,20 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
115115
*/
116116
for (i = 0; i < d->chip->num_regs; i++) {
117117
if (d->mask_base) {
118-
reg = d->get_irq_reg(d, d->mask_base, i);
119-
ret = regmap_update_bits(d->map, reg,
120-
d->mask_buf_def[i], d->mask_buf[i]);
121-
if (ret)
122-
dev_err(d->map->dev, "Failed to sync masks in %x\n",
123-
reg);
118+
if (d->chip->handle_mask_sync)
119+
d->chip->handle_mask_sync(d->map, i,
120+
d->mask_buf_def[i],
121+
d->mask_buf[i],
122+
d->chip->irq_drv_data);
123+
else {
124+
reg = d->get_irq_reg(d, d->mask_base, i);
125+
ret = regmap_update_bits(d->map, reg,
126+
d->mask_buf_def[i],
127+
d->mask_buf[i]);
128+
if (ret)
129+
dev_err(d->map->dev, "Failed to sync masks in %x\n",
130+
reg);
131+
}
124132
}
125133

126134
if (d->unmask_base) {
@@ -917,13 +925,23 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
917925
d->mask_buf[i] = d->mask_buf_def[i];
918926

919927
if (d->mask_base) {
920-
reg = d->get_irq_reg(d, d->mask_base, i);
921-
ret = regmap_update_bits(d->map, reg,
922-
d->mask_buf_def[i], d->mask_buf[i]);
923-
if (ret) {
924-
dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
925-
reg, ret);
926-
goto err_alloc;
928+
if (chip->handle_mask_sync) {
929+
ret = chip->handle_mask_sync(d->map, i,
930+
d->mask_buf_def[i],
931+
d->mask_buf[i],
932+
chip->irq_drv_data);
933+
if (ret)
934+
goto err_alloc;
935+
} else {
936+
reg = d->get_irq_reg(d, d->mask_base, i);
937+
ret = regmap_update_bits(d->map, reg,
938+
d->mask_buf_def[i],
939+
d->mask_buf[i]);
940+
if (ret) {
941+
dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
942+
reg, ret);
943+
goto err_alloc;
944+
}
927945
}
928946
}
929947

include/linux/regmap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,8 @@ struct regmap_irq_chip_data;
15801580
* before regmap_irq_handler process the interrupts.
15811581
* @handle_post_irq: Driver specific callback to handle interrupt from device
15821582
* after handling the interrupts in regmap_irq_handler().
1583+
* @handle_mask_sync: Callback used to handle IRQ mask syncs. The index will be
1584+
* in the range [0, num_regs)
15831585
* @set_type_virt: Driver specific callback to extend regmap_irq_set_type()
15841586
* and configure virt regs. Deprecated, use @set_type_config
15851587
* callback and config registers instead.
@@ -1641,6 +1643,9 @@ struct regmap_irq_chip {
16411643

16421644
int (*handle_pre_irq)(void *irq_drv_data);
16431645
int (*handle_post_irq)(void *irq_drv_data);
1646+
int (*handle_mask_sync)(struct regmap *map, int index,
1647+
unsigned int mask_buf_def,
1648+
unsigned int mask_buf, void *irq_drv_data);
16441649
int (*set_type_virt)(unsigned int **buf, unsigned int type,
16451650
unsigned long hwirq, int reg);
16461651
int (*set_type_config)(unsigned int **buf, unsigned int type,

0 commit comments

Comments
 (0)