Unverified Commit 69af4bca authored by William Breathitt Gray's avatar William Breathitt Gray Committed by Mark Brown
Browse files

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 <broonie@kernel.org>
Signed-off-by: default avatarWilliam Breathitt Gray <william.gray@linaro.org>
Link: https://lore.kernel.org/r/e083474b3d467a86e6cb53da8072de4515bd6276.1669100542.git.william.gray@linaro.org


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent acdce7aa
Loading
Loading
Loading
Loading
+31 −13
Original line number Diff line number Diff line
@@ -115,13 +115,21 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
	 */
	for (i = 0; i < d->chip->num_regs; i++) {
		if (d->mask_base) {
			if (d->chip->handle_mask_sync)
				d->chip->handle_mask_sync(d->map, i,
							  d->mask_buf_def[i],
							  d->mask_buf[i],
							  d->chip->irq_drv_data);
			else {
				reg = d->get_irq_reg(d, d->mask_base, i);
				ret = regmap_update_bits(d->map, reg,
					d->mask_buf_def[i], d->mask_buf[i]);
						d->mask_buf_def[i],
						d->mask_buf[i]);
				if (ret)
					dev_err(d->map->dev, "Failed to sync masks in %x\n",
						reg);
			}
		}

		if (d->unmask_base) {
			reg = d->get_irq_reg(d, d->unmask_base, i);
@@ -917,15 +925,25 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
		d->mask_buf[i] = d->mask_buf_def[i];

		if (d->mask_base) {
			if (chip->handle_mask_sync) {
				ret = chip->handle_mask_sync(d->map, i,
							     d->mask_buf_def[i],
							     d->mask_buf[i],
							     chip->irq_drv_data);
				if (ret)
					goto err_alloc;
			} else {
				reg = d->get_irq_reg(d, d->mask_base, i);
				ret = regmap_update_bits(d->map, reg,
					d->mask_buf_def[i], d->mask_buf[i]);
						d->mask_buf_def[i],
						d->mask_buf[i]);
				if (ret) {
					dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
						reg, ret);
					goto err_alloc;
				}
			}
		}

		if (d->unmask_base) {
			reg = d->get_irq_reg(d, d->unmask_base, i);
+5 −0
Original line number Diff line number Diff line
@@ -1580,6 +1580,8 @@ struct regmap_irq_chip_data;
 *		     before regmap_irq_handler process the interrupts.
 * @handle_post_irq: Driver specific callback to handle interrupt from device
 *		     after handling the interrupts in regmap_irq_handler().
 * @handle_mask_sync: Callback used to handle IRQ mask syncs. The index will be
 *		      in the range [0, num_regs)
 * @set_type_virt:   Driver specific callback to extend regmap_irq_set_type()
 *		     and configure virt regs. Deprecated, use @set_type_config
 *		     callback and config registers instead.
@@ -1641,6 +1643,9 @@ struct regmap_irq_chip {

	int (*handle_pre_irq)(void *irq_drv_data);
	int (*handle_post_irq)(void *irq_drv_data);
	int (*handle_mask_sync)(struct regmap *map, int index,
				unsigned int mask_buf_def,
				unsigned int mask_buf, void *irq_drv_data);
	int (*set_type_virt)(unsigned int **buf, unsigned int type,
			     unsigned long hwirq, int reg);
	int (*set_type_config)(unsigned int **buf, unsigned int type,