Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4a21fc2 authored by Stephen Boyd's avatar Stephen Boyd Committed by Mark Brown
Browse files

regmap: Allocate buffers with GFP_ATOMIC when fast_io == true



If a regmap is using fast_io, allocate the scratch buffer in
regmap_bulk_write() with GFP_ATOMIC instead of GFP_KERNEL.
Otherwise we may schedule while atomic.

Reported-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 6ff33f39
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ struct regmap {
	regmap_lock lock;
	regmap_unlock unlock;
	void *lock_arg; /* This is passed to lock/unlock functions */
	gfp_t alloc_flags;

	struct device *dev; /* Device we do I/O on */
	void *work_buf;     /* Scratch buffer used to format I/O */
+11 −1
Original line number Diff line number Diff line
@@ -561,6 +561,16 @@ struct regmap *__regmap_init(struct device *dev,
		}
		map->lock_arg = map;
	}

	/*
	 * When we write in fast-paths with regmap_bulk_write() don't allocate
	 * scratch buffers with sleeping allocations.
	 */
	if ((bus && bus->fast_io) || config->fast_io)
		map->alloc_flags = GFP_ATOMIC;
	else
		map->alloc_flags = GFP_KERNEL;

	map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
	map->format.pad_bytes = config->pad_bits / 8;
	map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
@@ -1786,7 +1796,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
		if (!val_count)
			return -EINVAL;

		wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
		wval = kmemdup(val, val_count * val_bytes, map->alloc_flags);
		if (!wval) {
			dev_err(map->dev, "Error in memory allocation\n");
			return -ENOMEM;