aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/mmc_queue.c41
-rw-r--r--drivers/mmc/mmc_queue.h3
2 files changed, 15 insertions, 29 deletions
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c
index 4ccdd82b680f..4e6a534e91d0 100644
--- a/drivers/mmc/mmc_queue.c
+++ b/drivers/mmc/mmc_queue.c
@@ -10,13 +10,13 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/blkdev.h> 12#include <linux/blkdev.h>
13#include <linux/kthread.h>
13 14
14#include <linux/mmc/card.h> 15#include <linux/mmc/card.h>
15#include <linux/mmc/host.h> 16#include <linux/mmc/host.h>
16#include "mmc_queue.h" 17#include "mmc_queue.h"
17 18
18#define MMC_QUEUE_EXIT (1 << 0) 19#define MMC_QUEUE_SUSPENDED (1 << 0)
19#define MMC_QUEUE_SUSPENDED (1 << 1)
20 20
21/* 21/*
22 * Prepare a MMC request. Essentially, this means passing the 22 * Prepare a MMC request. Essentially, this means passing the
@@ -59,7 +59,6 @@ static int mmc_queue_thread(void *d)
59{ 59{
60 struct mmc_queue *mq = d; 60 struct mmc_queue *mq = d;
61 struct request_queue *q = mq->queue; 61 struct request_queue *q = mq->queue;
62 DECLARE_WAITQUEUE(wait, current);
63 62
64 /* 63 /*
65 * Set iothread to ensure that we aren't put to sleep by 64 * Set iothread to ensure that we aren't put to sleep by
@@ -67,12 +66,7 @@ static int mmc_queue_thread(void *d)
67 */ 66 */
68 current->flags |= PF_MEMALLOC|PF_NOFREEZE; 67 current->flags |= PF_MEMALLOC|PF_NOFREEZE;
69 68
70 daemonize("mmcqd");
71
72 complete(&mq->thread_complete);
73
74 down(&mq->thread_sem); 69 down(&mq->thread_sem);
75 add_wait_queue(&mq->thread_wq, &wait);
76 do { 70 do {
77 struct request *req = NULL; 71 struct request *req = NULL;
78 72
@@ -84,7 +78,7 @@ static int mmc_queue_thread(void *d)
84 spin_unlock_irq(q->queue_lock); 78 spin_unlock_irq(q->queue_lock);
85 79
86 if (!req) { 80 if (!req) {
87 if (mq->flags & MMC_QUEUE_EXIT) 81 if (kthread_should_stop())
88 break; 82 break;
89 up(&mq->thread_sem); 83 up(&mq->thread_sem);
90 schedule(); 84 schedule();
@@ -95,10 +89,8 @@ static int mmc_queue_thread(void *d)
95 89
96 mq->issue_fn(mq, req); 90 mq->issue_fn(mq, req);
97 } while (1); 91 } while (1);
98 remove_wait_queue(&mq->thread_wq, &wait);
99 up(&mq->thread_sem); 92 up(&mq->thread_sem);
100 93
101 complete_and_exit(&mq->thread_complete, 0);
102 return 0; 94 return 0;
103} 95}
104 96
@@ -113,7 +105,7 @@ static void mmc_request(request_queue_t *q)
113 struct mmc_queue *mq = q->queuedata; 105 struct mmc_queue *mq = q->queuedata;
114 106
115 if (!mq->req) 107 if (!mq->req)
116 wake_up(&mq->thread_wq); 108 wake_up_process(mq->thread);
117} 109}
118 110
119/** 111/**
@@ -152,36 +144,31 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
152 GFP_KERNEL); 144 GFP_KERNEL);
153 if (!mq->sg) { 145 if (!mq->sg) {
154 ret = -ENOMEM; 146 ret = -ENOMEM;
155 goto cleanup; 147 goto cleanup_queue;
156 } 148 }
157 149
158 init_completion(&mq->thread_complete);
159 init_waitqueue_head(&mq->thread_wq);
160 init_MUTEX(&mq->thread_sem); 150 init_MUTEX(&mq->thread_sem);
161 151
162 ret = kernel_thread(mmc_queue_thread, mq, CLONE_KERNEL); 152 mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd");
163 if (ret >= 0) { 153 if (IS_ERR(mq->thread)) {
164 wait_for_completion(&mq->thread_complete); 154 ret = PTR_ERR(mq->thread);
165 init_completion(&mq->thread_complete); 155 goto free_sg;
166 ret = 0;
167 goto out;
168 } 156 }
169 157
170 cleanup: 158 return 0;
159
160 free_sg:
171 kfree(mq->sg); 161 kfree(mq->sg);
172 mq->sg = NULL; 162 mq->sg = NULL;
173 163 cleanup_queue:
174 blk_cleanup_queue(mq->queue); 164 blk_cleanup_queue(mq->queue);
175 out:
176 return ret; 165 return ret;
177} 166}
178EXPORT_SYMBOL(mmc_init_queue); 167EXPORT_SYMBOL(mmc_init_queue);
179 168
180void mmc_cleanup_queue(struct mmc_queue *mq) 169void mmc_cleanup_queue(struct mmc_queue *mq)
181{ 170{
182 mq->flags |= MMC_QUEUE_EXIT; 171 kthread_stop(mq->thread);
183 wake_up(&mq->thread_wq);
184 wait_for_completion(&mq->thread_complete);
185 172
186 kfree(mq->sg); 173 kfree(mq->sg);
187 mq->sg = NULL; 174 mq->sg = NULL;
diff --git a/drivers/mmc/mmc_queue.h b/drivers/mmc/mmc_queue.h
index 7182d2f69b4e..c9f139e764f6 100644
--- a/drivers/mmc/mmc_queue.h
+++ b/drivers/mmc/mmc_queue.h
@@ -6,8 +6,7 @@ struct task_struct;
6 6
7struct mmc_queue { 7struct mmc_queue {
8 struct mmc_card *card; 8 struct mmc_card *card;
9 struct completion thread_complete; 9 struct task_struct *thread;
10 wait_queue_head_t thread_wq;
11 struct semaphore thread_sem; 10 struct semaphore thread_sem;
12 unsigned int flags; 11 unsigned int flags;
13 struct request *req; 12 struct request *req;