diff options
author | Stephen Warren <swarren@nvidia.com> | 2012-04-04 17:48:30 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-04-06 05:47:34 -0400 |
commit | 0135bbcc7a0cc056f0203ff839466236b8e3dc19 (patch) | |
tree | 79f60f53754cfae8b9a5d9504502131d44ed3b14 /drivers/base/regmap | |
parent | dd775ae2549217d3ae09363e3edb305d0fa19928 (diff) |
regmap: introduce explicit bus_context for bus callbacks
The only context needed by I2C and SPI bus definitions is the device
itself; this can be converted to an i2c_client or spi_device in order
to perform IO on the device. However, other bus types may need more
context in order to perform IO. Enable this by having regmap_init accept
a bus_context parameter, and pass this to all bus callbacks. The
existing callbacks simply pass the struct device here. Future bus types
may pass something else.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/base/regmap')
-rw-r--r-- | drivers/base/regmap/internal.h | 1 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-i2c.c | 13 | ||||
-rw-r--r-- | drivers/base/regmap/regmap-spi.c | 13 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 19 |
4 files changed, 30 insertions, 16 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index fcafc5b2e65..b95fd1f2529 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h | |||
@@ -38,6 +38,7 @@ struct regmap { | |||
38 | void *work_buf; /* Scratch buffer used to format I/O */ | 38 | void *work_buf; /* Scratch buffer used to format I/O */ |
39 | struct regmap_format format; /* Buffer format */ | 39 | struct regmap_format format; /* Buffer format */ |
40 | const struct regmap_bus *bus; | 40 | const struct regmap_bus *bus; |
41 | void *bus_context; | ||
41 | 42 | ||
42 | #ifdef CONFIG_DEBUG_FS | 43 | #ifdef CONFIG_DEBUG_FS |
43 | struct dentry *debugfs; | 44 | struct dentry *debugfs; |
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index 9a3a8c56438..5f6b2478bf1 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c | |||
@@ -15,8 +15,9 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | 17 | ||
18 | static int regmap_i2c_write(struct device *dev, const void *data, size_t count) | 18 | static int regmap_i2c_write(void *context, const void *data, size_t count) |
19 | { | 19 | { |
20 | struct device *dev = context; | ||
20 | struct i2c_client *i2c = to_i2c_client(dev); | 21 | struct i2c_client *i2c = to_i2c_client(dev); |
21 | int ret; | 22 | int ret; |
22 | 23 | ||
@@ -29,10 +30,11 @@ static int regmap_i2c_write(struct device *dev, const void *data, size_t count) | |||
29 | return -EIO; | 30 | return -EIO; |
30 | } | 31 | } |
31 | 32 | ||
32 | static int regmap_i2c_gather_write(struct device *dev, | 33 | static int regmap_i2c_gather_write(void *context, |
33 | const void *reg, size_t reg_size, | 34 | const void *reg, size_t reg_size, |
34 | const void *val, size_t val_size) | 35 | const void *val, size_t val_size) |
35 | { | 36 | { |
37 | struct device *dev = context; | ||
36 | struct i2c_client *i2c = to_i2c_client(dev); | 38 | struct i2c_client *i2c = to_i2c_client(dev); |
37 | struct i2c_msg xfer[2]; | 39 | struct i2c_msg xfer[2]; |
38 | int ret; | 40 | int ret; |
@@ -62,10 +64,11 @@ static int regmap_i2c_gather_write(struct device *dev, | |||
62 | return -EIO; | 64 | return -EIO; |
63 | } | 65 | } |
64 | 66 | ||
65 | static int regmap_i2c_read(struct device *dev, | 67 | static int regmap_i2c_read(void *context, |
66 | const void *reg, size_t reg_size, | 68 | const void *reg, size_t reg_size, |
67 | void *val, size_t val_size) | 69 | void *val, size_t val_size) |
68 | { | 70 | { |
71 | struct device *dev = context; | ||
69 | struct i2c_client *i2c = to_i2c_client(dev); | 72 | struct i2c_client *i2c = to_i2c_client(dev); |
70 | struct i2c_msg xfer[2]; | 73 | struct i2c_msg xfer[2]; |
71 | int ret; | 74 | int ret; |
@@ -107,7 +110,7 @@ static struct regmap_bus regmap_i2c = { | |||
107 | struct regmap *regmap_init_i2c(struct i2c_client *i2c, | 110 | struct regmap *regmap_init_i2c(struct i2c_client *i2c, |
108 | const struct regmap_config *config) | 111 | const struct regmap_config *config) |
109 | { | 112 | { |
110 | return regmap_init(&i2c->dev, ®map_i2c, config); | 113 | return regmap_init(&i2c->dev, ®map_i2c, &i2c->dev, config); |
111 | } | 114 | } |
112 | EXPORT_SYMBOL_GPL(regmap_init_i2c); | 115 | EXPORT_SYMBOL_GPL(regmap_init_i2c); |
113 | 116 | ||
@@ -124,7 +127,7 @@ EXPORT_SYMBOL_GPL(regmap_init_i2c); | |||
124 | struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, | 127 | struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, |
125 | const struct regmap_config *config) | 128 | const struct regmap_config *config) |
126 | { | 129 | { |
127 | return devm_regmap_init(&i2c->dev, ®map_i2c, config); | 130 | return devm_regmap_init(&i2c->dev, ®map_i2c, &i2c->dev, config); |
128 | } | 131 | } |
129 | EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); | 132 | EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); |
130 | 133 | ||
diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 7c0c35a39c3..ffa46a92ad3 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c | |||
@@ -15,17 +15,19 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | 17 | ||
18 | static int regmap_spi_write(struct device *dev, const void *data, size_t count) | 18 | static int regmap_spi_write(void *context, const void *data, size_t count) |
19 | { | 19 | { |
20 | struct device *dev = context; | ||
20 | struct spi_device *spi = to_spi_device(dev); | 21 | struct spi_device *spi = to_spi_device(dev); |
21 | 22 | ||
22 | return spi_write(spi, data, count); | 23 | return spi_write(spi, data, count); |
23 | } | 24 | } |
24 | 25 | ||
25 | static int regmap_spi_gather_write(struct device *dev, | 26 | static int regmap_spi_gather_write(void *context, |
26 | const void *reg, size_t reg_len, | 27 | const void *reg, size_t reg_len, |
27 | const void *val, size_t val_len) | 28 | const void *val, size_t val_len) |
28 | { | 29 | { |
30 | struct device *dev = context; | ||
29 | struct spi_device *spi = to_spi_device(dev); | 31 | struct spi_device *spi = to_spi_device(dev); |
30 | struct spi_message m; | 32 | struct spi_message m; |
31 | struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, }, | 33 | struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, }, |
@@ -38,10 +40,11 @@ static int regmap_spi_gather_write(struct device *dev, | |||
38 | return spi_sync(spi, &m); | 40 | return spi_sync(spi, &m); |
39 | } | 41 | } |
40 | 42 | ||
41 | static int regmap_spi_read(struct device *dev, | 43 | static int regmap_spi_read(void *context, |
42 | const void *reg, size_t reg_size, | 44 | const void *reg, size_t reg_size, |
43 | void *val, size_t val_size) | 45 | void *val, size_t val_size) |
44 | { | 46 | { |
47 | struct device *dev = context; | ||
45 | struct spi_device *spi = to_spi_device(dev); | 48 | struct spi_device *spi = to_spi_device(dev); |
46 | 49 | ||
47 | return spi_write_then_read(spi, reg, reg_size, val, val_size); | 50 | return spi_write_then_read(spi, reg, reg_size, val, val_size); |
@@ -66,7 +69,7 @@ static struct regmap_bus regmap_spi = { | |||
66 | struct regmap *regmap_init_spi(struct spi_device *spi, | 69 | struct regmap *regmap_init_spi(struct spi_device *spi, |
67 | const struct regmap_config *config) | 70 | const struct regmap_config *config) |
68 | { | 71 | { |
69 | return regmap_init(&spi->dev, ®map_spi, config); | 72 | return regmap_init(&spi->dev, ®map_spi, &spi->dev, config); |
70 | } | 73 | } |
71 | EXPORT_SYMBOL_GPL(regmap_init_spi); | 74 | EXPORT_SYMBOL_GPL(regmap_init_spi); |
72 | 75 | ||
@@ -83,7 +86,7 @@ EXPORT_SYMBOL_GPL(regmap_init_spi); | |||
83 | struct regmap *devm_regmap_init_spi(struct spi_device *spi, | 86 | struct regmap *devm_regmap_init_spi(struct spi_device *spi, |
84 | const struct regmap_config *config) | 87 | const struct regmap_config *config) |
85 | { | 88 | { |
86 | return devm_regmap_init(&spi->dev, ®map_spi, config); | 89 | return devm_regmap_init(&spi->dev, ®map_spi, &spi->dev, config); |
87 | } | 90 | } |
88 | EXPORT_SYMBOL_GPL(devm_regmap_init_spi); | 91 | EXPORT_SYMBOL_GPL(devm_regmap_init_spi); |
89 | 92 | ||
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 7a3f535e481..bde30c5d5ee 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -163,6 +163,7 @@ static unsigned int regmap_parse_32(void *buf) | |||
163 | * | 163 | * |
164 | * @dev: Device that will be interacted with | 164 | * @dev: Device that will be interacted with |
165 | * @bus: Bus-specific callbacks to use with device | 165 | * @bus: Bus-specific callbacks to use with device |
166 | * @bus_context: Data passed to bus-specific callbacks | ||
166 | * @config: Configuration for register map | 167 | * @config: Configuration for register map |
167 | * | 168 | * |
168 | * The return value will be an ERR_PTR() on error or a valid pointer to | 169 | * The return value will be an ERR_PTR() on error or a valid pointer to |
@@ -171,6 +172,7 @@ static unsigned int regmap_parse_32(void *buf) | |||
171 | */ | 172 | */ |
172 | struct regmap *regmap_init(struct device *dev, | 173 | struct regmap *regmap_init(struct device *dev, |
173 | const struct regmap_bus *bus, | 174 | const struct regmap_bus *bus, |
175 | void *bus_context, | ||
174 | const struct regmap_config *config) | 176 | const struct regmap_config *config) |
175 | { | 177 | { |
176 | struct regmap *map; | 178 | struct regmap *map; |
@@ -193,6 +195,7 @@ struct regmap *regmap_init(struct device *dev, | |||
193 | map->format.buf_size += map->format.pad_bytes; | 195 | map->format.buf_size += map->format.pad_bytes; |
194 | map->dev = dev; | 196 | map->dev = dev; |
195 | map->bus = bus; | 197 | map->bus = bus; |
198 | map->bus_context = bus_context; | ||
196 | map->max_register = config->max_register; | 199 | map->max_register = config->max_register; |
197 | map->writeable_reg = config->writeable_reg; | 200 | map->writeable_reg = config->writeable_reg; |
198 | map->readable_reg = config->readable_reg; | 201 | map->readable_reg = config->readable_reg; |
@@ -316,6 +319,7 @@ static void devm_regmap_release(struct device *dev, void *res) | |||
316 | * | 319 | * |
317 | * @dev: Device that will be interacted with | 320 | * @dev: Device that will be interacted with |
318 | * @bus: Bus-specific callbacks to use with device | 321 | * @bus: Bus-specific callbacks to use with device |
322 | * @bus_context: Data passed to bus-specific callbacks | ||
319 | * @config: Configuration for register map | 323 | * @config: Configuration for register map |
320 | * | 324 | * |
321 | * The return value will be an ERR_PTR() on error or a valid pointer | 325 | * The return value will be an ERR_PTR() on error or a valid pointer |
@@ -325,6 +329,7 @@ static void devm_regmap_release(struct device *dev, void *res) | |||
325 | */ | 329 | */ |
326 | struct regmap *devm_regmap_init(struct device *dev, | 330 | struct regmap *devm_regmap_init(struct device *dev, |
327 | const struct regmap_bus *bus, | 331 | const struct regmap_bus *bus, |
332 | void *bus_context, | ||
328 | const struct regmap_config *config) | 333 | const struct regmap_config *config) |
329 | { | 334 | { |
330 | struct regmap **ptr, *regmap; | 335 | struct regmap **ptr, *regmap; |
@@ -333,7 +338,7 @@ struct regmap *devm_regmap_init(struct device *dev, | |||
333 | if (!ptr) | 338 | if (!ptr) |
334 | return ERR_PTR(-ENOMEM); | 339 | return ERR_PTR(-ENOMEM); |
335 | 340 | ||
336 | regmap = regmap_init(dev, bus, config); | 341 | regmap = regmap_init(dev, bus, bus_context, config); |
337 | if (!IS_ERR(regmap)) { | 342 | if (!IS_ERR(regmap)) { |
338 | *ptr = regmap; | 343 | *ptr = regmap; |
339 | devres_add(dev, ptr); | 344 | devres_add(dev, ptr); |
@@ -391,6 +396,8 @@ void regmap_exit(struct regmap *map) | |||
391 | { | 396 | { |
392 | regcache_exit(map); | 397 | regcache_exit(map); |
393 | regmap_debugfs_exit(map); | 398 | regmap_debugfs_exit(map); |
399 | if (map->bus->free_context) | ||
400 | map->bus->free_context(map->bus_context); | ||
394 | kfree(map->work_buf); | 401 | kfree(map->work_buf); |
395 | kfree(map); | 402 | kfree(map); |
396 | } | 403 | } |
@@ -444,12 +451,12 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
444 | */ | 451 | */ |
445 | if (val == (map->work_buf + map->format.pad_bytes + | 452 | if (val == (map->work_buf + map->format.pad_bytes + |
446 | map->format.reg_bytes)) | 453 | map->format.reg_bytes)) |
447 | ret = map->bus->write(map->dev, map->work_buf, | 454 | ret = map->bus->write(map->bus_context, map->work_buf, |
448 | map->format.reg_bytes + | 455 | map->format.reg_bytes + |
449 | map->format.pad_bytes + | 456 | map->format.pad_bytes + |
450 | val_len); | 457 | val_len); |
451 | else if (map->bus->gather_write) | 458 | else if (map->bus->gather_write) |
452 | ret = map->bus->gather_write(map->dev, map->work_buf, | 459 | ret = map->bus->gather_write(map->bus_context, map->work_buf, |
453 | map->format.reg_bytes + | 460 | map->format.reg_bytes + |
454 | map->format.pad_bytes, | 461 | map->format.pad_bytes, |
455 | val, val_len); | 462 | val, val_len); |
@@ -464,7 +471,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, | |||
464 | memcpy(buf, map->work_buf, map->format.reg_bytes); | 471 | memcpy(buf, map->work_buf, map->format.reg_bytes); |
465 | memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, | 472 | memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, |
466 | val, val_len); | 473 | val, val_len); |
467 | ret = map->bus->write(map->dev, buf, len); | 474 | ret = map->bus->write(map->bus_context, buf, len); |
468 | 475 | ||
469 | kfree(buf); | 476 | kfree(buf); |
470 | } | 477 | } |
@@ -498,7 +505,7 @@ int _regmap_write(struct regmap *map, unsigned int reg, | |||
498 | 505 | ||
499 | trace_regmap_hw_write_start(map->dev, reg, 1); | 506 | trace_regmap_hw_write_start(map->dev, reg, 1); |
500 | 507 | ||
501 | ret = map->bus->write(map->dev, map->work_buf, | 508 | ret = map->bus->write(map->bus_context, map->work_buf, |
502 | map->format.buf_size); | 509 | map->format.buf_size); |
503 | 510 | ||
504 | trace_regmap_hw_write_done(map->dev, reg, 1); | 511 | trace_regmap_hw_write_done(map->dev, reg, 1); |
@@ -639,7 +646,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | |||
639 | trace_regmap_hw_read_start(map->dev, reg, | 646 | trace_regmap_hw_read_start(map->dev, reg, |
640 | val_len / map->format.val_bytes); | 647 | val_len / map->format.val_bytes); |
641 | 648 | ||
642 | ret = map->bus->read(map->dev, map->work_buf, | 649 | ret = map->bus->read(map->bus_context, map->work_buf, |
643 | map->format.reg_bytes + map->format.pad_bytes, | 650 | map->format.reg_bytes + map->format.pad_bytes, |
644 | val, val_len); | 651 | val, val_len); |
645 | 652 | ||