mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	regmap: cache: Fall back to register by register read for cache defaults
If we are unable to read the cache defaults for a regmap then fall back on attempting to read them word by word. This is going to be painfully slow for large regmaps but might be adequate for smaller ones. Signed-off-by: Mark Brown <broonie@kernel.org> [maciej: Use cache_bypass around read and skipping of unreadable regs] Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com> Tested-by: Fabio Estevam <fabio.estevam@nxp.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
		
							parent
							
								
									bb2bb45d1b
								
							
						
					
					
						commit
						3245d460a1
					
				
					 1 changed files with 30 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -30,7 +30,7 @@ static int regcache_hw_init(struct regmap *map)
 | 
			
		|||
	int i, j;
 | 
			
		||||
	int ret;
 | 
			
		||||
	int count;
 | 
			
		||||
	unsigned int val;
 | 
			
		||||
	unsigned int reg, val;
 | 
			
		||||
	void *tmp_buf;
 | 
			
		||||
 | 
			
		||||
	if (!map->num_reg_defaults_raw)
 | 
			
		||||
| 
						 | 
				
			
			@ -67,27 +67,46 @@ static int regcache_hw_init(struct regmap *map)
 | 
			
		|||
		ret = regmap_raw_read(map, 0, tmp_buf,
 | 
			
		||||
				      map->num_reg_defaults_raw);
 | 
			
		||||
		map->cache_bypass = cache_bypass;
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			goto err_cache_free;
 | 
			
		||||
 | 
			
		||||
		if (ret == 0) {
 | 
			
		||||
			map->reg_defaults_raw = tmp_buf;
 | 
			
		||||
			map->cache_free = 1;
 | 
			
		||||
		} else {
 | 
			
		||||
			kfree(tmp_buf);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* fill the reg_defaults */
 | 
			
		||||
	for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
 | 
			
		||||
		if (regmap_volatile(map, i * map->reg_stride))
 | 
			
		||||
		reg = i * map->reg_stride;
 | 
			
		||||
 | 
			
		||||
		if (!regmap_readable(map, reg))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (regmap_volatile(map, reg))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (map->reg_defaults_raw) {
 | 
			
		||||
			val = regcache_get_val(map, map->reg_defaults_raw, i);
 | 
			
		||||
		map->reg_defaults[j].reg = i * map->reg_stride;
 | 
			
		||||
		} else {
 | 
			
		||||
			bool cache_bypass = map->cache_bypass;
 | 
			
		||||
 | 
			
		||||
			map->cache_bypass = true;
 | 
			
		||||
			ret = regmap_read(map, reg, &val);
 | 
			
		||||
			map->cache_bypass = cache_bypass;
 | 
			
		||||
			if (ret != 0) {
 | 
			
		||||
				dev_err(map->dev, "Failed to read %d: %d\n",
 | 
			
		||||
					reg, ret);
 | 
			
		||||
				goto err_free;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		map->reg_defaults[j].reg = reg;
 | 
			
		||||
		map->reg_defaults[j].def = val;
 | 
			
		||||
		j++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
err_cache_free:
 | 
			
		||||
	kfree(tmp_buf);
 | 
			
		||||
err_free:
 | 
			
		||||
	kfree(map->reg_defaults);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue