diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2013-11-25 07:41:00 -0500 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2013-12-03 15:22:26 -0500 |
commit | 791bb52a0cd2cc95f030e461cfafe26448bc6618 (patch) | |
tree | 6df3a043a100376081f039b452e2e6da3757af40 /drivers/iio/dac | |
parent | ae8bb9b10124ff266c35507b347b31f34c0fe05d (diff) |
iio:ad5791: Do not store transfer buffers on the stack
Some SPI controllers may not be able to handle transfer buffers that are placed
on the stack.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/dac')
-rw-r--r-- | drivers/iio/dac/ad5791.c | 46 |
1 files changed, 21 insertions, 25 deletions
diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 1e7f4cd7db83..79bf19945747 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c | |||
@@ -91,6 +91,11 @@ struct ad5791_state { | |||
91 | unsigned ctrl; | 91 | unsigned ctrl; |
92 | unsigned pwr_down_mode; | 92 | unsigned pwr_down_mode; |
93 | bool pwr_down; | 93 | bool pwr_down; |
94 | |||
95 | union { | ||
96 | __be32 d32; | ||
97 | u8 d8[4]; | ||
98 | } data[3] ____cacheline_aligned; | ||
94 | }; | 99 | }; |
95 | 100 | ||
96 | /** | 101 | /** |
@@ -104,48 +109,39 @@ enum ad5791_supported_device_ids { | |||
104 | ID_AD5791, | 109 | ID_AD5791, |
105 | }; | 110 | }; |
106 | 111 | ||
107 | static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val) | 112 | static int ad5791_spi_write(struct ad5791_state *st, u8 addr, u32 val) |
108 | { | 113 | { |
109 | union { | 114 | st->data[0].d32 = cpu_to_be32(AD5791_CMD_WRITE | |
110 | __be32 d32; | ||
111 | u8 d8[4]; | ||
112 | } data; | ||
113 | |||
114 | data.d32 = cpu_to_be32(AD5791_CMD_WRITE | | ||
115 | AD5791_ADDR(addr) | | 115 | AD5791_ADDR(addr) | |
116 | (val & AD5791_DAC_MASK)); | 116 | (val & AD5791_DAC_MASK)); |
117 | 117 | ||
118 | return spi_write(spi, &data.d8[1], 3); | 118 | return spi_write(st->spi, &st->data[0].d8[1], 3); |
119 | } | 119 | } |
120 | 120 | ||
121 | static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val) | 121 | static int ad5791_spi_read(struct ad5791_state *st, u8 addr, u32 *val) |
122 | { | 122 | { |
123 | union { | ||
124 | __be32 d32; | ||
125 | u8 d8[4]; | ||
126 | } data[3]; | ||
127 | int ret; | 123 | int ret; |
128 | struct spi_transfer xfers[] = { | 124 | struct spi_transfer xfers[] = { |
129 | { | 125 | { |
130 | .tx_buf = &data[0].d8[1], | 126 | .tx_buf = &st->data[0].d8[1], |
131 | .bits_per_word = 8, | 127 | .bits_per_word = 8, |
132 | .len = 3, | 128 | .len = 3, |
133 | .cs_change = 1, | 129 | .cs_change = 1, |
134 | }, { | 130 | }, { |
135 | .tx_buf = &data[1].d8[1], | 131 | .tx_buf = &st->data[1].d8[1], |
136 | .rx_buf = &data[2].d8[1], | 132 | .rx_buf = &st->data[2].d8[1], |
137 | .bits_per_word = 8, | 133 | .bits_per_word = 8, |
138 | .len = 3, | 134 | .len = 3, |
139 | }, | 135 | }, |
140 | }; | 136 | }; |
141 | 137 | ||
142 | data[0].d32 = cpu_to_be32(AD5791_CMD_READ | | 138 | st->data[0].d32 = cpu_to_be32(AD5791_CMD_READ | |
143 | AD5791_ADDR(addr)); | 139 | AD5791_ADDR(addr)); |
144 | data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP)); | 140 | st->data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP)); |
145 | 141 | ||
146 | ret = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers)); | 142 | ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); |
147 | 143 | ||
148 | *val = be32_to_cpu(data[2].d32); | 144 | *val = be32_to_cpu(st->data[2].d32); |
149 | 145 | ||
150 | return ret; | 146 | return ret; |
151 | } | 147 | } |
@@ -210,7 +206,7 @@ static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev, | |||
210 | } | 206 | } |
211 | st->pwr_down = pwr_down; | 207 | st->pwr_down = pwr_down; |
212 | 208 | ||
213 | ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl); | 209 | ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl); |
214 | 210 | ||
215 | return ret ? ret : len; | 211 | return ret ? ret : len; |
216 | } | 212 | } |
@@ -263,7 +259,7 @@ static int ad5791_read_raw(struct iio_dev *indio_dev, | |||
263 | 259 | ||
264 | switch (m) { | 260 | switch (m) { |
265 | case IIO_CHAN_INFO_RAW: | 261 | case IIO_CHAN_INFO_RAW: |
266 | ret = ad5791_spi_read(st->spi, chan->address, val); | 262 | ret = ad5791_spi_read(st, chan->address, val); |
267 | if (ret) | 263 | if (ret) |
268 | return ret; | 264 | return ret; |
269 | *val &= AD5791_DAC_MASK; | 265 | *val &= AD5791_DAC_MASK; |
@@ -330,7 +326,7 @@ static int ad5791_write_raw(struct iio_dev *indio_dev, | |||
330 | val &= AD5791_RES_MASK(chan->scan_type.realbits); | 326 | val &= AD5791_RES_MASK(chan->scan_type.realbits); |
331 | val <<= chan->scan_type.shift; | 327 | val <<= chan->scan_type.shift; |
332 | 328 | ||
333 | return ad5791_spi_write(st->spi, chan->address, val); | 329 | return ad5791_spi_write(st, chan->address, val); |
334 | 330 | ||
335 | default: | 331 | default: |
336 | return -EINVAL; | 332 | return -EINVAL; |
@@ -393,7 +389,7 @@ static int ad5791_probe(struct spi_device *spi) | |||
393 | dev_warn(&spi->dev, "reference voltage unspecified\n"); | 389 | dev_warn(&spi->dev, "reference voltage unspecified\n"); |
394 | } | 390 | } |
395 | 391 | ||
396 | ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); | 392 | ret = ad5791_spi_write(st, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); |
397 | if (ret) | 393 | if (ret) |
398 | goto error_disable_reg_neg; | 394 | goto error_disable_reg_neg; |
399 | 395 | ||
@@ -405,7 +401,7 @@ static int ad5791_probe(struct spi_device *spi) | |||
405 | | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) | | 401 | | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) | |
406 | AD5791_CTRL_BIN2SC; | 402 | AD5791_CTRL_BIN2SC; |
407 | 403 | ||
408 | ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl | | 404 | ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl | |
409 | AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI); | 405 | AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI); |
410 | if (ret) | 406 | if (ret) |
411 | goto error_disable_reg_neg; | 407 | goto error_disable_reg_neg; |