aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/mailbox.c63
1 files changed, 40 insertions, 23 deletions
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 0abfbaa59871..40424edae939 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -147,24 +147,40 @@ static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void *arg)
147 return ret; 147 return ret;
148} 148}
149 149
150struct omap_msg_tx_data {
151 mbox_msg_t msg;
152 void *arg;
153};
154
155static void omap_msg_tx_end_io(struct request *rq, int error)
156{
157 kfree(rq->special);
158 __blk_put_request(rq->q, rq);
159}
160
150int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg) 161int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg)
151{ 162{
163 struct omap_msg_tx_data *tx_data;
152 struct request *rq; 164 struct request *rq;
153 struct request_queue *q = mbox->txq->queue; 165 struct request_queue *q = mbox->txq->queue;
154 int ret = 0; 166
167 tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
168 if (unlikely(!tx_data))
169 return -ENOMEM;
155 170
156 rq = blk_get_request(q, WRITE, GFP_ATOMIC); 171 rq = blk_get_request(q, WRITE, GFP_ATOMIC);
157 if (unlikely(!rq)) { 172 if (unlikely(!rq)) {
158 ret = -ENOMEM; 173 kfree(tx_data);
159 goto fail; 174 return -ENOMEM;
160 } 175 }
161 176
162 rq->data = (void *)msg; 177 tx_data->msg = msg;
163 blk_insert_request(q, rq, 0, arg); 178 tx_data->arg = arg;
179 rq->end_io = omap_msg_tx_end_io;
180 blk_insert_request(q, rq, 0, tx_data);
164 181
165 schedule_work(&mbox->txq->work); 182 schedule_work(&mbox->txq->work);
166 fail: 183 return 0;
167 return ret;
168} 184}
169EXPORT_SYMBOL(omap_mbox_msg_send); 185EXPORT_SYMBOL(omap_mbox_msg_send);
170 186
@@ -178,22 +194,28 @@ static void mbox_tx_work(struct work_struct *work)
178 struct request_queue *q = mbox->txq->queue; 194 struct request_queue *q = mbox->txq->queue;
179 195
180 while (1) { 196 while (1) {
197 struct omap_msg_tx_data *tx_data;
198
181 spin_lock(q->queue_lock); 199 spin_lock(q->queue_lock);
182 rq = elv_next_request(q); 200 rq = blk_fetch_request(q);
183 spin_unlock(q->queue_lock); 201 spin_unlock(q->queue_lock);
184 202
185 if (!rq) 203 if (!rq)
186 break; 204 break;
187 205
188 ret = __mbox_msg_send(mbox, (mbox_msg_t) rq->data, rq->special); 206 tx_data = rq->special;
207
208 ret = __mbox_msg_send(mbox, tx_data->msg, tx_data->arg);
189 if (ret) { 209 if (ret) {
190 enable_mbox_irq(mbox, IRQ_TX); 210 enable_mbox_irq(mbox, IRQ_TX);
211 spin_lock(q->queue_lock);
212 blk_requeue_request(q, rq);
213 spin_unlock(q->queue_lock);
191 return; 214 return;
192 } 215 }
193 216
194 spin_lock(q->queue_lock); 217 spin_lock(q->queue_lock);
195 if (__blk_end_request(rq, 0, 0)) 218 __blk_end_request_all(rq, 0);
196 BUG();
197 spin_unlock(q->queue_lock); 219 spin_unlock(q->queue_lock);
198 } 220 }
199} 221}
@@ -218,16 +240,13 @@ static void mbox_rx_work(struct work_struct *work)
218 240
219 while (1) { 241 while (1) {
220 spin_lock_irqsave(q->queue_lock, flags); 242 spin_lock_irqsave(q->queue_lock, flags);
221 rq = elv_next_request(q); 243 rq = blk_fetch_request(q);
222 spin_unlock_irqrestore(q->queue_lock, flags); 244 spin_unlock_irqrestore(q->queue_lock, flags);
223 if (!rq) 245 if (!rq)
224 break; 246 break;
225 247
226 msg = (mbox_msg_t) rq->data; 248 msg = (mbox_msg_t)rq->special;
227 249 blk_end_request_all(rq, 0);
228 if (blk_end_request(rq, 0, 0))
229 BUG();
230
231 mbox->rxq->callback((void *)msg); 250 mbox->rxq->callback((void *)msg);
232 } 251 }
233} 252}
@@ -264,7 +283,6 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
264 goto nomem; 283 goto nomem;
265 284
266 msg = mbox_fifo_read(mbox); 285 msg = mbox_fifo_read(mbox);
267 rq->data = (void *)msg;
268 286
269 if (unlikely(mbox_seq_test(mbox, msg))) { 287 if (unlikely(mbox_seq_test(mbox, msg))) {
270 pr_info("mbox: Illegal seq bit!(%08x)\n", msg); 288 pr_info("mbox: Illegal seq bit!(%08x)\n", msg);
@@ -272,7 +290,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
272 mbox->err_notify(); 290 mbox->err_notify();
273 } 291 }
274 292
275 blk_insert_request(q, rq, 0, NULL); 293 blk_insert_request(q, rq, 0, (void *)msg);
276 if (mbox->ops->type == OMAP_MBOX_TYPE1) 294 if (mbox->ops->type == OMAP_MBOX_TYPE1)
277 break; 295 break;
278 } 296 }
@@ -329,16 +347,15 @@ omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf)
329 347
330 while (1) { 348 while (1) {
331 spin_lock_irqsave(q->queue_lock, flags); 349 spin_lock_irqsave(q->queue_lock, flags);
332 rq = elv_next_request(q); 350 rq = blk_fetch_request(q);
333 spin_unlock_irqrestore(q->queue_lock, flags); 351 spin_unlock_irqrestore(q->queue_lock, flags);
334 352
335 if (!rq) 353 if (!rq)
336 break; 354 break;
337 355
338 *p = (mbox_msg_t) rq->data; 356 *p = (mbox_msg_t)rq->special;
339 357
340 if (blk_end_request(rq, 0, 0)) 358 blk_end_request_all(rq, 0);
341 BUG();
342 359
343 if (unlikely(mbox_seq_test(mbox, *p))) { 360 if (unlikely(mbox_seq_test(mbox, *p))) {
344 pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p); 361 pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);