Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'regmap-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap into next

Pull regmap updates from Mark Brown:
"Another fairly quiet release, a few bug fixes and a couple of new
features:

- support for I2C devices connected to SMBus rather than full I2C
controllers contributed by Boris Brezillon. If the controller is
only capable of SMBus operation the framework will transparently
fall back to that

- suport for little endian values, contributed by Xiubo Li"

* tag 'regmap-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
regmap: mmio: Fix regmap_mmio_write for uneven counts
regmap: irq: Fix possible ZERO_SIZE_PTR pointer dereferencing error.
regmap: Add missing initialization of this_page
regmap: Fix possible ZERO_SIZE_PTR pointer dereferencing error.
regmap: i2c: fallback to SMBus if the adapter does not support standard I2C
regmap: add reg_read/reg_write callbacks to regmap_bus struct
regmap: rbtree: improve 64bits memory alignment
regmap: mmio: Fix the bug of 'offset' value parsing.
regmap: implement LE formatting/parsing for 16/32-bit values.

+227 -18
+4 -4
drivers/base/regmap/regcache-rbtree.c
··· 23 23 static int regcache_rbtree_exit(struct regmap *map); 24 24 25 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 26 /* block of adjacent registers */ 31 27 void *block; 32 28 /* Which registers are present */ 33 29 long *cache_present; 30 + /* base register handled by this block */ 31 + unsigned int base_reg; 34 32 /* number of registers available in the block */ 35 33 unsigned int blklen; 34 + /* the actual rbtree node holding this block */ 35 + struct rb_node node; 36 36 } __attribute__ ((packed)); 37 37 38 38 struct regcache_rbtree_ctx {
+102 -2
drivers/base/regmap/regmap-i2c.c
··· 14 14 #include <linux/i2c.h> 15 15 #include <linux/module.h> 16 16 17 + 18 + static int regmap_smbus_byte_reg_read(void *context, unsigned int reg, 19 + unsigned int *val) 20 + { 21 + struct device *dev = context; 22 + struct i2c_client *i2c = to_i2c_client(dev); 23 + int ret; 24 + 25 + if (reg > 0xff) 26 + return -EINVAL; 27 + 28 + ret = i2c_smbus_read_byte_data(i2c, reg); 29 + if (ret < 0) 30 + return ret; 31 + 32 + *val = ret; 33 + 34 + return 0; 35 + } 36 + 37 + static int regmap_smbus_byte_reg_write(void *context, unsigned int reg, 38 + unsigned int val) 39 + { 40 + struct device *dev = context; 41 + struct i2c_client *i2c = to_i2c_client(dev); 42 + 43 + if (val > 0xff || reg > 0xff) 44 + return -EINVAL; 45 + 46 + return i2c_smbus_write_byte_data(i2c, reg, val); 47 + } 48 + 49 + static struct regmap_bus regmap_smbus_byte = { 50 + .reg_write = regmap_smbus_byte_reg_write, 51 + .reg_read = regmap_smbus_byte_reg_read, 52 + }; 53 + 54 + static int regmap_smbus_word_reg_read(void *context, unsigned int reg, 55 + unsigned int *val) 56 + { 57 + struct device *dev = context; 58 + struct i2c_client *i2c = to_i2c_client(dev); 59 + int ret; 60 + 61 + if (reg > 0xff) 62 + return -EINVAL; 63 + 64 + ret = i2c_smbus_read_word_data(i2c, reg); 65 + if (ret < 0) 66 + return ret; 67 + 68 + *val = ret; 69 + 70 + return 0; 71 + } 72 + 73 + static int regmap_smbus_word_reg_write(void *context, unsigned int reg, 74 + unsigned int val) 75 + { 76 + struct device *dev = context; 77 + struct i2c_client *i2c = to_i2c_client(dev); 78 + 79 + if (val > 0xffff || reg > 0xff) 80 + return -EINVAL; 81 + 82 + return i2c_smbus_write_word_data(i2c, reg, val); 83 + } 84 + 85 + static struct regmap_bus regmap_smbus_word = { 86 + .reg_write = regmap_smbus_word_reg_write, 87 + .reg_read = regmap_smbus_word_reg_read, 88 + }; 89 + 17 90 static int regmap_i2c_write(void *context, const void *data, size_t count) 18 91 { 19 92 struct device *dev = context; ··· 170 97 .read = regmap_i2c_read, 171 98 }; 172 99 100 + static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c, 101 + const struct regmap_config *config) 102 + { 103 + if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) 104 + return &regmap_i2c; 105 + else if (config->val_bits == 16 && config->reg_bits == 8 && 106 + i2c_check_functionality(i2c->adapter, 107 + I2C_FUNC_SMBUS_WORD_DATA)) 108 + return &regmap_smbus_word; 109 + else if (config->val_bits == 8 && config->reg_bits == 8 && 110 + i2c_check_functionality(i2c->adapter, 111 + I2C_FUNC_SMBUS_BYTE_DATA)) 112 + return &regmap_smbus_byte; 113 + 114 + return ERR_PTR(-ENOTSUPP); 115 + } 116 + 173 117 /** 174 118 * regmap_init_i2c(): Initialise register map 175 119 * ··· 199 109 struct regmap *regmap_init_i2c(struct i2c_client *i2c, 200 110 const struct regmap_config *config) 201 111 { 202 - return regmap_init(&i2c->dev, &regmap_i2c, &i2c->dev, config); 112 + const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config); 113 + 114 + if (IS_ERR(bus)) 115 + return ERR_CAST(bus); 116 + 117 + return regmap_init(&i2c->dev, bus, &i2c->dev, config); 203 118 } 204 119 EXPORT_SYMBOL_GPL(regmap_init_i2c); 205 120 ··· 221 126 struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, 222 127 const struct regmap_config *config) 223 128 { 224 - return devm_regmap_init(&i2c->dev, &regmap_i2c, &i2c->dev, config); 129 + const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config); 130 + 131 + if (IS_ERR(bus)) 132 + return ERR_CAST(bus); 133 + 134 + return devm_regmap_init(&i2c->dev, bus, &i2c->dev, config); 225 135 } 226 136 EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); 227 137
+6 -3
drivers/base/regmap/regmap-irq.c
··· 10 10 * published by the Free Software Foundation. 11 11 */ 12 12 13 - #include <linux/export.h> 14 13 #include <linux/device.h> 15 - #include <linux/regmap.h> 16 - #include <linux/irq.h> 14 + #include <linux/export.h> 17 15 #include <linux/interrupt.h> 16 + #include <linux/irq.h> 18 17 #include <linux/irqdomain.h> 19 18 #include <linux/pm_runtime.h> 19 + #include <linux/regmap.h> 20 20 #include <linux/slab.h> 21 21 22 22 #include "internal.h" ··· 346 346 int i; 347 347 int ret = -ENOMEM; 348 348 u32 reg; 349 + 350 + if (chip->num_regs <= 0) 351 + return -EINVAL; 349 352 350 353 for (i = 0; i < chip->num_irqs; i++) { 351 354 if (chip->irqs[i].reg_offset % map->reg_stride)
+27 -8
drivers/base/regmap/regmap-mmio.c
··· 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 + } 68 + 69 + static inline unsigned int 70 + regmap_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 69 88 static int regmap_mmio_gather_write(void *context, ··· 90 71 const void *val, size_t val_size) 91 72 { 92 73 struct regmap_mmio_context *ctx = context; 93 - u32 offset; 74 + unsigned int offset; 94 75 int ret; 95 76 96 77 regmap_mmio_regsize_check(reg_size); ··· 101 82 return ret; 102 83 } 103 84 104 - offset = *(u32 *)reg; 85 + offset = regmap_mmio_get_offset(reg, reg_size); 105 86 106 87 while (val_size) { 107 88 switch (ctx->val_bytes) { ··· 137 118 static int regmap_mmio_write(void *context, const void *data, size_t count) 138 119 { 139 120 struct regmap_mmio_context *ctx = context; 140 - u32 offset = ctx->reg_bytes + ctx->pad_bytes; 121 + unsigned int offset = ctx->reg_bytes + ctx->pad_bytes; 141 122 142 - regmap_mmio_count_check(count); 123 + regmap_mmio_count_check(count, offset); 143 124 144 125 return regmap_mmio_gather_write(context, data, ctx->reg_bytes, 145 126 data + offset, count - offset); ··· 150 131 void *val, size_t val_size) 151 132 { 152 133 struct regmap_mmio_context *ctx = context; 153 - u32 offset; 134 + unsigned int offset; 154 135 int ret; 155 136 156 137 regmap_mmio_regsize_check(reg_size); ··· 161 142 return ret; 162 143 } 163 144 164 - offset = *(u32 *)reg; 145 + offset = regmap_mmio_get_offset(reg, reg_size); 165 146 166 147 while (val_size) { 167 148 switch (ctx->val_bytes) {
+82 -1
drivers/base/regmap/regmap.c
··· 35 35 unsigned int mask, unsigned int val, 36 36 bool *change); 37 37 38 + static int _regmap_bus_reg_read(void *context, unsigned int reg, 39 + unsigned int *val); 38 40 static int _regmap_bus_read(void *context, unsigned int reg, 39 41 unsigned int *val); 40 42 static int _regmap_bus_formatted_write(void *context, unsigned int reg, 41 43 unsigned int val); 44 + static int _regmap_bus_reg_write(void *context, unsigned int reg, 45 + unsigned int val); 42 46 static int _regmap_bus_raw_write(void *context, unsigned int reg, 43 47 unsigned int val); 44 48 ··· 196 192 b[0] = cpu_to_be16(val << shift); 197 193 } 198 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 + 199 202 static void regmap_format_16_native(void *buf, unsigned int val, 200 203 unsigned int shift) 201 204 { ··· 225 214 __be32 *b = buf; 226 215 227 216 b[0] = cpu_to_be32(val << shift); 217 + } 218 + 219 + static void regmap_format_32_le(void *buf, unsigned int val, unsigned int shift) 220 + { 221 + __le32 *b = buf; 222 + 223 + b[0] = cpu_to_le32(val << shift); 228 224 } 229 225 230 226 static void regmap_format_32_native(void *buf, unsigned int val, ··· 258 240 return be16_to_cpu(b[0]); 259 241 } 260 242 243 + static unsigned int regmap_parse_16_le(const void *buf) 244 + { 245 + const __le16 *b = buf; 246 + 247 + return le16_to_cpu(b[0]); 248 + } 249 + 261 250 static void regmap_parse_16_be_inplace(void *buf) 262 251 { 263 252 __be16 *b = buf; 264 253 265 254 b[0] = be16_to_cpu(b[0]); 255 + } 256 + 257 + static void regmap_parse_16_le_inplace(void *buf) 258 + { 259 + __le16 *b = buf; 260 + 261 + b[0] = le16_to_cpu(b[0]); 266 262 } 267 263 268 264 static unsigned int regmap_parse_16_native(const void *buf) ··· 301 269 return be32_to_cpu(b[0]); 302 270 } 303 271 272 + static unsigned int regmap_parse_32_le(const void *buf) 273 + { 274 + const __le32 *b = buf; 275 + 276 + return le32_to_cpu(b[0]); 277 + } 278 + 304 279 static void regmap_parse_32_be_inplace(void *buf) 305 280 { 306 281 __be32 *b = buf; 307 282 308 283 b[0] = be32_to_cpu(b[0]); 284 + } 285 + 286 + static void regmap_parse_32_le_inplace(void *buf) 287 + { 288 + __le32 *b = buf; 289 + 290 + b[0] = le32_to_cpu(b[0]); 309 291 } 310 292 311 293 static unsigned int regmap_parse_32_native(const void *buf) ··· 541 495 542 496 map->defer_caching = false; 543 497 goto skip_format_initialization; 498 + } else if (!bus->read || !bus->write) { 499 + map->reg_read = _regmap_bus_reg_read; 500 + map->reg_write = _regmap_bus_reg_write; 501 + 502 + map->defer_caching = false; 503 + goto skip_format_initialization; 544 504 } else { 545 505 map->reg_read = _regmap_bus_read; 546 506 } ··· 660 608 map->format.parse_val = regmap_parse_16_be; 661 609 map->format.parse_inplace = regmap_parse_16_be_inplace; 662 610 break; 611 + case REGMAP_ENDIAN_LITTLE: 612 + map->format.format_val = regmap_format_16_le; 613 + map->format.parse_val = regmap_parse_16_le; 614 + map->format.parse_inplace = regmap_parse_16_le_inplace; 615 + break; 663 616 case REGMAP_ENDIAN_NATIVE: 664 617 map->format.format_val = regmap_format_16_native; 665 618 map->format.parse_val = regmap_parse_16_native; ··· 685 628 map->format.format_val = regmap_format_32_be; 686 629 map->format.parse_val = regmap_parse_32_be; 687 630 map->format.parse_inplace = regmap_parse_32_be_inplace; 631 + break; 632 + case REGMAP_ENDIAN_LITTLE: 633 + map->format.format_val = regmap_format_32_le; 634 + map->format.parse_val = regmap_parse_32_le; 635 + map->format.parse_inplace = regmap_parse_32_le_inplace; 688 636 break; 689 637 case REGMAP_ENDIAN_NATIVE: 690 638 map->format.format_val = regmap_format_32_native; ··· 1346 1284 return ret; 1347 1285 } 1348 1286 1287 + static int _regmap_bus_reg_write(void *context, unsigned int reg, 1288 + unsigned int val) 1289 + { 1290 + struct regmap *map = context; 1291 + 1292 + return map->bus->reg_write(map->bus_context, reg, val); 1293 + } 1294 + 1349 1295 static int _regmap_bus_raw_write(void *context, unsigned int reg, 1350 1296 unsigned int val) 1351 1297 { ··· 1685 1615 size_t pair_size = reg_bytes + pad_bytes + val_bytes; 1686 1616 size_t len = pair_size * num_regs; 1687 1617 1618 + if (!len) 1619 + return -EINVAL; 1620 + 1688 1621 buf = kzalloc(len, GFP_KERNEL); 1689 1622 if (!buf) 1690 1623 return -ENOMEM; ··· 1735 1662 int ret; 1736 1663 int i, n; 1737 1664 struct reg_default *base; 1738 - unsigned int this_page; 1665 + unsigned int this_page = 0; 1739 1666 /* 1740 1667 * the set of registers are not neccessarily in order, but 1741 1668 * since the order of write must be preserved this algorithm ··· 1996 1923 val_len / map->format.val_bytes); 1997 1924 1998 1925 return ret; 1926 + } 1927 + 1928 + static int _regmap_bus_reg_read(void *context, unsigned int reg, 1929 + unsigned int *val) 1930 + { 1931 + struct regmap *map = context; 1932 + 1933 + return map->bus->reg_read(map->bus_context, reg, val); 1999 1934 } 2000 1935 2001 1936 static int _regmap_bus_read(void *context, unsigned int reg,
+6
include/linux/regmap.h
··· 276 276 typedef int (*regmap_hw_read)(void *context, 277 277 const void *reg_buf, size_t reg_size, 278 278 void *val_buf, size_t val_size); 279 + typedef int (*regmap_hw_reg_read)(void *context, unsigned int reg, 280 + unsigned int *val); 281 + typedef int (*regmap_hw_reg_write)(void *context, unsigned int reg, 282 + unsigned int val); 279 283 typedef struct regmap_async *(*regmap_hw_async_alloc)(void); 280 284 typedef void (*regmap_hw_free_context)(void *context); 281 285 ··· 313 309 regmap_hw_write write; 314 310 regmap_hw_gather_write gather_write; 315 311 regmap_hw_async_write async_write; 312 + regmap_hw_reg_write reg_write; 316 313 regmap_hw_read read; 314 + regmap_hw_reg_read reg_read; 317 315 regmap_hw_free_context free_context; 318 316 regmap_hw_async_alloc async_alloc; 319 317 u8 read_flag_mask;