aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2006-12-08 00:50:49 -0500
committerPierre Ossman <drzeus@drzeus.cx>2007-02-04 14:54:07 -0500
commit0803dd0c2594c7dc70c14ab00ea21e68605f5ba1 (patch)
tree6eb2ddd6a23d7456b00f68bc212fe7b7f37ed4c1
parent255ef22e89ecedcc594428444a72a29cb66153f5 (diff)
tifm_sd: Switch software timeout handler from work_struct to timer
Two changes are introduced to software timeout handler in order to simplify its management: 1. The implementation is switched from work_struct to timer 2. Previously, software timeout was rearmed with each interrupt. Now, current request must complete entirely within timeout interval. Signed-off-by: Alex Dubov <oakad@yahoo.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/tifm_sd.c34
1 files changed, 13 insertions, 21 deletions
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index 3e762770afcb..69b78eb16eff 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -95,11 +95,11 @@ struct tifm_sd {
95 card_state_t state; 95 card_state_t state;
96 unsigned int clk_freq; 96 unsigned int clk_freq;
97 unsigned int clk_div; 97 unsigned int clk_div;
98 unsigned long timeout_jiffies; // software timeout - 2 sec 98 unsigned long timeout_jiffies;
99 99
100 struct timer_list timer;
100 struct mmc_request *req; 101 struct mmc_request *req;
101 struct work_struct cmd_handler; 102 struct work_struct cmd_handler;
102 struct delayed_work abort_handler;
103 wait_queue_head_t can_eject; 103 wait_queue_head_t can_eject;
104 104
105 size_t written_blocks; 105 size_t written_blocks;
@@ -321,8 +321,6 @@ change_state:
321 return; 321 return;
322 } 322 }
323 323
324 queue_delayed_work(sock->wq, &host->abort_handler,
325 host->timeout_jiffies);
326} 324}
327 325
328/* Called from interrupt handler */ 326/* Called from interrupt handler */
@@ -335,7 +333,6 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
335 333
336 spin_lock(&sock->lock); 334 spin_lock(&sock->lock);
337 host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); 335 host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock));
338 cancel_delayed_work(&host->abort_handler);
339 336
340 if (sock_irq_status & FIFO_EVENT) { 337 if (sock_irq_status & FIFO_EVENT) {
341 fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); 338 fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
@@ -375,9 +372,6 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
375 || host->state == FIFO) { 372 || host->state == FIFO) {
376 host->req->cmd->error = error_code; 373 host->req->cmd->error = error_code;
377 tifm_sd_exec(host, host->req->stop); 374 tifm_sd_exec(host, host->req->stop);
378 queue_delayed_work(sock->wq,
379 &host->abort_handler,
380 host->timeout_jiffies);
381 host->state = SCMD; 375 host->state = SCMD;
382 goto done; 376 goto done;
383 } else { 377 } else {
@@ -506,9 +500,8 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
506 } 500 }
507 501
508 host->req = mrq; 502 host->req = mrq;
503 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
509 host->state = CMD; 504 host->state = CMD;
510 queue_delayed_work(sock->wq, &host->abort_handler,
511 host->timeout_jiffies);
512 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), 505 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
513 sock->addr + SOCK_CONTROL); 506 sock->addr + SOCK_CONTROL);
514 tifm_sd_exec(host, mrq->cmd); 507 tifm_sd_exec(host, mrq->cmd);
@@ -536,6 +529,7 @@ static void tifm_sd_end_cmd(struct work_struct *work)
536 529
537 spin_lock_irqsave(&sock->lock, flags); 530 spin_lock_irqsave(&sock->lock, flags);
538 531
532 del_timer(&host->timer);
539 mrq = host->req; 533 mrq = host->req;
540 host->req = NULL; 534 host->req = NULL;
541 host->state = IDLE; 535 host->state = IDLE;
@@ -610,9 +604,8 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
610 } 604 }
611 605
612 host->req = mrq; 606 host->req = mrq;
607 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
613 host->state = CMD; 608 host->state = CMD;
614 queue_delayed_work(sock->wq, &host->abort_handler,
615 host->timeout_jiffies);
616 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), 609 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
617 sock->addr + SOCK_CONTROL); 610 sock->addr + SOCK_CONTROL);
618 tifm_sd_exec(host, mrq->cmd); 611 tifm_sd_exec(host, mrq->cmd);
@@ -635,6 +628,7 @@ static void tifm_sd_end_cmd_nodma(struct work_struct *work)
635 628
636 spin_lock_irqsave(&sock->lock, flags); 629 spin_lock_irqsave(&sock->lock, flags);
637 630
631 del_timer(&host->timer);
638 mrq = host->req; 632 mrq = host->req;
639 host->req = NULL; 633 host->req = NULL;
640 host->state = IDLE; 634 host->state = IDLE;
@@ -673,14 +667,11 @@ static void tifm_sd_end_cmd_nodma(struct work_struct *work)
673 mmc_request_done(mmc, mrq); 667 mmc_request_done(mmc, mrq);
674} 668}
675 669
676static void tifm_sd_abort(struct work_struct *work) 670static void tifm_sd_abort(unsigned long data)
677{ 671{
678 struct tifm_sd *host =
679 container_of(work, struct tifm_sd, abort_handler.work);
680
681 printk(KERN_ERR DRIVER_NAME 672 printk(KERN_ERR DRIVER_NAME
682 ": card failed to respond for a long period of time"); 673 ": card failed to respond for a long period of time");
683 tifm_eject(host->dev); 674 tifm_eject(((struct tifm_sd*)data)->dev);
684} 675}
685 676
686static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) 677static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
@@ -785,6 +776,7 @@ static void tifm_sd_register_host(struct work_struct *work)
785 unsigned long flags; 776 unsigned long flags;
786 777
787 spin_lock_irqsave(&sock->lock, flags); 778 spin_lock_irqsave(&sock->lock, flags);
779 del_timer(&host->timer);
788 host->flags |= HOST_REG; 780 host->flags |= HOST_REG;
789 PREPARE_WORK(&host->cmd_handler, 781 PREPARE_WORK(&host->cmd_handler,
790 no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd); 782 no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd);
@@ -814,7 +806,7 @@ static int tifm_sd_probe(struct tifm_dev *sock)
814 host->clk_div = 61; 806 host->clk_div = 61;
815 init_waitqueue_head(&host->can_eject); 807 init_waitqueue_head(&host->can_eject);
816 INIT_WORK(&host->cmd_handler, tifm_sd_register_host); 808 INIT_WORK(&host->cmd_handler, tifm_sd_register_host);
817 INIT_DELAYED_WORK(&host->abort_handler, tifm_sd_abort); 809 setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host);
818 810
819 tifm_set_drvdata(sock, mmc); 811 tifm_set_drvdata(sock, mmc);
820 sock->signal_irq = tifm_sd_signal_irq; 812 sock->signal_irq = tifm_sd_signal_irq;
@@ -866,8 +858,7 @@ static int tifm_sd_probe(struct tifm_dev *sock)
866 writel(host->clk_div | TIFM_MMCSD_POWER, 858 writel(host->clk_div | TIFM_MMCSD_POWER,
867 sock->addr + SOCK_MMCSD_CONFIG); 859 sock->addr + SOCK_MMCSD_CONFIG);
868 860
869 queue_delayed_work(sock->wq, &host->abort_handler, 861 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
870 host->timeout_jiffies);
871 862
872 return 0; 863 return 0;
873} 864}
@@ -891,6 +882,7 @@ static void tifm_sd_remove(struct tifm_dev *sock)
891 struct tifm_sd *host = mmc_priv(mmc); 882 struct tifm_sd *host = mmc_priv(mmc);
892 unsigned long flags; 883 unsigned long flags;
893 884
885 del_timer_sync(&host->timer);
894 spin_lock_irqsave(&sock->lock, flags); 886 spin_lock_irqsave(&sock->lock, flags);
895 host->flags |= EJECT; 887 host->flags |= EJECT;
896 if (host->req) 888 if (host->req)