summaryrefslogtreecommitdiff
path: root/drivers/misc/mdbg
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
committerYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
commit8e4bff4cab0ddac6060645b0715210484d02ff40 (patch)
tree3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/misc/mdbg
Initial file dump from open source releaseHEADmaster
Diffstat (limited to 'drivers/misc/mdbg')
-rw-r--r--drivers/misc/mdbg/Kconfig24
-rw-r--r--drivers/misc/mdbg/Makefile9
-rw-r--r--drivers/misc/mdbg/mdbg.c621
-rw-r--r--drivers/misc/mdbg/mdbg.h24
-rw-r--r--drivers/misc/mdbg/mdbg_ring.c234
-rw-r--r--drivers/misc/mdbg/mdbg_ring.h54
-rw-r--r--drivers/misc/mdbg/mdbg_sdio.c158
-rw-r--r--drivers/misc/mdbg/mdbg_sdio.h37
-rw-r--r--drivers/misc/mdbg/mdbg_type.h65
9 files changed, 1226 insertions, 0 deletions
diff --git a/drivers/misc/mdbg/Kconfig b/drivers/misc/mdbg/Kconfig
new file mode 100644
index 00000000..8da0c1c4
--- /dev/null
+++ b/drivers/misc/mdbg/Kconfig
@@ -0,0 +1,24 @@
+
+menu "MARLIN DEBUG modules"
+config MDBG_SDIO
+ bool "MDBG SDIO INTERFACE"
+ default y
+ help
+ FOR MDBG SDIO INTERFACE
+
+config MDBG_RING
+ bool "MDBG RING BUFFER"
+ default y
+ help
+ FOR MDBG RING BUFFER
+
+config MDBG
+ tristate "MDBG"
+ depends on SDIODEV
+ depends on MDBG_RING
+ help
+ DEBUG SYSTEM FOR MARLIN.
+ If unsure, say N.
+
+
+endmenu
diff --git a/drivers/misc/mdbg/Makefile b/drivers/misc/mdbg/Makefile
new file mode 100644
index 00000000..db378e8d
--- /dev/null
+++ b/drivers/misc/mdbg/Makefile
@@ -0,0 +1,9 @@
+#mdbgdrv
+obj-$(CONFIG_MDBG) := mdbgdrv.o
+
+mdbgdrv-c-objs += mdbg_ring.o
+mdbgdrv-c-objs += mdbg_sdio.o
+mdbgdrv-c-objs += mdbg.o
+
+mdbgdrv-objs += $(mdbgdrv-c-objs)
+
diff --git a/drivers/misc/mdbg/mdbg.c b/drivers/misc/mdbg/mdbg.c
new file mode 100644
index 00000000..d377e481
--- /dev/null
+++ b/drivers/misc/mdbg/mdbg.c
@@ -0,0 +1,621 @@
+/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg.c */
+/*****Description: Marlin Debug System main file. Module,device & driver related defination. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/01/2014 */
+/************************************************************************************************************ */
+
+#include "mdbg.h"
+#include "mdbg_sdio.h"
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+
+#define MDBG_MAX_BUFFER_LEN (PAGE_SIZE)
+
+#define MDBG_WCN_WRITE (5)
+#define MDBG_CHANNEL_ASSERT (13)
+#define MDBG_CHANNEL_WDTIRQ (4)
+#define MDBG_CHANNEL_LOOPCHECK (15)
+#define MDBG_CHANNEL_AT_CMD (11)
+
+#define MDBG_WRITE_SIZE (64)
+#define MDBG_ASSERT_SIZE (1024)
+#define MDBG_WDTIRQ_SIZE (128)
+#define MDBG_LOOPCHECK_SIZE (128)
+#define MDBG_AT_CMD_SIZE (128)
+
+unsigned int mdbg_read_count = 0;
+unsigned int first_boot = 0;
+
+struct mdbg_devvice_t *mdbg_dev=NULL;
+wait_queue_head_t mdbg_wait;
+
+struct mdbg_proc_entry {
+ char *name;
+ struct proc_dir_entry *entry;
+ struct completion completed;
+ wait_queue_head_t rxwait;
+ unsigned int rcv_len;
+ void *buf;
+};
+
+struct mdbg_proc_t{
+ char *dir_name;
+ struct proc_dir_entry *procdir;
+ struct mdbg_proc_entry assert;
+ struct mdbg_proc_entry wdtirq;
+ struct mdbg_proc_entry loopcheck;
+ struct mdbg_proc_entry at_cmd;
+ char write_buf[MDBG_WRITE_SIZE];
+};
+
+static struct mdbg_proc_t *mdbg_proc=NULL;
+
+
+void mdbg_assert_interface(void)
+{
+ strncpy(mdbg_proc->assert.buf,"wifi channel is blocked",23);
+ printk(KERN_INFO "mdbg_assert_interface:%s\n",mdbg_proc->assert.buf);
+ mdbg_proc->assert.rcv_len = 23;
+ complete(&mdbg_proc->assert.completed);
+ wake_up_interruptible(&mdbg_proc->assert.rxwait);
+
+ return;
+}
+EXPORT_SYMBOL_GPL(mdbg_assert_interface);
+
+void mdbg_assert_read(void)
+{
+ int read_len;
+ read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_ASSERT);
+ if(read_len <= 0){
+ return;
+ }
+
+ if(read_len > MDBG_ASSERT_SIZE)
+ MDBG_ERR( "The assert data len:%d, beyond max read:%d",read_len,MDBG_ASSERT_SIZE);
+
+ sdio_dev_read(MDBG_CHANNEL_ASSERT,mdbg_proc->assert.buf,&read_len);
+ printk(KERN_INFO "mdbg_assert_read:%s\n",mdbg_proc->assert.buf);
+ mdbg_proc->assert.rcv_len = read_len;
+ complete(&mdbg_proc->assert.completed);
+ wake_up_interruptible(&mdbg_proc->assert.rxwait);
+
+ return;
+}
+EXPORT_SYMBOL_GPL(mdbg_assert_read);
+
+void mdbg_wdtirq_read(void)
+{
+ int read_len;
+ read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_WDTIRQ);
+ if(read_len <= 0){
+ return;
+ }
+
+ if(read_len > MDBG_WDTIRQ_SIZE)
+ MDBG_ERR( "The assert data len:%d, beyond max read:%d",read_len,MDBG_WDTIRQ_SIZE);
+
+ sdio_dev_read(MDBG_CHANNEL_WDTIRQ,mdbg_proc->wdtirq.buf,&read_len);
+ printk(KERN_INFO "mdbg_wdtirq_read:%s\n",mdbg_proc->wdtirq.buf);
+ mdbg_proc->wdtirq.rcv_len = read_len;
+ complete(&mdbg_proc->wdtirq.completed);
+ wake_up_interruptible(&mdbg_proc->wdtirq.rxwait);
+
+ return;
+}
+EXPORT_SYMBOL_GPL(mdbg_wdtirq_read);
+
+void mdbg_loopcheck_read(void)
+{
+ int read_len;
+
+ read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_LOOPCHECK);
+ if(read_len <= 0){
+ return;
+ }
+
+ if(read_len > MDBG_LOOPCHECK_SIZE)
+ MDBG_ERR( "The loopcheck data len:%d, beyond max read:%d",read_len,MDBG_LOOPCHECK_SIZE);
+
+ sdio_dev_read(MDBG_CHANNEL_LOOPCHECK,mdbg_proc->loopcheck.buf,&read_len);
+ printk(KERN_INFO "mdbg_loopcheck_read:%s\n",mdbg_proc->loopcheck.buf);
+ mdbg_proc->loopcheck.rcv_len = read_len;
+ complete(&mdbg_proc->loopcheck.completed);
+
+ return;
+}
+EXPORT_SYMBOL_GPL(mdbg_loopcheck_read);
+
+void mdbg_at_cmd_read(void)
+{
+ int read_len;
+
+ read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_AT_CMD);
+ if(read_len <= 0){
+ MDBG_ERR("MDBG_CHANNEL_AT_CMD len err\n");
+ return;
+ }
+
+ if(read_len > MDBG_AT_CMD_SIZE)
+ MDBG_ERR( "The at cmd data len:%d, beyond max read:%d",read_len,MDBG_AT_CMD_SIZE);
+
+ sdio_dev_read(MDBG_CHANNEL_AT_CMD,mdbg_proc->at_cmd.buf,&read_len);
+ mdbg_proc->at_cmd.rcv_len = read_len;
+ printk(KERN_INFO "mdbg_at_cmd_read:%s\n",mdbg_proc->at_cmd.buf);
+ complete(&mdbg_proc->at_cmd.completed);
+
+ return;
+}
+EXPORT_SYMBOL_GPL(mdbg_at_cmd_read);
+
+static int mdbg_proc_open(struct inode *inode, struct file *filp)
+{
+ struct mdbg_proc_entry *entry = (struct mdbg_proc_entry *)PDE_DATA(inode);
+ char *type = entry->name;
+
+ filp->private_data = entry;
+ //MDBG_ERR("%s type:%s\n",__func__,type);
+
+ return 0;
+}
+
+static int mdbg_proc_release(struct inode *inode, struct file *filp)
+{
+ struct mdbg_proc_entry *entry = (struct mdbg_proc_entry *)PDE_DATA(inode);
+ char *type = entry->name;
+
+ //MDBG_ERR("%s type:%s\n",__func__,type);
+
+ return 0;
+}
+
+static ssize_t mdbg_proc_read(struct file *filp,
+ char __user *buf, size_t count, loff_t *ppos)
+{
+ struct mdbg_proc_entry *entry = (struct mdbg_proc_entry *)filp->private_data;
+ char *type = entry->name;
+ int timeout = -1;
+ int len = 0;
+ int ret;
+
+ //printk(KERN_INFO "type:%s\n",type);
+ if (filp->f_flags & O_NONBLOCK) {
+ timeout = 0;
+ }
+
+ if(strcmp(type, "assert") == 0) {
+ if (timeout < 0){
+ while(1){
+ ret = wait_for_completion_timeout(&mdbg_proc->assert.completed,msecs_to_jiffies(1000));
+ if (ret != -ERESTARTSYS)
+ break;
+ }
+ }
+
+ if(copy_to_user((void __user *)buf, mdbg_proc->assert.buf, min(count,(size_t)MDBG_ASSERT_SIZE))){
+ MDBG_ERR( "Read assert info error\n");
+ }
+ len = mdbg_proc->assert.rcv_len;
+ mdbg_proc->assert.rcv_len = 0;
+ memset(mdbg_proc->assert.buf,0,MDBG_ASSERT_SIZE);
+ }
+
+ if(strcmp(type, "wdtirq") == 0) {
+ if (timeout < 0){
+ while(1){
+ ret = wait_for_completion_timeout(&mdbg_proc->wdtirq.completed,msecs_to_jiffies(1000));
+ if (ret != -ERESTARTSYS)
+ break;
+ }
+ }
+
+ if(copy_to_user((void __user *)buf, mdbg_proc->wdtirq.buf, min(count,(size_t)MDBG_WDTIRQ_SIZE))){
+ MDBG_ERR( "Read wdtirq info error\n");
+ }
+
+ len = mdbg_proc->wdtirq.rcv_len;
+ mdbg_proc->wdtirq.rcv_len = 0;
+ memset(mdbg_proc->wdtirq.buf,0,MDBG_WDTIRQ_SIZE);
+ }
+
+ if(strcmp(type, "loopcheck") == 0) {
+ if (timeout < 0){
+ while(1){
+ ret = wait_for_completion_timeout(&mdbg_proc->loopcheck.completed,msecs_to_jiffies(1000));
+ if (ret != -ERESTARTSYS)
+ break;
+ }
+ }
+
+ if(first_boot < 2){
+ if(copy_to_user((void __user *)buf, "loopcheck_ack", 13)){
+ MDBG_ERR("Read loopcheck first info error\n");
+ }
+ first_boot++;
+ len = 13;
+ }else if(get_sprd_marlin_status()){
+ if(copy_to_user((void __user *)buf, "loopcheck_ack", 13)){
+ MDBG_ERR("loopcheck gpio info error\n");
+ }
+ len = 13;
+ }else{
+ if(copy_to_user((void __user *)buf, mdbg_proc->loopcheck.buf, min(count,(size_t)MDBG_LOOPCHECK_SIZE))){
+ MDBG_ERR("Read loopcheck sdio info error\n");
+ }
+ len = mdbg_proc->loopcheck.rcv_len;
+ }
+ memset(mdbg_proc->loopcheck.buf,0,MDBG_LOOPCHECK_SIZE);
+ mdbg_proc->loopcheck.rcv_len = 0;
+ }
+
+ if(strcmp(type, "at_cmd") == 0) {
+ if (timeout < 0){
+ while(1){
+ ret = wait_for_completion_timeout(&mdbg_proc->at_cmd.completed,msecs_to_jiffies(1000));
+ if (ret != -ERESTARTSYS)
+ break;
+ }
+ }
+
+ if(copy_to_user((void __user *)buf, mdbg_proc->at_cmd.buf, min(count,(size_t)MDBG_AT_CMD_SIZE))){
+ MDBG_ERR("Read at cmd ack info error\n");
+ }
+
+ len = mdbg_proc->at_cmd.rcv_len;
+ mdbg_proc->at_cmd.rcv_len = 0;
+ memset(mdbg_proc->at_cmd.buf,0,MDBG_AT_CMD_SIZE);
+ }
+
+ return len;
+}
+
+static ssize_t mdbg_proc_write(struct file *filp,
+ const char __user *buf, size_t count, loff_t *ppos)
+{
+ int cnt = 0;
+ if(count > MDBG_WRITE_SIZE){
+ MDBG_ERR( "mdbg_proc_write count > MDBG_WRITE_SIZE\n");
+ return -ENOMEM;
+ }
+ memset(mdbg_proc->write_buf,0,MDBG_WRITE_SIZE);
+
+ if (copy_from_user(mdbg_proc->write_buf,buf,count )){
+ return -EFAULT;
+ }
+
+ printk(KERN_INFO "mdbg_proc->write_buf:%s\n",mdbg_proc->write_buf);
+
+ if(strncmp(mdbg_proc->write_buf,"startwcn",8) == 0){
+ first_boot = 0;
+ return count;
+ }
+
+ if(strncmp(mdbg_proc->write_buf,"dumpwcn",7) == 0){
+ mdbg_channel_init();
+ return count;
+ }
+
+ if(strncmp(mdbg_proc->write_buf,"at+loopcheck",12) == 0){
+ printk(KERN_INFO "mdbg start wake marlin\n");
+ while((set_marlin_wakeup(MDBG_CHANNEL_WRITE,0x3) < 0) && (cnt <= 3))
+ {
+ msleep(300);
+ cnt++;
+ }
+ cnt = 0;
+ }
+ else{
+ mdbg_send(mdbg_proc->write_buf , count, MDBG_WCN_WRITE);
+ }
+
+ return count;
+}
+
+static unsigned int mdbg_proc_poll(struct file *filp, poll_table *wait)
+{
+ struct mdbg_proc_entry *entry = (struct mdbg_proc_entry *)filp->private_data;
+ char *type = entry->name;
+ unsigned int mask = 0;
+ //printk(KERN_INFO "%s type:%s\n",__func__,type);
+
+ if(strcmp(type, "assert") == 0)
+ {
+ poll_wait(filp, &mdbg_proc->assert.rxwait, wait);
+ if(mdbg_proc->assert.rcv_len > 0)
+ mask |= POLLIN | POLLRDNORM;
+ }
+
+ if(strcmp(type, "wdtirq") == 0)
+ {
+ poll_wait(filp, &mdbg_proc->wdtirq.rxwait, wait);
+ if(mdbg_proc->wdtirq.rcv_len > 0)
+ mask |= POLLIN | POLLRDNORM;
+ }
+
+ return mask;
+}
+
+struct file_operations mdbg_proc_fops = {
+ .open = mdbg_proc_open,
+ .release = mdbg_proc_release,
+ .read = mdbg_proc_read,
+ .write = mdbg_proc_write,
+ .poll = mdbg_proc_poll,
+};
+
+LOCAL void mdbg_fs_channel_init(void)
+{
+ int retval=0;
+
+ mdbg_proc->assert.buf = kzalloc(MDBG_ASSERT_SIZE, GFP_KERNEL);
+ retval = sdiodev_readchn_init(MDBG_CHANNEL_ASSERT, mdbg_assert_read,0);
+
+ mdbg_proc->wdtirq.buf = kzalloc(MDBG_WDTIRQ_SIZE, GFP_KERNEL);
+ retval = sdiodev_readchn_init(MDBG_CHANNEL_WDTIRQ, mdbg_wdtirq_read,0);
+
+ mdbg_proc->loopcheck.buf = kzalloc(MDBG_LOOPCHECK_SIZE, GFP_KERNEL);
+ retval = sdiodev_readchn_init(MDBG_CHANNEL_LOOPCHECK, mdbg_loopcheck_read,0);
+
+ mdbg_proc->at_cmd.buf = kzalloc(MDBG_AT_CMD_SIZE, GFP_KERNEL);
+ retval = sdiodev_readchn_init(MDBG_CHANNEL_AT_CMD, mdbg_at_cmd_read,0);
+}
+
+LOCAL void mdbg_fs_channel_uninit(void)
+{
+ sdiodev_readchn_uninit(MDBG_CHANNEL_ASSERT);
+ kfree(mdbg_proc->assert.buf);
+ mdbg_proc->assert.buf= NULL;
+
+ sdiodev_readchn_uninit(MDBG_CHANNEL_WDTIRQ);
+ kfree(mdbg_proc->wdtirq.buf);
+ mdbg_proc->wdtirq.buf= NULL;
+
+ sdiodev_readchn_uninit(MDBG_CHANNEL_LOOPCHECK);
+ kfree(mdbg_proc->loopcheck.buf);
+ mdbg_proc->loopcheck.buf= NULL;
+
+ sdiodev_readchn_uninit(MDBG_CHANNEL_AT_CMD);
+ kfree(mdbg_proc->at_cmd.buf);
+ mdbg_proc->at_cmd.buf= NULL;
+}
+
+
+LOCAL void mdbg_fs_init(void)
+{
+ mdbg_proc = kzalloc(sizeof(struct mdbg_proc_t), GFP_KERNEL);
+ if (!mdbg_proc)
+ return;
+
+ mdbg_proc->dir_name = "mdbg";
+ mdbg_proc->procdir = proc_mkdir(mdbg_proc->dir_name, NULL);
+
+ mdbg_proc->assert.name = "assert";
+ mdbg_proc->assert.entry = proc_create_data(mdbg_proc->assert.name, S_IRUSR |S_IWUSR,
+ mdbg_proc->procdir, &mdbg_proc_fops, &(mdbg_proc->assert));
+
+ mdbg_proc->wdtirq.name = "wdtirq";
+ mdbg_proc->wdtirq.entry = proc_create_data(mdbg_proc->wdtirq.name, S_IRUSR | S_IWUSR,
+ mdbg_proc->procdir, &mdbg_proc_fops, &(mdbg_proc->wdtirq));
+
+ mdbg_proc->loopcheck.name = "loopcheck";
+ mdbg_proc->loopcheck.entry = proc_create_data(mdbg_proc->loopcheck.name, S_IRUSR | S_IWUSR,
+ mdbg_proc->procdir, &mdbg_proc_fops, &(mdbg_proc->loopcheck));
+
+ mdbg_proc->at_cmd.name = "at_cmd";
+ mdbg_proc->at_cmd.entry = proc_create_data(mdbg_proc->at_cmd.name, S_IRUSR | S_IWUSR,
+ mdbg_proc->procdir, &mdbg_proc_fops, &(mdbg_proc->at_cmd));
+
+ mdbg_fs_channel_init();
+
+ init_completion(&mdbg_proc->assert.completed);
+ init_completion(&mdbg_proc->wdtirq.completed);
+ init_completion(&mdbg_proc->loopcheck.completed);
+ init_completion(&mdbg_proc->at_cmd.completed);
+ init_waitqueue_head(&mdbg_proc->assert.rxwait);
+ init_waitqueue_head(&mdbg_proc->wdtirq.rxwait);
+ init_waitqueue_head(&mdbg_dev->rxwait);
+}
+
+LOCAL void mdbg_fs_init_exit(void)
+{
+ mdbg_fs_channel_uninit();
+
+ remove_proc_entry(mdbg_proc->assert.name , mdbg_proc->procdir);
+ remove_proc_entry(mdbg_proc->wdtirq.name , mdbg_proc->procdir);
+ remove_proc_entry(mdbg_proc->loopcheck.name , mdbg_proc->procdir);
+ remove_proc_entry(mdbg_proc->at_cmd.name , mdbg_proc->procdir);
+ remove_proc_entry(mdbg_proc->dir_name, NULL);
+
+ kfree(mdbg_proc);
+ mdbg_proc=NULL;
+}
+
+
+LOCAL ssize_t mdbg_read(struct file *filp,char __user *buf,size_t count,loff_t *pos)
+{
+ MDBG_SIZE_T read_size;;
+ int timeout = -1;
+ int rval;
+
+ if (filp->f_flags & O_NONBLOCK) {
+ timeout = 0;
+ }
+
+ if(count > MDBG_MAX_BUFFER_LEN)
+ count = MDBG_MAX_BUFFER_LEN;
+
+ if (timeout < 0){
+ /* wait forever */
+ rval = wait_event_interruptible(mdbg_wait,mdbg_read_count > 0);
+ if (rval < 0){
+ MDBG_ERR("mdbg_read wait interrupted!\n");
+ }
+ }else{
+ //MDBG_ERR("mdbg_read no blok\n");
+ }
+
+ mutex_lock(&mdbg_dev->mdbg_lock);
+
+ if(mdbg_read_count <= 0){
+ mutex_unlock(&mdbg_dev->mdbg_lock);
+ //MDBG_ERR("data no ready");
+ return 0;
+ }
+
+ read_size = mdbg_receive(mdbg_dev->read_buf , MDBG_MAX_BUFFER_LEN);
+ printk_ratelimited(KERN_INFO "%s read_size: %d mdbg_read_count:%d\n",__func__,read_size,mdbg_read_count);
+
+ if((read_size > 0) && (read_size <= MDBG_MAX_BUFFER_LEN)){
+ MDBG_LOG("Show %d bytes data.",read_size);
+
+ if(copy_to_user((void __user *)buf,mdbg_dev->read_buf ,read_size)){
+ mutex_unlock(&mdbg_dev->mdbg_lock);
+ MDBG_ERR("copy from user fail!");
+ return -EFAULT;
+ }
+ mdbg_read_count -= read_size;
+ mutex_unlock(&mdbg_dev->mdbg_lock);
+ return read_size;
+ }else{
+ mdbg_read_count = 0;
+ mutex_unlock(&mdbg_dev->mdbg_lock);
+ MDBG_LOG("Show no data");
+ return (0);
+ }
+}
+
+LOCAL ssize_t mdbg_write(struct file *filp, const char __user *buf,size_t count,loff_t *pos)
+{
+ MDBG_SIZE_T sent_size = 0;
+
+ if(NULL == buf || 0 == count){
+ MDBG_ERR("Param Error!");
+ return count;
+ }
+ mutex_lock(&mdbg_dev->mdbg_lock);
+
+ if (count > MDBG_MAX_BUFFER_LEN ){
+ mutex_unlock(&mdbg_dev->mdbg_lock);
+ MDBG_ERR("write too long!");
+ return -EINVAL;
+ }
+
+ memset(mdbg_dev->write_buf,0,MDBG_MAX_BUFFER_LEN);
+ if (copy_from_user(mdbg_dev->write_buf ,(void __user *)buf,count )){
+ mutex_unlock(&mdbg_dev->mdbg_lock);
+ MDBG_ERR("to user fail!");
+ return -EFAULT;
+ }
+
+ sent_size = mdbg_send(mdbg_dev->write_buf , count, MDBG_CHANNEL_WRITE);
+ mutex_unlock(&mdbg_dev->mdbg_lock);
+
+ MDBG_LOG("sent_size = %d",sent_size);
+ return count;
+}
+
+static int mdbg_open(struct inode *inode,struct file *filp)
+{
+ //printk(KERN_INFO "MDBG:%s entry\n",__func__);
+
+ if (mdbg_dev->open_count!=0) {
+ MDBG_ERR( "mdbg_open %d \n",mdbg_dev->open_count);
+ }
+
+ mdbg_dev->open_count++;
+
+ return 0;
+}
+
+static int mdbg_release(struct inode *inode,struct file *filp)
+{
+ //printk(KERN_INFO "MDBG:%s entry\n",__func__);
+
+ mdbg_dev->open_count--;
+ return 0;
+}
+
+static unsigned int mdbg_poll(struct file *filp, poll_table *wait)
+{
+ unsigned int mask = 0;
+
+ poll_wait(filp, &mdbg_dev->rxwait, wait);
+ if(mdbg_read_count > 0)
+ mask |= POLLIN | POLLRDNORM;
+
+ return mask;
+}
+
+static struct file_operations mdbg_fops = {
+ .owner = THIS_MODULE,
+ .read = mdbg_read,
+ .write = mdbg_write,
+ .open = mdbg_open,
+ .release = mdbg_release,
+ .poll = mdbg_poll,
+};
+static struct miscdevice mdbg_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "slog_wcn",
+ .fops = &mdbg_fops,
+};
+
+LOCAL int __init mdbg_module_init(void)
+{
+ int err;
+
+ MDBG_FUNC_ENTERY;
+
+ mdbg_dev = kzalloc(sizeof(*mdbg_dev), GFP_KERNEL);
+ if (!mdbg_dev)
+ return -ENOMEM;
+
+ mdbg_dev->read_buf = kzalloc(MDBG_MAX_BUFFER_LEN, GFP_KERNEL);
+ if (mdbg_dev->read_buf == NULL) {
+ MDBG_ERR("faile (NO MEM) Error!");
+ return -ENOMEM;
+ }
+ mdbg_dev->write_buf = kzalloc(MDBG_MAX_BUFFER_LEN, GFP_KERNEL);
+ if (mdbg_dev->write_buf == NULL) {
+ kfree(mdbg_dev->read_buf);
+ mdbg_dev->write_buf = NULL;
+ MDBG_ERR("faile (NO MEM) Error!");
+ return -ENOMEM;
+ }
+
+ mdbg_dev->open_count = 0;
+ mutex_init(&mdbg_dev->mdbg_lock);
+ init_waitqueue_head(&mdbg_wait);
+ err = mdbg_sdio_init();
+ if(err < 0)
+ return -ENOMEM;
+
+ mdbg_fs_init();
+
+ return misc_register(&mdbg_device);
+}
+
+LOCAL void __exit mdbg_module_exit(void)
+{
+ MDBG_FUNC_ENTERY;
+ mdbg_sdio_remove();
+ mdbg_fs_init_exit();
+ mutex_destroy(&mdbg_dev->mdbg_lock);
+ kfree(mdbg_dev->read_buf);
+ kfree(mdbg_dev->write_buf);
+ mdbg_dev->read_buf = NULL;
+ mdbg_dev->write_buf = NULL;
+ misc_deregister(&mdbg_device);
+}
+
+module_init(mdbg_module_init);
+module_exit(mdbg_module_exit);
+
+MODULE_AUTHOR("Fan Kou<fan.kou@spreadtrum.com>");
+MODULE_DESCRIPTION("MARLIN DEBUG SYSTEM.");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/misc/mdbg/mdbg.h b/drivers/misc/mdbg/mdbg.h
new file mode 100644
index 00000000..1293c5b5
--- /dev/null
+++ b/drivers/misc/mdbg/mdbg.h
@@ -0,0 +1,24 @@
+/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg.h */
+/*****Description: Marlin Debug System main file. Module,device & driver related defination. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/01/2014 */
+/************************************************************************************************************ */
+
+#ifndef _MARLIN_DEBUG_H
+#define _MARLIN_DEBUG_H
+
+
+#include "mdbg_type.h"
+
+struct mdbg_devvice_t{
+ int open_count;
+ struct mutex mdbg_lock;
+ char *read_buf;
+ char *write_buf;
+ wait_queue_head_t rxwait;
+};
+
+
+#endif
diff --git a/drivers/misc/mdbg/mdbg_ring.c b/drivers/misc/mdbg/mdbg_ring.c
new file mode 100644
index 00000000..830fc788
--- /dev/null
+++ b/drivers/misc/mdbg/mdbg_ring.c
@@ -0,0 +1,234 @@
+/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_ring.c */
+/*****Description: Marlin Debug System ring buffer implementation. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/01/2014 */
+/************************************************************************************************************ */
+
+/*******************************************************/
+/*********************INCLUDING********************/
+/*******************************************************/
+#include "mdbg_ring.h"
+
+/*******************************************************/
+/***********Local Functions Declaration************/
+/*******************************************************/
+#define MDBG_RING_LOCK_INIT(pRing) mutex_init(pRing->plock)
+#define MDBG_RING_LOCK_UNINIT(pRing) mutex_destroy(pRing->plock)
+#define MDBG_RING_LOCK(pRing) mutex_lock(pRing->plock)
+#define MDBG_RING_UNLOCK(pRing) mutex_unlock(pRing->plock)
+#define _MDBG_RING_REMAIN(rp,wp,size) ((u_long)wp >= (u_long)rp?(size - (u_long)wp + (u_long)rp - 1): ((u_long)rp - (u_long)wp -1))
+
+LOCAL MDBG_SIZE_T mdbg_ring_remain(MDBG_RING_T* pRing);
+LOCAL MDBG_SIZE_T mdbg_ring_content_len(MDBG_RING_T* pRing);
+LOCAL char* mdbg_ring_start(MDBG_RING_T* pRing);
+LOCAL char* mdbg_ring_end(MDBG_RING_T* pRing);
+LOCAL bool mdbg_ring_over_loop(MDBG_RING_T* pRing, u_long len, int rw);
+
+
+/*******************************************************/
+/******************Ring Life Cycle*******************/
+/*******************************************************/
+PUBLIC MDBG_RING_T* mdbg_ring(MDBG_SIZE_T size)
+{
+ MDBG_RING_T* pRing = NULL;
+ do{
+ if(size < MDBG_RING_MIN_SIZE){
+ MDBG_ERR("size error:%d",size);
+ break;
+ }
+ pRing = kmalloc(sizeof(MDBG_RING_T),GFP_KERNEL);
+ if(NULL == pRing){
+ MDBG_ERR("Ring malloc Failed.");
+ break;
+ }
+ pRing->pbuff = kmalloc(size,GFP_KERNEL);
+ if(NULL == pRing->pbuff){
+ MDBG_ERR("Ring buff malloc Failed.");
+ break;
+ }
+ pRing->plock = kmalloc(MDBG_RING_LOCK_SIZE, GFP_KERNEL);
+ if(NULL == pRing->plock){
+ MDBG_ERR("Ring lock malloc Failed.");
+ break;
+ }
+ MDBG_RING_LOCK_INIT(pRing);
+ memset(pRing->pbuff,0,size);
+ pRing->size = size;
+ pRing->rp = pRing->pbuff;
+ pRing->wp = pRing->pbuff;
+ pRing->end = (char*)(((u_long)pRing->pbuff) + (pRing->size - 1));
+ return (pRing);//created a MDBG_RING!
+ }while(0);
+ mdbg_ring_destroy(pRing);
+ return (NULL);//failed
+}
+
+PUBLIC void mdbg_ring_destroy(MDBG_RING_T* pRing)
+{
+ MDBG_LOG("pRing = %p",pRing);
+ MDBG_LOG("pRing->pbuff = %p",pRing->pbuff);
+ if(pRing != NULL){
+ if(pRing->pbuff != NULL){
+ MDBG_LOG("to free pRing->pbuff.");
+ kfree(pRing->pbuff);
+ pRing->pbuff = NULL;
+ }
+ if(pRing->plock != NULL){
+ MDBG_LOG("to free pRing->plock.");
+ MDBG_RING_LOCK_UNINIT(pRing);
+ kfree(pRing->plock);
+ pRing->plock = NULL;
+ }
+ MDBG_LOG("to free pRing.");
+ kfree(pRing);
+ pRing = NULL;
+ }
+ return;
+}
+
+/*******************************************************/
+/****************Ring RW Fucntions*****************/
+/*******************************************************/
+PUBLIC int mdbg_ring_read(MDBG_RING_T* pRing, char* buf, int len)
+{
+ int len1,len2 = 0;
+ int cont_len = 0;
+ int read_len = 0;
+ char* pstart = NULL;
+ char* pend = NULL;
+
+ if((NULL == buf) ||(NULL == pRing) ||(0 == len)){
+ MDBG_ERR("Ring Read Failed, Param Error!,buf=%p,pRing=%p,len=%d",buf,pRing,len);
+ return (MDBG_ERR_BAD_PARAM);
+ }
+ MDBG_RING_LOCK(pRing);
+ cont_len = mdbg_ring_content_len(pRing);
+ read_len = cont_len >= len?len:cont_len;
+ pstart = mdbg_ring_start(pRing);
+ pend = mdbg_ring_end(pRing);
+ MDBG_LOG("read_len=%d",read_len);
+ MDBG_LOG("buf=%p",buf);
+ MDBG_LOG("pstart=%p",pstart);
+ MDBG_LOG("pend=%p",pend);
+ MDBG_LOG("pRing->rp=%p",pRing->rp);
+
+ if((0 == read_len)||(0 == cont_len)){
+ MDBG_LOG("read_len=0 OR Ring Empty.");
+ MDBG_RING_UNLOCK(pRing);
+ return (0);//ring empty
+ }
+
+ if(mdbg_ring_over_loop(pRing,read_len,MDBG_RING_R)){
+ MDBG_LOG("Ring loopover.");
+ len1 = pend - pRing->rp + 1;
+ len2 = read_len -len1;
+ memcpy(buf, pRing->rp, len1);
+ memcpy((buf+ len1), pstart, len2);
+ pRing->rp = (char *)((u_long)pstart + len2);
+ }else{
+ memcpy(buf, pRing->rp, read_len);
+ pRing->rp += read_len;
+ }
+ MDBG_LOG("Ring did read len =%d.",read_len);
+ MDBG_RING_UNLOCK(pRing);
+ return (read_len);
+}
+
+PUBLIC int mdbg_ring_write(MDBG_RING_T* pRing, char* buf, int len)
+{
+ int len1,len2 = 0;
+ char* pstart = NULL;
+ char* pend = NULL;
+
+ if((NULL == pRing) || (NULL == buf)||(0 == len)){
+ MDBG_ERR("Ring Write Failed, Param Error!,buf=%p,pRing=%p,len=%d",buf,pRing,len);
+ return (MDBG_ERR_BAD_PARAM);
+ }
+ pstart = mdbg_ring_start(pRing);
+ pend = mdbg_ring_end(pRing);
+ MDBG_LOG("pstart = %p",pstart);
+ MDBG_LOG("pend = %p",pend);
+ MDBG_LOG("buf = %p",buf);
+ MDBG_LOG("len = %d",len);
+ MDBG_LOG("pRing->wp = %p",pRing->wp);
+
+ if(mdbg_ring_over_loop(pRing, len, MDBG_RING_W)){
+ MDBG_LOG("Ring overloop.");
+ len1 = pend - pRing->wp + 1;
+ len2 = len - len1;
+ memcpy(pRing->wp, buf, len1);
+ memcpy(pstart, (buf + len1), len2);
+ pRing->wp = (char *)((u_long)pstart + len2);
+
+ }else{
+ memcpy(pRing->wp, buf, len);
+ pRing->wp += len;
+ }
+ MDBG_LOG("Ring Wrote len = %d",len);
+ return (len);
+}
+
+PUBLIC char* mdbg_ring_write_ext(MDBG_RING_T* pRing, MDBG_SIZE_T len)
+{
+ char* wp = NULL;
+ MDBG_LOG("pRing=%p,pRing->wp=%p,len=%d.", pRing, pRing->wp, len);
+
+ if((NULL == pRing)||(0 == len)){
+ MDBG_ERR("Ring Write Ext Failed, Param Error!");
+ return (NULL);
+ }
+
+ if(mdbg_ring_over_loop(pRing, len, MDBG_RING_R)||mdbg_ring_will_full(pRing, len)){
+ MDBG_LOG("Ring Write Ext Failed, Ring State Error!,overloop=%d,full=%d.",mdbg_ring_over_loop(pRing, len, MDBG_RING_R),mdbg_ring_will_full(pRing, len));
+ return (NULL);
+ }
+ MDBG_RING_LOCK(pRing);
+ wp = pRing->wp;
+ pRing->wp += len;
+ MDBG_LOG("return wp=%p,pRing->wp=%p.", wp, pRing->wp);
+ MDBG_RING_UNLOCK(pRing);
+ return (wp);
+}
+
+/*******************************************************/
+/******************Utility Fucntions*******************/
+/*******************************************************/
+
+PUBLIC bool mdbg_ring_will_full(MDBG_RING_T* pRing, int len)
+{
+ return(len > mdbg_ring_remain(pRing));
+}
+
+
+LOCAL MDBG_SIZE_T mdbg_ring_remain(MDBG_RING_T* pRing)
+{
+ return ((MDBG_SIZE_T)_MDBG_RING_REMAIN(pRing->rp, pRing->wp, pRing->size));
+}
+
+LOCAL MDBG_SIZE_T mdbg_ring_content_len(MDBG_RING_T* pRing)
+{
+ return (pRing->size - mdbg_ring_remain(pRing) - 1);
+}
+
+LOCAL char* mdbg_ring_start(MDBG_RING_T* pRing)
+{
+ return(pRing->pbuff);
+}
+
+LOCAL char* mdbg_ring_end(MDBG_RING_T* pRing)
+{
+ return(pRing->end);
+}
+
+LOCAL bool mdbg_ring_over_loop(MDBG_RING_T* pRing, u_long len, int rw)
+{
+ if(MDBG_RING_R == rw){
+ return ((u_long)pRing->rp + len > (u_long)mdbg_ring_end(pRing));
+ }else{
+ return ((u_long)pRing->wp + len > (u_long)mdbg_ring_end(pRing));
+ }
+}
+
+
diff --git a/drivers/misc/mdbg/mdbg_ring.h b/drivers/misc/mdbg/mdbg_ring.h
new file mode 100644
index 00000000..f09d3513
--- /dev/null
+++ b/drivers/misc/mdbg/mdbg_ring.h
@@ -0,0 +1,54 @@
+/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_ring.h */
+/*****Description: Marlin Debug System ring buffer definition. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/01/2014 */
+/************************************************************************************************************ */
+
+#ifndef _MDBG_RING_H
+#define _MDBG_RING_H
+
+/*******************************************************/
+/*********************INCLUDING********************/
+/*******************************************************/
+#include "mdbg_type.h"
+#include <linux/mutex.h>
+
+/*******************************************************/
+/******************Macor Definitions****************/
+/*******************************************************/
+#define MDBG_RING_R 0
+#define MDBG_RING_W 1
+
+#define MDBG_RING_MIN_SIZE (1024 * 4)
+
+#define MDBG_RING_LOCK_SIZE (sizeof(mdbg_ring_lock))
+
+
+/*******************************************************/
+/******************Type Definitions*****************/
+/*******************************************************/
+typedef struct mutex mdbg_ring_lock;
+
+typedef struct mdbg_ring_t {
+ MDBG_SIZE_T size;
+ char * pbuff;
+ char* rp;
+ char* wp;
+ char* end;
+ mdbg_ring_lock* plock;
+}MDBG_RING_T;
+
+/*******************************************************/
+/***********Public Interface Declaration************/
+/*******************************************************/
+MDBG_RING_T* mdbg_ring(MDBG_SIZE_T size);
+void mdbg_ring_destroy(MDBG_RING_T* pRing);
+int mdbg_ring_read(MDBG_RING_T* pRing, char* buf, int len);
+int mdbg_ring_write(MDBG_RING_T* pRing, char* buf, int len);
+char* mdbg_ring_write_ext(MDBG_RING_T* pRing, MDBG_SIZE_T len);
+bool mdbg_ring_will_full(MDBG_RING_T* pRing, int len);
+
+#endif
+
diff --git a/drivers/misc/mdbg/mdbg_sdio.c b/drivers/misc/mdbg/mdbg_sdio.c
new file mode 100644
index 00000000..f7367bed
--- /dev/null
+++ b/drivers/misc/mdbg/mdbg_sdio.c
@@ -0,0 +1,158 @@
+/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_sdio.c */
+/*****Description: Marlin Debug System Sdio related interface functions. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/09/2014 */
+/************************************************************************************************************ */
+
+/*******************************************************/
+/*********************INCLUDING********************/
+/*******************************************************/
+#include "mdbg_sdio.h"
+#include "mdbg_ring.h"
+#include "mdbg.h"
+#include <linux/mutex.h>
+
+
+/*******************************************************/
+/******************Global Variables*****************/
+/*******************************************************/
+MDBG_RING_T* rx_ring;
+struct mutex mdbg_read_mutex;
+extern unsigned int mdbg_read_count;
+extern wait_queue_head_t mdbg_wait;
+extern unsigned int first_boot;
+extern struct mdbg_devvice_t *mdbg_dev;
+/*******************************************************/
+/******************Local Variables*******************/
+/*******************************************************/
+LOCAL uint8_t* mdbg_rx_buff;
+MDBG_SIZE_T sdio_read_len;
+static struct wake_lock mdbg_wake_lock;
+/*******************************************************/
+/***********Local Functions Declaration************/
+/*******************************************************/
+LOCAL void mdbg_sdio_read(void);
+LOCAL MDBG_SIZE_T mdbg_sdio_write(char* buff, MDBG_SIZE_T len,uint32 chn);
+
+/*******************************************************/
+/************MDBG SDIO Life Cycle****************/
+/*******************************************************/
+PUBLIC int mdbg_sdio_init(void)
+{
+ int err = 0;
+ rx_ring = mdbg_ring(MDBG_RX_RING_SIZE);
+ if(!rx_ring){
+ MDBG_ERR("Ring malloc error.");
+ err = (MDBG_ERR_MALLOC_FAIL);
+ }
+
+ mdbg_rx_buff = kmalloc(MDBG_RX_BUFF_SIZE, GFP_KERNEL);
+ if(!mdbg_rx_buff){
+ MDBG_ERR("mdbg_rx_buff malloc error.");
+ err = (MDBG_ERR_MALLOC_FAIL);
+ }
+
+ mutex_init(&mdbg_read_mutex);
+
+ wake_lock_init(&mdbg_wake_lock, WAKE_LOCK_SUSPEND, "mdbg_wake_lock");
+ MDBG_LOG("mdbg_sdio_init!");
+
+ return (err);
+}
+
+PUBLIC void mdbg_sdio_remove(void)
+{
+ MDBG_FUNC_ENTERY;
+ wake_lock_destroy(&mdbg_wake_lock);
+ sdiodev_readchn_uninit(MDBG_CHANNEL_READ);
+ mdbg_ring_destroy(rx_ring);
+ if(mdbg_rx_buff){
+ kfree(mdbg_rx_buff);
+ }
+}
+
+int mdbg_channel_init(void)
+{
+ int err = 0;
+
+ mdbg_read_count = 0;
+ first_boot = 0;
+ err = sdiodev_readchn_init(MDBG_CHANNEL_READ, mdbg_sdio_read,0);
+ if(err != 0){
+ MDBG_ERR("Sdio dev read channel init failed!");
+ }
+
+ if(rx_ring->pbuff != NULL)
+ memset(rx_ring->pbuff,0,MDBG_RX_RING_SIZE);
+ return err;
+}
+EXPORT_SYMBOL_GPL(mdbg_channel_init);
+
+
+/*******************************************************/
+/***********MDBG SDIO IO Functions**************/
+/*******************************************************/
+LOCAL MDBG_SIZE_T mdbg_sdio_write(char* buff, MDBG_SIZE_T len,uint32 chn)
+{
+ int cnt = 0;
+ MDBG_LOG("buff=%p,len=%d,[%s]",buff,len,buff);
+ if(1 != get_sdiohal_status()){
+ return 0;
+ }
+ while((set_marlin_wakeup(MDBG_CHANNEL_WRITE,0x3) < 0) && (cnt <= 3))
+ {
+ msleep(300);
+ cnt++;
+ }
+
+ sdio_dev_write(chn, buff, len);
+ return len;
+}
+
+PUBLIC void mdbg_sdio_read(void)
+{
+ wake_lock(&mdbg_wake_lock);
+ mutex_lock(&mdbg_read_mutex);
+ //set_marlin_wakeup(MDBG_CHANNEL_READ,0x1);
+ sdio_read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_READ);
+ if(sdio_read_len <= 0)
+ {
+ MDBG_ERR("[%s][%d]\n",__func__, sdio_read_len);
+ wake_unlock(&mdbg_wake_lock);
+ mutex_unlock(&mdbg_read_mutex);
+ return;
+ }
+ sdio_dev_read(MDBG_CHANNEL_READ,mdbg_rx_buff,&sdio_read_len);
+ sdio_read_len = mdbg_ring_write(rx_ring,mdbg_rx_buff, sdio_read_len);
+ mdbg_read_count += sdio_read_len;
+ wake_up_interruptible(&mdbg_wait);
+ wake_up_interruptible(&mdbg_dev->rxwait);
+
+ wake_unlock(&mdbg_wake_lock);
+ mutex_unlock(&mdbg_read_mutex);
+ return;
+}
+EXPORT_SYMBOL_GPL(mdbg_sdio_read);
+
+/*******************************************************/
+/**************MDBG IO Functions******************/
+/*******************************************************/
+PUBLIC MDBG_SIZE_T mdbg_send(char* buff, MDBG_SIZE_T len,uint32 chn)
+{
+ MDBG_SIZE_T sent_size = 0;
+
+ MDBG_LOG("BYTE MODE");
+ wake_lock(&mdbg_wake_lock);
+ sent_size = mdbg_sdio_write(buff, len,chn);
+ wake_unlock(&mdbg_wake_lock);
+ return len;
+}
+
+PUBLIC MDBG_SIZE_T mdbg_receive(char* buff, MDBG_SIZE_T len)
+{
+ return (mdbg_ring_read(rx_ring, buff, len));
+}
+
+
diff --git a/drivers/misc/mdbg/mdbg_sdio.h b/drivers/misc/mdbg/mdbg_sdio.h
new file mode 100644
index 00000000..97106f26
--- /dev/null
+++ b/drivers/misc/mdbg/mdbg_sdio.h
@@ -0,0 +1,37 @@
+/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_sdio.h */
+/*****Description: Marlin Debug System Sdio related interface functions. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/09/2014 */
+/************************************************************************************************************ */
+
+#ifndef _MDBG_SDIO_H
+#define _MDBG_SDIO_H
+
+/*******************************************************/
+/*********************INCLUDING********************/
+/*******************************************************/
+#include "mdbg_type.h"
+
+/*******************************************************/
+/******************Macor Definitions****************/
+/*******************************************************/
+#define MDBG_BYTE_MODE 0
+#define MDBG_WRITE_LEN (128)
+
+#define MDBG_CHANNEL_READ (14)
+#define MDBG_CHANNEL_WRITE (6)
+#define MDBG_MAX_RETRY (3)
+#define MDBG_RX_BUFF_SIZE (4096)
+
+/*******************************************************/
+/***********Public Interface Declaration************/
+/*******************************************************/
+int mdbg_sdio_init(void);
+void mdbg_sdio_remove(void);
+MDBG_SIZE_T mdbg_send(char* buff, MDBG_SIZE_T len, uint32 chn);
+MDBG_SIZE_T mdbg_receive(char* buff, MDBG_SIZE_T len);
+int mdbg_channel_init(void);
+
+#endif
diff --git a/drivers/misc/mdbg/mdbg_type.h b/drivers/misc/mdbg/mdbg_type.h
new file mode 100644
index 00000000..40974e79
--- /dev/null
+++ b/drivers/misc/mdbg/mdbg_type.h
@@ -0,0 +1,65 @@
+/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_type.h */
+/*****Description: Marlin Debug System type defination. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/01/2014 */
+/************************************************************************************************************ */
+
+#ifndef _MDBG_TYPE_H
+#define _MDBG_TYPE_H
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/input.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+
+#include "../sdiodev/sdio_dev.h"
+
+#define PUBLIC
+#define LOCAL static
+
+#define MDBG_HEADER "MDBG: "
+#define MDBG_HEADER_ERR "MDBG_ERR: "
+#define MDBG_DEBUG_MODE 0
+
+#define MDBG_ERR(fmt,args...) printk(MDBG_HEADER_ERR "%s:" fmt "\n", __func__, ## args)
+#if MDBG_DEBUG_MODE
+#define MDBG_LOG(fmt,args...) printk(MDBG_HEADER "%s:" fmt "\n", __func__, ## args)
+#else
+#define MDBG_LOG(fmt,args...)
+#endif
+
+#define MDBG_FUNC_ENTERY MDBG_LOG("ENTER.")
+#define MDBG_FUNC_EXIT MDBG_LOG("EXIT.")
+
+
+#define MDBG_RX_RING_SIZE (1024*1024)
+
+
+/*******************************************************/
+/**************MDBG ERROR CODE***************/
+/*******************************************************/
+#define MDBG_SUCCESS (0)
+#define MDBG_ERR_RING_FULL (-1)
+#define MDBG_ERR_MALLOC_FAIL (-2)
+#define MDBG_ERR_BAD_PARAM (-3)
+#define MDBG_ERR_SDIO_ERR (-4)
+#define MDBG_ERR_TIMEOUT (-5)
+#define MDBG_ERR_NO_FILE (-6)
+
+
+typedef long int MDBG_SIZE_T;
+
+
+#endif