aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-05-11 16:57:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-05-11 16:57:47 -0400
commitef208162b7b4c40de1825a61677e167c081f5fee (patch)
treec83bda45c233fab8f3b8ebf30d7b9f880908d567
parenta156e0682f5b328094c273435a46e32e100ba898 (diff)
parentc8b350424d1862619c311204290cd42bae4ebaa3 (diff)
Merge tag 'spi-fix-v4.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fixes from Mark Brown: "A number of driver specific fixes (including several missing dependencies for randconfig type cases) plus two core fixes. One makes the setup_transfer() callback optional which unbreaks some drivers which had been merged with it omitted due to local versions of this patch and another ensures that we don't corrupt data by leaking internal dummy buffers to callers, causing the callers to think they allocated those buffers" * tag 'spi-fix-v4.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi: fsl-espi: fix behaviour for full-duplex xfers spi: fsl-spi: fix devm_ioremap_resource() error case spi: Kconfig: Add SOC_LS1021A to SPI_FSL_DSPI dependence spi/omap2-mcpsi: Always call spi_finalize_current_message() spi: fsl-spi: use devm_ioremap_resource() to map parameter ram on CPM1 spi: bitbang: Make setup_transfer() callback optional spi: check tx_buf and rx_buf in spi_unmap_msg spi: bcm2835: change timeout of polling driver to 1s spi: bcm2835: Add GPIOLIB dependency
-rw-r--r--drivers/spi/Kconfig3
-rw-r--r--drivers/spi/spi-bcm2835.c5
-rw-r--r--drivers/spi/spi-bitbang.c17
-rw-r--r--drivers/spi/spi-fsl-cpm.c40
-rw-r--r--drivers/spi/spi-fsl-espi.c45
-rw-r--r--drivers/spi/spi-omap2-mcspi.c16
-rw-r--r--drivers/spi/spi.c9
7 files changed, 89 insertions, 46 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 198f96b7fb45..72b059081559 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -78,6 +78,7 @@ config SPI_ATMEL
78config SPI_BCM2835 78config SPI_BCM2835
79 tristate "BCM2835 SPI controller" 79 tristate "BCM2835 SPI controller"
80 depends on ARCH_BCM2835 || COMPILE_TEST 80 depends on ARCH_BCM2835 || COMPILE_TEST
81 depends on GPIOLIB
81 help 82 help
82 This selects a driver for the Broadcom BCM2835 SPI master. 83 This selects a driver for the Broadcom BCM2835 SPI master.
83 84
@@ -302,7 +303,7 @@ config SPI_FSL_SPI
302config SPI_FSL_DSPI 303config SPI_FSL_DSPI
303 tristate "Freescale DSPI controller" 304 tristate "Freescale DSPI controller"
304 select REGMAP_MMIO 305 select REGMAP_MMIO
305 depends on SOC_VF610 || COMPILE_TEST 306 depends on SOC_VF610 || SOC_LS1021A || COMPILE_TEST
306 help 307 help
307 This enables support for the Freescale DSPI controller in master 308 This enables support for the Freescale DSPI controller in master
308 mode. VF610 platform uses the controller. 309 mode. VF610 platform uses the controller.
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index f63864a893c5..37875cf942f7 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -164,13 +164,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
164 unsigned long xfer_time_us) 164 unsigned long xfer_time_us)
165{ 165{
166 struct bcm2835_spi *bs = spi_master_get_devdata(master); 166 struct bcm2835_spi *bs = spi_master_get_devdata(master);
167 unsigned long timeout = jiffies + 167 /* set timeout to 1 second of maximum polling */
168 max(4 * xfer_time_us * HZ / 1000000, 2uL); 168 unsigned long timeout = jiffies + HZ;
169 169
170 /* enable HW block without interrupts */ 170 /* enable HW block without interrupts */
171 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); 171 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA);
172 172
173 /* set timeout to 4x the expected time, or 2 jiffies */
174 /* loop until finished the transfer */ 173 /* loop until finished the transfer */
175 while (bs->rx_len) { 174 while (bs->rx_len) {
176 /* read from fifo as much as possible */ 175 /* read from fifo as much as possible */
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index 5ef6638d5e8a..840a4984d365 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi)
180{ 180{
181 struct spi_bitbang_cs *cs = spi->controller_state; 181 struct spi_bitbang_cs *cs = spi->controller_state;
182 struct spi_bitbang *bitbang; 182 struct spi_bitbang *bitbang;
183 int retval;
184 unsigned long flags; 183 unsigned long flags;
185 184
186 bitbang = spi_master_get_devdata(spi->master); 185 bitbang = spi_master_get_devdata(spi->master);
@@ -197,9 +196,11 @@ int spi_bitbang_setup(struct spi_device *spi)
197 if (!cs->txrx_word) 196 if (!cs->txrx_word)
198 return -EINVAL; 197 return -EINVAL;
199 198
200 retval = bitbang->setup_transfer(spi, NULL); 199 if (bitbang->setup_transfer) {
201 if (retval < 0) 200 int retval = bitbang->setup_transfer(spi, NULL);
202 return retval; 201 if (retval < 0)
202 return retval;
203 }
203 204
204 dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); 205 dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs);
205 206
@@ -295,9 +296,11 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
295 296
296 /* init (-1) or override (1) transfer params */ 297 /* init (-1) or override (1) transfer params */
297 if (do_setup != 0) { 298 if (do_setup != 0) {
298 status = bitbang->setup_transfer(spi, t); 299 if (bitbang->setup_transfer) {
299 if (status < 0) 300 status = bitbang->setup_transfer(spi, t);
300 break; 301 if (status < 0)
302 break;
303 }
301 if (do_setup == -1) 304 if (do_setup == -1)
302 do_setup = 0; 305 do_setup = 0;
303 } 306 }
diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c
index 9c46a3058743..896add8cfd3b 100644
--- a/drivers/spi/spi-fsl-cpm.c
+++ b/drivers/spi/spi-fsl-cpm.c
@@ -24,6 +24,7 @@
24#include <linux/of_address.h> 24#include <linux/of_address.h>
25#include <linux/spi/spi.h> 25#include <linux/spi/spi.h>
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/platform_device.h>
27 28
28#include "spi-fsl-cpm.h" 29#include "spi-fsl-cpm.h"
29#include "spi-fsl-lib.h" 30#include "spi-fsl-lib.h"
@@ -269,17 +270,6 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
269 if (mspi->flags & SPI_CPM2) { 270 if (mspi->flags & SPI_CPM2) {
270 pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); 271 pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
271 out_be16(spi_base, pram_ofs); 272 out_be16(spi_base, pram_ofs);
272 } else {
273 struct spi_pram __iomem *pram = spi_base;
274 u16 rpbase = in_be16(&pram->rpbase);
275
276 /* Microcode relocation patch applied? */
277 if (rpbase) {
278 pram_ofs = rpbase;
279 } else {
280 pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
281 out_be16(spi_base, pram_ofs);
282 }
283 } 273 }
284 274
285 iounmap(spi_base); 275 iounmap(spi_base);
@@ -292,7 +282,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
292 struct device_node *np = dev->of_node; 282 struct device_node *np = dev->of_node;
293 const u32 *iprop; 283 const u32 *iprop;
294 int size; 284 int size;
295 unsigned long pram_ofs;
296 unsigned long bds_ofs; 285 unsigned long bds_ofs;
297 286
298 if (!(mspi->flags & SPI_CPM_MODE)) 287 if (!(mspi->flags & SPI_CPM_MODE))
@@ -319,8 +308,26 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
319 } 308 }
320 } 309 }
321 310
322 pram_ofs = fsl_spi_cpm_get_pram(mspi); 311 if (mspi->flags & SPI_CPM1) {
323 if (IS_ERR_VALUE(pram_ofs)) { 312 struct resource *res;
313 void *pram;
314
315 res = platform_get_resource(to_platform_device(dev),
316 IORESOURCE_MEM, 1);
317 pram = devm_ioremap_resource(dev, res);
318 if (IS_ERR(pram))
319 mspi->pram = NULL;
320 else
321 mspi->pram = pram;
322 } else {
323 unsigned long pram_ofs = fsl_spi_cpm_get_pram(mspi);
324
325 if (IS_ERR_VALUE(pram_ofs))
326 mspi->pram = NULL;
327 else
328 mspi->pram = cpm_muram_addr(pram_ofs);
329 }
330 if (mspi->pram == NULL) {
324 dev_err(dev, "can't allocate spi parameter ram\n"); 331 dev_err(dev, "can't allocate spi parameter ram\n");
325 goto err_pram; 332 goto err_pram;
326 } 333 }
@@ -346,8 +353,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
346 goto err_dummy_rx; 353 goto err_dummy_rx;
347 } 354 }
348 355
349 mspi->pram = cpm_muram_addr(pram_ofs);
350
351 mspi->tx_bd = cpm_muram_addr(bds_ofs); 356 mspi->tx_bd = cpm_muram_addr(bds_ofs);
352 mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd)); 357 mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd));
353 358
@@ -375,7 +380,8 @@ err_dummy_rx:
375err_dummy_tx: 380err_dummy_tx:
376 cpm_muram_free(bds_ofs); 381 cpm_muram_free(bds_ofs);
377err_bds: 382err_bds:
378 cpm_muram_free(pram_ofs); 383 if (!(mspi->flags & SPI_CPM1))
384 cpm_muram_free(cpm_muram_offset(mspi->pram));
379err_pram: 385err_pram:
380 fsl_spi_free_dummy_rx(); 386 fsl_spi_free_dummy_rx();
381 return -ENOMEM; 387 return -ENOMEM;
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index d0a73a09a9bd..80d245ac846f 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -359,14 +359,16 @@ static void fsl_espi_rw_trans(struct spi_message *m,
359 struct fsl_espi_transfer *trans, u8 *rx_buff) 359 struct fsl_espi_transfer *trans, u8 *rx_buff)
360{ 360{
361 struct fsl_espi_transfer *espi_trans = trans; 361 struct fsl_espi_transfer *espi_trans = trans;
362 unsigned int n_tx = espi_trans->n_tx; 362 unsigned int total_len = espi_trans->len;
363 unsigned int n_rx = espi_trans->n_rx;
364 struct spi_transfer *t; 363 struct spi_transfer *t;
365 u8 *local_buf; 364 u8 *local_buf;
366 u8 *rx_buf = rx_buff; 365 u8 *rx_buf = rx_buff;
367 unsigned int trans_len; 366 unsigned int trans_len;
368 unsigned int addr; 367 unsigned int addr;
369 int i, pos, loop; 368 unsigned int tx_only;
369 unsigned int rx_pos = 0;
370 unsigned int pos;
371 int i, loop;
370 372
371 local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL); 373 local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL);
372 if (!local_buf) { 374 if (!local_buf) {
@@ -374,36 +376,48 @@ static void fsl_espi_rw_trans(struct spi_message *m,
374 return; 376 return;
375 } 377 }
376 378
377 for (pos = 0, loop = 0; pos < n_rx; pos += trans_len, loop++) { 379 for (pos = 0, loop = 0; pos < total_len; pos += trans_len, loop++) {
378 trans_len = n_rx - pos; 380 trans_len = total_len - pos;
379 if (trans_len > SPCOM_TRANLEN_MAX - n_tx)
380 trans_len = SPCOM_TRANLEN_MAX - n_tx;
381 381
382 i = 0; 382 i = 0;
383 tx_only = 0;
383 list_for_each_entry(t, &m->transfers, transfer_list) { 384 list_for_each_entry(t, &m->transfers, transfer_list) {
384 if (t->tx_buf) { 385 if (t->tx_buf) {
385 memcpy(local_buf + i, t->tx_buf, t->len); 386 memcpy(local_buf + i, t->tx_buf, t->len);
386 i += t->len; 387 i += t->len;
388 if (!t->rx_buf)
389 tx_only += t->len;
387 } 390 }
388 } 391 }
389 392
393 /* Add additional TX bytes to compensate SPCOM_TRANLEN_MAX */
394 if (loop > 0)
395 trans_len += tx_only;
396
397 if (trans_len > SPCOM_TRANLEN_MAX)
398 trans_len = SPCOM_TRANLEN_MAX;
399
400 /* Update device offset */
390 if (pos > 0) { 401 if (pos > 0) {
391 addr = fsl_espi_cmd2addr(local_buf); 402 addr = fsl_espi_cmd2addr(local_buf);
392 addr += pos; 403 addr += rx_pos;
393 fsl_espi_addr2cmd(addr, local_buf); 404 fsl_espi_addr2cmd(addr, local_buf);
394 } 405 }
395 406
396 espi_trans->n_tx = n_tx; 407 espi_trans->len = trans_len;
397 espi_trans->n_rx = trans_len;
398 espi_trans->len = trans_len + n_tx;
399 espi_trans->tx_buf = local_buf; 408 espi_trans->tx_buf = local_buf;
400 espi_trans->rx_buf = local_buf; 409 espi_trans->rx_buf = local_buf;
401 fsl_espi_do_trans(m, espi_trans); 410 fsl_espi_do_trans(m, espi_trans);
402 411
403 memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len); 412 /* If there is at least one RX byte then copy it to rx_buf */
413 if (tx_only < SPCOM_TRANLEN_MAX)
414 memcpy(rx_buf + rx_pos, espi_trans->rx_buf + tx_only,
415 trans_len - tx_only);
416
417 rx_pos += trans_len - tx_only;
404 418
405 if (loop > 0) 419 if (loop > 0)
406 espi_trans->actual_length += espi_trans->len - n_tx; 420 espi_trans->actual_length += espi_trans->len - tx_only;
407 else 421 else
408 espi_trans->actual_length += espi_trans->len; 422 espi_trans->actual_length += espi_trans->len;
409 } 423 }
@@ -418,6 +432,7 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
418 u8 *rx_buf = NULL; 432 u8 *rx_buf = NULL;
419 unsigned int n_tx = 0; 433 unsigned int n_tx = 0;
420 unsigned int n_rx = 0; 434 unsigned int n_rx = 0;
435 unsigned int xfer_len = 0;
421 struct fsl_espi_transfer espi_trans; 436 struct fsl_espi_transfer espi_trans;
422 437
423 list_for_each_entry(t, &m->transfers, transfer_list) { 438 list_for_each_entry(t, &m->transfers, transfer_list) {
@@ -427,11 +442,13 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
427 n_rx += t->len; 442 n_rx += t->len;
428 rx_buf = t->rx_buf; 443 rx_buf = t->rx_buf;
429 } 444 }
445 if ((t->tx_buf) || (t->rx_buf))
446 xfer_len += t->len;
430 } 447 }
431 448
432 espi_trans.n_tx = n_tx; 449 espi_trans.n_tx = n_tx;
433 espi_trans.n_rx = n_rx; 450 espi_trans.n_rx = n_rx;
434 espi_trans.len = n_tx + n_rx; 451 espi_trans.len = xfer_len;
435 espi_trans.actual_length = 0; 452 espi_trans.actual_length = 0;
436 espi_trans.status = 0; 453 espi_trans.status = 0;
437 454
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 4df8942058de..d1a5b9fc3eba 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -1210,6 +1210,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
1210 struct omap2_mcspi *mcspi; 1210 struct omap2_mcspi *mcspi;
1211 struct omap2_mcspi_dma *mcspi_dma; 1211 struct omap2_mcspi_dma *mcspi_dma;
1212 struct spi_transfer *t; 1212 struct spi_transfer *t;
1213 int status;
1213 1214
1214 spi = m->spi; 1215 spi = m->spi;
1215 mcspi = spi_master_get_devdata(master); 1216 mcspi = spi_master_get_devdata(master);
@@ -1229,7 +1230,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
1229 tx_buf ? "tx" : "", 1230 tx_buf ? "tx" : "",
1230 rx_buf ? "rx" : "", 1231 rx_buf ? "rx" : "",
1231 t->bits_per_word); 1232 t->bits_per_word);
1232 return -EINVAL; 1233 status = -EINVAL;
1234 goto out;
1233 } 1235 }
1234 1236
1235 if (m->is_dma_mapped || len < DMA_MIN_BYTES) 1237 if (m->is_dma_mapped || len < DMA_MIN_BYTES)
@@ -1241,7 +1243,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
1241 if (dma_mapping_error(mcspi->dev, t->tx_dma)) { 1243 if (dma_mapping_error(mcspi->dev, t->tx_dma)) {
1242 dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", 1244 dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
1243 'T', len); 1245 'T', len);
1244 return -EINVAL; 1246 status = -EINVAL;
1247 goto out;
1245 } 1248 }
1246 } 1249 }
1247 if (mcspi_dma->dma_rx && rx_buf != NULL) { 1250 if (mcspi_dma->dma_rx && rx_buf != NULL) {
@@ -1253,14 +1256,19 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
1253 if (tx_buf != NULL) 1256 if (tx_buf != NULL)
1254 dma_unmap_single(mcspi->dev, t->tx_dma, 1257 dma_unmap_single(mcspi->dev, t->tx_dma,
1255 len, DMA_TO_DEVICE); 1258 len, DMA_TO_DEVICE);
1256 return -EINVAL; 1259 status = -EINVAL;
1260 goto out;
1257 } 1261 }
1258 } 1262 }
1259 } 1263 }
1260 1264
1261 omap2_mcspi_work(mcspi, m); 1265 omap2_mcspi_work(mcspi, m);
1266 /* spi_finalize_current_message() changes the status inside the
1267 * spi_message, save the status here. */
1268 status = m->status;
1269out:
1262 spi_finalize_current_message(master); 1270 spi_finalize_current_message(master);
1263 return 0; 1271 return status;
1264} 1272}
1265 1273
1266static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) 1274static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index d5d7d2235163..50910d85df5a 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -583,6 +583,15 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg)
583 rx_dev = master->dma_rx->device->dev; 583 rx_dev = master->dma_rx->device->dev;
584 584
585 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 585 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
586 /*
587 * Restore the original value of tx_buf or rx_buf if they are
588 * NULL.
589 */
590 if (xfer->tx_buf == master->dummy_tx)
591 xfer->tx_buf = NULL;
592 if (xfer->rx_buf == master->dummy_rx)
593 xfer->rx_buf = NULL;
594
586 if (!master->can_dma(master, msg->spi, xfer)) 595 if (!master->can_dma(master, msg->spi, xfer))
587 continue; 596 continue;
588 597