Commit 1683c329 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull regmap fixes from Mark Brown:
 "The most important fix here is for missing dropping of the RCU read
  lock when syncing maple tree register caches, the physical devices I
  have that use the code don't do any syncing so I'd only ever tested
  this with virtual devices and missed the fact that we need to drop the
  lock in order to write to buses that need to sleep.

  Otherwise there's a fix for an edge case when splitting up large batch
  writes which has been lurking for a long time, a check to make sure
  nobody writes new drivers with a bug that was found in several
  SoundWire drivers and a tweak to the way the new kunit tests are
  enabled to ensure they don't cause regmap to be enabled when it
  wouldn't otherwise be"

* tag 'regmap-fix-v6.4-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
  regmap: maple: Drop the RCU read lock while syncing registers
  regmap: sdw: check for invalid multi-register writes config
  regmap: Account for register length when chunking
  regmap: REGMAP_KUNIT should not select REGMAP
parents 6d86b56f 0cc65780
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -4,16 +4,23 @@
# subsystems should select the appropriate symbols.

config REGMAP
	bool "Register Map support" if KUNIT_ALL_TESTS
	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO || REGMAP_FSI)
	select IRQ_DOMAIN if REGMAP_IRQ
	select MDIO_BUS if REGMAP_MDIO
	bool
	help
	  Enable support for the Register Map (regmap) access API.

	  Usually, this option is automatically selected when needed.
	  However, you may want to enable it manually for running the regmap
	  KUnit tests.

	  If unsure, say N.

config REGMAP_KUNIT
	tristate "KUnit tests for regmap"
	depends on KUNIT
	depends on KUNIT && REGMAP
	default KUNIT_ALL_TESTS
	select REGMAP
	select REGMAP_RAM

config REGMAP_AC97
+4 −1
Original line number Diff line number Diff line
@@ -203,15 +203,18 @@ static int regcache_maple_sync(struct regmap *map, unsigned int min,

	mas_for_each(&mas, entry, max) {
		for (r = max(mas.index, lmin); r <= min(mas.last, lmax); r++) {
			mas_pause(&mas);
			rcu_read_unlock();
			ret = regcache_sync_val(map, r, entry[r - mas.index]);
			if (ret != 0)
				goto out;
			rcu_read_lock();
		}
	}

out:
	rcu_read_unlock();

out:
	map->cache_bypass = false;

	return ret;
+4 −0
Original line number Diff line number Diff line
@@ -59,6 +59,10 @@ static int regmap_sdw_config_check(const struct regmap_config *config)
	if (config->pad_bits != 0)
		return -ENOTSUPP;

	/* Only bulk writes are supported not multi-register writes */
	if (config->can_multi_write)
		return -ENOTSUPP;

	return 0;
}

+4 −2
Original line number Diff line number Diff line
@@ -2082,6 +2082,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
	size_t val_count = val_len / val_bytes;
	size_t chunk_count, chunk_bytes;
	size_t chunk_regs = val_count;
	size_t max_data = map->max_raw_write - map->format.reg_bytes -
			map->format.pad_bytes;
	int ret, i;

	if (!val_count)
@@ -2089,8 +2091,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,

	if (map->use_single_write)
		chunk_regs = 1;
	else if (map->max_raw_write && val_len > map->max_raw_write)
		chunk_regs = map->max_raw_write / val_bytes;
	else if (map->max_raw_write && val_len > max_data)
		chunk_regs = max_data / val_bytes;

	chunk_count = val_count / chunk_regs;
	chunk_bytes = chunk_regs * val_bytes;