aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap/regmap-mmio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/regmap/regmap-mmio.c')
-rw-r--r--drivers/base/regmap/regmap-mmio.c56
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
27struct regmap_mmio_context { 27struct 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
35static 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
50static 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
65static inline void regmap_mmio_count_check(size_t count)
66{
67 BUG_ON(count % 2 != 0);
68}
69
33static int regmap_mmio_gather_write(void *context, 70static 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
82static int regmap_mmio_write(void *context, const void *data, size_t count) 119static 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
89static int regmap_mmio_read(void *context, 130static 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)