Loading drivers/base/regmap/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ config REGMAP default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ) select IRQ_DOMAIN if REGMAP_IRQ select REGMAP_HWSPINLOCK if HWSPINLOCK=y bool config REGCACHE_COMPRESSED Loading Loading @@ -36,3 +37,6 @@ config REGMAP_MMIO config REGMAP_IRQ bool config REGMAP_HWSPINLOCK bool drivers/base/regmap/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,8 @@ struct regmap { struct rb_root range_tree; void *selector_work_buf; /* Scratch buffer used for selector */ struct hwspinlock *hwlock; }; struct regcache_ops { Loading drivers/base/regmap/regmap-spi.c +1 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ static int regmap_spi_read(void *context, return spi_write_then_read(spi, reg, reg_size, val, val_size); } static struct regmap_bus regmap_spi = { static const struct regmap_bus regmap_spi = { .write = regmap_spi_write, .gather_write = regmap_spi_gather_write, .async_write = regmap_spi_async_write, Loading drivers/base/regmap/regmap-spmi.c +2 −2 Original line number Diff line number Diff line Loading @@ -83,7 +83,7 @@ static int regmap_spmi_base_write(void *context, const void *data, count - 1); } static struct regmap_bus regmap_spmi_base = { static const struct regmap_bus regmap_spmi_base = { .read = regmap_spmi_base_read, .write = regmap_spmi_base_write, .gather_write = regmap_spmi_base_gather_write, Loading Loading @@ -203,7 +203,7 @@ static int regmap_spmi_ext_write(void *context, const void *data, count - 2); } static struct regmap_bus regmap_spmi_ext = { static const struct regmap_bus regmap_spmi_ext = { .read = regmap_spmi_ext_read, .write = regmap_spmi_ext_write, .gather_write = regmap_spmi_ext_gather_write, Loading drivers/base/regmap/regmap.c +95 −16 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/sched.h> #include <linux/delay.h> #include <linux/log2.h> #include <linux/hwspinlock.h> #define CREATE_TRACE_POINTS #include "trace.h" Loading Loading @@ -413,6 +414,51 @@ static unsigned int regmap_parse_64_native(const void *buf) } #endif #ifdef REGMAP_HWSPINLOCK static void regmap_lock_hwlock(void *__map) { struct regmap *map = __map; hwspin_lock_timeout(map->hwlock, UINT_MAX); } static void regmap_lock_hwlock_irq(void *__map) { struct regmap *map = __map; hwspin_lock_timeout_irq(map->hwlock, UINT_MAX); } static void regmap_lock_hwlock_irqsave(void *__map) { struct regmap *map = __map; hwspin_lock_timeout_irqsave(map->hwlock, UINT_MAX, &map->spinlock_flags); } static void regmap_unlock_hwlock(void *__map) { struct regmap *map = __map; hwspin_unlock(map->hwlock); } static void regmap_unlock_hwlock_irq(void *__map) { struct regmap *map = __map; hwspin_unlock_irq(map->hwlock); } static void regmap_unlock_hwlock_irqrestore(void *__map) { struct regmap *map = __map; hwspin_unlock_irqrestore(map->hwlock, &map->spinlock_flags); } #endif static void regmap_lock_mutex(void *__map) { struct regmap *map = __map; Loading Loading @@ -627,6 +673,34 @@ struct regmap *__regmap_init(struct device *dev, map->lock = config->lock; map->unlock = config->unlock; map->lock_arg = config->lock_arg; } else if (config->hwlock_id) { #ifdef REGMAP_HWSPINLOCK map->hwlock = hwspin_lock_request_specific(config->hwlock_id); if (!map->hwlock) { ret = -ENXIO; goto err_map; } switch (config->hwlock_mode) { case HWLOCK_IRQSTATE: map->lock = regmap_lock_hwlock_irqsave; map->unlock = regmap_unlock_hwlock_irqrestore; break; case HWLOCK_IRQ: map->lock = regmap_lock_hwlock_irq; map->unlock = regmap_unlock_hwlock_irq; break; default: map->lock = regmap_lock_hwlock; map->unlock = regmap_unlock_hwlock; break; } map->lock_arg = map; #else ret = -EINVAL; goto err_map; #endif } else { if ((bus && bus->fast_io) || config->fast_io) { Loading Loading @@ -729,7 +803,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_2_6_write; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -739,7 +813,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_4_12_write; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -749,7 +823,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_7_9_write; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -759,7 +833,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_10_14_write; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -779,13 +853,13 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_reg = regmap_format_16_native; break; default: goto err_map; goto err_hwlock; } break; case 24: if (reg_endian != REGMAP_ENDIAN_BIG) goto err_map; goto err_hwlock; map->format.format_reg = regmap_format_24; break; Loading @@ -801,7 +875,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_reg = regmap_format_32_native; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -818,13 +892,13 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_reg = regmap_format_64_native; break; default: goto err_map; goto err_hwlock; } break; #endif default: goto err_map; goto err_hwlock; } if (val_endian == REGMAP_ENDIAN_NATIVE) Loading Loading @@ -853,12 +927,12 @@ struct regmap *__regmap_init(struct device *dev, map->format.parse_val = regmap_parse_16_native; break; default: goto err_map; goto err_hwlock; } break; case 24: if (val_endian != REGMAP_ENDIAN_BIG) goto err_map; goto err_hwlock; map->format.format_val = regmap_format_24; map->format.parse_val = regmap_parse_24; break; Loading @@ -879,7 +953,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.parse_val = regmap_parse_32_native; break; default: goto err_map; goto err_hwlock; } break; #ifdef CONFIG_64BIT Loading @@ -900,7 +974,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.parse_val = regmap_parse_64_native; break; default: goto err_map; goto err_hwlock; } break; #endif Loading @@ -909,18 +983,18 @@ struct regmap *__regmap_init(struct device *dev, if (map->format.format_write) { if ((reg_endian != REGMAP_ENDIAN_BIG) || (val_endian != REGMAP_ENDIAN_BIG)) goto err_map; goto err_hwlock; map->use_single_write = true; } if (!map->format.format_write && !(map->format.format_reg && map->format.format_val)) goto err_map; goto err_hwlock; map->work_buf = kzalloc(map->format.buf_size, GFP_KERNEL); if (map->work_buf == NULL) { ret = -ENOMEM; goto err_map; goto err_hwlock; } if (map->format.format_write) { Loading Loading @@ -1041,6 +1115,9 @@ struct regmap *__regmap_init(struct device *dev, err_range: regmap_range_exit(map); kfree(map->work_buf); err_hwlock: if (IS_ENABLED(REGMAP_HWSPINLOCK) && map->hwlock) hwspin_lock_free(map->hwlock); err_map: kfree(map); err: Loading Loading @@ -1228,6 +1305,8 @@ void regmap_exit(struct regmap *map) kfree(async->work_buf); kfree(async); } if (IS_ENABLED(REGMAP_HWSPINLOCK) && map->hwlock) hwspin_lock_free(map->hwlock); kfree(map); } EXPORT_SYMBOL_GPL(regmap_exit); Loading Loading
drivers/base/regmap/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ config REGMAP default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ) select IRQ_DOMAIN if REGMAP_IRQ select REGMAP_HWSPINLOCK if HWSPINLOCK=y bool config REGCACHE_COMPRESSED Loading Loading @@ -36,3 +37,6 @@ config REGMAP_MMIO config REGMAP_IRQ bool config REGMAP_HWSPINLOCK bool
drivers/base/regmap/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,8 @@ struct regmap { struct rb_root range_tree; void *selector_work_buf; /* Scratch buffer used for selector */ struct hwspinlock *hwlock; }; struct regcache_ops { Loading
drivers/base/regmap/regmap-spi.c +1 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ static int regmap_spi_read(void *context, return spi_write_then_read(spi, reg, reg_size, val, val_size); } static struct regmap_bus regmap_spi = { static const struct regmap_bus regmap_spi = { .write = regmap_spi_write, .gather_write = regmap_spi_gather_write, .async_write = regmap_spi_async_write, Loading
drivers/base/regmap/regmap-spmi.c +2 −2 Original line number Diff line number Diff line Loading @@ -83,7 +83,7 @@ static int regmap_spmi_base_write(void *context, const void *data, count - 1); } static struct regmap_bus regmap_spmi_base = { static const struct regmap_bus regmap_spmi_base = { .read = regmap_spmi_base_read, .write = regmap_spmi_base_write, .gather_write = regmap_spmi_base_gather_write, Loading Loading @@ -203,7 +203,7 @@ static int regmap_spmi_ext_write(void *context, const void *data, count - 2); } static struct regmap_bus regmap_spmi_ext = { static const struct regmap_bus regmap_spmi_ext = { .read = regmap_spmi_ext_read, .write = regmap_spmi_ext_write, .gather_write = regmap_spmi_ext_gather_write, Loading
drivers/base/regmap/regmap.c +95 −16 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/sched.h> #include <linux/delay.h> #include <linux/log2.h> #include <linux/hwspinlock.h> #define CREATE_TRACE_POINTS #include "trace.h" Loading Loading @@ -413,6 +414,51 @@ static unsigned int regmap_parse_64_native(const void *buf) } #endif #ifdef REGMAP_HWSPINLOCK static void regmap_lock_hwlock(void *__map) { struct regmap *map = __map; hwspin_lock_timeout(map->hwlock, UINT_MAX); } static void regmap_lock_hwlock_irq(void *__map) { struct regmap *map = __map; hwspin_lock_timeout_irq(map->hwlock, UINT_MAX); } static void regmap_lock_hwlock_irqsave(void *__map) { struct regmap *map = __map; hwspin_lock_timeout_irqsave(map->hwlock, UINT_MAX, &map->spinlock_flags); } static void regmap_unlock_hwlock(void *__map) { struct regmap *map = __map; hwspin_unlock(map->hwlock); } static void regmap_unlock_hwlock_irq(void *__map) { struct regmap *map = __map; hwspin_unlock_irq(map->hwlock); } static void regmap_unlock_hwlock_irqrestore(void *__map) { struct regmap *map = __map; hwspin_unlock_irqrestore(map->hwlock, &map->spinlock_flags); } #endif static void regmap_lock_mutex(void *__map) { struct regmap *map = __map; Loading Loading @@ -627,6 +673,34 @@ struct regmap *__regmap_init(struct device *dev, map->lock = config->lock; map->unlock = config->unlock; map->lock_arg = config->lock_arg; } else if (config->hwlock_id) { #ifdef REGMAP_HWSPINLOCK map->hwlock = hwspin_lock_request_specific(config->hwlock_id); if (!map->hwlock) { ret = -ENXIO; goto err_map; } switch (config->hwlock_mode) { case HWLOCK_IRQSTATE: map->lock = regmap_lock_hwlock_irqsave; map->unlock = regmap_unlock_hwlock_irqrestore; break; case HWLOCK_IRQ: map->lock = regmap_lock_hwlock_irq; map->unlock = regmap_unlock_hwlock_irq; break; default: map->lock = regmap_lock_hwlock; map->unlock = regmap_unlock_hwlock; break; } map->lock_arg = map; #else ret = -EINVAL; goto err_map; #endif } else { if ((bus && bus->fast_io) || config->fast_io) { Loading Loading @@ -729,7 +803,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_2_6_write; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -739,7 +813,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_4_12_write; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -749,7 +823,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_7_9_write; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -759,7 +833,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_write = regmap_format_10_14_write; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -779,13 +853,13 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_reg = regmap_format_16_native; break; default: goto err_map; goto err_hwlock; } break; case 24: if (reg_endian != REGMAP_ENDIAN_BIG) goto err_map; goto err_hwlock; map->format.format_reg = regmap_format_24; break; Loading @@ -801,7 +875,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_reg = regmap_format_32_native; break; default: goto err_map; goto err_hwlock; } break; Loading @@ -818,13 +892,13 @@ struct regmap *__regmap_init(struct device *dev, map->format.format_reg = regmap_format_64_native; break; default: goto err_map; goto err_hwlock; } break; #endif default: goto err_map; goto err_hwlock; } if (val_endian == REGMAP_ENDIAN_NATIVE) Loading Loading @@ -853,12 +927,12 @@ struct regmap *__regmap_init(struct device *dev, map->format.parse_val = regmap_parse_16_native; break; default: goto err_map; goto err_hwlock; } break; case 24: if (val_endian != REGMAP_ENDIAN_BIG) goto err_map; goto err_hwlock; map->format.format_val = regmap_format_24; map->format.parse_val = regmap_parse_24; break; Loading @@ -879,7 +953,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.parse_val = regmap_parse_32_native; break; default: goto err_map; goto err_hwlock; } break; #ifdef CONFIG_64BIT Loading @@ -900,7 +974,7 @@ struct regmap *__regmap_init(struct device *dev, map->format.parse_val = regmap_parse_64_native; break; default: goto err_map; goto err_hwlock; } break; #endif Loading @@ -909,18 +983,18 @@ struct regmap *__regmap_init(struct device *dev, if (map->format.format_write) { if ((reg_endian != REGMAP_ENDIAN_BIG) || (val_endian != REGMAP_ENDIAN_BIG)) goto err_map; goto err_hwlock; map->use_single_write = true; } if (!map->format.format_write && !(map->format.format_reg && map->format.format_val)) goto err_map; goto err_hwlock; map->work_buf = kzalloc(map->format.buf_size, GFP_KERNEL); if (map->work_buf == NULL) { ret = -ENOMEM; goto err_map; goto err_hwlock; } if (map->format.format_write) { Loading Loading @@ -1041,6 +1115,9 @@ struct regmap *__regmap_init(struct device *dev, err_range: regmap_range_exit(map); kfree(map->work_buf); err_hwlock: if (IS_ENABLED(REGMAP_HWSPINLOCK) && map->hwlock) hwspin_lock_free(map->hwlock); err_map: kfree(map); err: Loading Loading @@ -1228,6 +1305,8 @@ void regmap_exit(struct regmap *map) kfree(async->work_buf); kfree(async); } if (IS_ENABLED(REGMAP_HWSPINLOCK) && map->hwlock) hwspin_lock_free(map->hwlock); kfree(map); } EXPORT_SYMBOL_GPL(regmap_exit); Loading