From: "ext C.A, Subramaniam" <subramaniam.ca@xxxxxx> Subject: [PATCH 10/10] omap mailbox: OMAP4 Mailbox-driver Patch to support tasklet implementation Date: Fri, 4 Sep 2009 13:48:45 +0200 > From e759173e77f73fabce5177b4f685df20b16c6922 Mon Sep 17 00:00:00 2001 > From: C A Subramaniam <subramaniam.ca@xxxxxx> > Date: Thu, 3 Sep 2009 17:42:35 +0530 > Subject: [PATCH 10/10] omap mailbox: OMAP4 Mailbox-driver Patch to support tasklet > implementation > > This patch uses a tasklet implementation for > sending mailbox messages. > > Signed-off-by: C A Subramaniam <subramaniam.ca@xxxxxx> > Signed-off-by: Ramesh Gupta G <grgupta@xxxxxx> > --- > arch/arm/mach-omap2/mailbox.c | 43 ++++++++++----- > arch/arm/plat-omap/include/mach/mailbox.h | 16 +++++- > arch/arm/plat-omap/mailbox.c | 80 ++++++++++++++--------------- > 3 files changed, 81 insertions(+), 58 deletions(-) > > diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c > index 52a1670..45aea98 100644 > --- a/arch/arm/mach-omap2/mailbox.c > +++ b/arch/arm/mach-omap2/mailbox.c > @@ -236,6 +237,17 @@ static struct omap_mbox_ops omap2_mbox_ops = { > .restore_ctx = omap2_mbox_restore_ctx, > }; > > + > +static struct omap_mbox_task omap_mbox_1_tasklet = { > + .arg = NULL, > +}; > + > +static struct omap_mbox_task omap_mbox_2_tasklet = { > + .arg = NULL, > +}; As I described in the comment on [PATCH 8/10], I think that it would be better to keep "mach-omap2/mailbox.c" simple and to add some additional logic on "plat-omap/mailbox.c". Would it be possbile to move this tasklet implementation to "plat-omap/mailbox.c"? > + > + > + > /* > * MAILBOX 0: ARM -> DSP, > * MAILBOX 1: ARM <- DSP. > @@ -272,6 +284,7 @@ struct omap_mbox mbox_1_info = { > .name = "mailbox-1", > .ops = &omap2_mbox_ops, > .priv = &omap2_mbox_1_priv, > + .tx_tasklet = &omap_mbox_1_tasklet, > }; > EXPORT_SYMBOL(mbox_1_info); > #else > @@ -305,8 +318,10 @@ struct omap_mbox mbox_2_info = { > .name = "mailbox-2", > .ops = &omap2_mbox_ops, > .priv = &omap2_mbox_2_priv, > + .tx_tasklet = &omap_mbox_2_tasklet, > }; > EXPORT_SYMBOL(mbox_2_info); > + > #endif > > > diff --git a/arch/arm/plat-omap/include/mach/mailbox.h b/arch/arm/plat-omap/include/mach/mailbox.h > index bf06953..5271345 100644 > --- a/arch/arm/plat-omap/include/mach/mailbox.h > +++ b/arch/arm/plat-omap/include/mach/mailbox.h > @@ -28,8 +28,10 @@ struct omap_mbox_ops { > int (*fifo_empty)(struct omap_mbox *mbox); > int (*fifo_full)(struct omap_mbox *mbox); > /* irq */ > - void (*enable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq); > - void (*disable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq); > + void (*enable_irq)(struct omap_mbox *mbox, > + omap_mbox_irq_t irq); > + void (*disable_irq)(struct omap_mbox *mbox, > + omap_mbox_irq_t irq); > void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq); > int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq); > /* ctx */ > @@ -45,12 +47,22 @@ struct omap_mbox_queue { > struct omap_mbox *mbox; > }; > > +struct omap_mbox_task{ > + spinlock_t lock; > + struct tasklet_struct *t; > + mbox_msg_t msg; > + void *arg; > +}; > + > + > struct omap_mbox { > char *name; > unsigned int irq; > > struct omap_mbox_queue *txq, *rxq; > > + struct omap_mbox_task *tx_tasklet; > + > struct omap_mbox_ops *ops; > > mbox_msg_t seq_snd, seq_rcv; > diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c > index 84cf6af..b5e53d4 100644 > --- a/arch/arm/plat-omap/mailbox.c > +++ b/arch/arm/plat-omap/mailbox.c > @@ -63,60 +63,49 @@ static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) > /* > * message sender > */ > -static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) > +static void __mbox_msg_send(unsigned long tx) > { > + struct omap_mbox_task *tx_data = (struct omap_mbox_task *)tx; > + struct omap_mbox *mbox = (struct omap_mbox *)tx_data->arg; > + mbox_msg_t msg = tx_data->msg; > int ret = 0, i = 1000; > > while (mbox_fifo_full(mbox)) { > - if (mbox->ops->type == OMAP_MBOX_TYPE2) > - return -1; > - if (--i == 0) > - return -1; > + if (mbox->ops->type == OMAP_MBOX_TYPE2) { > + printk(KERN_ERR "Invalid mailbox type\n"); > + return ; > + } > + if (--i == 0) { > + printk(KERN_ERR "Time out writing to mailbox\n"); > + return ; > + } > udelay(1); > } > mbox_fifo_write(mbox, msg); > - return ret; > -} > - > -struct omap_msg_tx_data { > - mbox_msg_t msg; > - void *arg; > -}; > + tx_data->arg = NULL; > + spin_unlock(&(mbox->tx_tasklet->lock)); > > -static void omap_msg_tx_end_io(struct request *rq, int error) > -{ > - kfree(rq->special); > - __blk_put_request(rq->q, rq); > + return; > } > > + > int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) > { > - struct omap_msg_tx_data *tx_data; > - struct request *rq; > - struct request_queue *q = mbox->txq->queue; > + struct omap_mbox_task *tx_task = mbox->tx_tasklet; > > - tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC); > - if (unlikely(!tx_data)) > - return -ENOMEM; > - > - rq = blk_get_request(q, WRITE, GFP_ATOMIC); > - if (unlikely(!rq)) { > - kfree(tx_data); > - return -ENOMEM; > - } > + spin_lock(&(mbox->tx_tasklet->lock)); > + tx_task->arg = (void *)mbox; > + tx_task->msg = msg; > > - tx_data->msg = msg; > - rq->end_io = omap_msg_tx_end_io; > - blk_insert_request(q, rq, 0, tx_data); > + tasklet_schedule(tx_task->t); > > - schedule_work(&mbox->txq->work); > return 0; > } > EXPORT_SYMBOL(omap_mbox_msg_send); > > static void mbox_tx_work(struct work_struct *work) > { > - int ret; > + int ret = 0; > struct request *rq; > struct omap_mbox_queue *mq = container_of(work, > struct omap_mbox_queue, work); > @@ -124,8 +113,6 @@ static void mbox_tx_work(struct work_struct *work) > struct request_queue *q = mbox->txq->queue; > > while (1) { > - struct omap_msg_tx_data *tx_data; > - > spin_lock(q->queue_lock); > rq = blk_fetch_request(q); > spin_unlock(q->queue_lock); > @@ -133,9 +120,6 @@ static void mbox_tx_work(struct work_struct *work) > if (!rq) > break; > > - tx_data = rq->special; > - > - ret = __mbox_msg_send(mbox, tx_data->msg); > if (ret) { > omap_mbox_enable_irq(mbox, IRQ_TX); > spin_lock(q->queue_lock); > @@ -206,7 +190,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) > goto nomem; > > msg = mbox_fifo_read(mbox); > - > + rq->special = (void *)msg; > > blk_insert_request(q, rq, 0, (void *)msg); > if (mbox->ops->type == OMAP_MBOX_TYPE1) > @@ -298,13 +282,25 @@ static int omap_mbox_startup(struct omap_mbox *mbox) > } > mbox->rxq = mq; > > + mbox->tx_tasklet->t = kzalloc(sizeof(struct tasklet_struct), > + GFP_KERNEL); > + if (!mbox->tx_tasklet->t) { > + ret = -ENOMEM; > + goto fail_alloc_tasklet; > + } > + spin_lock_init(&mbox->tx_tasklet->lock); > + tasklet_init(mbox->tx_tasklet->t, __mbox_msg_send, > + (unsigned long)mbox->tx_tasklet); > + > return 0; > > - fail_alloc_rxq: > +fail_alloc_tasklet: > + mbox_queue_free(mbox->rxq); > +fail_alloc_rxq: > mbox_queue_free(mbox->txq); > - fail_alloc_txq: > +fail_alloc_txq: > free_irq(mbox->irq, mbox); > - fail_request_irq: > +fail_request_irq: > if (unlikely(mbox->ops->shutdown)) > mbox->ops->shutdown(mbox); > > -- > 1.5.3.2 > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html