From 7f9fb67358a2bcaacbdfeee12e0f19e98c8bdf55 Mon Sep 17 00:00:00 2001 From: Xu Yilun Date: Wed, 19 Aug 2020 15:34:56 +0800 Subject: regmap: add Intel SPI Slave to AVMM Bus Bridge support This patch add support for regmap APIs that are intended to be used by the drivers of some SPI slave chips which integrate the "SPI slave to Avalon Master Bridge" (spi-avmm) IP. The spi-avmm IP acts as a bridge to convert encoded streams of bytes from the host to the chip's internal register read/write on Avalon bus. The driver implements the register read/write operations for a generic SPI master to access the sub devices behind spi-avmm bridge. Signed-off-by: Xu Yilun Signed-off-by: Wu Hao Signed-off-by: Matthew Gerlach Signed-off-by: Russ Weight Reviewed-by: Tom Rix Reviewed-by: Luis Claudio R. Goncalves Link: https://lore.kernel.org/r/1597822497-25107-2-git-send-email-yilun.xu@intel.com Signed-off-by: Mark Brown --- include/linux/regmap.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'include/linux/regmap.h') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 1970ed59d49f..d865d8fea535 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -567,6 +567,10 @@ 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 *__regmap_init_spi_avmm(struct spi_device *spi, + 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, @@ -620,6 +624,10 @@ struct regmap *__devm_regmap_init_i3c(struct i3c_device *i3c, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); +struct regmap *__devm_regmap_init_spi_avmm(struct spi_device *spi, + 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 * for each call. No-op if CONFIG_LOCKDEP is not set. @@ -806,6 +814,19 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__regmap_init_sdw, #config, \ sdw, config) +/** + * regmap_init_spi_avmm() - Initialize register map for Intel SPI Slave + * to AVMM Bus Bridge + * + * @spi: 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_spi_avmm(spi, config) \ + __regmap_lockdep_wrapper(__regmap_init_spi_avmm, #config, \ + spi, config) /** * devm_regmap_init() - Initialise managed register map @@ -993,6 +1014,21 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__devm_regmap_init_i3c, #config, \ i3c, config) +/** + * devm_regmap_init_spi_avmm() - Initialize register map for Intel SPI Slave + * to AVMM Bus Bridge + * + * @spi: 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 map will be automatically freed by the + * device management code. + */ +#define devm_regmap_init_spi_avmm(spi, config) \ + __regmap_lockdep_wrapper(__devm_regmap_init_spi_avmm, #config, \ + spi, config) + int regmap_mmio_attach_clk(struct regmap *map, struct clk *clk); void regmap_mmio_detach_clk(struct regmap *map); void regmap_exit(struct regmap *map); -- cgit v1.2.3 From 21f8e4828c44da39b0670c5d99d5728b739542a1 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Wed, 2 Sep 2020 17:18:43 +0300 Subject: regmap: Add can_sleep configuration option Regmap can't sleep if spinlock is used for the locking protection. This patch fixes regression caused by a previous commit that switched regmap to use fsleep() and this broke Amlogic S922X platform. This patch adds new configuration option for regmap users, allowing to specify whether regmap operations can sleep and assuming that sleep is allowed if mutex is used for the regmap locking protection. Reported-by: Marek Szyprowski Fixes: 2b32d2f7ce0a ("regmap: Use flexible sleep") Signed-off-by: Dmitry Osipenko Tested-by: Marek Szyprowski Link: https://lore.kernel.org/r/20200902141843.6591-1-digetx@gmail.com Signed-off-by: Mark Brown --- include/linux/regmap.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux/regmap.h') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index d865d8fea535..0c49d59168b5 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -342,6 +342,7 @@ typedef void (*regmap_unlock)(void *); * @hwlock_id: Specify the hardware spinlock id. * @hwlock_mode: The hardware spinlock mode, should be HWLOCK_IRQSTATE, * HWLOCK_IRQ or 0. + * @can_sleep: Optional, specifies whether regmap operations can sleep. */ struct regmap_config { const char *name; @@ -398,6 +399,8 @@ struct regmap_config { bool use_hwlock; unsigned int hwlock_id; unsigned int hwlock_mode; + + bool can_sleep; }; /** -- cgit v1.2.3 From ea470b82f205fc1b0b5276575da519bb7d86db25 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 25 Sep 2020 17:48:55 +0100 Subject: regmap: add support to regmap_field_bulk_alloc/free apis Usage of regmap_field_alloc becomes much overhead when number of fields exceed more than 3. QCOM LPASS driver has extensively converted to use regmap_fields. Using new bulk api to allocate fields makes it much more cleaner code to read! Signed-off-by: Srinivas Kandagatla Tested-by: Srinivasa Rao Mandadapu Link: https://lore.kernel.org/r/20200925164856.10315-2-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- include/linux/regmap.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/linux/regmap.h') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 1970ed59d49f..eafe833f0103 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1150,6 +1150,17 @@ struct regmap_field *devm_regmap_field_alloc(struct device *dev, struct regmap *regmap, struct reg_field reg_field); void devm_regmap_field_free(struct device *dev, struct regmap_field *field); +int regmap_field_bulk_alloc(struct regmap *regmap, + struct regmap_field **rm_field, + struct reg_field *reg_field, + int num_fields); +void regmap_field_bulk_free(struct regmap_field *field); +int devm_regmap_field_bulk_alloc(struct device *dev, struct regmap *regmap, + struct regmap_field **field, + struct reg_field *reg_field, int num_fields); +void devm_regmap_field_bulk_free(struct device *dev, + struct regmap_field *field); + int regmap_field_read(struct regmap_field *field, unsigned int *val); int regmap_field_update_bits_base(struct regmap_field *field, unsigned int mask, unsigned int val, -- cgit v1.2.3 From 3a6f0fb7b8eb5ef0447da1332225b8c87ee207d0 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 5 Oct 2020 19:47:19 +0530 Subject: regmap: irq: Add support to clear ack registers For particular codec HWs have requirement to toggle interrupt clear register twice 0->1->0. To accommodate it, need to add one more field (clear_ack) in the regmap_irq struct and update regmap-irq driver to support it. Signed-off-by: Laxminath Kasam Link: https://lore.kernel.org/r/1601907440-13373-1-git-send-email-lkasam@codeaurora.org Signed-off-by: Mark Brown --- include/linux/regmap.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/regmap.h') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index a35ec0a0d6e0..e7834d98207f 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1355,6 +1355,7 @@ struct regmap_irq_sub_irq_map { * @mask_invert: Inverted mask register: cleared bits are masked out. * @use_ack: Use @ack register even if it is zero. * @ack_invert: Inverted ack register: cleared bits for ack. + * @clear_ack: Use this to set 1 and 0 or vice-versa to clear interrupts. * @wake_invert: Inverted wake register: cleared bits are wake enabled. * @type_invert: Invert the type flags. * @type_in_mask: Use the mask registers for controlling irq type. For @@ -1403,6 +1404,7 @@ struct regmap_irq_chip { bool mask_invert:1; bool use_ack:1; bool ack_invert:1; + bool clear_ack:1; bool wake_invert:1; bool runtime_pm:1; bool type_invert:1; -- cgit v1.2.3 From 6e1e90ec027509a7e8d4efbd77a65b32b5a8b3ec Mon Sep 17 00:00:00 2001 From: Adrian Ratiu Date: Wed, 14 Oct 2020 23:30:24 +0300 Subject: regmap: mmio: add config option to allow relaxed MMIO accesses On some platforms (eg armv7 due to the CONFIG_ARM_DMA_MEM_BUFFERABLE) MMIO R/W operations always add memory barriers which can increase load, decrease battery life or in general reduce performance unnecessarily on devices which access a lot of configuration registers and where ordering does not matter (eg. media accelerators like the Verisilicon / Hantro video decoders). Drivers used to call the relaxed MMIO variants directly but since they are now accessing the MMIO registers via regmaps (to compensate for different VPU HW reg layouts via regmap fields), there is a need for a relaxed API / config to preserve existing behaviour. Cc: Mark Brown Signed-off-by: Adrian Ratiu Link: https://lore.kernel.org/r/20201014203024.954369-1-adrian.ratiu@collabora.com Signed-off-by: Mark Brown --- include/linux/regmap.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux/regmap.h') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index e7834d98207f..126fe700d1d8 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -315,6 +315,10 @@ typedef void (*regmap_unlock)(void *); * masks are used. * @zero_flag_mask: If set, read_flag_mask and write_flag_mask are used even * if they are both empty. + * @use_relaxed_mmio: If set, MMIO R/W operations will not use memory barriers. + * This can avoid load on devices which don't require strict + * orderings, but drivers should carefully add any explicit + * memory barriers when they may require them. * @use_single_read: If set, converts the bulk read operation into a series of * single read operations. This is useful for a device that * does not support bulk read. @@ -388,6 +392,7 @@ struct regmap_config { bool use_single_read; bool use_single_write; + bool use_relaxed_mmio; bool can_multi_write; enum regmap_endian reg_format_endian; -- cgit v1.2.3 From fb5103f9d6ce197b4d0b67b4e60e68470f5293d1 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 4 Nov 2020 01:22:23 +0800 Subject: regmap/SoundWire: sdw: add support for SoundWire 1.2 MBQ The SoundWire 1.1 specification only allowed for reads and writes of bytes. The SoundWire 1.2 specification adds a new capability to transfer "Multi-Byte Quantities" (MBQ) across the bus. The transfers still happens one-byte-at-a-time, but the update is atomic. For example when writing a 16-bit volume, the first byte transferred is only taken into account when the second byte is successfully transferred. The mechanism is symmetrical for read and writes: - On a read, the address of the last byte to be read is modified by setting the MBQ bit - On a write, the address of all but the last byte to be written are modified by setting the MBQ bit. The address for the last byte relies on the MBQ bit being cleared. The current definitions for MBQ-based controls in the SDCA draft standard are limited to 16 bits for volumes, so for now this is the only supported format. An update will be provided if and when support for 24-bit and 32-bit values is specified by the SDCA standard. One possible objection is that this code could have been handled with regmap-sdw.c. However this is a new spec addition not handled by every SoundWire 1.1 and non-SDCA device, so there's no reason to load code that will never be used. Also in practice it's extremely unlikely that CONFIG_REGMAP would not be selected with CONFIG_REGMAP_MBQ selected. However there's no functional dependency between the two modules so they can be selected separately. Reviewed-by: Rander Wang Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Signed-off-by: Pierre-Louis Bossart Signed-off-by: Bard Liao Reviewed-by: Vinod Koul Link: https://lore.kernel.org/r/20201103172226.4278-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- include/linux/regmap.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'include/linux/regmap.h') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index e7834d98207f..a652d1474d6a 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -570,6 +570,10 @@ 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 *__regmap_init_sdw_mbq(struct sdw_slave *sdw, + const struct regmap_config *config, + struct lock_class_key *lock_key, + const char *lock_name); struct regmap *__regmap_init_spi_avmm(struct spi_device *spi, const struct regmap_config *config, struct lock_class_key *lock_key, @@ -619,6 +623,10 @@ 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); +struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw, + const struct regmap_config *config, + struct lock_class_key *lock_key, + const char *lock_name); struct regmap *__devm_regmap_init_slimbus(struct slim_device *slimbus, const struct regmap_config *config, struct lock_class_key *lock_key, @@ -817,6 +825,19 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__regmap_init_sdw, #config, \ sdw, config) +/** + * regmap_init_sdw_mbq() - 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_mbq(sdw, config) \ + __regmap_lockdep_wrapper(__regmap_init_sdw_mbq, #config, \ + sdw, config) + /** * regmap_init_spi_avmm() - Initialize register map for Intel SPI Slave * to AVMM Bus Bridge @@ -989,6 +1010,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__devm_regmap_init_sdw, #config, \ sdw, config) +/** + * devm_regmap_init_sdw_mbq() - 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_mbq(sdw, config) \ + __regmap_lockdep_wrapper(__devm_regmap_init_sdw_mbq, #config, \ + sdw, config) + /** * devm_regmap_init_slimbus() - Initialise managed register map * -- cgit v1.2.3