aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/tifm_sd.c
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2007-04-12 02:59:22 -0400
committerPierre Ossman <drzeus@drzeus.cx>2007-05-01 07:04:14 -0400
commit592d372ae89dd5b43117cf5113a910f67f6e6a7e (patch)
tree08026df22b405decd2976e5245a42628eaca2a65 /drivers/mmc/tifm_sd.c
parentb039d4a187a4064c926159db063004377281b041 (diff)
tifm_sd: remove wait for power off on remove
This wait was needed because of the mmc layer failure to wait for completion of all outstanding commands before host removal. It should be fixed now in the mmc layer. Signed-off-by: Alex Dubov <oakad@yahoo.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/tifm_sd.c')
-rw-r--r--drivers/mmc/tifm_sd.c25
1 files changed, 10 insertions, 15 deletions
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index fe236cb95e5c..bf00e8cf670c 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -80,7 +80,6 @@ typedef enum {
80enum { 80enum {
81 FIFO_RDY = 0x0001, /* hardware dependent value */ 81 FIFO_RDY = 0x0001, /* hardware dependent value */
82 EJECT = 0x0004, 82 EJECT = 0x0004,
83 EJECT_DONE = 0x0008,
84 CARD_BUSY = 0x0010, 83 CARD_BUSY = 0x0010,
85 OPENDRAIN = 0x0040, /* hardware dependent value */ 84 OPENDRAIN = 0x0040, /* hardware dependent value */
86 CARD_EVENT = 0x0100, /* hardware dependent value */ 85 CARD_EVENT = 0x0100, /* hardware dependent value */
@@ -99,7 +98,6 @@ struct tifm_sd {
99 struct tasklet_struct finish_tasklet; 98 struct tasklet_struct finish_tasklet;
100 struct timer_list timer; 99 struct timer_list timer;
101 struct mmc_request *req; 100 struct mmc_request *req;
102 wait_queue_head_t notify;
103 101
104 size_t written_blocks; 102 size_t written_blocks;
105 size_t buffer_size; 103 size_t buffer_size;
@@ -738,12 +736,6 @@ static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
738 /* chip_select : maybe later */ 736 /* chip_select : maybe later */
739 //vdd 737 //vdd
740 //power is set before probe / after remove 738 //power is set before probe / after remove
741 //I believe, power_off when already marked for eject is sufficient to
742 // allow removal.
743 if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) {
744 host->flags |= EJECT_DONE;
745 wake_up_all(&host->notify);
746 }
747 739
748 spin_unlock_irqrestore(&sock->lock, flags); 740 spin_unlock_irqrestore(&sock->lock, flags);
749} 741}
@@ -854,7 +846,6 @@ static int tifm_sd_probe(struct tifm_dev *sock)
854 host->dev = sock; 846 host->dev = sock;
855 host->timeout_jiffies = msecs_to_jiffies(1000); 847 host->timeout_jiffies = msecs_to_jiffies(1000);
856 848
857 init_waitqueue_head(&host->notify);
858 tasklet_init(&host->finish_tasklet, 849 tasklet_init(&host->finish_tasklet,
859 no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd, 850 no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd,
860 (unsigned long)host); 851 (unsigned long)host);
@@ -896,28 +887,32 @@ static void tifm_sd_remove(struct tifm_dev *sock)
896 struct tifm_sd *host = mmc_priv(mmc); 887 struct tifm_sd *host = mmc_priv(mmc);
897 unsigned long flags; 888 unsigned long flags;
898 889
899 del_timer_sync(&host->timer); 890 spin_lock_irqsave(&sock->lock, flags);
891 host->flags |= EJECT;
900 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); 892 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
901 mmiowb(); 893 mmiowb();
894 spin_unlock_irqrestore(&sock->lock, flags);
895
896 tasklet_kill(&host->finish_tasklet);
897
902 spin_lock_irqsave(&sock->lock, flags); 898 spin_lock_irqsave(&sock->lock, flags);
903 host->flags |= EJECT;
904 if (host->req) { 899 if (host->req) {
905 writel(TIFM_FIFO_INT_SETALL, 900 writel(TIFM_FIFO_INT_SETALL,
906 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); 901 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
907 writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); 902 writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
903 host->req->cmd->error = MMC_ERR_TIMEOUT;
904 if (host->req->stop)
905 host->req->stop->error = MMC_ERR_TIMEOUT;
908 tasklet_schedule(&host->finish_tasklet); 906 tasklet_schedule(&host->finish_tasklet);
909 } 907 }
910 spin_unlock_irqrestore(&sock->lock, flags); 908 spin_unlock_irqrestore(&sock->lock, flags);
911 wait_event_timeout(host->notify, host->flags & EJECT_DONE,
912 host->timeout_jiffies);
913 tasklet_kill(&host->finish_tasklet);
914 mmc_remove_host(mmc); 909 mmc_remove_host(mmc);
910 dev_dbg(&sock->dev, "after remove\n");
915 911
916 /* The meaning of the bit majority in this constant is unknown. */ 912 /* The meaning of the bit majority in this constant is unknown. */
917 writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), 913 writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
918 sock->addr + SOCK_CONTROL); 914 sock->addr + SOCK_CONTROL);
919 915
920 tifm_set_drvdata(sock, NULL);
921 mmc_free_host(mmc); 916 mmc_free_host(mmc);
922} 917}
923 918