diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-03-17 17:42:28 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2011-03-23 05:42:10 -0400 |
commit | 334e9ab8f9bb90ddf1eff0b07609961a628064b6 (patch) | |
tree | 662945d7aed6adb546ed3915186e86b2f56b3cad /drivers/mfd | |
parent | 4c4d887822070410e3be519e1a4ff933fb899ba8 (diff) |
mfd: Avoid copying data in WM8994 I2C write
As well as providing a trivial performance optimisation this also avoids
allocating a copy of the message on the stack which is beneficial when
doing large transfers.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/wm8994-core.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 749c31d29b09..ce93796e7f57 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -580,25 +580,29 @@ static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg, | |||
580 | return 0; | 580 | return 0; |
581 | } | 581 | } |
582 | 582 | ||
583 | /* Currently we allocate the write buffer on the stack; this is OK for | ||
584 | * small writes - if we need to do large writes this will need to be | ||
585 | * revised. | ||
586 | */ | ||
587 | static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg, | 583 | static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg, |
588 | int bytes, void *src) | 584 | int bytes, void *src) |
589 | { | 585 | { |
590 | struct i2c_client *i2c = wm8994->control_data; | 586 | struct i2c_client *i2c = wm8994->control_data; |
591 | unsigned char msg[bytes + 2]; | 587 | struct i2c_msg xfer[2]; |
592 | int ret; | 588 | int ret; |
593 | 589 | ||
594 | reg = cpu_to_be16(reg); | 590 | reg = cpu_to_be16(reg); |
595 | memcpy(&msg[0], ®, 2); | ||
596 | memcpy(&msg[2], src, bytes); | ||
597 | 591 | ||
598 | ret = i2c_master_send(i2c, msg, bytes + 2); | 592 | xfer[0].addr = i2c->addr; |
593 | xfer[0].flags = 0; | ||
594 | xfer[0].len = 2; | ||
595 | xfer[0].buf = (char *)® | ||
596 | |||
597 | xfer[1].addr = i2c->addr; | ||
598 | xfer[1].flags = I2C_M_NOSTART; | ||
599 | xfer[1].len = bytes; | ||
600 | xfer[1].buf = (char *)src; | ||
601 | |||
602 | ret = i2c_transfer(i2c->adapter, xfer, 2); | ||
599 | if (ret < 0) | 603 | if (ret < 0) |
600 | return ret; | 604 | return ret; |
601 | if (ret < bytes + 2) | 605 | if (ret != 2) |
602 | return -EIO; | 606 | return -EIO; |
603 | 607 | ||
604 | return 0; | 608 | return 0; |