diff options
Diffstat (limited to 'drivers/base/regmap')
-rw-r--r-- | drivers/base/regmap/regcache-rbtree.c | 8 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-irq.c | 9 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-mmio.c | 6 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 57 |
4 files changed, 69 insertions, 11 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, | |||
23 | static int regcache_rbtree_exit(struct regmap *map); | 23 | static int regcache_rbtree_exit(struct regmap *map); |
24 | 24 | ||
25 | struct regcache_rbtree_node { | 25 | struct 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 | ||
38 | struct regcache_rbtree_ctx { | 38 | struct regcache_rbtree_ctx { |
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index edf88f20cbce..6299a50a5960 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c | |||
@@ -10,13 +10,13 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/export.h> | ||
14 | #include <linux/device.h> | 13 | #include <linux/device.h> |
15 | #include <linux/regmap.h> | 14 | #include <linux/export.h> |
16 | #include <linux/irq.h> | ||
17 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/irq.h> | ||
18 | #include <linux/irqdomain.h> | 17 | #include <linux/irqdomain.h> |
19 | #include <linux/pm_runtime.h> | 18 | #include <linux/pm_runtime.h> |
19 | #include <linux/regmap.h> | ||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | 21 | ||
22 | #include "internal.h" | 22 | #include "internal.h" |
@@ -347,6 +347,9 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, | |||
347 | int ret = -ENOMEM; | 347 | int ret = -ENOMEM; |
348 | u32 reg; | 348 | u32 reg; |
349 | 349 | ||
350 | if (chip->num_regs <= 0) | ||
351 | return -EINVAL; | ||
352 | |||
350 | for (i = 0; i < chip->num_irqs; i++) { | 353 | for (i = 0; i < chip->num_irqs; i++) { |
351 | if (chip->irqs[i].reg_offset % map->reg_stride) | 354 | if (chip->irqs[i].reg_offset % map->reg_stride) |
352 | return -EINVAL; | 355 | return -EINVAL; |
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index dff32c6b2474..04a329a377e9 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c | |||
@@ -61,9 +61,9 @@ static int regmap_mmio_regbits_check(size_t reg_bits) | |||
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | static inline void regmap_mmio_count_check(size_t count) | 64 | static 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 | } | 67 | } |
68 | 68 | ||
69 | static inline unsigned int | 69 | static inline unsigned int |
@@ -139,7 +139,7 @@ static int regmap_mmio_write(void *context, const void *data, size_t count) | |||
139 | struct regmap_mmio_context *ctx = context; | 139 | struct regmap_mmio_context *ctx = context; |
140 | unsigned int offset = ctx->reg_bytes + ctx->pad_bytes; | 140 | unsigned int offset = ctx->reg_bytes + ctx->pad_bytes; |
141 | 141 | ||
142 | regmap_mmio_count_check(count); | 142 | regmap_mmio_count_check(count, offset); |
143 | 143 | ||
144 | return regmap_mmio_gather_write(context, data, ctx->reg_bytes, | 144 | return regmap_mmio_gather_write(context, data, ctx->reg_bytes, |
145 | data + offset, count - offset); | 145 | data + offset, count - offset); |
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 | ||
195 | static 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 | |||
195 | static void regmap_format_16_native(void *buf, unsigned int val, | 202 | static 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 | ||
226 | static 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 | |||
219 | static void regmap_format_32_native(void *buf, unsigned int val, | 233 | static 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 | ||
257 | static 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 | |||
243 | static void regmap_parse_16_be_inplace(void *buf) | 264 | static 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 | ||
271 | static void regmap_parse_16_le_inplace(void *buf) | ||
272 | { | ||
273 | __le16 *b = buf; | ||
274 | |||
275 | b[0] = le16_to_cpu(b[0]); | ||
276 | } | ||
277 | |||
250 | static unsigned int regmap_parse_16_native(const void *buf) | 278 | static 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 | ||
300 | static 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 | |||
272 | static void regmap_parse_32_be_inplace(void *buf) | 307 | static 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 | ||
314 | static void regmap_parse_32_le_inplace(void *buf) | ||
315 | { | ||
316 | __le32 *b = buf; | ||
317 | |||
318 | b[0] = le32_to_cpu(b[0]); | ||
319 | } | ||
320 | |||
279 | static unsigned int regmap_parse_32_native(const void *buf) | 321 | static 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 |