diff options
Diffstat (limited to 'drivers/base/regmap/regmap-mmio.c')
-rw-r--r-- | drivers/base/regmap/regmap-mmio.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index 81f977510775..de45a1e1548f 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c | |||
@@ -26,10 +26,47 @@ | |||
26 | 26 | ||
27 | struct regmap_mmio_context { | 27 | struct regmap_mmio_context { |
28 | void __iomem *regs; | 28 | void __iomem *regs; |
29 | unsigned reg_bytes; | ||
29 | unsigned val_bytes; | 30 | unsigned val_bytes; |
31 | unsigned pad_bytes; | ||
30 | struct clk *clk; | 32 | struct clk *clk; |
31 | }; | 33 | }; |
32 | 34 | ||
35 | static inline void regmap_mmio_regsize_check(size_t reg_size) | ||
36 | { | ||
37 | switch (reg_size) { | ||
38 | case 1: | ||
39 | case 2: | ||
40 | case 4: | ||
41 | #ifdef CONFIG_64BIT | ||
42 | case 8: | ||
43 | #endif | ||
44 | break; | ||
45 | default: | ||
46 | BUG(); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | static int regmap_mmio_regbits_check(size_t reg_bits) | ||
51 | { | ||
52 | switch (reg_bits) { | ||
53 | case 8: | ||
54 | case 16: | ||
55 | case 32: | ||
56 | #ifdef CONFIG_64BIT | ||
57 | case 64: | ||
58 | #endif | ||
59 | return 0; | ||
60 | default: | ||
61 | return -EINVAL; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | static inline void regmap_mmio_count_check(size_t count) | ||
66 | { | ||
67 | BUG_ON(count % 2 != 0); | ||
68 | } | ||
69 | |||
33 | static int regmap_mmio_gather_write(void *context, | 70 | static int regmap_mmio_gather_write(void *context, |
34 | const void *reg, size_t reg_size, | 71 | const void *reg, size_t reg_size, |
35 | const void *val, size_t val_size) | 72 | const void *val, size_t val_size) |
@@ -38,7 +75,7 @@ static int regmap_mmio_gather_write(void *context, | |||
38 | u32 offset; | 75 | u32 offset; |
39 | int ret; | 76 | int ret; |
40 | 77 | ||
41 | BUG_ON(reg_size != 4); | 78 | regmap_mmio_regsize_check(reg_size); |
42 | 79 | ||
43 | if (!IS_ERR(ctx->clk)) { | 80 | if (!IS_ERR(ctx->clk)) { |
44 | ret = clk_enable(ctx->clk); | 81 | ret = clk_enable(ctx->clk); |
@@ -81,9 +118,13 @@ static int regmap_mmio_gather_write(void *context, | |||
81 | 118 | ||
82 | static int regmap_mmio_write(void *context, const void *data, size_t count) | 119 | static int regmap_mmio_write(void *context, const void *data, size_t count) |
83 | { | 120 | { |
84 | BUG_ON(count < 4); | 121 | struct regmap_mmio_context *ctx = context; |
122 | u32 offset = ctx->reg_bytes + ctx->pad_bytes; | ||
123 | |||
124 | regmap_mmio_count_check(count); | ||
85 | 125 | ||
86 | return regmap_mmio_gather_write(context, data, 4, data + 4, count - 4); | 126 | return regmap_mmio_gather_write(context, data, ctx->reg_bytes, |
127 | data + offset, count - offset); | ||
87 | } | 128 | } |
88 | 129 | ||
89 | static int regmap_mmio_read(void *context, | 130 | static int regmap_mmio_read(void *context, |
@@ -94,7 +135,7 @@ static int regmap_mmio_read(void *context, | |||
94 | u32 offset; | 135 | u32 offset; |
95 | int ret; | 136 | int ret; |
96 | 137 | ||
97 | BUG_ON(reg_size != 4); | 138 | regmap_mmio_regsize_check(reg_size); |
98 | 139 | ||
99 | if (!IS_ERR(ctx->clk)) { | 140 | if (!IS_ERR(ctx->clk)) { |
100 | ret = clk_enable(ctx->clk); | 141 | ret = clk_enable(ctx->clk); |
@@ -165,8 +206,9 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, | |||
165 | int min_stride; | 206 | int min_stride; |
166 | int ret; | 207 | int ret; |
167 | 208 | ||
168 | if (config->reg_bits != 32) | 209 | ret = regmap_mmio_regbits_check(config->reg_bits); |
169 | return ERR_PTR(-EINVAL); | 210 | if (ret) |
211 | return ERR_PTR(ret); | ||
170 | 212 | ||
171 | if (config->pad_bits) | 213 | if (config->pad_bits) |
172 | return ERR_PTR(-EINVAL); | 214 | return ERR_PTR(-EINVAL); |
@@ -209,6 +251,8 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, | |||
209 | 251 | ||
210 | ctx->regs = regs; | 252 | ctx->regs = regs; |
211 | ctx->val_bytes = config->val_bits / 8; | 253 | ctx->val_bytes = config->val_bits / 8; |
254 | ctx->reg_bytes = config->reg_bits / 8; | ||
255 | ctx->pad_bytes = config->pad_bits / 8; | ||
212 | ctx->clk = ERR_PTR(-ENODEV); | 256 | ctx->clk = ERR_PTR(-ENODEV); |
213 | 257 | ||
214 | if (clk_id == NULL) | 258 | if (clk_id == NULL) |