commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=2fa2531e3460ad5e4a7bc1e951d4d12fe40f40a4
branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/trunk

Signed-off-by: Sonic Zhang <[email protected]>
---
 drivers/staging/icc/core/protocol.c |  323 ++++++++++++++++++++++++-----------
 1 files changed, 227 insertions(+), 96 deletions(-)

diff --git a/drivers/staging/icc/core/protocol.c b/drivers/staging/icc/core/protocol.c
index a3d7d41..2404c1a 100644
--- a/drivers/staging/icc/core/protocol.c
+++ b/drivers/staging/icc/core/protocol.c
@@ -4,7 +4,7 @@
  */
 
 
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
@@ -19,32 +19,57 @@
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
 #include <asm/cacheflush.h>
+#include <asm/icc.h>
 
 
-struct sm_icc_desc *icc_info;
-struct sm_proto *sm_protos[SP_MAX];
-struct proc_dir_entry *icc_dump;
+#define DRIVER_NAME "icc"
 
-static int icc_init(void)
+
+static struct bfin_icc {
+	struct miscdevice mdev;
+	int low_irq;
+	int high_irq;
+	struct mutex mutex;
+	struct sm_icc_desc icc_info;
+	struct sm_proto *sm_protos[SP_MAX];
+	struct proc_dir_entry *icc_dump;
+	char name[20];
+} *bfin_icc;
+
+
+void icc_send_ipi_cpu(unsigned int cpu, int irq)
 {
-	icc_info = kzalloc(sizeof(struct sm_icc_desc), GFP_KERNEL);
-	if (!icc_info)
-		return -ENOMEM;
-	return 0;
+	platform_send_ipi_cpu(cpu, irq);
+}
+
+void icc_send_ipi_cpu_low(unsigned int cpu)
+{
+	platform_send_ipi_cpu(cpu, ICC_LOW_SEND);
 }
 
-void wakeup_icc_thread(void)
+void icc_send_ipi_cpu_high(unsigned int cpu)
 {
-	if (icc_info->iccq_thread)
-		wake_up_process(icc_info->iccq_thread);
-	wake_up(&icc_info->iccq_rx_wait);
+	platform_send_ipi_cpu(cpu, ICC_HIGH_SEND);
 }
 
-static int init_sm_message_queue(void)
+static void icc_clear_ipi_cpu(unsigned int cpu, int irq)
 {
-	icc_info->icc_queue = (struct sm_message_queue *)MSGQ_START_ADDR;
-	memset(icc_info->icc_queue, 0, sizeof(struct sm_message_queue)*2);
+	platform_clear_ipi(cpu, irq);
+}
+
+static void wakeup_icc_thread(void)
+{
+	if (bfin_icc->icc_info.iccq_thread)
+		wake_up_process(bfin_icc->icc_info.iccq_thread);
+	wake_up(&bfin_icc->icc_info.iccq_rx_wait);
+}
+
+static int init_sm_message_queue(struct bfin_icc *icc)
+{
+	icc->icc_info.icc_queue = (struct sm_message_queue *)MSGQ_START_ADDR;
+	memset(icc->icc_info.icc_queue, 0, sizeof(struct sm_message_queue)*2);
 	return 0;
 }
 
@@ -63,20 +88,23 @@ static int get_msg_src(struct sm_msg *msg)
 		return 0;
 }
 
-static int init_sm_session_table(void)
+static int init_sm_session_table(struct bfin_icc *icc)
 {
-	icc_info->sessions_table = kzalloc(sizeof(struct sm_session_table),
-					GFP_KERNEL);
-	if (!icc_info->sessions_table)
+	struct sm_session_table *sessions_table;
+
+	sessions_table = icc->icc_info.sessions_table =
+		kzalloc(sizeof(struct sm_session_table), GFP_KERNEL);
+
+	if (!sessions_table)
 		return -ENOMEM;
-	mutex_init(&icc_info->sessions_table->lock);
-	icc_info->sessions_table->nfree = MAX_ENDPOINTS;
+	mutex_init(&sessions_table->lock);
+	sessions_table->nfree = MAX_ENDPOINTS;
 	return 0;
 }
 
 static int sm_message_enqueue(int dstcpu, int srccpu, struct sm_msg *msg)
 {
-	struct sm_message_queue *outqueue = &icc_info->icc_queue[dstcpu];
+	struct sm_message_queue *outqueue = &bfin_icc->icc_info.icc_queue[dstcpu];
 	uint16_t sent = sm_atomic_read(&outqueue->sent);
 	uint16_t received = sm_atomic_read(&outqueue->received);
 	if ((sent - received) >= (SM_MSGQ_LEN - 1)) {
@@ -93,7 +121,7 @@ static int sm_message_enqueue(int dstcpu, int srccpu, struct sm_msg *msg)
 
 static int sm_message_dequeue(int srccpu, struct sm_msg *msg)
 {
-	struct sm_message_queue *inqueue = &icc_info->icc_queue[srccpu];
+	struct sm_message_queue *inqueue = &bfin_icc->icc_info.icc_queue[srccpu];
 	uint16_t received;
 	memset(msg, 0, sizeof(struct sm_msg));
 	received = sm_atomic_read(&inqueue->received);
@@ -151,7 +179,7 @@ found_slot:
 
 static int sm_create_session(uint32_t src_ep, uint32_t type)
 {
-	struct sm_session_table *table = icc_info->sessions_table;
+	struct sm_session_table *table = bfin_icc->icc_info.sessions_table;
 	int index = sm_find_session(src_ep, 0, table);
 	if (index >= 0 && index < 32) {
 		sm_debug("already bound index %d srcep %d\n", index, src_ep);
@@ -171,7 +199,7 @@ static int sm_create_session(uint32_t src_ep, uint32_t type)
 		table->sessions[index].n_uncompleted = 0;
 		table->sessions[index].n_avail = 0;
 		table->sessions[index].type = type;
-		table->sessions[index].proto_ops = sm_protos[type];
+		table->sessions[index].proto_ops = bfin_icc->sm_protos[type];
 		INIT_LIST_HEAD(&table->sessions[index].rx_messages);
 		INIT_LIST_HEAD(&table->sessions[index].tx_messages);
 		init_waitqueue_head(&table->sessions[index].rx_wait);
@@ -185,7 +213,7 @@ static int sm_create_session(uint32_t src_ep, uint32_t type)
 static struct sm_session *sm_index_to_session(uint32_t session_idx)
 {
 	struct sm_session *session;
-	struct sm_session_table *table = icc_info->sessions_table;
+	struct sm_session_table *table = bfin_icc->icc_info.sessions_table;
 	if (session_idx < 0 && session_idx >= MAX_SESSIONS)
 		return NULL;
 	if (!test_bit(session_idx, (unsigned long *)table->bits))
@@ -196,7 +224,7 @@ static struct sm_session *sm_index_to_session(uint32_t session_idx)
 
 static uint32_t sm_session_to_index(struct sm_session *session)
 {
-	struct sm_session_table *table = icc_info->sessions_table;
+	struct sm_session_table *table = bfin_icc->icc_info.sessions_table;
 	if ((session >= &table->sessions[0])
 		&& (session < &table->sessions[MAX_SESSIONS])) {
 		return (session - &table->sessions[0])/sizeof(struct sm_session);
@@ -206,7 +234,7 @@ static uint32_t sm_session_to_index(struct sm_session *session)
 
 static int iccqueue_getpending(uint32_t srccpu)
 {
-	struct sm_message_queue *inqueue = &icc_info->icc_queue[srccpu];
+	struct sm_message_queue *inqueue = &bfin_icc->icc_info.icc_queue[srccpu];
 	uint16_t sent = sm_atomic_read(&inqueue->sent);
 	uint16_t received = sm_atomic_read(&inqueue->received);
 	uint16_t pending;
@@ -425,7 +453,7 @@ sm_send_scalar(uint32_t session_idx, uint32_t dst_ep, uint32_t dst_cpu,
 retry:
 	ret = sm_send_message_internal(&m->msg, m->dst, m->src);
 	if ((!nonblock) && (ret == -EAGAIN)) {
-		interruptible_sleep_on(&icc_info->iccq_tx_wait);
+		interruptible_sleep_on(&bfin_icc->icc_info.iccq_tx_wait);
 		goto retry;
 	} else {
 		goto out;
@@ -498,13 +526,13 @@ retry:
 	ret = sm_send_message_internal(&m->msg, m->dst, m->src);
 	if (ret == -EAGAIN) {
 		if (nonblock) {
-			mutex_lock(&icc_info->sessions_table->lock);
+			mutex_lock(&bfin_icc->icc_info.sessions_table->lock);
 			list_del(&m->next);
-			mutex_unlock(&icc_info->sessions_table->lock);
+			mutex_unlock(&bfin_icc->icc_info.sessions_table->lock);
 			goto fail2;
 		}
 		sm_debug(">>>>sleep on send queue\n");
-		interruptible_sleep_on(&icc_info->iccq_tx_wait);
+		interruptible_sleep_on(&bfin_icc->icc_info.iccq_tx_wait);
 		sm_debug("<<<<wakeup send queue\n");
 		goto retry;
 	} else {
@@ -547,12 +575,12 @@ static int sm_recv_scalar(uint32_t session_idx, uint32_t *src_ep,
 		return -EINTR;
 	}
 
-	mutex_lock(&icc_info->sessions_table->lock);
+	mutex_lock(&bfin_icc->icc_info.sessions_table->lock);
 	message = list_first_entry(&session->rx_messages, struct sm_message, next);
 	msg = &message->msg;
 
 	list_del(&message->next);
-	mutex_unlock(&icc_info->sessions_table->lock);
+	mutex_unlock(&bfin_icc->icc_info.sessions_table->lock);
 
 	if (src_ep)
 		*src_ep = msg->src_ep;
@@ -618,11 +646,11 @@ static int sm_recv_packet(uint32_t session_idx, uint32_t *src_ep,
 		return -EINTR;
 	}
 
-	mutex_lock(&icc_info->sessions_table->lock);
+	mutex_lock(&bfin_icc->icc_info.sessions_table->lock);
 	message = list_first_entry(&session->rx_messages, struct sm_message, next);
 	msg = &message->msg;
 	list_del(&message->next);
-	mutex_unlock(&icc_info->sessions_table->lock);
+	mutex_unlock(&bfin_icc->icc_info.sessions_table->lock);
 
 	if (src_ep)
 		*src_ep = msg->src_ep;
@@ -751,12 +779,12 @@ static int sm_destroy_session(uint32_t session_idx)
 	struct sm_message *message;
 	struct sm_msg *msg;
 	struct sm_session *session;
-	struct sm_session_table *table = icc_info->sessions_table;
+	struct sm_session_table *table = bfin_icc->icc_info.sessions_table;
 	session = sm_index_to_session(session_idx);
 	if (!session)
 		return -EINVAL;
 
-	mutex_lock(&icc_info->sessions_table->lock);
+	mutex_lock(&table->lock);
 	while (!list_empty(&session->rx_messages)) {
 		sm_debug("drain rx list\n");
 		message = list_first_entry(&session->rx_messages,
@@ -772,19 +800,19 @@ static int sm_destroy_session(uint32_t session_idx)
 		list_del(&message->next);
 		kfree(message);
 	}
-	mutex_unlock(&icc_info->sessions_table->lock);
+	mutex_unlock(&table->lock);
 
-	mutex_lock(&icc_info->sessions_table->lock);
+	mutex_lock(&table->lock);
 	while (!list_empty(&session->tx_messages)) {
-		mutex_unlock(&icc_info->sessions_table->lock);
+		mutex_unlock(&table->lock);
 		set_current_state(TASK_INTERRUPTIBLE);
 		sm_debug("drain tx list\n");
 		schedule_timeout(HZ * 2);
 		sm_debug("drain tx list1\n");
 		set_current_state(TASK_RUNNING);
-		mutex_lock(&icc_info->sessions_table->lock);
+		mutex_lock(&table->lock);
 	}
-	mutex_unlock(&icc_info->sessions_table->lock);
+	mutex_unlock(&table->lock);
 
 	if (session->flags == SM_CONNECT) {
 		sm_send_close(session, session->remote_ep, 1);
@@ -805,7 +833,7 @@ static int
 icc_open(struct inode *inode, struct file *file)
 {
 	int ret = 0;
-	struct sm_session_table *table = icc_info->sessions_table;
+	struct sm_session_table *table = bfin_icc->icc_info.sessions_table;
 	table->refcnt++;
 	return ret;
 }
@@ -814,7 +842,7 @@ static int
 icc_release(struct inode *inode, struct file *file)
 {
 	int ret = 0;
-	struct sm_session_table *table = icc_info->sessions_table;
+	struct sm_session_table *table = bfin_icc->icc_info.sessions_table;
 	int i;
 	pid_t pid = current->pid;
 	table->refcnt--;
@@ -830,11 +858,12 @@ int icc_get_node_status(void *user_param, uint32_t size)
 {
 	int ret = 0;
 	struct sm_node_status *param = kzalloc(sizeof(struct sm_node_status), GFP_KERNEL);
+	struct sm_session_table *table = bfin_icc->icc_info.sessions_table;
 	if (!param)
 		return -ENOMEM;
-	param->session_mask = icc_info->sessions_table->session_mask;
-	param->session_pending = icc_info->sessions_table->session_pending;
-	param->nfree = icc_info->sessions_table->nfree;
+	param->session_mask = table->session_mask;
+	param->session_pending = table->session_pending;
+	param->nfree = table->nfree;
 	if (copy_to_user(user_param, (void *)param, size))
 		ret = -EFAULT;
 
@@ -890,7 +919,7 @@ int icc_handle_scalar_cmd(struct sm_msg *msg)
 
 	switch (SM_SCALAR_CMDARG(scalar0)) {
 	case SM_SCALAR_CMD_GET_SESSION_ID:
-		index = sm_find_session(scalar1, 0, icc_info->sessions_table);
+		index = sm_find_session(scalar1, 0, bfin_icc->icc_info.sessions_table);
 		session = sm_index_to_session(index);
 		if (session) {
 			scalar0 = MK_SM_SCALAR_CMD_ACK(SM_SCALAR_CMD_GET_SESSION_ID);
@@ -1015,7 +1044,7 @@ unsigned int icc_poll(struct file *file, poll_table *wait)
 	int cpu = blackfin_core_id();
 	int pending;
 
-	poll_wait(file, &icc_info->iccq_rx_wait, wait);
+	poll_wait(file, &bfin_icc->icc_info.iccq_rx_wait, wait);
 
 	pending = iccqueue_getpending(cpu);
 	if (pending)
@@ -1033,13 +1062,6 @@ static const struct file_operations icc_fops = {
 	.poll		= icc_poll,
 };
 
-static struct miscdevice icc_dev = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name  = "icc",
-	.fops  = &icc_fops,
-};
-
-
 static int msg_recv_internal(struct sm_msg *msg, struct sm_session *session)
 {
 	int cpu = blackfin_core_id();
@@ -1065,12 +1087,12 @@ static int msg_recv_internal(struct sm_msg *msg, struct sm_session *session)
 		session->handle(message, session);
 		return 0;
 	}
-	mutex_lock(&icc_info->sessions_table->lock);
+	mutex_lock(&bfin_icc->icc_info.sessions_table->lock);
 	list_add_tail(&message->next, &session->rx_messages);
 	session->n_avail++;
 	sm_debug("%s wakeup wait thread avail %d\n", __func__, (int)session->n_avail);
 	wake_up(&session->rx_wait);
-	mutex_unlock(&icc_info->sessions_table->lock);
+	mutex_unlock(&bfin_icc->icc_info.sessions_table->lock);
 	return ret;
 }
 
@@ -1086,10 +1108,10 @@ static int sm_default_sendmsg(struct sm_message *message, struct sm_session *ses
 		flush_dcache_range(msg->payload, msg->payload + msg->length);
 	case SP_SCALAR:
 	case SP_SESSION_SCALAR:
-		mutex_lock(&icc_info->sessions_table->lock);
+		mutex_lock(&bfin_icc->icc_info.sessions_table->lock);
 		list_add_tail(&message->next, &session->tx_messages);
 		session->n_uncompleted++;
-		mutex_unlock(&icc_info->sessions_table->lock);
+		mutex_unlock(&bfin_icc->icc_info.sessions_table->lock);
 		break;
 	case SM_PACKET_ERROR:
 		sm_debug("SM ERROR %08x\n", (uint32_t)msg->payload);
@@ -1106,11 +1128,12 @@ sm_default_recvmsg(struct sm_msg *msg, struct sm_session *session)
 	int ret = 0;
 	int cpu = blackfin_core_id();
 	struct sm_message *uncompleted;
+	struct sm_session_table *table = bfin_icc->icc_info.sessions_table;
 	sm_debug("%s msg type %x\n", __func__, (uint32_t)msg->type);
 	switch (msg->type) {
 	case SM_PACKET_CONSUMED:
 	case SM_SESSION_PACKET_CONSUMED:
-		mutex_lock(&icc_info->sessions_table->lock);
+		mutex_lock(&table->lock);
 		/* icc queue is FIFO, so handle first message */
 		list_for_each_entry(uncompleted, &session->tx_messages, next) {
 			if (uncompleted->msg.payload == msg->payload) {
@@ -1118,19 +1141,19 @@ sm_default_recvmsg(struct sm_msg *msg, struct sm_session *session)
 				goto matched;
 			}
 		}
-		mutex_unlock(&icc_info->sessions_table->lock);
+		mutex_unlock(&table->lock);
 		break;
 matched:
 		list_del(&uncompleted->next);
-		mutex_unlock(&icc_info->sessions_table->lock);
+		mutex_unlock(&table->lock);
 		kfree(uncompleted);
 		kfree((void *)msg->payload);
 		session->n_uncompleted--;
-		wake_up(&icc_info->iccq_tx_wait);
+		wake_up(&bfin_icc->icc_info.iccq_tx_wait);
 		break;
 	case SM_SCALAR_CONSUMED:
 	case SM_SESSION_SCALAR_CONSUMED:
-		mutex_lock(&icc_info->sessions_table->lock);
+		mutex_lock(&table->lock);
 		/* icc queue is FIFO, so handle first message */
 		list_for_each_entry(uncompleted, &session->tx_messages, next) {
 			if (uncompleted->msg.payload == msg->payload) {
@@ -1138,14 +1161,14 @@ matched:
 				goto matched1;
 			}
 		}
-		mutex_unlock(&icc_info->sessions_table->lock);
+		mutex_unlock(&table->lock);
 		break;
 matched1:
 		list_del(&uncompleted->next);
-		mutex_unlock(&icc_info->sessions_table->lock);
+		mutex_unlock(&table->lock);
 		kfree(uncompleted);
 		session->n_uncompleted--;
-		wake_up(&icc_info->iccq_tx_wait);
+		wake_up(&bfin_icc->icc_info.iccq_tx_wait);
 		break;
 	case SM_SESSION_PACKET_CONNECT_ACK:
 	case SM_SESSION_SCALAR_CONNECT_ACK:
@@ -1323,7 +1346,7 @@ struct sm_proto session_scalar_proto = {
 
 void msg_handle(int cpu)
 {
-	struct sm_message_queue *inqueue = &icc_info->icc_queue[cpu];
+	struct sm_message_queue *inqueue = &bfin_icc->icc_info.icc_queue[cpu];
 	uint16_t received = sm_atomic_read(&inqueue->received);
 	struct sm_msg *msg;
 	struct sm_session *session;
@@ -1337,7 +1360,7 @@ void msg_handle(int cpu)
 		return;
 	}
 
-	index = sm_find_session(msg->dst_ep, 0, icc_info->sessions_table);
+	index = sm_find_session(msg->dst_ep, 0, bfin_icc->icc_info.sessions_table);
 
 	session = sm_index_to_session(index);
 	sm_debug("session %p index %d msg type%x\n", session, index, (uint32_t)msg->type);
@@ -1345,7 +1368,7 @@ void msg_handle(int cpu)
 	if (!session) {
 		sm_debug("discard msg type %x\n", (uint32_t)msg->type);
 		sm_message_dequeue(cpu, msg);
-		wake_up(&icc_info->iccq_tx_wait);
+		wake_up(&bfin_icc->icc_info.iccq_tx_wait);
 		return;
 	}
 
@@ -1378,15 +1401,15 @@ static int message_queue_thread(void *d)
 	return 0;
 }
 
-void register_sm_proto(void)
+void register_sm_proto(struct bfin_icc *icc)
 {
-	sm_protos[SP_CORE_CONTROL] = &core_control_proto;
-	sm_protos[SP_TASK_MANAGER] = &task_manager_proto;
-	sm_protos[SP_RES_MANAGER] = &res_manager_proto;
-	sm_protos[SP_PACKET] = &packet_proto;
-	sm_protos[SP_SESSION_PACKET] = &session_packet_proto;
-	sm_protos[SP_SCALAR] = &scalar_proto;
-	sm_protos[SP_SESSION_SCALAR] = &session_scalar_proto;
+	icc->sm_protos[SP_CORE_CONTROL] = &core_control_proto;
+	icc->sm_protos[SP_TASK_MANAGER] = &task_manager_proto;
+	icc->sm_protos[SP_RES_MANAGER] = &res_manager_proto;
+	icc->sm_protos[SP_PACKET] = &packet_proto;
+	icc->sm_protos[SP_SESSION_PACKET] = &session_packet_proto;
+	icc->sm_protos[SP_SCALAR] = &scalar_proto;
+	icc->sm_protos[SP_SESSION_SCALAR] = &session_scalar_proto;
 }
 
 static int
@@ -1397,7 +1420,7 @@ icc_write_proc(struct file *file, const char __user * buffer,
 	unsigned long val;
 	int ret;
 	struct sm_session *session;
-	struct sm_session_table *table = icc_info->sessions_table;
+	struct sm_session_table *table = bfin_icc->icc_info.sessions_table;
 
 	ret = copy_from_user(line, buffer, count);
 	if (ret)
@@ -1418,16 +1441,88 @@ icc_write_proc(struct file *file, const char __user * buffer,
 	return count;
 }
 
-static int __init bfin_icc_test_init(void)
+static irqreturn_t ipi_handler_int0(int irq, void *dev_instance)
 {
-	int ret = 0;
+	unsigned int cpu = blackfin_core_id();
 
-	ret = icc_init();
-	init_sm_message_queue();
+	platform_clear_ipi(cpu, ICC_LOW_RECV);
 
-	init_sm_session_table();
+	wakeup_icc_thread();
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
+{
+	unsigned int cpu = blackfin_core_id();
 
-	register_sm_proto();
+	platform_clear_ipi(cpu, ICC_HIGH_RECV);
+	return IRQ_HANDLED;
+}
+
+static int __devinit bfin_icc_probe(struct platform_device *pdev)
+{
+	struct bfin_icc *icc = NULL;
+	struct sm_icc_desc *icc_info;
+	int ret;
+
+	if (bfin_icc) {
+		dev_err(&pdev->dev, "Can't register more than one bfin_icc device.\n");
+		return -ENOENT;
+	}
+
+	icc = kzalloc(sizeof(*icc), GFP_KERNEL);
+	if (!icc) {
+		dev_err(&pdev->dev, "fail to malloc bfin_icc\n");
+		return -ENOMEM;
+	}
+
+	mutex_init(&icc->mutex);
+	icc->mdev.minor	= MISC_DYNAMIC_MINOR;
+	snprintf(icc->name, 20, "%s", DRIVER_NAME);
+	icc->mdev.name	= icc->name;
+	icc->mdev.fops	= &icc_fops;
+
+	icc->low_irq = platform_get_irq(pdev, 0);
+	if (icc->low_irq < 0) {
+		dev_err(&pdev->dev, "No ICC Low IRQ specified\n");
+		ret = -ENOENT;
+		goto out_error_free_mem;
+	}
+
+	ret = request_irq(icc->low_irq, ipi_handler_int0, IRQF_PERCPU,
+				"ICC Low IRQ", icc);
+	if (ret) {
+		dev_err(&pdev->dev, "Fail to request ICC Low IRQ\n");
+		goto out_error_free_mem;
+	}
+
+	icc->high_irq = platform_get_irq(pdev, 1);
+	if (icc->high_irq < 0) {
+		dev_err(&pdev->dev, "No ICC High IRQ specified\n");
+		ret = -ENOENT;
+		goto out_error_free_low_irq;
+	}
+
+	ret = request_irq(icc->high_irq, ipi_handler_int1, IRQF_PERCPU,
+				"ICC High IRQ", icc);
+	if (ret) {
+		dev_err(&pdev->dev, "Fail to request ICC High IRQ\n");
+		goto out_error_free_low_irq;
+	}
+
+	ret = misc_register(&icc->mdev);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot register ICC miscdev\n");
+		return ret;
+	}
+
+	init_sm_message_queue(icc);
+
+	init_sm_session_table(icc);
+
+	register_sm_proto(icc);
+
+	icc_info = &icc->icc_info;
 
 	init_waitqueue_head(&icc_info->iccq_rx_wait);
 	init_waitqueue_head(&icc_info->iccq_tx_wait);
@@ -1436,16 +1531,52 @@ static int __init bfin_icc_test_init(void)
 	if (IS_ERR(icc_info->iccq_thread))
 		sm_debug("kthread create failed %ld\n", PTR_ERR(icc_info->iccq_thread));
 
-	icc_dump = create_proc_entry("icc_dump", 644, NULL);
-	icc_dump->write_proc = icc_write_proc;
-	return misc_register(&icc_dev);
+	icc->icc_dump = create_proc_entry("icc_dump", 644, NULL);
+	icc->icc_dump->write_proc = icc_write_proc;
+
+	dev_set_drvdata(&pdev->dev, icc);
+	bfin_icc = icc;
+
+	dev_info(&pdev->dev, "initialized\n");
+
+	return 0;
+
+out_error_free_low_irq:
+	free_irq(icc->low_irq, icc);
+out_error_free_mem:
+	kfree(icc);
+	return ret;
 }
-module_init(bfin_icc_test_init);
 
-static void __exit bfin_icc_test_exit(void)
+static int __devexit bfin_icc_remove(struct platform_device *pdev)
 {
-	misc_deregister(&icc_dev);
+	struct bfin_icc *icc = platform_get_drvdata(pdev);
+
+	bfin_icc = NULL;
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	if (icc) {
+		misc_deregister(&icc->mdev);
+		free_irq(icc->high_irq, icc);
+		free_irq(icc->low_irq, icc);
+		kfree(icc);
+	}
+
+	return 0;
 }
-module_exit(bfin_icc_test_exit);
 
-MODULE_DESCRIPTION("BFIN ICC"); MODULE_LICENSE("GPL");
+static struct platform_driver bfin_icc_driver = {
+	.probe     = bfin_icc_probe,
+	.remove    = __devexit_p(bfin_icc_remove),
+	.driver    = {
+		.name  = DRIVER_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+module_platform_driver(bfin_icc_driver);
+
+MODULE_AUTHOR("Steven Miao <[email protected]>");
+MODULE_DESCRIPTION("Blackfin ICC driver");
+MODULE_LICENSE("GPL");
+
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to