aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/mpc52xx.h2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c35
2 files changed, 36 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h
index 1f41382eda38..0acc7c7c28d1 100644
--- a/arch/powerpc/include/asm/mpc52xx.h
+++ b/arch/powerpc/include/asm/mpc52xx.h
@@ -307,6 +307,7 @@ struct mpc52xx_lpbfifo_request {
307 size_t size; 307 size_t size;
308 size_t pos; /* current position of transfer */ 308 size_t pos; /* current position of transfer */
309 int flags; 309 int flags;
310 int defer_xfer_start;
310 311
311 /* What to do when finished */ 312 /* What to do when finished */
312 void (*callback)(struct mpc52xx_lpbfifo_request *); 313 void (*callback)(struct mpc52xx_lpbfifo_request *);
@@ -323,6 +324,7 @@ struct mpc52xx_lpbfifo_request {
323extern int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req); 324extern int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req);
324extern void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req); 325extern void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req);
325extern void mpc52xx_lpbfifo_poll(void); 326extern void mpc52xx_lpbfifo_poll(void);
327extern int mpc52xx_lpbfifo_start_xfer(struct mpc52xx_lpbfifo_request *req);
326 328
327/* mpc52xx_pic.c */ 329/* mpc52xx_pic.c */
328extern void mpc52xx_init_irq(void); 330extern void mpc52xx_init_irq(void);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index d61fb1c0c1a0..2351f9e0fb6f 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -170,7 +170,8 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
170 out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bit_fields); 170 out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bit_fields);
171 171
172 /* Kick it off */ 172 /* Kick it off */
173 out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01); 173 if (!lpbfifo.req->defer_xfer_start)
174 out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
174 if (dma) 175 if (dma)
175 bcom_enable(lpbfifo.bcom_cur_task); 176 bcom_enable(lpbfifo.bcom_cur_task);
176} 177}
@@ -421,6 +422,38 @@ int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req)
421} 422}
422EXPORT_SYMBOL(mpc52xx_lpbfifo_submit); 423EXPORT_SYMBOL(mpc52xx_lpbfifo_submit);
423 424
425int mpc52xx_lpbfifo_start_xfer(struct mpc52xx_lpbfifo_request *req)
426{
427 unsigned long flags;
428
429 if (!lpbfifo.regs)
430 return -ENODEV;
431
432 spin_lock_irqsave(&lpbfifo.lock, flags);
433
434 /*
435 * If the req pointer is already set and a transfer was
436 * started on submit, then this transfer is in progress
437 */
438 if (lpbfifo.req && !lpbfifo.req->defer_xfer_start) {
439 spin_unlock_irqrestore(&lpbfifo.lock, flags);
440 return -EBUSY;
441 }
442
443 /*
444 * If the req was previously submitted but not
445 * started, start it now
446 */
447 if (lpbfifo.req && lpbfifo.req == req &&
448 lpbfifo.req->defer_xfer_start) {
449 out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
450 }
451
452 spin_unlock_irqrestore(&lpbfifo.lock, flags);
453 return 0;
454}
455EXPORT_SYMBOL(mpc52xx_lpbfifo_start_xfer);
456
424void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req) 457void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req)
425{ 458{
426 unsigned long flags; 459 unsigned long flags;