diff options
Diffstat (limited to 'drivers/mmc/mmc_queue.c')
-rw-r--r-- | drivers/mmc/mmc_queue.c | 41 |
1 files changed, 14 insertions, 27 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 | } |
178 | EXPORT_SYMBOL(mmc_init_queue); | 167 | EXPORT_SYMBOL(mmc_init_queue); |
179 | 168 | ||
180 | void mmc_cleanup_queue(struct mmc_queue *mq) | 169 | void 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; |