Loading drivers/base/regmap/internal.h +3 −0 Original line number Diff line number Diff line Loading @@ -131,7 +131,10 @@ struct regmap { struct reg_default *reg_defaults; const void *reg_defaults_raw; void *cache; /* if set, the cache contains newer data than the HW */ u32 cache_dirty; /* if set, the HW registers are known to match map->reg_defaults */ bool no_sync_defaults; struct reg_default *patch; int patch_regs; Loading drivers/base/regmap/regcache.c +30 −15 Original line number Diff line number Diff line Loading @@ -249,6 +249,22 @@ int regcache_write(struct regmap *map, return 0; } static bool regcache_reg_needs_sync(struct regmap *map, unsigned int reg, unsigned int val) { int ret; /* If we don't know the chip just got reset, then sync everything. */ if (!map->no_sync_defaults) return true; /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, reg); if (ret >= 0 && val == map->reg_defaults[ret].def) return false; return true; } static int regcache_default_sync(struct regmap *map, unsigned int min, unsigned int max) { Loading @@ -266,9 +282,7 @@ static int regcache_default_sync(struct regmap *map, unsigned int min, if (ret) return ret; /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, reg); if (ret >= 0 && val == map->reg_defaults[ret].def) if (!regcache_reg_needs_sync(map, reg, val)) continue; map->cache_bypass = 1; Loading Loading @@ -342,6 +356,7 @@ int regcache_sync(struct regmap *map) /* Restore the bypass state */ map->async = false; map->cache_bypass = bypass; map->no_sync_defaults = false; map->unlock(map->lock_arg); regmap_async_complete(map); Loading Loading @@ -397,6 +412,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min, /* Restore the bypass state */ map->cache_bypass = bypass; map->async = false; map->no_sync_defaults = false; map->unlock(map->lock_arg); regmap_async_complete(map); Loading Loading @@ -461,18 +477,23 @@ void regcache_cache_only(struct regmap *map, bool enable) EXPORT_SYMBOL_GPL(regcache_cache_only); /** * regcache_mark_dirty: Mark the register cache as dirty * regcache_mark_dirty: Indicate that HW registers were reset to default values * * @map: map to mark * * Mark the register cache as dirty, for example due to the device * having been powered down for suspend. If the cache is not marked * as dirty then the cache sync will be suppressed. * Inform regcache that the device has been powered down or reset, so that * on resume, regcache_sync() knows to write out all non-default values * stored in the cache. * * If this function is not called, regcache_sync() will assume that * the hardware state still matches the cache state, modulo any writes that * happened when cache_only was true. */ void regcache_mark_dirty(struct regmap *map) { map->lock(map->lock_arg); map->cache_dirty = true; map->no_sync_defaults = true; map->unlock(map->lock_arg); } EXPORT_SYMBOL_GPL(regcache_mark_dirty); Loading Loading @@ -613,10 +634,7 @@ static int regcache_sync_block_single(struct regmap *map, void *block, continue; val = regcache_get_val(map, block, i); /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, regtmp); if (ret >= 0 && val == map->reg_defaults[ret].def) if (!regcache_reg_needs_sync(map, regtmp, val)) continue; map->cache_bypass = 1; Loading Loading @@ -688,10 +706,7 @@ static int regcache_sync_block_raw(struct regmap *map, void *block, } val = regcache_get_val(map, block, i); /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, regtmp); if (ret >= 0 && val == map->reg_defaults[ret].def) { if (!regcache_reg_needs_sync(map, regtmp, val)) { ret = regcache_sync_block_raw_flush(map, &data, base, regtmp); if (ret != 0) Loading drivers/base/regmap/regmap-irq.c +2 −9 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) if (!d->chip->init_ack_masked) continue; /* * Ack all the masked interrupts uncondictionly, * Ack all the masked interrupts unconditionally, * OR if there is masked interrupt which hasn't been Acked, * it'll be ignored in irq handler, then may introduce irq storm */ Loading Loading @@ -306,19 +306,12 @@ static int regmap_irq_map(struct irq_domain *h, unsigned int virq, irq_set_chip_data(virq, data); irq_set_chip(virq, &data->irq_chip); irq_set_nested_thread(virq, 1); /* ARM needs us to explicitly flag the IRQ as valid * and will set them noprobe when we do so. */ #ifdef CONFIG_ARM set_irq_flags(virq, IRQF_VALID); #else irq_set_noprobe(virq); #endif return 0; } static struct irq_domain_ops regmap_domain_ops = { static const struct irq_domain_ops regmap_domain_ops = { .map = regmap_irq_map, .xlate = irq_domain_xlate_twocell, }; Loading drivers/base/regmap/regmap.c +24 −0 Original line number Diff line number Diff line Loading @@ -2609,6 +2609,30 @@ int regmap_get_val_bytes(struct regmap *map) } EXPORT_SYMBOL_GPL(regmap_get_val_bytes); /** * regmap_get_max_register(): Report the max register value * * Report the max register value, mainly intended to for use by * generic infrastructure built on top of regmap. */ int regmap_get_max_register(struct regmap *map) { return map->max_register ? map->max_register : -EINVAL; } EXPORT_SYMBOL_GPL(regmap_get_max_register); /** * regmap_get_reg_stride(): Report the register address stride * * Report the register address stride, mainly intended to for use by * generic infrastructure built on top of regmap. */ int regmap_get_reg_stride(struct regmap *map) { return map->reg_stride; } EXPORT_SYMBOL_GPL(regmap_get_reg_stride); int regmap_parse_val(struct regmap *map, const void *buf, unsigned int *val) { Loading include/linux/regmap.h +14 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,8 @@ int regmap_update_bits_check_async(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change); int regmap_get_val_bytes(struct regmap *map); int regmap_get_max_register(struct regmap *map); int regmap_get_reg_stride(struct regmap *map); int regmap_async_complete(struct regmap *map); bool regmap_can_raw_write(struct regmap *map); Loading Loading @@ -676,6 +678,18 @@ static inline int regmap_get_val_bytes(struct regmap *map) return -EINVAL; } static inline int regmap_get_max_register(struct regmap *map) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regmap_get_reg_stride(struct regmap *map) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regcache_sync(struct regmap *map) { WARN_ONCE(1, "regmap API is disabled"); Loading Loading
drivers/base/regmap/internal.h +3 −0 Original line number Diff line number Diff line Loading @@ -131,7 +131,10 @@ struct regmap { struct reg_default *reg_defaults; const void *reg_defaults_raw; void *cache; /* if set, the cache contains newer data than the HW */ u32 cache_dirty; /* if set, the HW registers are known to match map->reg_defaults */ bool no_sync_defaults; struct reg_default *patch; int patch_regs; Loading
drivers/base/regmap/regcache.c +30 −15 Original line number Diff line number Diff line Loading @@ -249,6 +249,22 @@ int regcache_write(struct regmap *map, return 0; } static bool regcache_reg_needs_sync(struct regmap *map, unsigned int reg, unsigned int val) { int ret; /* If we don't know the chip just got reset, then sync everything. */ if (!map->no_sync_defaults) return true; /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, reg); if (ret >= 0 && val == map->reg_defaults[ret].def) return false; return true; } static int regcache_default_sync(struct regmap *map, unsigned int min, unsigned int max) { Loading @@ -266,9 +282,7 @@ static int regcache_default_sync(struct regmap *map, unsigned int min, if (ret) return ret; /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, reg); if (ret >= 0 && val == map->reg_defaults[ret].def) if (!regcache_reg_needs_sync(map, reg, val)) continue; map->cache_bypass = 1; Loading Loading @@ -342,6 +356,7 @@ int regcache_sync(struct regmap *map) /* Restore the bypass state */ map->async = false; map->cache_bypass = bypass; map->no_sync_defaults = false; map->unlock(map->lock_arg); regmap_async_complete(map); Loading Loading @@ -397,6 +412,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min, /* Restore the bypass state */ map->cache_bypass = bypass; map->async = false; map->no_sync_defaults = false; map->unlock(map->lock_arg); regmap_async_complete(map); Loading Loading @@ -461,18 +477,23 @@ void regcache_cache_only(struct regmap *map, bool enable) EXPORT_SYMBOL_GPL(regcache_cache_only); /** * regcache_mark_dirty: Mark the register cache as dirty * regcache_mark_dirty: Indicate that HW registers were reset to default values * * @map: map to mark * * Mark the register cache as dirty, for example due to the device * having been powered down for suspend. If the cache is not marked * as dirty then the cache sync will be suppressed. * Inform regcache that the device has been powered down or reset, so that * on resume, regcache_sync() knows to write out all non-default values * stored in the cache. * * If this function is not called, regcache_sync() will assume that * the hardware state still matches the cache state, modulo any writes that * happened when cache_only was true. */ void regcache_mark_dirty(struct regmap *map) { map->lock(map->lock_arg); map->cache_dirty = true; map->no_sync_defaults = true; map->unlock(map->lock_arg); } EXPORT_SYMBOL_GPL(regcache_mark_dirty); Loading Loading @@ -613,10 +634,7 @@ static int regcache_sync_block_single(struct regmap *map, void *block, continue; val = regcache_get_val(map, block, i); /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, regtmp); if (ret >= 0 && val == map->reg_defaults[ret].def) if (!regcache_reg_needs_sync(map, regtmp, val)) continue; map->cache_bypass = 1; Loading Loading @@ -688,10 +706,7 @@ static int regcache_sync_block_raw(struct regmap *map, void *block, } val = regcache_get_val(map, block, i); /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, regtmp); if (ret >= 0 && val == map->reg_defaults[ret].def) { if (!regcache_reg_needs_sync(map, regtmp, val)) { ret = regcache_sync_block_raw_flush(map, &data, base, regtmp); if (ret != 0) Loading
drivers/base/regmap/regmap-irq.c +2 −9 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) if (!d->chip->init_ack_masked) continue; /* * Ack all the masked interrupts uncondictionly, * Ack all the masked interrupts unconditionally, * OR if there is masked interrupt which hasn't been Acked, * it'll be ignored in irq handler, then may introduce irq storm */ Loading Loading @@ -306,19 +306,12 @@ static int regmap_irq_map(struct irq_domain *h, unsigned int virq, irq_set_chip_data(virq, data); irq_set_chip(virq, &data->irq_chip); irq_set_nested_thread(virq, 1); /* ARM needs us to explicitly flag the IRQ as valid * and will set them noprobe when we do so. */ #ifdef CONFIG_ARM set_irq_flags(virq, IRQF_VALID); #else irq_set_noprobe(virq); #endif return 0; } static struct irq_domain_ops regmap_domain_ops = { static const struct irq_domain_ops regmap_domain_ops = { .map = regmap_irq_map, .xlate = irq_domain_xlate_twocell, }; Loading
drivers/base/regmap/regmap.c +24 −0 Original line number Diff line number Diff line Loading @@ -2609,6 +2609,30 @@ int regmap_get_val_bytes(struct regmap *map) } EXPORT_SYMBOL_GPL(regmap_get_val_bytes); /** * regmap_get_max_register(): Report the max register value * * Report the max register value, mainly intended to for use by * generic infrastructure built on top of regmap. */ int regmap_get_max_register(struct regmap *map) { return map->max_register ? map->max_register : -EINVAL; } EXPORT_SYMBOL_GPL(regmap_get_max_register); /** * regmap_get_reg_stride(): Report the register address stride * * Report the register address stride, mainly intended to for use by * generic infrastructure built on top of regmap. */ int regmap_get_reg_stride(struct regmap *map) { return map->reg_stride; } EXPORT_SYMBOL_GPL(regmap_get_reg_stride); int regmap_parse_val(struct regmap *map, const void *buf, unsigned int *val) { Loading
include/linux/regmap.h +14 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,8 @@ int regmap_update_bits_check_async(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change); int regmap_get_val_bytes(struct regmap *map); int regmap_get_max_register(struct regmap *map); int regmap_get_reg_stride(struct regmap *map); int regmap_async_complete(struct regmap *map); bool regmap_can_raw_write(struct regmap *map); Loading Loading @@ -676,6 +678,18 @@ static inline int regmap_get_val_bytes(struct regmap *map) return -EINVAL; } static inline int regmap_get_max_register(struct regmap *map) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regmap_get_reg_stride(struct regmap *map) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regcache_sync(struct regmap *map) { WARN_ONCE(1, "regmap API is disabled"); Loading