aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-bitbang.c
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-07-05 15:07:27 -0400
committerMark Brown <broonie@linaro.org>2013-07-17 13:13:01 -0400
commit2025172e32808a327b00f968c72baa79adc594c2 (patch)
treeb0de1d0846e557e1c485e088ba55d6c227a8d7c8 /drivers/spi/spi-bitbang.c
parent91b308586793b48c590c9ac3528bbacb8ef53e15 (diff)
spi/bitbang: Use core message pump
Convert drivers using bitbang to use the core mesasge pump infrastructure, saving some code and meaning that these drivers get to take advantage of work done on improving the core implementation. Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-bitbang.c')
-rw-r--r--drivers/spi/spi-bitbang.c100
1 files changed, 30 insertions, 70 deletions
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index 8b8487c9694e..c100875cfd42 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -255,6 +255,21 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
255 * Drivers can provide word-at-a-time i/o primitives, or provide 255 * Drivers can provide word-at-a-time i/o primitives, or provide
256 * transfer-at-a-time ones to leverage dma or fifo hardware. 256 * transfer-at-a-time ones to leverage dma or fifo hardware.
257 */ 257 */
258
259static int spi_bitbang_prepare_hardware(struct spi_master *spi)
260{
261 struct spi_bitbang *bitbang;
262 unsigned long flags;
263
264 bitbang = spi_master_get_devdata(spi);
265
266 spin_lock_irqsave(&bitbang->lock, flags);
267 bitbang->busy = 1;
268 spin_unlock_irqrestore(&bitbang->lock, flags);
269
270 return 0;
271}
272
258static int spi_bitbang_transfer_one(struct spi_device *spi, 273static int spi_bitbang_transfer_one(struct spi_device *spi,
259 struct spi_message *m) 274 struct spi_message *m)
260{ 275{
@@ -346,7 +361,6 @@ static int spi_bitbang_transfer_one(struct spi_device *spi,
346 } 361 }
347 362
348 m->status = status; 363 m->status = status;
349 m->complete(m->context);
350 364
351 /* normally deactivate chipselect ... unless no error and 365 /* normally deactivate chipselect ... unless no error and
352 * cs_change has hinted that the next message will probably 366 * cs_change has hinted that the next message will probably
@@ -358,54 +372,23 @@ static int spi_bitbang_transfer_one(struct spi_device *spi,
358 ndelay(nsecs); 372 ndelay(nsecs);
359 } 373 }
360 374
361 return status; 375 spi_finalize_current_message(spi->master);
362}
363
364static void bitbang_work(struct work_struct *work)
365{
366 struct spi_bitbang *bitbang =
367 container_of(work, struct spi_bitbang, work);
368 unsigned long flags;
369 struct spi_message *m, *_m;
370
371 spin_lock_irqsave(&bitbang->lock, flags);
372 bitbang->busy = 1;
373 list_for_each_entry_safe(m, _m, &bitbang->queue, queue) {
374 list_del(&m->queue);
375 spin_unlock_irqrestore(&bitbang->lock, flags);
376
377 spi_bitbang_transfer_one(m->spi, m);
378 376
379 spin_lock_irqsave(&bitbang->lock, flags); 377 return status;
380 }
381 bitbang->busy = 0;
382 spin_unlock_irqrestore(&bitbang->lock, flags);
383} 378}
384 379
385/** 380static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
386 * spi_bitbang_transfer - default submit to transfer queue
387 */
388static int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)
389{ 381{
390 struct spi_bitbang *bitbang; 382 struct spi_bitbang *bitbang;
391 unsigned long flags; 383 unsigned long flags;
392 int status = 0;
393
394 m->actual_length = 0;
395 m->status = -EINPROGRESS;
396 384
397 bitbang = spi_master_get_devdata(spi->master); 385 bitbang = spi_master_get_devdata(spi);
398 386
399 spin_lock_irqsave(&bitbang->lock, flags); 387 spin_lock_irqsave(&bitbang->lock, flags);
400 if (!spi->max_speed_hz) 388 bitbang->busy = 0;
401 status = -ENETDOWN;
402 else {
403 list_add_tail(&m->queue, &bitbang->queue);
404 queue_work(bitbang->workqueue, &bitbang->work);
405 }
406 spin_unlock_irqrestore(&bitbang->lock, flags); 389 spin_unlock_irqrestore(&bitbang->lock, flags);
407 390
408 return status; 391 return 0;
409} 392}
410 393
411/*----------------------------------------------------------------------*/ 394/*----------------------------------------------------------------------*/
@@ -436,20 +419,22 @@ static int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)
436int spi_bitbang_start(struct spi_bitbang *bitbang) 419int spi_bitbang_start(struct spi_bitbang *bitbang)
437{ 420{
438 struct spi_master *master = bitbang->master; 421 struct spi_master *master = bitbang->master;
439 int status;
440 422
441 if (!master || !bitbang->chipselect) 423 if (!master || !bitbang->chipselect)
442 return -EINVAL; 424 return -EINVAL;
443 425
444 INIT_WORK(&bitbang->work, bitbang_work);
445 spin_lock_init(&bitbang->lock); 426 spin_lock_init(&bitbang->lock);
446 INIT_LIST_HEAD(&bitbang->queue);
447 427
448 if (!master->mode_bits) 428 if (!master->mode_bits)
449 master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; 429 master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
450 430
451 if (!master->transfer) 431 if (master->transfer || master->transfer_one_message)
452 master->transfer = spi_bitbang_transfer; 432 return -EINVAL;
433
434 master->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
435 master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
436 master->transfer_one_message = spi_bitbang_transfer_one;
437
453 if (!bitbang->txrx_bufs) { 438 if (!bitbang->txrx_bufs) {
454 bitbang->use_dma = 0; 439 bitbang->use_dma = 0;
455 bitbang->txrx_bufs = spi_bitbang_bufs; 440 bitbang->txrx_bufs = spi_bitbang_bufs;
@@ -462,32 +447,11 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
462 } 447 }
463 } else if (!master->setup) 448 } else if (!master->setup)
464 return -EINVAL; 449 return -EINVAL;
465 if (master->transfer == spi_bitbang_transfer &&
466 !bitbang->setup_transfer)
467 return -EINVAL;
468
469 /* this task is the only thing to touch the SPI bits */
470 bitbang->busy = 0;
471 bitbang->workqueue = create_singlethread_workqueue(
472 dev_name(master->dev.parent));
473 if (bitbang->workqueue == NULL) {
474 status = -EBUSY;
475 goto err1;
476 }
477 450
478 /* driver may get busy before register() returns, especially 451 /* driver may get busy before register() returns, especially
479 * if someone registered boardinfo for devices 452 * if someone registered boardinfo for devices
480 */ 453 */
481 status = spi_register_master(master); 454 return spi_register_master(master);
482 if (status < 0)
483 goto err2;
484
485 return status;
486
487err2:
488 destroy_workqueue(bitbang->workqueue);
489err1:
490 return status;
491} 455}
492EXPORT_SYMBOL_GPL(spi_bitbang_start); 456EXPORT_SYMBOL_GPL(spi_bitbang_start);
493 457
@@ -498,10 +462,6 @@ int spi_bitbang_stop(struct spi_bitbang *bitbang)
498{ 462{
499 spi_unregister_master(bitbang->master); 463 spi_unregister_master(bitbang->master);
500 464
501 WARN_ON(!list_empty(&bitbang->queue));
502
503 destroy_workqueue(bitbang->workqueue);
504
505 return 0; 465 return 0;
506} 466}
507EXPORT_SYMBOL_GPL(spi_bitbang_stop); 467EXPORT_SYMBOL_GPL(spi_bitbang_stop);