diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-08-22 12:45:39 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-08-22 12:59:20 -0400 |
commit | c0409feb86893f5ccf73964c7b2b47ca64bdb014 (patch) | |
tree | cb889f2e239a6261e8b657979b932b32bae579da /drivers/input/misc/ad714x-spi.c | |
parent | 6337de2204be3b7b40825a1d30de30e514e8947b (diff) |
Input: ad714x - use DMA-safe buffers for spi_write()
spi_write() requires use of DMA-safe (cacheline aligned) buffers.
Also use the same buffers when reading data since to avoid extra
locking and potential memory allocation in spi_write_then_read().
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/misc/ad714x-spi.c')
-rw-r--r-- | drivers/input/misc/ad714x-spi.c | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c index 0c7f9488f5cb..306577dc0b98 100644 --- a/drivers/input/misc/ad714x-spi.c +++ b/drivers/input/misc/ad714x-spi.c | |||
@@ -30,31 +30,54 @@ static int ad714x_spi_resume(struct device *dev) | |||
30 | 30 | ||
31 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); | 31 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); |
32 | 32 | ||
33 | static int ad714x_spi_read(struct device *dev, | 33 | static int ad714x_spi_read(struct ad714x_chip *chip, |
34 | unsigned short reg, unsigned short *data) | 34 | unsigned short reg, unsigned short *data) |
35 | { | 35 | { |
36 | struct spi_device *spi = to_spi_device(dev); | 36 | struct spi_device *spi = to_spi_device(chip->dev); |
37 | unsigned short tx = cpu_to_be16(AD714x_SPI_CMD_PREFIX | | 37 | struct spi_message message; |
38 | struct spi_transfer xfer[2]; | ||
39 | int error; | ||
40 | |||
41 | spi_message_init(&message); | ||
42 | memset(xfer, 0, sizeof(xfer)); | ||
43 | |||
44 | chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | | ||
38 | AD714x_SPI_READ | reg); | 45 | AD714x_SPI_READ | reg); |
39 | int ret; | 46 | xfer[0].tx_buf = &chip->xfer_buf[0]; |
47 | xfer[0].len = sizeof(chip->xfer_buf[0]); | ||
48 | spi_message_add_tail(&xfer[0], &message); | ||
40 | 49 | ||
41 | ret = spi_write_then_read(spi, &tx, 2, data, 2); | 50 | xfer[1].rx_buf = &chip->xfer_buf[1]; |
51 | xfer[1].len = sizeof(chip->xfer_buf[1]); | ||
52 | spi_message_add_tail(&xfer[1], &message); | ||
42 | 53 | ||
43 | *data = be16_to_cpup(data); | 54 | error = spi_sync(spi, &message); |
55 | if (unlikely(error)) { | ||
56 | dev_err(chip->dev, "SPI read error: %d\n", error); | ||
57 | return error; | ||
58 | } | ||
44 | 59 | ||
45 | return ret; | 60 | *data = be16_to_cpu(chip->xfer_buf[1]); |
61 | return 0; | ||
46 | } | 62 | } |
47 | 63 | ||
48 | static int ad714x_spi_write(struct device *dev, | 64 | static int ad714x_spi_write(struct ad714x_chip *chip, |
49 | unsigned short reg, unsigned short data) | 65 | unsigned short reg, unsigned short data) |
50 | { | 66 | { |
51 | struct spi_device *spi = to_spi_device(dev); | 67 | struct spi_device *spi = to_spi_device(chip->dev); |
52 | unsigned short tx[2] = { | 68 | int error; |
53 | cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg), | ||
54 | cpu_to_be16(data) | ||
55 | }; | ||
56 | 69 | ||
57 | return spi_write(spi, (u8 *)tx, 4); | 70 | chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg); |
71 | chip->xfer_buf[1] = cpu_to_be16(data); | ||
72 | |||
73 | error = spi_write(spi, (u8 *)chip->xfer_buf, | ||
74 | 2 * sizeof(*chip->xfer_buf)); | ||
75 | if (unlikely(error)) { | ||
76 | dev_err(chip->dev, "SPI write error: %d\n", error); | ||
77 | return error; | ||
78 | } | ||
79 | |||
80 | return 0; | ||
58 | } | 81 | } |
59 | 82 | ||
60 | static int __devinit ad714x_spi_probe(struct spi_device *spi) | 83 | static int __devinit ad714x_spi_probe(struct spi_device *spi) |