| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682 |
- /*****************************************************************************
- *
- * Filename:
- * ---------
- * ccci_fs.c
- *
- * Project:
- * --------
- * YuSu
- *
- * Description:
- * ------------
- * MT6516 CCCI RPC
- *
- * Author:
- * -------
- *
- *
- ****************************************************************************/
- #include <linux/sched.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/device.h>
- #include <linux/cdev.h>
- #include <linux/kfifo.h>
- #include <linux/spinlock.h>
- #include <linux/interrupt.h>
- #include <linux/delay.h>
- #include <linux/uaccess.h>
- #include <linux/timer.h>
- #include <linux/delay.h>
- #include <linux/semaphore.h>
- #include <linux/version.h>
- #include <ccci.h>
- /*********************************************************************************
- * RPC Daemon section
- *********************************************************************************/
- #if defined(CONFIG_MTK_TC1_FEATURE)
- struct rpc_stream_msg_t {
- unsigned length;
- unsigned index;
- };
- static void rpc_daemon_notify(int md_id, unsigned int buff_index);
- #define RPC_CCCI_TC1_CMD 0x00003000
- #define CCCI_RPC_IOC_MAGIC 'R'
- #define CCCI_RPC_IOCTL_GET_INDEX _IO(CCCI_RPC_IOC_MAGIC, 1)
- #define CCCI_RPC_IOCTL_SEND _IOR(CCCI_RPC_IOC_MAGIC, 2, unsigned int)
- #endif /* CONFIG_MTK_TC1_FEATURE */
- struct rpc_ctl_block_t {
- spinlock_t rpc_fifo_lock;
- struct RPC_BUF *rpc_buf_vir;
- unsigned int rpc_buf_phy;
- unsigned int rpc_buf_len;
- struct kfifo rpc_fifo;
- struct work_struct rpc_work;
- int m_md_id;
- int rpc_smem_instance_size;
- int rpc_max_buf_size;
- int rpc_ch_num;
- #if defined(CONFIG_MTK_TC1_FEATURE)
- spinlock_t rpc_daemon_fifo_lock;
- struct kfifo rpc_daemon_fifo;
- atomic_t rpcd_response_done;
- wait_queue_head_t rpcd_send_waitq;
- wait_queue_head_t rpcd_response_waitq;
- struct cdev rpc_cdev;
- dev_t rpc_dev_num;
- atomic_t md_is_ready;
- struct MD_CALL_BACK_QUEUE md_status_update_call_back;
- #ifdef _DEBUG_RPCD
- atomic_t rpcd_resp_indx;
- #endif
- #endif
- };
- static struct rpc_ctl_block_t *rpc_ctl_block[MAX_MD_NUM];
- static int get_pkt_info(int md_id, unsigned int *pktnum, struct RPC_PKT *pkt_info,
- char *pdata)
- {
- unsigned int pkt_num = *((unsigned int *)pdata);
- unsigned int idx = 0;
- unsigned int i = 0;
- struct rpc_ctl_block_t *ctl_b = rpc_ctl_block[md_id];
- CCCI_RPC_MSG(md_id, "package number = 0x%08X\n", pkt_num);
- if (pkt_num > IPC_RPC_MAX_ARG_NUM)
- return -1;
- idx = sizeof(unsigned int);
- for (i = 0; i < pkt_num; i++) {
- pkt_info[i].len = *((unsigned int *)(pdata + idx));
- idx += sizeof(unsigned int);
- pkt_info[i].buf = (pdata + idx);
- CCCI_RPC_MSG(md_id, "pak[%d]: vir = 0x%08X, len = 0x%08X\n", i,
- (unsigned int)pkt_info[i].buf, pkt_info[i].len);
- /* 4 byte alignment */
- idx += ((pkt_info[i].len + 3) >> 2) << 2;
- }
- if (idx > ctl_b->rpc_max_buf_size) {
- CCCI_MSG_INF(md_id, "rpc",
- "over flow, pdata = %p, idx = 0x%08X, max = %p\n",
- pdata, idx, pdata + ctl_b->rpc_max_buf_size);
- return -1;
- }
- *pktnum = pkt_num;
- return 0;
- }
- static int rpc_write(int md_id, int buf_idx, struct RPC_PKT *pkt_src,
- unsigned int pkt_num)
- {
- int ret = 0;
- struct ccci_msg_t msg;
- struct RPC_BUF *rpc_buf_tmp = NULL;
- unsigned char *pdata = NULL;
- unsigned int data_len = 0;
- unsigned int i = 0;
- unsigned int AlignLength = 0;
- struct rpc_ctl_block_t *ctl_b = rpc_ctl_block[md_id];
- /* rpc_buf_tmp = ctl_b->rpc_buf_vir + buf_idx; */
- rpc_buf_tmp =
- (struct RPC_BUF *) ((unsigned int)(ctl_b->rpc_buf_vir) +
- ctl_b->rpc_smem_instance_size * buf_idx);
- rpc_buf_tmp->op_id = IPC_RPC_API_RESP_ID | rpc_buf_tmp->op_id;
- pdata = rpc_buf_tmp->buf;
- *((unsigned int *)pdata) = pkt_num;
- pdata += sizeof(unsigned int);
- data_len += sizeof(unsigned int);
- for (i = 0; i < pkt_num; i++) {
- if ((data_len + 2 * sizeof(unsigned int) + pkt_src[i].len) >
- ctl_b->rpc_max_buf_size) {
- CCCI_MSG_INF(md_id, "rpc", "Stream buffer full!!\n");
- ret = -CCCI_ERR_LARGE_THAN_BUF_SIZE;
- goto _Exit;
- }
- *((unsigned int *)pdata) = pkt_src[i].len;
- pdata += sizeof(unsigned int);
- data_len += sizeof(unsigned int);
- /* 4 byte aligned */
- AlignLength = ((pkt_src[i].len + 3) >> 2) << 2;
- data_len += AlignLength;
- if (pdata != pkt_src[i].buf)
- memcpy(pdata, pkt_src[i].buf, pkt_src[i].len);
- else
- CCCI_RPC_MSG(md_id, "same addr, no copy\n");
- pdata += AlignLength;
- }
- /* msg.data0 = ctl_b->rpc_buf_phy + (sizeof(struct RPC_BUF) * buf_idx); */
- msg.data0 =
- (unsigned int)(ctl_b->rpc_buf_phy) - get_md2_ap_phy_addr_fixed() +
- ctl_b->rpc_smem_instance_size * buf_idx;
- msg.data1 = data_len + 4;
- msg.reserved = buf_idx;
- msg.channel = CCCI_RPC_TX;
- CCCI_RPC_MSG(md_id, "Write, %08X, %08X, %08X, %08X\n",
- msg.data0, msg.data1, msg.channel, msg.reserved);
- /* wait memory updated*/
- mb();
- ret = ccci_message_send(md_id, &msg, 1);
- if (ret != sizeof(struct ccci_msg_t)) {
- CCCI_MSG_INF(md_id, "rpc", "fail send msg <%d>!!!\n", ret);
- return ret;
- }
- ret = 0;
- _Exit:
- return ret;
- }
- static void ccci_rpc_work(struct work_struct *work)
- {
- int pkt_num = 0;
- int ret_val = 0;
- unsigned int buf_idx = 0;
- struct RPC_PKT pkt[IPC_RPC_MAX_ARG_NUM] = { {0}, };
- struct RPC_BUF *rpc_buf_tmp = NULL;
- unsigned int tmp_data[4];
- struct rpc_ctl_block_t *ctl_b = container_of(work, struct rpc_ctl_block_t, rpc_work);
- int md_id = ctl_b->m_md_id;
- #ifdef _DEBUG_RPCD
- int resp_inx;
- #endif
- CCCI_RPC_MSG(md_id, "ccci_rpc_work++\n");
- if (ctl_b->rpc_buf_vir == NULL) {
- CCCI_MSG_INF(md_id, "rpc", "invalid rpc_buf_vir!!\n");
- return;
- }
- while (kfifo_out(&ctl_b->rpc_fifo, &buf_idx, sizeof(unsigned int))) {
- if (buf_idx < 0 || buf_idx > ctl_b->rpc_ch_num) {
- CCCI_MSG_INF(md_id, "rpc", "invalid idx %d\n", buf_idx);
- ret_val = FS_PARAM_ERROR; /* !!!!! Make more meaningful */
- pkt[pkt_num].len = sizeof(unsigned int);
- pkt[pkt_num++].buf = (void *)&ret_val;
- goto _Next;
- }
- pkt_num = 0;
- memset(pkt, 0x00, sizeof(struct RPC_PKT) * IPC_RPC_MAX_ARG_NUM);
- /* rpc_buf_tmp = ctl_b->rpc_buf_vir + buf_idx; */
- rpc_buf_tmp =
- (struct RPC_BUF *) ((unsigned int)(ctl_b->rpc_buf_vir) +
- ctl_b->rpc_smem_instance_size * buf_idx);
- if (get_pkt_info(md_id, &pkt_num, pkt, rpc_buf_tmp->buf) < 0) {
- CCCI_MSG_INF(md_id, "rpc", "Fail to get packet info\n");
- ret_val = FS_PARAM_ERROR; /* !!!!! Make more meaningful */
- pkt[pkt_num].len = sizeof(unsigned int);
- pkt[pkt_num++].buf = (void *)&ret_val;
- goto _Next;
- }
- #if defined(CONFIG_MTK_TC1_FEATURE)
- if ((rpc_buf_tmp->op_id & 0x0000F000) == RPC_CCCI_TC1_CMD) {
- #ifdef _DEBUG_RPCD
- resp_inx = atomic_read(&ctl_b->rpcd_resp_indx);
- CCCI_DBG_MSG(ctl_b->m_md_id, "rpc",
- "op_id=0x%X, Wait RPCD [Resp=%d]\n",
- rpc_buf_tmp->op_id, resp_inx);
- #endif
- rpc_daemon_notify(md_id, buf_idx);
- wait_event_interruptible(ctl_b->rpcd_response_waitq,
- atomic_read
- (&ctl_b->rpcd_response_done)
- == 1);
- atomic_set(&ctl_b->rpcd_response_done, 0);
- #ifdef _DEBUG_RPCD
- CCCI_DBG_MSG(ctl_b->m_md_id, "rpc",
- "Done RPCD CMD [Resp=%d]\n", resp_inx);
- #endif
- continue;
- }
- #endif
- CCCI_RPC_MSG(md_id, "call ccci_rpc_work_helper()\n");
- ccci_rpc_work_helper(md_id, &pkt_num, pkt, rpc_buf_tmp, tmp_data);
- _Next:
- if (rpc_write(md_id, buf_idx, pkt, pkt_num) != 0) {
- CCCI_MSG_INF(md_id, "rpc",
- "fail to write packet!!\r\n");
- return;
- }
- }
- CCCI_RPC_MSG(md_id, "ccci_rpc_work--\n");
- }
- static void ccci_rpc_callback(void *private)
- {
- struct logic_channel_info_t *ch_info = (struct logic_channel_info_t *) private;
- struct ccci_msg_t msg;
- struct rpc_ctl_block_t *ctl_b = (struct rpc_ctl_block_t *) ch_info->m_owner;
- int md_id = ctl_b->m_md_id;
- while (get_logic_ch_data(ch_info, &msg)) {
- CCCI_RPC_MSG(md_id,
- "ccci_rpc_callback, %08X, %08X, %08X, %08X\n",
- msg.data0, msg.data1, msg.channel, msg.reserved);
- spin_lock_bh(&ctl_b->rpc_fifo_lock);
- kfifo_in(&ctl_b->rpc_fifo, &msg.reserved, sizeof(unsigned int));
- spin_unlock_bh(&ctl_b->rpc_fifo_lock);
- }
- schedule_work(&ctl_b->rpc_work);
- CCCI_RPC_MSG(md_id, "ccci_rpc_callback --\n");
- }
- #if defined(CONFIG_MTK_TC1_FEATURE)
- void rpc_daemon_notify(int md_id, unsigned int buff_index)
- {
- struct rpc_ctl_block_t *ctl_b = rpc_ctl_block[md_id];
- #ifdef _DEBUG_RPCD
- CCCI_RPC_MSG(md_id, "[CCCI_RPC] rpc_daemon_notify(%d) [Resp=%d]\n",
- buff_index, atomic_read(&ctl_b->rpcd_resp_indx));
- #endif
- spin_lock_bh(&ctl_b->rpc_daemon_fifo_lock);
- kfifo_in(&ctl_b->rpc_daemon_fifo, &buff_index, sizeof(unsigned int));
- spin_unlock_bh(&ctl_b->rpc_daemon_fifo_lock);
- wake_up_interruptible(&ctl_b->rpcd_send_waitq);
- }
- static int rpc_get_share_mem_index(struct file *file)
- {
- int ret;
- struct rpc_ctl_block_t *ctl_b = (struct rpc_ctl_block_t *) file->private_data;
- if (ctl_b == NULL) {
- CCCI_ERR_MSG(ctl_b->m_md_id, "rpc_get_share_mem_index:ctl_b == NULL\n");
- return -EFAULT;
- }
- #ifdef _DEBUG_RPCD
- atomic_inc(&ctl_b->rpcd_resp_indx);
- CCCI_RPC_MSG(ctl_b->m_md_id, "get index start [Resp=%d]\n",
- atomic_read(&ctl_b->rpcd_resp_indx));
- #endif
- if (wait_event_interruptible
- (ctl_b->rpcd_send_waitq,
- kfifo_len(&ctl_b->rpc_daemon_fifo) != 0) != 0) {
- CCCI_MSG_INF(ctl_b->m_md_id, "rpc",
- "return rpc_get_share_mem_index():ERESTARTSYS\n");
- return -ERESTARTSYS;
- }
- if (kfifo_out
- (&ctl_b->rpc_daemon_fifo, (unsigned int *)&ret,
- sizeof(int)) != sizeof(int)) {
- CCCI_MSG_INF(ctl_b->m_md_id, "rpc",
- "Unable to get new request from fifo\n");
- return -EFAULT;
- }
- #ifdef _DEBUG_RPCD
- CCCI_RPC_MSG(ctl_b->m_md_id, "get index end [Resp=%d]\n",
- atomic_read(&ctl_b->rpcd_resp_indx));
- #endif
- return ret;
- }
- static void wakeup_rpc_work(struct rpc_ctl_block_t *ctl_b)
- {
- CCCI_RPC_MSG(ctl_b->m_md_id, "wakeup rpc_work\n");
- atomic_set(&ctl_b->rpcd_response_done, 1);
- wake_up_interruptible(&ctl_b->rpcd_response_waitq);
- }
- static void ccci_rpc_resetfifo(struct rpc_ctl_block_t *ctl_b)
- {
- CCCI_MSG("(%d) ccci_rpc_resetfifo\n", ctl_b->m_md_id);
- spin_lock_bh(&ctl_b->rpc_fifo_lock);
- kfifo_reset(&ctl_b->rpc_fifo);
- spin_unlock_bh(&ctl_b->rpc_fifo_lock);
- spin_lock_bh(&ctl_b->rpc_daemon_fifo_lock);
- kfifo_reset(&ctl_b->rpc_daemon_fifo);
- spin_unlock_bh(&ctl_b->rpc_daemon_fifo_lock);
- }
- static void rpc_md_ev_callback(struct MD_CALL_BACK_QUEUE *queue, unsigned long data)
- {
- struct rpc_ctl_block_t *ctl_b =
- container_of(queue, struct rpc_ctl_block_t, md_status_update_call_back);
- CCCI_DBG_MSG(ctl_b->m_md_id, "rpc", "rpc_md_ev_callback++\n");
- switch (data) {
- case CCCI_MD_RESET:
- CCCI_MSG_INF(ctl_b->m_md_id, "rpc", "MD reset call chain !\n");
- atomic_set(&ctl_b->md_is_ready, 0);
- ccci_rpc_resetfifo(ctl_b);
- wakeup_rpc_work(ctl_b);
- break;
- case CCCI_MD_BOOTUP:
- atomic_set(&ctl_b->rpcd_response_done, 0);
- atomic_set(&ctl_b->md_is_ready, 1);
- CCCI_MSG_INF(ctl_b->m_md_id, "rpc",
- "MD boot up successfully.\n");
- break;
- }
- CCCI_DBG_MSG(ctl_b->m_md_id, "rpc", "rpc_md_ev_callback--\n");
- }
- static int rpc_daemon_send_helper(struct file *file, unsigned long arg)
- {
- void __user *argp;
- struct ccci_msg_t msg;
- struct rpc_stream_msg_t message;
- int md_id;
- int ret = 0;
- struct rpc_ctl_block_t *ctl_b = (struct rpc_ctl_block_t *) file->private_data; /* rpc_ctl_block[0]; */
- #ifdef _DEBUG_RPCD
- CCCI_DBG_MSG(ctl_b->m_md_id, "rpc", "Send RPCD -> MD [Resp=%d]\n",
- atomic_read(&ctl_b->rpcd_resp_indx));
- #endif
- if (ctl_b == NULL) {
- ret = -EFAULT;
- goto _send_return;
- }
- md_id = ctl_b->m_md_id;
- argp = (void __user *)arg;
- if (atomic_read(&ctl_b->md_is_ready) == 0) {
- CCCI_MSG_INF(ctl_b->m_md_id, "rpc",
- "rpc_daemon_send_helper-- by MD_RESET!\n");
- ret = -EINTR;
- goto _send_return;
- }
- if (copy_from_user((void *)&message, argp, sizeof(struct rpc_stream_msg_t))) {
- ret = -EFAULT;
- goto _send_return;
- }
- msg.data0 =
- (unsigned int)(ctl_b->rpc_buf_phy) - get_md2_ap_phy_addr_fixed() +
- ctl_b->rpc_smem_instance_size * message.index;
- msg.data1 = message.length + 4;
- msg.reserved = message.index;
- msg.channel = CCCI_RPC_TX;
- CCCI_RPC_MSG(md_id, "Write, %08X, %08X, %08X, %08X\n",
- msg.data0, msg.data1, msg.channel, msg.reserved);
- /* wait memory updated*/
- mb();
- ret = ccci_message_send(md_id, &msg, 1);
- if (ret != sizeof(struct ccci_msg_t)) {
- CCCI_MSG_INF(md_id, "rpc", "fail send msg <%d>!!!\n", ret);
- goto _send_return;
- }
- _send_return:
- CCCI_DBG_MSG(ctl_b->m_md_id, "rpc", "rpc_daemon_send_helper--(%d)\n",
- ret);
- wakeup_rpc_work(ctl_b);
- return ret;
- }
- static int rpc_mmap(struct file *file, struct vm_area_struct *vma)
- {
- unsigned long off, start, len;
- struct rpc_ctl_block_t *ctl_b = (struct rpc_ctl_block_t *) file->private_data; /* rpc_ctl_block[0]; */
- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
- return -EINVAL;
- off = vma->vm_pgoff << PAGE_SHIFT;
- start = (unsigned long)ctl_b->rpc_buf_phy;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + ctl_b->rpc_smem_instance_size);
- if ((vma->vm_end - vma->vm_start + off) > len)
- return -EINVAL;
- off += start & PAGE_MASK;
- vma->vm_pgoff = off >> PAGE_SHIFT;
- vma->vm_flags |= (VM_DONTEXPAND | VM_DONTDUMP);
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- return remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start, vma->vm_page_prot);
- }
- static long rpc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
- {
- int ret;
- switch (cmd) {
- case CCCI_RPC_IOCTL_GET_INDEX:
- ret = rpc_get_share_mem_index(file);
- break;
- case CCCI_RPC_IOCTL_SEND:
- ret = rpc_daemon_send_helper(file, arg);
- break;
- default:
- ret = -ENOIOCTLCMD;
- break;
- }
- return ret;
- }
- static int rpc_open(struct inode *inode, struct file *file)
- {
- int major = imajor(inode);
- int md_id;
- md_id = get_md_id_by_dev_major(major);
- file->private_data = (void *)rpc_ctl_block[md_id];
- return 0;
- }
- static int rpc_release(struct inode *inode, struct file *file)
- {
- return 0;
- }
- static const struct file_operations rpc_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = rpc_ioctl,
- .open = rpc_open,
- .mmap = rpc_mmap,
- .release = rpc_release,
- };
- static int rpc_device_init(struct rpc_ctl_block_t *ctl_b)
- {
- int ret;
- int major, minor;
- char name[16];
- int md_id = ctl_b->m_md_id;
- CCCI_MSG_INF(md_id, "rpc", "rpc_device_init++\n");
- ctl_b->md_status_update_call_back.call = rpc_md_ev_callback;
- ctl_b->md_status_update_call_back.next = NULL,
- CCCI_MSG_INF(md_id, "rpc", "register md_db rpc_md_ev_callback\n");
- md_register_call_chain(md_id, &ctl_b->md_status_update_call_back);
- #ifdef _DEBUG_RPCD
- atomic_set(&ctl_b->rpcd_resp_indx, 0);
- #endif
- atomic_set(&ctl_b->md_is_ready, 1);
- atomic_set(&ctl_b->rpcd_response_done, 0);
- init_waitqueue_head(&ctl_b->rpcd_response_waitq);
- init_waitqueue_head(&ctl_b->rpcd_send_waitq);
- ret = get_dev_id_by_md_id(md_id, "rpc", &major, &minor);
- if (ret < 0) {
- CCCI_MSG_INF(md_id, "rpc", "get rpc dev id fail: %d\n", ret);
- goto _ret;
- }
- spin_lock_init(&ctl_b->rpc_daemon_fifo_lock);
- ret =
- kfifo_alloc(&ctl_b->rpc_daemon_fifo, sizeof(unsigned int) * 8,
- GFP_KERNEL);
- if (ret) {
- CCCI_MSG_INF(md_id, "rpc", "unable to create daemon fifo\n");
- goto _ret;
- }
- if (md_id)
- snprintf(name, 16, "ccci%d_rpc", md_id + 1);
- else
- strcpy(name, "ccci_rpc");
- ctl_b->rpc_dev_num = MKDEV(major, minor); /* Using FS major, sub id is 1, not 0 */
- ret = register_chrdev_region(ctl_b->rpc_dev_num, 1, name);
- if (ret) {
- CCCI_MSG_INF(md_id, "rpc",
- "ccci_rpc: Register character device failed\n");
- goto _ret_kfifo_free;
- }
- cdev_init(&ctl_b->rpc_cdev, &rpc_fops);
- ctl_b->rpc_cdev.owner = THIS_MODULE;
- ctl_b->rpc_cdev.ops = &rpc_fops;
- ret = cdev_add(&ctl_b->rpc_cdev, ctl_b->rpc_dev_num, 1);
- if (ret) {
- CCCI_MSG_INF(md_id, "rpc",
- "ccci_rpc: Char device add failed\n");
- unregister_chrdev_region(ctl_b->rpc_dev_num, 1);
- goto _ret_kfifo_free;
- }
- goto _ret;
- _ret_kfifo_free:
- kfifo_free(&ctl_b->rpc_daemon_fifo);
- _ret:
- CCCI_MSG_INF(md_id, "rpc", "rpc_device_init--\n");
- return ret;
- }
- void rpc_device_deinit(int md_id)
- {
- struct rpc_ctl_block_t *ctl_b = rpc_ctl_block[md_id];
- kfifo_free(&ctl_b->rpc_daemon_fifo);
- cdev_del(&ctl_b->rpc_cdev);
- unregister_chrdev_region(ctl_b->rpc_dev_num, 1);
- }
- #endif /* CONFIG_MTK_TC1_FEATURE */
- int __init ccci_rpc_init(int md_id)
- {
- int ret;
- struct rpc_ctl_block_t *ctl_b;
- struct rpc_cfg_inf_t rpc_cfg;
- int rpc_buf_vir, rpc_buf_phy, rpc_buf_len;
- /* Allocate fs ctrl struct memory */
- ctl_b = kmalloc(sizeof(struct rpc_ctl_block_t), GFP_KERNEL);
- if (ctl_b == NULL)
- return -CCCI_ERR_GET_MEM_FAIL;
- memset(ctl_b, 0, sizeof(struct rpc_ctl_block_t));
- rpc_ctl_block[md_id] = ctl_b;
- /* Get rpc config information */
- ccci_get_sub_module_cfg(md_id, "rpc", (char *)&rpc_cfg, sizeof(struct rpc_cfg_inf_t));
- ccci_rpc_base_req(md_id, &rpc_buf_vir, &rpc_buf_phy, &rpc_buf_len);
- ctl_b->rpc_buf_vir = (struct RPC_BUF *) rpc_buf_vir;
- ctl_b->rpc_buf_phy = (unsigned int)rpc_buf_phy;
- ctl_b->rpc_buf_len = rpc_buf_len;
- ctl_b->rpc_max_buf_size = rpc_cfg.rpc_max_buf_size;
- ctl_b->rpc_ch_num = rpc_cfg.rpc_ch_num;
- ctl_b->rpc_smem_instance_size =
- sizeof(struct RPC_BUF) + ctl_b->rpc_max_buf_size;
- /* Note!!!!! we should check cofigure mistake */
- /* Init ctl_b */
- ctl_b->m_md_id = md_id;
- spin_lock_init(&ctl_b->rpc_fifo_lock);
- ret =
- kfifo_alloc(&ctl_b->rpc_fifo, sizeof(unsigned) * ctl_b->rpc_ch_num,
- GFP_KERNEL);
- if (ret < 0) {
- CCCI_MSG_INF(md_id, "rpc", "Unable to create fifo\n");
- goto _KFIFO_ALLOC_FAIL;
- }
- INIT_WORK(&ctl_b->rpc_work, ccci_rpc_work);
- /* modem related channel registration. */
- CCCI_RPC_MSG(md_id,
- "rpc_buf_vir=0x%p, rpc_buf_phy=0x%08X, rpc_buf_len=0x%08X\n",
- ctl_b->rpc_buf_vir, ctl_b->rpc_buf_phy,
- ctl_b->rpc_buf_len);
- register_to_logic_ch(md_id, CCCI_RPC_RX, ccci_rpc_callback, ctl_b);
- #if defined(CONFIG_MTK_TC1_FEATURE)
- register_to_logic_ch(md_id, CCCI_RPC_TX, ccci_rpc_callback, ctl_b);
- ret = rpc_device_init(ctl_b);
- if (0 != ret)
- goto _KFIFO_ALLOC_FAIL;
- #endif
- return ret;
- _KFIFO_ALLOC_FAIL:
- kfree(ctl_b);
- rpc_ctl_block[md_id] = NULL;
- return ret;
- }
- void __exit ccci_rpc_exit(int md_id)
- {
- struct rpc_ctl_block_t *ctl_b;
- CCCI_RPC_MSG(md_id, "ccci_rpc_exit\n");
- ctl_b = rpc_ctl_block[md_id];
- if (ctl_b == NULL)
- return;
- #if defined(CONFIG_MTK_TC1_FEATURE)
- rpc_device_deinit(md_id);
- #endif
- kfifo_free(&ctl_b->rpc_fifo);
- un_register_to_logic_ch(md_id, CCCI_RPC_RX);
- #if defined(CONFIG_MTK_TC1_FEATURE)
- un_register_to_logic_ch(md_id, CCCI_RPC_TX);
- #endif
- kfree(ctl_b);
- rpc_ctl_block[md_id] = NULL;
- }
|