diff options
author | Alex Dubov <oakad@yahoo.com> | 2006-12-08 00:50:49 -0500 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-02-04 14:54:07 -0500 |
commit | 0803dd0c2594c7dc70c14ab00ea21e68605f5ba1 (patch) | |
tree | 6eb2ddd6a23d7456b00f68bc212fe7b7f37ed4c1 | |
parent | 255ef22e89ecedcc594428444a72a29cb66153f5 (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.c | 34 |
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 | ||
676 | static void tifm_sd_abort(struct work_struct *work) | 670 | static 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 | ||
686 | static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 677 | static 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) |