aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-omap-100k.c103
1 files changed, 17 insertions, 86 deletions
diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
index 5999285f4cbd..d4fcca9dc8e5 100644
--- a/drivers/spi/spi-omap-100k.c
+++ b/drivers/spi/spi-omap-100k.c
@@ -83,11 +83,6 @@
83#define SPI_SHUTDOWN 1 83#define SPI_SHUTDOWN 1
84 84
85struct omap1_spi100k { 85struct omap1_spi100k {
86 struct work_struct work;
87
88 /* lock protects queue and registers */
89 spinlock_t lock;
90 struct list_head msg_queue;
91 struct spi_master *master; 86 struct spi_master *master;
92 struct clk *ick; 87 struct clk *ick;
93 struct clk *fck; 88 struct clk *fck;
@@ -104,8 +99,6 @@ struct omap1_spi100k_cs {
104 int word_len; 99 int word_len;
105}; 100};
106 101
107static struct workqueue_struct *omap1_spi100k_wq;
108
109#define MOD_REG_BIT(val, mask, set) do { \ 102#define MOD_REG_BIT(val, mask, set) do { \
110 if (set) \ 103 if (set) \
111 val |= mask; \ 104 val |= mask; \
@@ -321,6 +314,16 @@ static int omap1_spi100k_setup(struct spi_device *spi)
321 return ret; 314 return ret;
322} 315}
323 316
317static int omap1_spi100k_prepare_hardware(struct spi_master *master)
318{
319 struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
320
321 clk_enable(spi100k->ick);
322 clk_enable(spi100k->fck);
323
324 return 0;
325}
326
324static int omap1_spi100k_transfer_one_message(struct spi_master *master, 327static int omap1_spi100k_transfer_one_message(struct spi_master *master,
325 struct spi_message *m) 328 struct spi_message *m)
326{ 329{
@@ -383,64 +386,18 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master,
383 omap1_spi100k_force_cs(spi100k, 0); 386 omap1_spi100k_force_cs(spi100k, 0);
384 387
385 m->status = status; 388 m->status = status;
386 m->complete(m->context); 389
390 spi_finalize_current_message(master);
387 391
388 return status; 392 return status;
389} 393}
390 394
391static void omap1_spi100k_work(struct work_struct *work) 395static int omap1_spi100k_unprepare_hardware(struct spi_master *master)
392{ 396{
393 struct omap1_spi100k *spi100k; 397 struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
394
395 spi100k = container_of(work, struct omap1_spi100k, work);
396 spin_lock_irq(&spi100k->lock);
397
398 clk_enable(spi100k->ick);
399 clk_enable(spi100k->fck);
400
401 /* We only enable one channel at a time -- the one whose message is
402 * at the head of the queue -- although this controller would gladly
403 * arbitrate among multiple channels. This corresponds to "single
404 * channel" master mode. As a side effect, we need to manage the
405 * chipselect with the FORCE bit ... CS != channel enable.
406 */
407 while (!list_empty(&spi100k->msg_queue)) {
408 struct spi_message *m;
409
410 m = container_of(spi100k->msg_queue.next, struct spi_message,
411 queue);
412
413 list_del_init(&m->queue);
414 spin_unlock_irq(&spi100k->lock);
415
416 omap1_spi100k_transfer_one_message(m->spi->master, m);
417
418 spin_lock_irq(&spi100k->lock);
419 }
420 398
421 clk_disable(spi100k->ick); 399 clk_disable(spi100k->ick);
422 clk_disable(spi100k->fck); 400 clk_disable(spi100k->fck);
423 spin_unlock_irq(&spi100k->lock);
424}
425
426static int omap1_spi100k_transfer(struct spi_device *spi, struct spi_message *m)
427{
428 struct omap1_spi100k *spi100k;
429 unsigned long flags;
430
431 m->actual_length = 0;
432 m->status = -EINPROGRESS;
433
434 spi100k = spi_master_get_devdata(spi->master);
435
436 /* Don't accept new work if we're shutting down */
437 if (spi100k->state == SPI_SHUTDOWN)
438 return -ESHUTDOWN;
439
440 spin_lock_irqsave(&spi100k->lock, flags);
441 list_add_tail(&m->queue, &spi100k->msg_queue);
442 queue_work(omap1_spi100k_wq, &spi100k->work);
443 spin_unlock_irqrestore(&spi100k->lock, flags);
444 401
445 return 0; 402 return 0;
446} 403}
@@ -464,7 +421,9 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
464 master->bus_num = pdev->id; 421 master->bus_num = pdev->id;
465 422
466 master->setup = omap1_spi100k_setup; 423 master->setup = omap1_spi100k_setup;
467 master->transfer = omap1_spi100k_transfer; 424 master->transfer_one_message = omap1_spi100k_transfer_one_message;
425 master->prepare_transfer_hardware = omap1_spi100k_prepare_hardware;
426 master->unprepare_transfer_hardware = omap1_spi100k_unprepare_hardware;
468 master->cleanup = NULL; 427 master->cleanup = NULL;
469 master->num_chipselect = 2; 428 master->num_chipselect = 2;
470 master->mode_bits = MODEBITS; 429 master->mode_bits = MODEBITS;
@@ -484,10 +443,6 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
484 */ 443 */
485 spi100k->base = (void __iomem *) pdev->dev.platform_data; 444 spi100k->base = (void __iomem *) pdev->dev.platform_data;
486 445
487 INIT_WORK(&spi100k->work, omap1_spi100k_work);
488
489 spin_lock_init(&spi100k->lock);
490 INIT_LIST_HEAD(&spi100k->msg_queue);
491 spi100k->ick = clk_get(&pdev->dev, "ick"); 446 spi100k->ick = clk_get(&pdev->dev, "ick");
492 if (IS_ERR(spi100k->ick)) { 447 if (IS_ERR(spi100k->ick)) {
493 dev_dbg(&pdev->dev, "can't get spi100k_ick\n"); 448 dev_dbg(&pdev->dev, "can't get spi100k_ick\n");
@@ -524,27 +479,11 @@ static int omap1_spi100k_remove(struct platform_device *pdev)
524 struct spi_master *master; 479 struct spi_master *master;
525 struct omap1_spi100k *spi100k; 480 struct omap1_spi100k *spi100k;
526 struct resource *r; 481 struct resource *r;
527 unsigned limit = 500;
528 unsigned long flags;
529 int status = 0; 482 int status = 0;
530 483
531 master = platform_get_drvdata(pdev); 484 master = platform_get_drvdata(pdev);
532 spi100k = spi_master_get_devdata(master); 485 spi100k = spi_master_get_devdata(master);
533 486
534 spin_lock_irqsave(&spi100k->lock, flags);
535
536 spi100k->state = SPI_SHUTDOWN;
537 while (!list_empty(&spi100k->msg_queue) && limit--) {
538 spin_unlock_irqrestore(&spi100k->lock, flags);
539 msleep(10);
540 spin_lock_irqsave(&spi100k->lock, flags);
541 }
542
543 if (!list_empty(&spi100k->msg_queue))
544 status = -EBUSY;
545
546 spin_unlock_irqrestore(&spi100k->lock, flags);
547
548 if (status != 0) 487 if (status != 0)
549 return status; 488 return status;
550 489
@@ -569,20 +508,12 @@ static struct platform_driver omap1_spi100k_driver = {
569 508
570static int __init omap1_spi100k_init(void) 509static int __init omap1_spi100k_init(void)
571{ 510{
572 omap1_spi100k_wq = create_singlethread_workqueue(
573 omap1_spi100k_driver.driver.name);
574
575 if (omap1_spi100k_wq == NULL)
576 return -1;
577
578 return platform_driver_probe(&omap1_spi100k_driver, omap1_spi100k_probe); 511 return platform_driver_probe(&omap1_spi100k_driver, omap1_spi100k_probe);
579} 512}
580 513
581static void __exit omap1_spi100k_exit(void) 514static void __exit omap1_spi100k_exit(void)
582{ 515{
583 platform_driver_unregister(&omap1_spi100k_driver); 516 platform_driver_unregister(&omap1_spi100k_driver);
584
585 destroy_workqueue(omap1_spi100k_wq);
586} 517}
587 518
588module_init(omap1_spi100k_init); 519module_init(omap1_spi100k_init);