aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/regmap')
-rw-r--r--drivers/base/regmap/regcache-rbtree.c8
-rw-r--r--drivers/base/regmap/regmap-mmio.c35
-rw-r--r--drivers/base/regmap/regmap.c57
3 files changed, 87 insertions, 13 deletions
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 930cad4e5df8..6a7e4fa12854 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -23,16 +23,16 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
23static int regcache_rbtree_exit(struct regmap *map); 23static int regcache_rbtree_exit(struct regmap *map);
24 24
25struct regcache_rbtree_node { 25struct regcache_rbtree_node {
26 /* the actual rbtree node holding this block */
27 struct rb_node node;
28 /* base register handled by this block */
29 unsigned int base_reg;
30 /* block of adjacent registers */ 26 /* block of adjacent registers */
31 void *block; 27 void *block;
32 /* Which registers are present */ 28 /* Which registers are present */
33 long *cache_present; 29 long *cache_present;
30 /* base register handled by this block */
31 unsigned int base_reg;
34 /* number of registers available in the block */ 32 /* number of registers available in the block */
35 unsigned int blklen; 33 unsigned int blklen;
34 /* the actual rbtree node holding this block */
35 struct rb_node node;
36} __attribute__ ((packed)); 36} __attribute__ ((packed));
37 37
38struct regcache_rbtree_ctx { 38struct regcache_rbtree_ctx {
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c
index 1e03e7f8bacb..04a329a377e9 100644
--- a/drivers/base/regmap/regmap-mmio.c
+++ b/drivers/base/regmap/regmap-mmio.c
@@ -61,9 +61,28 @@ static int regmap_mmio_regbits_check(size_t reg_bits)
61 } 61 }
62} 62}
63 63
64static inline void regmap_mmio_count_check(size_t count) 64static inline void regmap_mmio_count_check(size_t count, u32 offset)
65{ 65{
66 BUG_ON(count % 2 != 0); 66 BUG_ON(count <= offset);
67}
68
69static inline unsigned int
70regmap_mmio_get_offset(const void *reg, size_t reg_size)
71{
72 switch (reg_size) {
73 case 1:
74 return *(u8 *)reg;
75 case 2:
76 return *(u16 *)reg;
77 case 4:
78 return *(u32 *)reg;
79#ifdef CONFIG_64BIT
80 case 8:
81 return *(u64 *)reg;
82#endif
83 default:
84 BUG();
85 }
67} 86}
68 87
69static int regmap_mmio_gather_write(void *context, 88static int regmap_mmio_gather_write(void *context,
@@ -71,7 +90,7 @@ static int regmap_mmio_gather_write(void *context,
71 const void *val, size_t val_size) 90 const void *val, size_t val_size)
72{ 91{
73 struct regmap_mmio_context *ctx = context; 92 struct regmap_mmio_context *ctx = context;
74 u32 offset; 93 unsigned int offset;
75 int ret; 94 int ret;
76 95
77 regmap_mmio_regsize_check(reg_size); 96 regmap_mmio_regsize_check(reg_size);
@@ -82,7 +101,7 @@ static int regmap_mmio_gather_write(void *context,
82 return ret; 101 return ret;
83 } 102 }
84 103
85 offset = *(u32 *)reg; 104 offset = regmap_mmio_get_offset(reg, reg_size);
86 105
87 while (val_size) { 106 while (val_size) {
88 switch (ctx->val_bytes) { 107 switch (ctx->val_bytes) {
@@ -118,9 +137,9 @@ static int regmap_mmio_gather_write(void *context,
118static int regmap_mmio_write(void *context, const void *data, size_t count) 137static int regmap_mmio_write(void *context, const void *data, size_t count)
119{ 138{
120 struct regmap_mmio_context *ctx = context; 139 struct regmap_mmio_context *ctx = context;
121 u32 offset = ctx->reg_bytes + ctx->pad_bytes; 140 unsigned int offset = ctx->reg_bytes + ctx->pad_bytes;
122 141
123 regmap_mmio_count_check(count); 142 regmap_mmio_count_check(count, offset);
124 143
125 return regmap_mmio_gather_write(context, data, ctx->reg_bytes, 144 return regmap_mmio_gather_write(context, data, ctx->reg_bytes,
126 data + offset, count - offset); 145 data + offset, count - offset);
@@ -131,7 +150,7 @@ static int regmap_mmio_read(void *context,
131 void *val, size_t val_size) 150 void *val, size_t val_size)
132{ 151{
133 struct regmap_mmio_context *ctx = context; 152 struct regmap_mmio_context *ctx = context;
134 u32 offset; 153 unsigned int offset;
135 int ret; 154 int ret;
136 155
137 regmap_mmio_regsize_check(reg_size); 156 regmap_mmio_regsize_check(reg_size);
@@ -142,7 +161,7 @@ static int regmap_mmio_read(void *context,
142 return ret; 161 return ret;
143 } 162 }
144 163
145 offset = *(u32 *)reg; 164 offset = regmap_mmio_get_offset(reg, reg_size);
146 165
147 while (val_size) { 166 while (val_size) {
148 switch (ctx->val_bytes) { 167 switch (ctx->val_bytes) {
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 63e30ef096e2..2615cc180d35 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -192,6 +192,13 @@ static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift)
192 b[0] = cpu_to_be16(val << shift); 192 b[0] = cpu_to_be16(val << shift);
193} 193}
194 194
195static void regmap_format_16_le(void *buf, unsigned int val, unsigned int shift)
196{
197 __le16 *b = buf;
198
199 b[0] = cpu_to_le16(val << shift);
200}
201
195static void regmap_format_16_native(void *buf, unsigned int val, 202static void regmap_format_16_native(void *buf, unsigned int val,
196 unsigned int shift) 203 unsigned int shift)
197{ 204{
@@ -216,6 +223,13 @@ static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift)
216 b[0] = cpu_to_be32(val << shift); 223 b[0] = cpu_to_be32(val << shift);
217} 224}
218 225
226static void regmap_format_32_le(void *buf, unsigned int val, unsigned int shift)
227{
228 __le32 *b = buf;
229
230 b[0] = cpu_to_le32(val << shift);
231}
232
219static void regmap_format_32_native(void *buf, unsigned int val, 233static void regmap_format_32_native(void *buf, unsigned int val,
220 unsigned int shift) 234 unsigned int shift)
221{ 235{
@@ -240,6 +254,13 @@ static unsigned int regmap_parse_16_be(const void *buf)
240 return be16_to_cpu(b[0]); 254 return be16_to_cpu(b[0]);
241} 255}
242 256
257static unsigned int regmap_parse_16_le(const void *buf)
258{
259 const __le16 *b = buf;
260
261 return le16_to_cpu(b[0]);
262}
263
243static void regmap_parse_16_be_inplace(void *buf) 264static void regmap_parse_16_be_inplace(void *buf)
244{ 265{
245 __be16 *b = buf; 266 __be16 *b = buf;
@@ -247,6 +268,13 @@ static void regmap_parse_16_be_inplace(void *buf)
247 b[0] = be16_to_cpu(b[0]); 268 b[0] = be16_to_cpu(b[0]);
248} 269}
249 270
271static void regmap_parse_16_le_inplace(void *buf)
272{
273 __le16 *b = buf;
274
275 b[0] = le16_to_cpu(b[0]);
276}
277
250static unsigned int regmap_parse_16_native(const void *buf) 278static unsigned int regmap_parse_16_native(const void *buf)
251{ 279{
252 return *(u16 *)buf; 280 return *(u16 *)buf;
@@ -269,6 +297,13 @@ static unsigned int regmap_parse_32_be(const void *buf)
269 return be32_to_cpu(b[0]); 297 return be32_to_cpu(b[0]);
270} 298}
271 299
300static unsigned int regmap_parse_32_le(const void *buf)
301{
302 const __le32 *b = buf;
303
304 return le32_to_cpu(b[0]);
305}
306
272static void regmap_parse_32_be_inplace(void *buf) 307static void regmap_parse_32_be_inplace(void *buf)
273{ 308{
274 __be32 *b = buf; 309 __be32 *b = buf;
@@ -276,6 +311,13 @@ static void regmap_parse_32_be_inplace(void *buf)
276 b[0] = be32_to_cpu(b[0]); 311 b[0] = be32_to_cpu(b[0]);
277} 312}
278 313
314static void regmap_parse_32_le_inplace(void *buf)
315{
316 __le32 *b = buf;
317
318 b[0] = le32_to_cpu(b[0]);
319}
320
279static unsigned int regmap_parse_32_native(const void *buf) 321static unsigned int regmap_parse_32_native(const void *buf)
280{ 322{
281 return *(u32 *)buf; 323 return *(u32 *)buf;
@@ -608,6 +650,11 @@ struct regmap *regmap_init(struct device *dev,
608 map->format.parse_val = regmap_parse_16_be; 650 map->format.parse_val = regmap_parse_16_be;
609 map->format.parse_inplace = regmap_parse_16_be_inplace; 651 map->format.parse_inplace = regmap_parse_16_be_inplace;
610 break; 652 break;
653 case REGMAP_ENDIAN_LITTLE:
654 map->format.format_val = regmap_format_16_le;
655 map->format.parse_val = regmap_parse_16_le;
656 map->format.parse_inplace = regmap_parse_16_le_inplace;
657 break;
611 case REGMAP_ENDIAN_NATIVE: 658 case REGMAP_ENDIAN_NATIVE:
612 map->format.format_val = regmap_format_16_native; 659 map->format.format_val = regmap_format_16_native;
613 map->format.parse_val = regmap_parse_16_native; 660 map->format.parse_val = regmap_parse_16_native;
@@ -629,6 +676,11 @@ struct regmap *regmap_init(struct device *dev,
629 map->format.parse_val = regmap_parse_32_be; 676 map->format.parse_val = regmap_parse_32_be;
630 map->format.parse_inplace = regmap_parse_32_be_inplace; 677 map->format.parse_inplace = regmap_parse_32_be_inplace;
631 break; 678 break;
679 case REGMAP_ENDIAN_LITTLE:
680 map->format.format_val = regmap_format_32_le;
681 map->format.parse_val = regmap_parse_32_le;
682 map->format.parse_inplace = regmap_parse_32_le_inplace;
683 break;
632 case REGMAP_ENDIAN_NATIVE: 684 case REGMAP_ENDIAN_NATIVE:
633 map->format.format_val = regmap_format_32_native; 685 map->format.format_val = regmap_format_32_native;
634 map->format.parse_val = regmap_parse_32_native; 686 map->format.parse_val = regmap_parse_32_native;
@@ -1615,6 +1667,9 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
1615 size_t pair_size = reg_bytes + pad_bytes + val_bytes; 1667 size_t pair_size = reg_bytes + pad_bytes + val_bytes;
1616 size_t len = pair_size * num_regs; 1668 size_t len = pair_size * num_regs;
1617 1669
1670 if (!len)
1671 return -EINVAL;
1672
1618 buf = kzalloc(len, GFP_KERNEL); 1673 buf = kzalloc(len, GFP_KERNEL);
1619 if (!buf) 1674 if (!buf)
1620 return -ENOMEM; 1675 return -ENOMEM;
@@ -1662,7 +1717,7 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
1662 int ret; 1717 int ret;
1663 int i, n; 1718 int i, n;
1664 struct reg_default *base; 1719 struct reg_default *base;
1665 unsigned int this_page; 1720 unsigned int this_page = 0;
1666 /* 1721 /*
1667 * the set of registers are not neccessarily in order, but 1722 * the set of registers are not neccessarily in order, but
1668 * since the order of write must be preserved this algorithm 1723 * since the order of write must be preserved this algorithm