diff options
-rw-r--r-- | drivers/mmc/tifm_sd.c | 25 |
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 { | |||
80 | enum { | 80 | enum { |
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 | ||