aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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