forked from coolsnowwolf/lede
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
generic: backport regmap reg_base and downshift features
- Loading branch information
1 parent
1a232d6
commit c9360b1
Showing
4 changed files
with
243 additions
and
1 deletion.
There are no files selected for viewing
90 changes: 90 additions & 0 deletions
90
...nux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
From 86fc59ef818beb0e1945d17f8e734898baba7e4e Mon Sep 17 00:00:00 2001 | ||
From: Colin Foster <colin.foster@in-advantage.com> | ||
Date: Sun, 13 Mar 2022 15:45:23 -0700 | ||
Subject: [PATCH 1/2] regmap: add configurable downshift for addresses | ||
|
||
Add an additional reg_downshift to be applied to register addresses before | ||
any register accesses. An example of a device that uses this is a VSC7514 | ||
chip, which require each register address to be downshifted by two if the | ||
access is performed over a SPI bus. | ||
|
||
Signed-off-by: Colin Foster <colin.foster@in-advantage.com> | ||
Link: https://lore.kernel.org/r/20220313224524.399947-2-colin.foster@in-advantage.com | ||
Signed-off-by: Mark Brown <broonie@kernel.org> | ||
--- | ||
drivers/base/regmap/internal.h | 1 + | ||
drivers/base/regmap/regmap.c | 5 +++++ | ||
include/linux/regmap.h | 3 +++ | ||
3 files changed, 9 insertions(+) | ||
|
||
--- a/drivers/base/regmap/internal.h | ||
+++ b/drivers/base/regmap/internal.h | ||
@@ -31,6 +31,7 @@ struct regmap_format { | ||
size_t buf_size; | ||
size_t reg_bytes; | ||
size_t pad_bytes; | ||
+ size_t reg_downshift; | ||
size_t val_bytes; | ||
void (*format_write)(struct regmap *map, | ||
unsigned int reg, unsigned int val); | ||
--- a/drivers/base/regmap/regmap.c | ||
+++ b/drivers/base/regmap/regmap.c | ||
@@ -823,6 +823,7 @@ struct regmap *__regmap_init(struct devi | ||
|
||
map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); | ||
map->format.pad_bytes = config->pad_bits / 8; | ||
+ map->format.reg_downshift = config->reg_downshift; | ||
map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); | ||
map->format.buf_size = DIV_ROUND_UP(config->reg_bits + | ||
config->val_bits + config->pad_bits, 8); | ||
@@ -1735,6 +1736,7 @@ static int _regmap_raw_write_impl(struct | ||
return ret; | ||
} | ||
|
||
+ reg >>= map->format.reg_downshift; | ||
map->format.format_reg(map->work_buf, reg, map->reg_shift); | ||
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, | ||
map->write_flag_mask); | ||
@@ -1905,6 +1907,7 @@ static int _regmap_bus_formatted_write(v | ||
return ret; | ||
} | ||
|
||
+ reg >>= map->format.reg_downshift; | ||
map->format.format_write(map, reg, val); | ||
|
||
trace_regmap_hw_write_start(map, reg, 1); | ||
@@ -2346,6 +2349,7 @@ static int _regmap_raw_multi_reg_write(s | ||
unsigned int reg = regs[i].reg; | ||
unsigned int val = regs[i].def; | ||
trace_regmap_hw_write_start(map, reg, 1); | ||
+ reg >>= map->format.reg_downshift; | ||
map->format.format_reg(u8, reg, map->reg_shift); | ||
u8 += reg_bytes + pad_bytes; | ||
map->format.format_val(u8, val, 0); | ||
@@ -2673,6 +2677,7 @@ static int _regmap_raw_read(struct regma | ||
return ret; | ||
} | ||
|
||
+ reg >>= map->format.reg_downshift; | ||
map->format.format_reg(map->work_buf, reg, map->reg_shift); | ||
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, | ||
map->read_flag_mask); | ||
--- a/include/linux/regmap.h | ||
+++ b/include/linux/regmap.h | ||
@@ -237,6 +237,8 @@ typedef void (*regmap_unlock)(void *); | ||
* @reg_stride: The register address stride. Valid register addresses are a | ||
* multiple of this value. If set to 0, a value of 1 will be | ||
* used. | ||
+ * @reg_downshift: The number of bits to downshift the register before | ||
+ * performing any operations. | ||
* @pad_bits: Number of bits of padding between register and value. | ||
* @val_bits: Number of bits in a register value, mandatory. | ||
* | ||
@@ -360,6 +362,7 @@ struct regmap_config { | ||
|
||
int reg_bits; | ||
int reg_stride; | ||
+ int reg_downshift; | ||
int pad_bits; | ||
int val_bits; | ||
|
95 changes: 95 additions & 0 deletions
95
...eneric/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
From 0074f3f2b1e43d3cedd97e47fb6980db6d2ba79e Mon Sep 17 00:00:00 2001 | ||
From: Colin Foster <colin.foster@in-advantage.com> | ||
Date: Sun, 13 Mar 2022 15:45:24 -0700 | ||
Subject: [PATCH 2/2] regmap: allow a defined reg_base to be added to every | ||
address | ||
|
||
There's an inconsistency that arises when a register set can be accessed | ||
internally via MMIO, or externally via SPI. The VSC7514 chip allows both | ||
modes of operation. When internally accessed, the system utilizes __iomem, | ||
devm_ioremap_resource, and devm_regmap_init_mmio. | ||
|
||
For SPI it isn't possible to utilize memory-mapped IO. To properly operate, | ||
the resource base must be added to the register before every operation. | ||
|
||
Signed-off-by: Colin Foster <colin.foster@in-advantage.com> | ||
Link: https://lore.kernel.org/r/20220313224524.399947-3-colin.foster@in-advantage.com | ||
Signed-off-by: Mark Brown <broonie@kernel.org> | ||
--- | ||
drivers/base/regmap/internal.h | 1 + | ||
drivers/base/regmap/regmap.c | 6 ++++++ | ||
include/linux/regmap.h | 3 +++ | ||
3 files changed, 10 insertions(+) | ||
|
||
--- a/drivers/base/regmap/internal.h | ||
+++ b/drivers/base/regmap/internal.h | ||
@@ -63,6 +63,7 @@ struct regmap { | ||
regmap_unlock unlock; | ||
void *lock_arg; /* This is passed to lock/unlock functions */ | ||
gfp_t alloc_flags; | ||
+ unsigned int reg_base; | ||
|
||
struct device *dev; /* Device we do I/O on */ | ||
void *work_buf; /* Scratch buffer used to format I/O */ | ||
--- a/drivers/base/regmap/regmap.c | ||
+++ b/drivers/base/regmap/regmap.c | ||
@@ -821,6 +821,8 @@ struct regmap *__regmap_init(struct devi | ||
else | ||
map->alloc_flags = GFP_KERNEL; | ||
|
||
+ map->reg_base = config->reg_base; | ||
+ | ||
map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); | ||
map->format.pad_bytes = config->pad_bits / 8; | ||
map->format.reg_downshift = config->reg_downshift; | ||
@@ -1736,6 +1738,7 @@ static int _regmap_raw_write_impl(struct | ||
return ret; | ||
} | ||
|
||
+ reg += map->reg_base; | ||
reg >>= map->format.reg_downshift; | ||
map->format.format_reg(map->work_buf, reg, map->reg_shift); | ||
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, | ||
@@ -1907,6 +1910,7 @@ static int _regmap_bus_formatted_write(v | ||
return ret; | ||
} | ||
|
||
+ reg += map->reg_base; | ||
reg >>= map->format.reg_downshift; | ||
map->format.format_write(map, reg, val); | ||
|
||
@@ -2349,6 +2353,7 @@ static int _regmap_raw_multi_reg_write(s | ||
unsigned int reg = regs[i].reg; | ||
unsigned int val = regs[i].def; | ||
trace_regmap_hw_write_start(map, reg, 1); | ||
+ reg += map->reg_base; | ||
reg >>= map->format.reg_downshift; | ||
map->format.format_reg(u8, reg, map->reg_shift); | ||
u8 += reg_bytes + pad_bytes; | ||
@@ -2677,6 +2682,7 @@ static int _regmap_raw_read(struct regma | ||
return ret; | ||
} | ||
|
||
+ reg += map->reg_base; | ||
reg >>= map->format.reg_downshift; | ||
map->format.format_reg(map->work_buf, reg, map->reg_shift); | ||
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, | ||
--- a/include/linux/regmap.h | ||
+++ b/include/linux/regmap.h | ||
@@ -239,6 +239,8 @@ typedef void (*regmap_unlock)(void *); | ||
* used. | ||
* @reg_downshift: The number of bits to downshift the register before | ||
* performing any operations. | ||
+ * @reg_base: Value to be added to every register address before performing any | ||
+ * operation. | ||
* @pad_bits: Number of bits of padding between register and value. | ||
* @val_bits: Number of bits in a register value, mandatory. | ||
* | ||
@@ -363,6 +365,7 @@ struct regmap_config { | ||
int reg_bits; | ||
int reg_stride; | ||
int reg_downshift; | ||
+ unsigned int reg_base; | ||
int pad_bits; | ||
int val_bits; | ||
|
57 changes: 57 additions & 0 deletions
57
...generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
From 697c3892d825fb78f42ec8e53bed065dd728db3e Mon Sep 17 00:00:00 2001 | ||
From: Daniel Golle <daniel@makrotopia.org> | ||
Date: Mon, 30 Jan 2023 02:04:57 +0000 | ||
Subject: [PATCH] regmap: apply reg_base and reg_downshift for single register | ||
ops | ||
|
||
reg_base and reg_downshift currently don't have any effect if used with | ||
a regmap_bus or regmap_config which only offers single register | ||
operations (ie. reg_read, reg_write and optionally reg_update_bits). | ||
|
||
Fix that and take them into account also for regmap_bus with only | ||
reg_read and read_write operations by applying reg_base and | ||
reg_downshift in _regmap_bus_reg_write, _regmap_bus_reg_read. | ||
|
||
Also apply reg_base and reg_downshift in _regmap_update_bits, but only | ||
in case the operation is carried out with a reg_update_bits call | ||
defined in either regmap_bus or regmap_config. | ||
|
||
Fixes: 0074f3f2b1e43d ("regmap: allow a defined reg_base to be added to every address") | ||
Fixes: 86fc59ef818beb ("regmap: add configurable downshift for addresses") | ||
Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||
Tested-by: Colin Foster <colin.foster@in-advantage.com> | ||
Link: https://lore.kernel.org/r/Y9clyVS3tQEHlUhA@makrotopia.org | ||
Signed-off-by: Mark Brown <broonie@kernel.org> | ||
--- | ||
drivers/base/regmap/regmap.c | 6 ++++++ | ||
1 file changed, 6 insertions(+) | ||
|
||
--- a/drivers/base/regmap/regmap.c | ||
+++ b/drivers/base/regmap/regmap.c | ||
@@ -1929,6 +1929,8 @@ static int _regmap_bus_reg_write(void *c | ||
{ | ||
struct regmap *map = context; | ||
|
||
+ reg += map->reg_base; | ||
+ reg >>= map->format.reg_downshift; | ||
return map->bus->reg_write(map->bus_context, reg, val); | ||
} | ||
|
||
@@ -2703,6 +2705,8 @@ static int _regmap_bus_reg_read(void *co | ||
{ | ||
struct regmap *map = context; | ||
|
||
+ reg += map->reg_base; | ||
+ reg >>= map->format.reg_downshift; | ||
return map->bus->reg_read(map->bus_context, reg, val); | ||
} | ||
|
||
@@ -3078,6 +3082,8 @@ static int _regmap_update_bits(struct re | ||
*change = false; | ||
|
||
if (regmap_volatile(map, reg) && map->reg_update_bits) { | ||
+ reg += map->reg_base; | ||
+ reg >>= map->format.reg_downshift; | ||
ret = map->reg_update_bits(map->bus_context, reg, mask, val); | ||
if (ret == 0 && change) | ||
*change = true; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters