commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=6de0793f9e739fa9bbaca81b4871d5f3047e9a87
branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/2012R1

find icc_info by message

Signed-off-by: Steven Miao <[email protected]>
---
 arch/blackfin/include/asm/icc.h         |    8 +-
 arch/blackfin/mach-bf609/boards/ezkit.c |   10 +-
 drivers/staging/icc/core/protocol.c     |  163 +++++++++++++++++++------------
 drivers/staging/icc/include/icc.h       |    7 +-
 4 files changed, 113 insertions(+), 75 deletions(-)

diff --git a/arch/blackfin/include/asm/icc.h b/arch/blackfin/include/asm/icc.h
index 39f2ed2..31cfef8 100644
--- a/arch/blackfin/include/asm/icc.h
+++ b/arch/blackfin/include/asm/icc.h
@@ -9,14 +9,16 @@
 
 #include <linux/cpumask.h>
 
-struct icc_slave_platform_data {
+struct icc_peer_platform_data {
+	u32	peerid;
 	u32	irq;
 	u32	notify;
+	u32 	phy_peer_mem;
 };
 
 struct icc_platform_data {
-	u32	slave_count;
-	struct icc_slave_platform_data *slave_info;
+	u32	peer_count;
+	struct icc_peer_platform_data *peer_info;
 };
 
 void platform_send_ipi(cpumask_t callmap, int irq);
diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c
index e038094..605374f 100644
--- a/arch/blackfin/mach-bf609/boards/ezkit.c
+++ b/arch/blackfin/mach-bf609/boards/ezkit.c
@@ -1112,18 +1112,20 @@ static struct platform_device bfin_crypto_crc_device = {
 #if defined(CONFIG_ICC)
 #include <asm/icc.h>
 #define ICC_NAME "icc"
-#define ICC_SLAVE_COUNT	1
+#define ICC_PEER_COUNT	1
 
-static struct icc_slave_platform_data bfin_icc_slave_data[ICC_SLAVE_COUNT] = {
+static struct icc_peer_platform_data bfin_icc_peer_data[ICC_PEER_COUNT] = {
 	{
+		.peerid = 1,
 		.irq = IRQ_SOFT0,
 		.notify = IRQ_SOFT1,
+		.phy_peer_mem = L2_START,
 	},
 };
 
 static struct icc_platform_data bfin_icc_data = {
-	.slave_count = ICC_SLAVE_COUNT,
-	.slave_info = bfin_icc_slave_data,
+	.peer_count = ICC_PEER_COUNT,
+	.peer_info = bfin_icc_peer_data,
 };
 
 static struct platform_device bfin_icc_device = {
diff --git a/drivers/staging/icc/core/protocol.c b/drivers/staging/icc/core/protocol.c
index ab9679c..1e03a42 100644
--- a/drivers/staging/icc/core/protocol.c
+++ b/drivers/staging/icc/core/protocol.c
@@ -29,7 +29,7 @@
 
 static struct bfin_icc {
 	struct miscdevice mdev;
-	int slave_count;
+	int peer_count;
 	wait_queue_head_t icc_rx_wait;
 	struct sm_session_table *sessions_table;
 	struct sm_icc_desc *icc_info;
@@ -56,19 +56,48 @@ static void wakeup_icc_thread(struct sm_icc_desc *icc_info)
 	wake_up(&bfin_icc->icc_rx_wait);
 }
 
-static int get_msg_src(struct sm_msg *msg)
+static struct sm_message_queue *icc_get_inqueue(struct sm_msg *msg)
 {
-	unsigned int n = 0;
-	unsigned int offset;
-	unsigned int align = 256;
-	offset = (unsigned int)msg - MSGQ_START_ADDR;
-	if (align < sizeof(struct sm_message_queue))
-		align = (sizeof(struct sm_message_queue) + align - 1) / align;
-	n = offset / align;
-	if ((n % 2) == 0)
-		return n + 1;
+	uint32_t queue_size = sizeof(struct sm_message_queue);
+	uint32_t n = (uint32_t)msg / queue_size;
+	return (struct sm_message_queue *)(n * queue_size);
+}
+
+static struct sm_icc_desc *get_icc_peer(struct sm_msg *msg)
+{
+	struct sm_icc_desc *icc_info = bfin_icc->icc_info;
+	int i;
+	uint32_t msg_addr = (uint32_t)msg;
+	BUG_ON(!msg);
+	for (i = 0; i < bfin_icc->peer_count; i++) {
+		if (((uint32_t)icc_info[i].icc_queue < msg_addr) &&
+		(msg_addr < (uint32_t)icc_info[i].icc_queue + 2 * sizeof(struct sm_message_queue)))
+			break;
+	}
+
+	if (i == bfin_icc->peer_count)
+		return NULL;
+	return &icc_info[i];
+}
+
+static struct sm_message_queue *sm_find_queue(struct sm_message *message, struct sm_session *session)
+{
+	uint16_t dst = message->dst;
+	struct sm_icc_desc *icc_info = bfin_icc->icc_info;
+	int i;
+	if (!message || !session)
+		return NULL;
+	for (i = 0; i < bfin_icc->peer_count; i++) {
+		if (icc_info[i].peer_cpu == dst)
+			break;
+	}
+	if (i == bfin_icc->peer_count)
+		return NULL;
+	message->icc_info = &icc_info[i];
+	if (session->queue_priority)
+		return icc_info[i].icc_high_queue;
 	else
-		return 0;
+		return icc_info[i].icc_queue;
 }
 
 static int init_sm_session_table(struct bfin_icc *icc)
@@ -100,10 +129,10 @@ static int sm_message_enqueue(struct sm_message_queue *icc_queue, struct sm_msg
 	return 0;
 }
 
-static int sm_message_dequeue(struct sm_message_queue *icc_queue, struct sm_msg *msg)
+static int sm_message_dequeue(struct sm_msg *msg)
 {
 	/* icc_queue[0] is the queue to receive message */
-	struct sm_message_queue *inqueue = icc_queue;
+	struct sm_message_queue *inqueue = icc_get_inqueue(msg);
 	uint16_t received;
 
 	memset(msg, 0, sizeof(struct sm_msg));
@@ -241,12 +270,17 @@ static int iccqueue_getpending(struct sm_icc_desc *icc_info)
 }
 
 static int sm_send_message_internal(struct sm_session *session,
-					struct sm_msg *msg)
+					struct sm_message *message)
 {
-	struct sm_icc_desc *icc_info = session->icc_info;
+	struct sm_message_queue *icc_queue = sm_find_queue(message, session);
+	struct sm_msg *msg = &message->msg;
 	int ret = 0;
+	struct sm_icc_desc *icc_info = message->icc_info;
+	BUG_ON(!icc_info);
+	if (!icc_queue)
+		return -EINVAL;
 	sm_debug("%s: dst %d %08x\n", __func__, icc_info->peer_cpu, (uint32_t)msg->type);
-	ret = sm_message_enqueue(SM_GET_ICC_QUEUE(session), msg);
+	ret = sm_message_enqueue(icc_queue, msg);
 	if (!ret)
 		icc_send_ipi_cpu(icc_info->peer_cpu, icc_info->notify);
 	return ret;
@@ -258,26 +292,26 @@ sm_send_control_msg(struct sm_session *session, uint32_t remote_ep,
 			uint32_t dst_cpu, uint32_t payload,
 			uint32_t len, uint32_t type)
 {
-	struct sm_msg *m;
+	struct sm_message *message;
 	int ret = 0;
 
-	m = kzalloc(sizeof(struct sm_msg), GFP_KERNEL);
-	if (!m)
+	message = kzalloc(sizeof(struct sm_message), GFP_KERNEL);
+	if (!message)
 		return -ENOMEM;
 
-	m->type = type;
+	message->msg.type = type;
 	if (session)
-		m->src_ep = session->local_ep;
-	m->dst_ep = remote_ep;
-	m->length = len;
-	m->payload = payload;
-
-	session->icc_info = &bfin_icc->icc_info[dst_cpu - 1];
-
-	ret = sm_send_message_internal(session, m);
+		message->msg.src_ep = session->local_ep;
+	message->msg.dst_ep = remote_ep;
+	message->msg.length = len;
+	message->msg.payload = payload;
+	message->dst = dst_cpu;
+	message->src = "">
+
+	ret = sm_send_message_internal(session, message);
 	if (ret)
 		return -EAGAIN;
-	kfree(m);
+	kfree(message);
 	return ret;
 
 }
@@ -436,8 +470,6 @@ sm_send_scalar(uint32_t session_idx, uint32_t dst_ep, uint32_t dst_cpu,
 	m->msg.length = scalar1;
 	m->msg.type = type;
 
-	session->icc_info = &bfin_icc->icc_info[dst_cpu - 1];
-
 	if (session->proto_ops->sendmsg) {
 		ret = session->proto_ops->sendmsg(m, session);
 	} else {
@@ -449,9 +481,9 @@ sm_send_scalar(uint32_t session_idx, uint32_t dst_ep, uint32_t dst_cpu,
 
 	sm_debug("%s: scalar0 %x scalar1 %x type %x dst %d dstep %d src %d srcep %d\n", __func__, scalar0, scalar1, (uint32_t)m->msg.type, (int)m->dst, (int)m->msg.dst_ep, (int)m->src, (int)m->msg.src_ep);
 retry:
-	ret = sm_send_message_internal(session, &m->msg);
+	ret = sm_send_message_internal(session, m);
 	if ((!nonblock) && (ret == -EAGAIN)) {
-		interruptible_sleep_on(&session->icc_info->iccq_tx_wait);
+		interruptible_sleep_on(&m->icc_info->iccq_tx_wait);
 		goto retry;
 	} else {
 		goto out;
@@ -502,6 +534,7 @@ sm_send_packet(uint32_t session_idx, uint32_t dst_ep, uint32_t dst_cpu,
 
 		if (copy_from_user((void *)m->msg.payload, buf, m->msg.length)) {
 			ret = -EFAULT;
+			sm_debug("copy failed\n");
 			goto fail2;
 		}
 
@@ -510,8 +543,6 @@ sm_send_packet(uint32_t session_idx, uint32_t dst_ep, uint32_t dst_cpu,
 		goto fail1;
 	}
 
-	session->icc_info = &bfin_icc->icc_info[dst_cpu - 1];
-
 	if (session->proto_ops->sendmsg) {
 		ret = session->proto_ops->sendmsg(m, session);
 	} else {
@@ -523,7 +554,7 @@ sm_send_packet(uint32_t session_idx, uint32_t dst_ep, uint32_t dst_cpu,
 
 	sm_debug("%s: len %d type %x dst %d dstep %d src %d srcep %d\n", __func__, (int)m->msg.length, (int)m->msg.type, (int)m->dst, (int)m->msg.dst_ep, (int)m->src, (int)m->msg.src_ep);
 retry:
-	ret = sm_send_message_internal(session, &m->msg);
+	ret = sm_send_message_internal(session, m);
 	if (ret == -EAGAIN) {
 		if (nonblock) {
 			mutex_lock(&bfin_icc->sessions_table->lock);
@@ -532,7 +563,7 @@ retry:
 			goto fail2;
 		}
 		sm_debug(">>>>sleep on send queue\n");
-		interruptible_sleep_on(&session->icc_info->iccq_tx_wait);
+		interruptible_sleep_on(&m->icc_info->iccq_tx_wait);
 		sm_debug("<<<<wakeup send queue\n");
 		goto retry;
 	} else {
@@ -910,6 +941,7 @@ int icc_handle_scalar_cmd(struct sm_msg *msg)
 	uint32_t scalar0, scalar1;
 	uint16_t src_cpu;
 	struct sm_session *session;
+	struct sm_icc_desc *icc_info;
 	int index;
 
 	if (msg->type != SM_SCALAR_READY_64)
@@ -918,7 +950,8 @@ int icc_handle_scalar_cmd(struct sm_msg *msg)
 	scalar0 = msg->payload;
 	scalar1 = msg->length;
 
-	src_cpu = get_msg_src(msg);
+	icc_info = get_icc_peer(msg);
+	src_cpu = icc_info->peer_cpu;
 
 	if (SM_SCALAR_CMD(scalar0) != SM_SCALAR_CMD_HEAD)
 		return 0;
@@ -1052,7 +1085,7 @@ unsigned int icc_poll(struct file *file, poll_table *wait)
 
 	poll_wait(file, &bfin_icc->icc_rx_wait, wait);
 
-	for (i = 0, icc_info = bfin_icc->icc_info; i < bfin_icc->slave_count; i++, icc_info++) {
+	for (i = 0, icc_info = bfin_icc->icc_info; i < bfin_icc->peer_count; i++, icc_info++) {
 		pending = iccqueue_getpending(icc_info);
 		if (pending) {
 			mask |= POLLIN | POLLRDNORM;
@@ -1074,10 +1107,14 @@ static const struct file_operations icc_fops = {
 
 static int msg_recv_internal(struct sm_msg *msg, struct sm_session *session)
 {
-	struct sm_icc_desc *icc_info = session->icc_info;
+	struct sm_icc_desc *icc_info;
 	int cpu = blackfin_core_id();
 	struct sm_message *message;
 	int ret = 0;
+
+	icc_info = get_icc_peer(msg);
+	BUG_ON(!icc_info);
+
 	message = kzalloc(sizeof(struct sm_message), GFP_KERNEL);
 	if (!message)
 		return -ENOMEM;
@@ -1107,6 +1144,8 @@ static int msg_recv_internal(struct sm_msg *msg, struct sm_session *session)
 	return ret;
 }
 
+
+
 static int sm_default_sendmsg(struct sm_message *message, struct sm_session *session)
 {
 	struct sm_msg *msg = &message->msg;
@@ -1136,10 +1175,12 @@ static int sm_default_sendmsg(struct sm_message *message, struct sm_session *ses
 static int
 sm_default_recvmsg(struct sm_msg *msg, struct sm_session *session)
 {
-	struct sm_icc_desc *icc_info = session->icc_info;
+	struct sm_icc_desc *icc_info;
 	int ret = 0;
 	struct sm_message *uncompleted;
 	struct sm_session_table *table = bfin_icc->sessions_table;
+	icc_info = get_icc_peer(msg);
+	BUG_ON(!icc_info);
 	sm_debug("%s msg type %x\n", __func__, (uint32_t)msg->type);
 	switch (msg->type) {
 	case SM_PACKET_CONSUMED:
@@ -1251,7 +1292,7 @@ matched1:
 		ret = -EINVAL;
 	};
 
-	sm_message_dequeue(SM_GET_ICC_QUEUE(session), msg);
+	sm_message_dequeue(msg);
 	return ret;
 }
 
@@ -1301,7 +1342,7 @@ static int sm_task_recvmsg(struct sm_msg *msg, struct sm_session *session)
 	default:
 		break;
 	};
-	sm_message_dequeue(SM_GET_ICC_QUEUE(session), msg);
+	sm_message_dequeue(msg);
 	return 0;
 }
 
@@ -1374,7 +1415,7 @@ int __msg_handle(struct sm_icc_desc *icc_info, struct sm_message_queue *inqueue)
 
 	if (msg->type == SM_BAD_MSG) {
 		printk(KERN_WARNING "%s", (char *)msg->payload);
-		sm_message_dequeue(inqueue, msg);
+		sm_message_dequeue(msg);
 		return 1;
 	}
 
@@ -1385,13 +1426,12 @@ int __msg_handle(struct sm_icc_desc *icc_info, struct sm_message_queue *inqueue)
 
 	if (!session) {
 		sm_debug("discard msg type %x\n", (uint32_t)msg->type);
-		sm_message_dequeue(inqueue, msg);
+		sm_message_dequeue(msg);
 		wake_up(&icc_info->iccq_tx_wait);
 		return 1;
 	}
 
-	session->icc_info = icc_info;
-	session->queue_priority = inqueue == session->icc_info->icc_high_queue;
+	session->queue_priority = (inqueue == icc_info->icc_high_queue);
 	if (session->proto_ops->recvmsg)
 		session->proto_ops->recvmsg(msg, session);
 	else
@@ -1466,8 +1506,8 @@ icc_write_proc(struct file *file, const char __user * buffer,
 		return -EINVAL;
 
 	session = &table->sessions[val];
-	sm_debug(" %ld", session->local_ep);
-	sm_debug(" %ld", session->remote_ep);
+	sm_debug(" %x", session->local_ep);
+	sm_debug(" %x", session->remote_ep);
 	sm_debug(" %X", (uint32_t)session->type);
 	sm_debug(" %X\n", (uint32_t)session->flags);
 	return count;
@@ -1495,7 +1535,7 @@ static int __devinit bfin_icc_probe(struct platform_device *pdev)
 		return -ENOENT;
 	}
 
-	if (!icc_data || icc_data->slave_count <= 0) {
+	if (!icc_data || icc_data->peer_count <= 0) {
 		dev_err(&pdev->dev, "No ICC platform data are defined.\n");
 		return -ENOENT;
 	}
@@ -1510,27 +1550,26 @@ static int __devinit bfin_icc_probe(struct platform_device *pdev)
 	snprintf(icc->name, 20, "%s", DRIVER_NAME);
 	icc->mdev.name	= icc->name;
 	icc->mdev.fops	= &icc_fops;
-	icc->slave_count = icc_data->slave_count;
+	icc->peer_count = icc_data->peer_count;
 	init_waitqueue_head(&icc->icc_rx_wait);
 
-	icc->icc_info = kzalloc(sizeof(struct sm_icc_desc) * icc->slave_count, GFP_KERNEL);
+	icc->icc_info = kzalloc(sizeof(struct sm_icc_desc) * icc->peer_count, GFP_KERNEL);
 	if (!icc->icc_info) {
 		dev_err(&pdev->dev, "fail to malloc icc_info array\n");
 		ret = -ENOMEM;
 		goto out_error_free_mem;
 	}
 
-	for (i = 0, icc_info = icc->icc_info; i < icc->slave_count; i++, icc_info++) {
-		icc_info->peer_cpu = i + 1;
-
-		icc_info->notify = icc_data->slave_info[i].notify;
+	for (i = 0, icc_info = icc->icc_info; i < icc->peer_count; i++, icc_info++) {
+		icc_info->peer_cpu = icc_data->peer_info[i].peerid;
+		icc_info->notify = icc_data->peer_info[i].notify;
 		if( icc_info->notify < 0) {
 			dev_err(&pdev->dev, "No ICC Notify specified\n");
 			ret = -ENOENT;
 			goto out_error_free_mem;
 		}
 
-		icc_info->irq = icc_data->slave_info[i].irq;
+		icc_info->irq = icc_data->peer_info[i].irq;
 		if (icc_info->irq < 0) {
 			dev_err(&pdev->dev, "No ICC receive IRQ specified\n");
 			ret = -ENOENT;
@@ -1545,8 +1584,8 @@ static int __devinit bfin_icc_probe(struct platform_device *pdev)
 		}
 
 		/* icc_queue[0] is rx queue, icc_queue[1] is tx queue. */
-		icc_info->icc_queue = (struct sm_message_queue *)MSGQ_START_ADDR + i * SM_MSGQ_NUM;
-		icc_info->icc_high_queue = (struct sm_message_queue *)MSGQ_START_ADDR + 2 + i * SM_MSGQ_NUM;
+		icc_info->icc_queue = (struct sm_message_queue *)icc_data->peer_info[i].phy_peer_mem;
+		icc_info->icc_high_queue = (struct sm_message_queue *)icc_info->icc_queue + 2;
 		memset(icc_info->icc_queue, 0, sizeof(struct sm_message_queue) * SM_MSGQ_NUM);
 
 		init_waitqueue_head(&icc->icc_rx_wait);
@@ -1578,7 +1617,7 @@ static int __devinit bfin_icc_probe(struct platform_device *pdev)
 	return 0;
 
 out_error_free_irq:
-	for (i = 0, icc_info = icc->icc_info; i < icc->slave_count; i++, icc_info++) {
+	for (i = 0, icc_info = icc->icc_info; i < icc->peer_count; i++, icc_info++) {
 		if (icc_info->irq)
 			free_irq(icc_info->irq, icc_info);
 	}
@@ -1600,7 +1639,7 @@ static int __devexit bfin_icc_remove(struct platform_device *pdev)
 
 	if (icc) {
 		misc_deregister(&icc->mdev);
-		for (i = 0, icc_info = icc->icc_info; i < icc->slave_count; i++, icc_info++) {
+		for (i = 0, icc_info = icc->icc_info; i < icc->peer_count; i++, icc_info++) {
 			if (icc_info->irq)
 				free_irq(icc_info->irq, icc_info);
 		}
diff --git a/drivers/staging/icc/include/icc.h b/drivers/staging/icc/include/icc.h
index ff77fac..07a38568 100644
--- a/drivers/staging/icc/include/icc.h
+++ b/drivers/staging/icc/include/icc.h
@@ -137,6 +137,7 @@ struct sm_message {
 	uint16_t dst;
 	uint16_t src;
 	struct sm_msg msg;
+	struct sm_icc_desc *icc_info;
 	uint32_t flags;
 };
 
@@ -149,17 +150,12 @@ struct sm_message_queue {
 	struct sm_msg messages[SM_MSGQ_LEN];
 } __attribute__((__aligned__(256)));
 
-#define MSGQ_START_ADDR         L2_START
 #define SM_MSGQ_NUM		4 /* 2 low bi-direction fifos and 2 high ones */
 #define MSGQ_SIZE		(sizeof(struct sm_message_queue) * SM_MSGQ_NUM)
 
 #define DEBUG_MSG_LINE		128
 #define DEBUG_MSG_BUF_SIZE	(DEBUG_MSG_LINE * SM_MSGQ_LEN)
 
-#define SM_GET_ICC_QUEUE(session) \
-	(session->queue_priority ? session->icc_info->icc_high_queue : \
-	session->icc_info->icc_queue)
-
 struct sm_icc_desc {
 	uint32_t peer_cpu;
 	struct sm_message_queue *icc_queue;
@@ -182,7 +178,6 @@ struct sm_session {
 	uint32_t	flags;
 	int (*handle)(struct sm_message *msg, struct sm_session *session);
 	struct sm_proto *proto_ops;
-	struct sm_icc_desc *icc_info;
 	uint32_t	queue_priority;
 	wait_queue_head_t rx_wait;
 } __attribute__((__aligned__(4)));
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to