From c9b41fcf272b4926b373d21c2b83dfe374313780 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 6 Dec 2017 15:26:21 +0100 Subject: regmap: allow to disable all locking mechanisms We have a use case in the at24 EEPROM driver (recently converted to using regmap instead of raw i2c/smbus calls) where we read from/write to the regmap in a loop, while protecting the entire loop with a mutex. Currently this implicitly makes us use two mutexes - one in the driver and one in regmap. While browsing the code for similar use cases I noticed a significant number of places where locking *seems* redundant. Allow users to completely disable any locking mechanisms in regmap config. Signed-off-by: Bartosz Golaszewski Signed-off-by: Mark Brown --- include/linux/regmap.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 15eddc1353ba..072a90229e34 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -264,6 +264,9 @@ typedef void (*regmap_unlock)(void *); * field is NULL but precious_table (see below) is not, the * check is performed on such table (a register is precious if * it belongs to one of the ranges specified by precious_table). + * @disable_locking: This regmap is either protected by external means or + * is guaranteed not be be accessed from multiple threads. + * Don't use any locking mechanisms. * @lock: Optional lock callback (overrides regmap's default lock * function, based on spinlock or mutex). * @unlock: As above for unlocking. @@ -333,6 +336,8 @@ struct regmap_config { bool (*readable_reg)(struct device *dev, unsigned int reg); bool (*volatile_reg)(struct device *dev, unsigned int reg); bool (*precious_reg)(struct device *dev, unsigned int reg); + + bool disable_locking; regmap_lock lock; regmap_unlock unlock; void *lock_arg; -- cgit From a4887813c3a9481ab87c8a71ab1de50b975cc823 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Mon, 25 Dec 2017 14:37:09 +0800 Subject: regmap: Add one flag to indicate if a hwlock should be used Since the hwlock id 0 is valid for hardware spinlock core, but now id 0 is treated as one invalid value for regmap. Thus we should add one extra flag for regmap config to indicate if a hardware spinlock should be used, then id 0 can be valid for regmap to request. Signed-off-by: Baolin Wang Signed-off-by: Mark Brown --- include/linux/regmap.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 15eddc1353ba..c78e0057df66 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -317,6 +317,7 @@ typedef void (*regmap_unlock)(void *); * * @ranges: Array of configuration entries for virtual address ranges. * @num_ranges: Number of range configuration entries. + * @use_hwlock: Indicate if a hardware spinlock should be used. * @hwlock_id: Specify the hardware spinlock id. * @hwlock_mode: The hardware spinlock mode, should be HWLOCK_IRQSTATE, * HWLOCK_IRQ or 0. @@ -365,6 +366,7 @@ struct regmap_config { const struct regmap_range_cfg *ranges; unsigned int num_ranges; + bool use_hwlock; unsigned int hwlock_id; unsigned int hwlock_mode; }; -- cgit From 7c22ce6e218403fc8746f7915b5a391d8227f7e1 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 8 Jan 2018 15:50:59 +0530 Subject: regmap: Add SoundWire bus support SoundWire bus provides sdw_read() and sdw_write() APIs for Slave devices to program the registers. Provide support in regmap for SoundWire bus. Signed-off-by: Hardik T Shah Signed-off-by: Sanyog Kale Reviewed-by: Philippe Ombredanne Acked-by: Pierre-Louis Bossart Reviewed-by: Takashi Iwai Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- include/linux/regmap.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'include') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index c78e0057df66..eab9c0a29837 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -30,6 +30,7 @@ struct regmap; struct regmap_range_cfg; struct regmap_field; struct snd_ac97; +struct sdw_slave; /* An enum of all the supported cache types */ enum regcache_type { @@ -526,6 +527,10 @@ struct regmap *__regmap_init_ac97(struct snd_ac97 *ac97, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); +struct regmap *__regmap_init_sdw(struct sdw_slave *sdw, + const struct regmap_config *config, + struct lock_class_key *lock_key, + const char *lock_name); struct regmap *__devm_regmap_init(struct device *dev, const struct regmap_bus *bus, @@ -563,6 +568,10 @@ struct regmap *__devm_regmap_init_ac97(struct snd_ac97 *ac97, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); +struct regmap *__devm_regmap_init_sdw(struct sdw_slave *sdw, + const struct regmap_config *config, + struct lock_class_key *lock_key, + const char *lock_name); /* * Wrapper for regmap_init macros to include a unique lockdep key and name @@ -711,6 +720,20 @@ int regmap_attach_dev(struct device *dev, struct regmap *map, ac97, config) bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); +/** + * regmap_init_sdw() - Initialise register map + * + * @sdw: Device that will be interacted with + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer to + * a struct regmap. + */ +#define regmap_init_sdw(sdw, config) \ + __regmap_lockdep_wrapper(__regmap_init_sdw, #config, \ + sdw, config) + + /** * devm_regmap_init() - Initialise managed register map * @@ -841,6 +864,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__devm_regmap_init_ac97, #config, \ ac97, config) +/** + * devm_regmap_init_sdw() - Initialise managed register map + * + * @sdw: Device that will be interacted with + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer + * to a struct regmap. The regmap will be automatically freed by the + * device management code. + */ +#define devm_regmap_init_sdw(sdw, config) \ + __regmap_lockdep_wrapper(__devm_regmap_init_sdw, #config, \ + sdw, config) + void regmap_exit(struct regmap *map); int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config); -- cgit From 9bf485c955bcb707a5e679bcc74075deb0bc8531 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Sun, 7 Jan 2018 17:19:09 -0600 Subject: regmap: Allow empty read/write_flag_mask All zero read and write masks in the regmap config are used to signal no special mask is needed and the bus defaults are used. In some devices all zero read/write masks are the special mask and bus defaults should not be used. To signal this a new variable is added. For example SPI often sets bit 7 in address to signal to the device a read is requested. On TI AFE44xx parts with SPI interfaces no bit needs to be set as registers are either read or write only and the operation can be determined from the address only. For this case both masks must be zero to not effect the address. Signed-off-by: Andrew F. Davis Signed-off-by: Mark Brown --- include/linux/regmap.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 15eddc1353ba..f8bff272c429 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -296,7 +296,10 @@ typedef void (*regmap_unlock)(void *); * a read. * @write_flag_mask: Mask to be set in the top bytes of the register when doing * a write. If both read_flag_mask and write_flag_mask are - * empty the regmap_bus default masks are used. + * empty and zero_flag_mask is not set the regmap_bus default + * masks are used. + * @zero_flag_mask: If set, read_flag_mask and write_flag_mask are used even + * if they are both empty. * @use_single_rw: If set, converts the bulk read and write operations into * a series of single read and write operations. This is useful * for device that does not support bulk read and write. @@ -355,6 +358,7 @@ struct regmap_config { unsigned long read_flag_mask; unsigned long write_flag_mask; + bool zero_flag_mask; bool use_single_rw; bool can_multi_write; -- cgit