All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] ARM: OMAP: Restructuring mailbox blk queues
@ 2007-03-17  9:19 Trilok Soni
  2007-03-19  6:52 ` Hiroshi DOYU
  0 siblings, 1 reply; 2+ messages in thread
From: Trilok Soni @ 2007-03-17  9:19 UTC (permalink / raw)
  To: linux-omap-open-source; +Cc: Hiroshi DOYU

[-- Attachment #1: Type: text/plain, Size: 104 bytes --]

Attached patch on mailbox fwk restructuring are confirmed to be
working by Doyu-San.

-- 
--Trilok Soni

[-- Attachment #2: 0002-ARM-OMAP-Restructuring-mailbox-blk-queues.txt --]
[-- Type: text/plain, Size: 12443 bytes --]

From nobody Mon Sep 17 00:00:00 2001
From: Trilok Soni <soni.trilok@gmail.com>
Date: Sat, 17 Mar 2007 20:17:57 +0530
Subject: [PATCH 2/2] ARM: OMAP: Restructuring mailbox blk queues

From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>

Signed-off-by: Trilok Soni <soni.trilok@gmail.com>

---

 arch/arm/plat-omap/dsp/dsp_common.h |    1 
 arch/arm/plat-omap/dsp/dsp_core.c   |   17 +--
 arch/arm/plat-omap/mailbox.c        |  212 +++++++++++++++++++++++------------
 include/asm-arm/arch-omap/mailbox.h |   17 +--
 4 files changed, 157 insertions(+), 90 deletions(-)

100a5ffb52ee158823be7a196ec72f67deac1a3d
diff --git a/arch/arm/plat-omap/dsp/dsp_common.h b/arch/arm/plat-omap/dsp/dsp_common.h
index d2ebb42..9a515dd 100644
--- a/arch/arm/plat-omap/dsp/dsp_common.h
+++ b/arch/arm/plat-omap/dsp/dsp_common.h
@@ -24,6 +24,7 @@
 #ifndef DRIVER_DSP_COMMON_H
 #define DRIVER_DSP_COMMON_H
 
+#include <linux/clk.h>
 #include "hardware_dsp.h"
 
 #define DSPSPACE_SIZE	0x1000000
diff --git a/arch/arm/plat-omap/dsp/dsp_core.c b/arch/arm/plat-omap/dsp/dsp_core.c
index 4002fc7..4d10d4b 100644
--- a/arch/arm/plat-omap/dsp/dsp_core.c
+++ b/arch/arm/plat-omap/dsp/dsp_core.c
@@ -339,14 +339,14 @@ int dsp_mbcmd_send_and_wait_exarg(struct
 /*
  * mbcmd receiver
  */
-static void mbcmd_receiver(mbox_msg_t msg)
+static int mbcmd_receiver(void *data)
 {
-	struct mbcmd *mb = (struct mbcmd *)&msg;
+	struct mbcmd *mb = data;
 
 	if (cmdinfo[mb->cmd_h] == NULL) {
 		printk(KERN_ERR
-		       "invalid message (%08x) for mbcmd_receiver().\n", msg);
-		return;
+		       "invalid message for mbcmd_receiver().\n");
+		return -EINVAL;
 	}
 
 	(*mbseq_expect)++;
@@ -359,6 +359,7 @@ static void mbcmd_receiver(mbox_msg_t ms
 	else
 		printk(KERN_ERR "mbox: %s is not allowed from DSP.\n",
 		       cmd_name(*mb));
+	return 0;
 }
 
 static int mbsync_hold_mem_active;
@@ -411,16 +412,16 @@ static int __init dsp_mbox_init(void)
 		return -ENODEV;
 	}
 
-	omap_dsp->mbox->msg_receive_cb = mbcmd_receiver;
-	omap_dsp->mbox->msg_sender_cb = mbcmd_sender_prepare;
+	omap_dsp->mbox->rxq->callback = mbcmd_receiver;
+	omap_dsp->mbox->txq->callback = mbcmd_sender_prepare;
 
 	return 0;
 }
 
 static void dsp_mbox_exit(void)
 {
-	omap_dsp->mbox->msg_sender_cb = NULL;
-	omap_dsp->mbox->msg_receive_cb = NULL;
+	omap_dsp->mbox->rxq->callback = NULL;
+	omap_dsp->mbox->txq->callback = NULL;
 
 	if (mbsync_hold_mem_active) {
 		dsp_mem_disable((void *)daram_base);
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 416e056..fd948c0 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -59,8 +59,8 @@ static int __mbox_msg_send(struct omap_m
 		udelay(1);
 	}
 
-	if (mbox->msg_sender_cb && arg) {
-		ret = mbox->msg_sender_cb(arg);
+	if (arg && mbox->txq->callback) {
+		ret = mbox->txq->callback(arg);
 		if (ret)
 			goto out;
 	}
@@ -74,78 +74,113 @@ static int __mbox_msg_send(struct omap_m
 int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg)
 {
 	struct request *rq;
+	struct request_queue *q = mbox->txq->queue;
 	int ret = 0;
 
-	rq = blk_get_request(mbox->txq, WRITE, GFP_ATOMIC);
+	rq = blk_get_request(q, WRITE, GFP_ATOMIC);
 	if (unlikely(!rq)) {
 		ret = -ENOMEM;
 		goto fail;
 	}
 
 	rq->data = (void *)msg;
-	blk_insert_request(mbox->txq, rq, 0, arg);
+	blk_insert_request(q, rq, 0, arg);
+
+	schedule_work(&mbox->txq->work);
  fail:
 	return ret;
 }
 EXPORT_SYMBOL(omap_mbox_msg_send);
 
+static void mbox_tx_work(struct work_struct *work)
+{
+	int ret;
+	struct request *rq;
+	struct omap_mbox_queue *mq = container_of(work, struct omap_mbox_queue, work);
+	struct omap_mbox *mbox = mq->queue->queuedata;
+	struct request_queue *q = mbox->txq->queue;
+
+	while (1) {
+		spin_lock(q->queue_lock);
+		rq = elv_next_request(q);
+		spin_unlock(q->queue_lock);
+
+		if (!rq)
+			break;
+
+		ret = __mbox_msg_send(mbox, (mbox_msg_t) rq->data, rq->special);
+		if (ret) {
+			enable_mbox_irq(mbox, IRQ_TX);
+			return;
+		}
+
+		spin_lock(q->queue_lock);
+		blkdev_dequeue_request(rq);
+		end_that_request_last(rq, 0);
+		spin_unlock(q->queue_lock);
+	}
+}
+
 /*
  * Message receiver(workqueue)
  */
-static void mbox_msg_receiver(struct work_struct *work)
+static void mbox_rx_work(struct work_struct *work)
 {
-	struct omap_mbox *mbox =
-	    container_of(work, struct omap_mbox, msg_receive);
-	struct request_queue *q = mbox->rxq;
+	struct omap_mbox_queue *mq = container_of(work, struct omap_mbox_queue, work);
+	struct omap_mbox *mbox = mq->queue->queuedata;
+	struct request_queue *q = mbox->rxq->queue;
 	struct request *rq;
 	mbox_msg_t msg;
+	unsigned long flags;
 
-	if (mbox->msg_receive_cb == NULL) {
+	if (mbox->rxq->callback == NULL) {
 		sysfs_notify(&mbox->dev.kobj, NULL, "mbox");
 		return;
 	}
 
 	while (1) {
+		spin_lock_irqsave(q->queue_lock, flags);
 		rq = elv_next_request(q);
+		spin_unlock_irqrestore(q->queue_lock, flags);
 		if (!rq)
 			break;
 
-		msg = (mbox_msg_t)rq->data;
+		msg = (mbox_msg_t) rq->data;
 
+		spin_lock_irqsave(q->queue_lock, flags);
 		blkdev_dequeue_request(rq);
 		end_that_request_last(rq, 0);
+		spin_unlock_irqrestore(q->queue_lock, flags);
 
-		if (mbox->msg_receive_cb)
-			mbox->msg_receive_cb(msg);
+		mbox->rxq->callback((void *)msg);
 	}
 }
 
 /*
  * Mailbox interrupt handler
  */
-static void mbox_txq_fn(request_queue_t *q)
+static void mbox_txq_fn(request_queue_t * q)
 {
-	struct omap_mbox *mbox = q->queuedata;
-	int ret;
-	struct request *rq;
+}
 
-	while ((rq = elv_next_request(q)) != NULL) {
-		ret = __mbox_msg_send(mbox, (mbox_msg_t)rq->data, rq->special);
-		if (ret) {
-			blk_stop_queue(q);
-			enable_mbox_irq(mbox, IRQ_TX);
-			return;
-		}
-		blkdev_dequeue_request(rq);
-		end_that_request_last(rq, 0);
-	}
+static void mbox_rxq_fn(request_queue_t * q)
+{
 }
 
-static void mbox_rxq_fn(request_queue_t *q)
+static void __mbox_tx_interrupt(struct omap_mbox *mbox)
+{
+	disable_mbox_irq(mbox, IRQ_TX);
+	ack_mbox_irq(mbox, IRQ_TX);
+	schedule_work(&mbox->txq->work);
+}
+
+static void __mbox_rx_interrupt(struct omap_mbox *mbox)
 {
 	struct request *rq;
-	struct omap_mbox *mbox = q->queuedata;
 	mbox_msg_t msg;
+	request_queue_t *q = mbox->rxq->queue;
+
+	disable_mbox_irq(mbox, IRQ_RX);
 
 	while (!mbox_fifo_empty(mbox)) {
 		rq = blk_get_request(q, WRITE, GFP_ATOMIC);
@@ -161,7 +196,7 @@ static void mbox_rxq_fn(request_queue_t 
 				mbox->err_notify();
 		}
 
-		blk_insert_request(mbox->rxq, rq, 0, NULL);
+		blk_insert_request(q, rq, 0, NULL);
 		if (mbox->ops->type == OMAP_MBOX_TYPE1)
 			break;
 	}
@@ -169,24 +204,19 @@ static void mbox_rxq_fn(request_queue_t 
 	/* no more messages in the fifo. clear IRQ source. */
 	ack_mbox_irq(mbox, IRQ_RX);
 	enable_mbox_irq(mbox, IRQ_RX);
- nomem:
-	queue_work(mbox->workq, &mbox->msg_receive);
+      nomem:
+	schedule_work(&mbox->rxq->work);
 }
 
 static irqreturn_t mbox_interrupt(int irq, void *p)
 {
 	struct omap_mbox *mbox = (struct omap_mbox *)p;
 
-	if (is_mbox_irq(mbox, IRQ_TX)) {
-		disable_mbox_irq(mbox, IRQ_TX);
-		ack_mbox_irq(mbox, IRQ_TX);
-		blk_start_queue(mbox->txq);
-	}
+	if (is_mbox_irq(mbox, IRQ_TX))
+		__mbox_tx_interrupt(mbox);
 
-	if (is_mbox_irq(mbox, IRQ_RX)) {
-		disable_mbox_irq(mbox, IRQ_RX);
-		blk_start_queue(mbox->rxq);
-	}
+	if (is_mbox_irq(mbox, IRQ_RX))
+		__mbox_rx_interrupt(mbox);
 
 	return IRQ_HANDLED;
 }
@@ -213,18 +243,28 @@ omap_mbox_write(struct device *dev, stru
 }
 
 static ssize_t
-omap_mbox_read(struct device *dev, struct device_attribute *attr,
-	       char * buf)
+omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf)
 {
+	unsigned long flags;
 	struct request *rq;
-	mbox_msg_t *p = (mbox_msg_t *)buf;
+	mbox_msg_t *p = (mbox_msg_t *) buf;
 	struct omap_mbox *mbox = dev_get_drvdata(dev);
-	struct request_queue *q = mbox->rxq;
+	struct request_queue *q = mbox->rxq->queue;
+
+	while (1) {
+		spin_lock_irqsave(q->queue_lock, flags);
+		rq = elv_next_request(q);
+		spin_unlock_irqrestore(q->queue_lock, flags);
+
+		if (!rq)
+			break;
 
-	while ((rq = elv_next_request(q)) != NULL) {
-		*p = (mbox_msg_t)rq->data;
+		*p = (mbox_msg_t) rq->data;
+
+		spin_lock_irqsave(q->queue_lock, flags);
 		blkdev_dequeue_request(rq);
 		end_that_request_last(rq, 0);
+		spin_unlock_irqrestore(q->queue_lock, flags);
 
 		if (unlikely(mbox_seq_test(mbox, *p))) {
 			pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);
@@ -235,7 +275,7 @@ omap_mbox_read(struct device *dev, struc
 
 	pr_debug("%02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
 
-	return (size_t)((char *)p - buf);
+	return (size_t) ((char *)p - buf);
 }
 
 static DEVICE_ATTR(mbox, S_IRUGO | S_IWUSR, omap_mbox_read, omap_mbox_write);
@@ -251,10 +291,43 @@ static struct class omap_mbox_class = {
 	.name = "omap_mbox",
 };
 
+static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
+					request_fn_proc * proc,
+					void (*work) (struct work_struct *))
+{
+	request_queue_t *q;
+	struct omap_mbox_queue *mq;
+
+	mq = kzalloc(sizeof(struct omap_mbox_queue), GFP_KERNEL);
+	if (!mq)
+		return NULL;
+
+	spin_lock_init(&mq->lock);
+
+	q = blk_init_queue(proc, &mq->lock);
+	if (!q)
+		goto error;
+	q->queuedata = mbox;
+	mq->queue = q;
+
+	INIT_WORK(&mq->work, work);
+
+	return mq;
+error:
+	kfree(mq);
+	return NULL;
+}
+
+static void mbox_queue_free(struct omap_mbox_queue *q)
+{
+	blk_cleanup_queue(q->queue);
+	kfree(q);
+}
+
 static int omap_mbox_init(struct omap_mbox *mbox)
 {
 	int ret;
-	request_queue_t *q;
+	struct omap_mbox_queue *mq;
 
 	if (likely(mbox->ops->startup)) {
 		ret = mbox->ops->startup(mbox);
@@ -277,9 +350,6 @@ static int omap_mbox_init(struct omap_mb
 		goto fail_create_mbox;
 	}
 
-	spin_lock_init(&mbox->lock);
-	INIT_WORK(&mbox->msg_receive, mbox_msg_receiver);
-
 	ret = request_irq(mbox->irq, mbox_interrupt, IRQF_DISABLED,
 			  mbox->name, mbox);
 	if (unlikely(ret)) {
@@ -289,23 +359,25 @@ static int omap_mbox_init(struct omap_mb
 	}
 	enable_mbox_irq(mbox, IRQ_RX);
 
-	q = blk_init_queue(mbox_txq_fn, &mbox->lock);
-	if (!q)
-		goto fail_blkinit_txq;
-	mbox->txq = q;
-	q->queuedata = mbox;
+	mq = mbox_queue_alloc(mbox, mbox_txq_fn, mbox_tx_work);
+	if (!mq) {
+		ret = -ENOMEM;
+		goto fail_alloc_txq;
+	}
+	mbox->txq = mq;
 
-	q = blk_init_queue(mbox_rxq_fn, &mbox->lock);
-	if (!q)
-		goto fail_blkinit_rxq;
-	mbox->rxq = q;
-	q->queuedata = mbox;
+	mq = mbox_queue_alloc(mbox, mbox_rxq_fn, mbox_rx_work);
+	if (!mq) {
+		ret = -ENOMEM;
+		goto fail_alloc_rxq;
+	}
+	mbox->rxq = mq;
 
 	return 0;
 
- fail_blkinit_rxq:
-	blk_cleanup_queue(mbox->txq);
- fail_blkinit_txq:
+ fail_alloc_rxq:
+	mbox_queue_free(mbox->txq);
+ fail_alloc_txq:
 	free_irq(mbox->irq, mbox);
  fail_request_irq:
 	device_remove_file(&mbox->dev, &dev_attr_mbox);
@@ -320,11 +392,8 @@ static int omap_mbox_init(struct omap_mb
 
 static void omap_mbox_fini(struct omap_mbox *mbox)
 {
-	blk_cleanup_queue(mbox->txq);
-	blk_cleanup_queue(mbox->rxq);
-
-	flush_workqueue(mbox->workq);
-	destroy_workqueue(mbox->workq);
+	mbox_queue_free(mbox->txq);
+	mbox_queue_free(mbox->rxq);
 
 	free_irq(mbox->irq, mbox);
 	device_remove_file(&mbox->dev, &dev_attr_mbox);
@@ -349,7 +418,6 @@ static struct omap_mbox **find_mboxes(co
 struct omap_mbox *omap_mbox_get(const char *name)
 {
 	struct omap_mbox *mbox;
-	char queue_name[MBOX_NAME_LEN];
 	int ret;
 
 	read_lock(&mboxes_lock);
@@ -359,10 +427,6 @@ struct omap_mbox *omap_mbox_get(const ch
 		return ERR_PTR(-ENOENT);
 	}
 
-	strcpy(queue_name, "mailbox/");
-	strcat(queue_name, mbox->name);
-	mbox->workq = create_singlethread_workqueue(queue_name);
-
 	read_unlock(&mboxes_lock);
 
 	ret = omap_mbox_init(mbox);
diff --git a/include/asm-arm/arch-omap/mailbox.h b/include/asm-arm/arch-omap/mailbox.h
index 8d12ced..4bf0909 100644
--- a/include/asm-arm/arch-omap/mailbox.h
+++ b/include/asm-arm/arch-omap/mailbox.h
@@ -35,18 +35,19 @@ struct omap_mbox_ops {
 	int		(*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
 };
 
+struct omap_mbox_queue {
+	spinlock_t		lock;
+	request_queue_t		*queue;
+	struct work_struct	work;
+	int	(*callback)(void *);
+	struct omap_mbox	*mbox;
+};
+
 struct omap_mbox {
 	char			*name;
-	spinlock_t		lock;
 	unsigned int		irq;
 
-	struct workqueue_struct	*workq;
-	struct work_struct	msg_receive;
-
-	request_queue_t		*txq, *rxq;
-
-	void	(*msg_receive_cb)(mbox_msg_t);
-	int	(*msg_sender_cb)(void*);
+	struct omap_mbox_queue	*txq, *rxq;
 
 	struct omap_mbox_ops	*ops;
 
-- 
1.3.3


[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH 2/2] ARM: OMAP: Restructuring mailbox blk queues
  2007-03-17  9:19 [PATCH 2/2] ARM: OMAP: Restructuring mailbox blk queues Trilok Soni
@ 2007-03-19  6:52 ` Hiroshi DOYU
  0 siblings, 0 replies; 2+ messages in thread
From: Hiroshi DOYU @ 2007-03-19  6:52 UTC (permalink / raw)
  To: soni.trilok; +Cc: linux-omap-open-source

From: "ext Trilok Soni" <soni.trilok@gmail.com>
Subject: [PATCH 2/2] ARM: OMAP: Restructuring mailbox blk queues
Date: Sat, 17 Mar 2007 14:49:32 +0530

> From nobody Mon Sep 17 00:00:00 2001
> From: Trilok Soni <soni.trilok@gmail.com>
> Date: Sat, 17 Mar 2007 20:17:57 +0530
> Subject: [PATCH 2/2] ARM: OMAP: Restructuring mailbox blk queues
> 
> From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
> 
> Signed-off-by: Trilok Soni <soni.trilok@gmail.com>
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-03-19  6:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-17  9:19 [PATCH 2/2] ARM: OMAP: Restructuring mailbox blk queues Trilok Soni
2007-03-19  6:52 ` Hiroshi DOYU

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.