aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-bitbang.c100
-rw-r--r--include/linux/spi/spi_bitbang.h4
2 files changed, 30 insertions, 74 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);
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h
index b5aa215493f6..daebaba886aa 100644
--- a/include/linux/spi/spi_bitbang.h
+++ b/include/linux/spi/spi_bitbang.h
@@ -4,11 +4,7 @@
4#include <linux/workqueue.h> 4#include <linux/workqueue.h>
5 5
6struct spi_bitbang { 6struct spi_bitbang {
7 struct workqueue_struct *workqueue;
8 struct work_struct work;
9
10 spinlock_t lock; 7 spinlock_t lock;
11 struct list_head queue;
12 u8 busy; 8 u8 busy;
13 u8 use_dma; 9 u8 use_dma;
14 u8 flags; /* extra spi->mode support */ 10 u8 flags; /* extra spi->mode support */