static int client_init(emd_dev_client_t *client, int major,int sub_id) { int ret = 0; if( (sub_id >= EMD_CHR_CLIENT_NUM) || (sub_id < 0) ){ EMD_MSG_INF("chr","client_init:sub_id(%d) error\n",sub_id); return -1; } // 1. Clear client memset(client, 0, sizeof(emd_dev_client_t)); // 2. Setting device id client->major_dev_id = major; client->sub_dev_id = sub_id; // 3. Init wait queue head, wake lock, spin loc and semaphore init_waitqueue_head(&client->wait_q); spin_lock_init(&client->lock); mutex_init(&client->emd_mutex); // 4. Set user_num to zero client->user_num = 0; // 5. Alloc and init kfifo ret=kfifo_alloc(&client->fifo, EMD_MAX_MESSAGE_NUM*sizeof(int),GFP_ATOMIC); if (ret){ EMD_MSG_INF("chr","kfifo alloc failed(ret=%d).\n",ret); return ret; } EMD_MSG_INF("chr","client_init:sub_id=%d\n",client->sub_dev_id); return 0; }
// emd_reset_register: register a user for emd reset // @name: user name // return a handle if success; return negative value if failure int emd_reset_register(char *name) { int handle; if (name == NULL) { EMD_MSG_INF("chr","[Error]emd_reset_register name=null\n"); return -1; } mutex_lock(&emd_reset_mutex); for (handle = 0; handle < NR_EMD_RESET_USER; handle++) { if (emd_reset_sta[handle].is_allocate == 0) { emd_reset_sta[handle].is_allocate = 1; break; } } if (handle < NR_EMD_RESET_USER) { emd_reset_sta[handle].is_reset = 0; mutex_unlock(&emd_reset_mutex); snprintf(emd_reset_sta[handle].name,EMD_RESET_USER_NAME_SIZE,name); EMD_MSG_INF("chr","Register a reset handle by %s(%d)\n", current->comm, handle); return handle; } else { EMD_MSG_INF("chr","[Error]no reset handler\n"); mutex_unlock(&emd_reset_mutex); return -1; } }
int get_eint_info(const char *name, eint_inf_t *eint_item) { #ifdef CONFIG_OF struct device_node *node; char buf[64]; int ints[2]; if ((NULL==name) || (NULL==eint_item)) { EMD_MSG_INF("chr","%s: get invalid arguments:%p,%p\n", __func__, name, eint_item); return -1; } snprintf(buf, 64, "mediatek, %s-eint", name); EMD_MSG_INF("chr","%s: find:%s\n", __func__, buf); node = of_find_compatible_node(NULL, NULL, buf); if (node) { of_property_read_u32_array(node, "debounce", ints, ARRAY_SIZE(ints)); eint_item->gpio_id = ints[0]; eint_item->debounce_time = ints[1]; eint_item->irq_id = irq_of_parse_and_map(node, 0); } else { EMD_MSG_INF("chr","%s: can't find %s\n", __func__, name); return -2; } #endif return 0; }
/****************************************************************************************** * Driver functions region ******************************************************************************************/ static int emd_dev_open(struct inode *inode, struct file *file) { int index=iminor(inode); int ret=0; EMD_MSG_INF("chr","Open by %s sub_id:%d\n",current->comm,index); if( (index >= EMD_CHR_CLIENT_NUM) || (index < 0) ){ EMD_MSG_INF("chr","Open func get invalid dev sub id\n"); return -1; } mutex_lock(&drv_client[index].emd_mutex); if(drv_client[index].user_num > 0){ EMD_MSG_INF("chr","Multi-Open not support!\n"); mutex_unlock(&drv_client[index].emd_mutex); return -1; } drv_client[index].user_num++; mutex_unlock(&drv_client[index].emd_mutex); file->private_data=&drv_client[index]; nonseekable_open(inode,file); return ret; }
int cm_do_md_power_off(void) { EMD_MSG_INF("chr","cm_do_md_power_off\n"); atomic_set(&traffic_on, 0); atomic_set(&allow_wk_md, 0); // Release download key to let md can enter normal boot mt_set_gpio_dir(GPIO_EXT_MD_DL_KEY, 1); #ifdef GPIO_EXT_USB_SW2 mt_set_gpio_out(GPIO_EXT_MD_DL_KEY, 0);//set evb #else mt_set_gpio_out(GPIO_EXT_MD_DL_KEY, 1);//set phone #endif cm_disable_ext_md_wdt_irq(); cm_disable_ext_md_wakeup_irq(); cm_disable_ext_md_exp_irq(); mt_set_gpio_dir(GPIO_EXT_AP_WK_MD, 1); mt_set_gpio_out(GPIO_EXT_AP_WK_MD, 0); #ifndef GPIO_EXT_USB_SW2 mt_set_gpio_dir(GPIO_EXT_MD_META, 1); mt_set_gpio_out(GPIO_EXT_MD_META, 0); #endif mt_set_gpio_out(GPIO_EXT_MD_PWR_KEY, 0); //EMD_MSG_INF("chr","cm_do_md_power_off:GPIO_EXT_MD_PWR_KEY(%d)2\n",mt_get_gpio_out(GPIO_EXT_MD_PWR_KEY)); mt_set_gpio_dir(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_WK_AP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_dir(GPIO_EXT_MD_EXP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_EXP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_EXP, 0); mt_set_gpio_dir(GPIO_EXT_MD_DUMP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_DUMP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_DUMP, 0); //For low power, we switch UART GPIO when power off md mt_set_gpio_mode(GPIO_UART_URXD1_PIN, 0); mt_set_gpio_mode(GPIO_UART_UTXD1_PIN, 0); mt_set_gpio_mode(GPIO_UART_URTS1_PIN, 0); mt_set_gpio_mode(GPIO_UART_UCTS1_PIN, 0); mt_set_gpio_dir(GPIO_UART_URXD1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_URXD1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_URXD1_PIN, 0); mt_set_gpio_dir(GPIO_UART_UTXD1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_UTXD1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_UTXD1_PIN, 0); mt_set_gpio_dir(GPIO_UART_URTS1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_URTS1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_URTS1_PIN, 0); mt_set_gpio_dir(GPIO_UART_UCTS1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_UCTS1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_UCTS1_PIN, 0); EMD_MSG_INF("chr","uart gpio pull down\n"); cm_dump_gpio(); return 0; }
void cm_gpio_setup(void) { EMD_MSG_INF("chr","cm_gpio_setup 1\n"); atomic_set(&traffic_on, 0); atomic_set(&allow_wk_md, 0); // MD wake up AP pin mt_set_gpio_pull_enable(GPIO_EXT_MD_WK_AP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_dir(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_mode(GPIO_EXT_MD_WK_AP, GPIO_EXT_MD_WK_AP_M_EINT); EMD_MSG_INF("chr","cm_gpio_setup:GPIO_EXT_MD_WK_AP(%x)=%d\n",GPIO_EXT_MD_WK_AP,mt_get_gpio_out(GPIO_EXT_MD_WK_AP)); // AP wake up MD pin mt_set_gpio_mode(GPIO_EXT_AP_WK_MD, GPIO_EXT_AP_WK_MD_M_GPIO); // GPIO Mode mt_set_gpio_dir(GPIO_EXT_AP_WK_MD, 1); mt_set_gpio_out(GPIO_EXT_AP_WK_MD, 0); EMD_MSG_INF("chr","cm_gpio_setup:GPIO_EXT_AP_WK_MD(%x)=%d\n",GPIO_EXT_AP_WK_MD,mt_get_gpio_out(GPIO_EXT_AP_WK_MD)); // Rest MD pin mt_set_gpio_mode(GPIO_EXT_MD_RST, GPIO_EXT_MD_RST_M_GPIO); //GPIO202 is reset pin mt_set_gpio_pull_enable(GPIO_EXT_MD_RST, 0); mt_set_gpio_pull_select(GPIO_EXT_MD_RST, 1); cm_relese_rst_signal(); EMD_MSG_INF("chr","cm_gpio_setup 4\n"); EMD_MSG_INF("chr","cm_gpio_setup:GPIO_EXT_MD_RST(%x)=%d\n",GPIO_EXT_MD_RST,mt_get_gpio_out(GPIO_EXT_MD_RST)); // MD power key pin mt_set_gpio_mode(GPIO_EXT_MD_PWR_KEY, GPIO_EXT_MD_PWR_KEY_M_GPIO); //GPIO 200 is power key mt_set_gpio_pull_enable(GPIO_EXT_MD_PWR_KEY, 0); mt_set_gpio_dir(GPIO_EXT_MD_PWR_KEY, 1); mt_set_gpio_out(GPIO_EXT_MD_PWR_KEY, 0); EMD_MSG_INF("chr","cm_gpio_setup:GPIO_EXT_MD_PWR_KEY(%x)=%d\n",GPIO_EXT_MD_PWR_KEY,mt_get_gpio_out(GPIO_EXT_MD_PWR_KEY)); // MD WDT irq pin mt_set_gpio_pull_enable(GPIO_EXT_MD_WD, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WD, 1); mt_set_gpio_dir(GPIO_EXT_MD_WD, 0); mt_set_gpio_mode(GPIO_EXT_MD_WD, GPIO_EXT_MD_WD_M_EINT); // EINT168 EMD_MSG_INF("chr","cm_gpio_setup GPIO_EXT_MD_WD(%x)(in)=%d\n",GPIO_EXT_MD_WD,mt_get_gpio_in(GPIO_EXT_MD_WD)); // MD Exception irq pin mt_set_gpio_pull_enable(GPIO_EXT_MD_EXP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_EXP, 1); mt_set_gpio_dir(GPIO_EXT_MD_EXP, 0); mt_set_gpio_mode(GPIO_EXT_MD_EXP, GPIO_EXT_MD_EXP_M_EINT); // EMD_MSG_INF("chr","cm_gpio_setup GPIO_EXT_MD_EXP(%x)(in)=%d\n",GPIO_EXT_MD_EXP,mt_get_gpio_in(GPIO_EXT_MD_EXP)); #ifndef GPIO_EXT_USB_SW2 mt_set_gpio_mode(GPIO_EXT_MD_META, GPIO_EXT_MD_META_M_GPIO); mt_set_gpio_dir(GPIO_EXT_MD_META, 1);// Using input floating mt_set_gpio_out(GPIO_EXT_MD_META, 0);// Default @ reset state EMD_MSG_INF("chr","cm_gpio_setup:phone GPIO_EXT_MD_META(%x)=%d\n",GPIO_EXT_MD_META,mt_get_gpio_out(GPIO_EXT_MD_META)); #else mt_set_gpio_pull_enable(GPIO_EXT_MD_DUMP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_DUMP, 0); mt_set_gpio_dir(GPIO_EXT_MD_DUMP, 1); mt_set_gpio_mode(GPIO_EXT_MD_DUMP, GPIO_EXT_MD_DUMP_M_GPIO); EMD_MSG_INF("chr","cm_gpio_setup:evb GPIO_EXT_MD_DUMP(%x)(in)=(%d)\n",GPIO_EXT_MD_DUMP,mt_get_gpio_in(GPIO_EXT_MD_DUMP)); #endif // Configure eint eint_var_init(); }
void cm_release_wakeup_md_signal(void) { if(atomic_read(&allow_wk_md)) { mt_set_gpio_out(GPIO_EXT_AP_WK_MD, 1); EMD_MSG_INF("chr","cm_release_wakeup_md_signal:GPIO_EXT_AP_WK_MD=%d,1!\n",mt_get_gpio_out(GPIO_EXT_AP_WK_MD)); } else { EMD_MSG_INF("chr","cm_release_wakeup_md_signal:GPIO_EXT_AP_WK_MD=%d,ignore!\n",mt_get_gpio_out(GPIO_EXT_AP_WK_MD)); } }
void cm_dump_gpio(void) { unsigned int pin =0; pin=GPIO_EXT_MD_DL_KEY; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_DL_KEY: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_PWR_KEY; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_PWR_KEY: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_RST; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_RST: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_WD; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_WD: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_WK_AP; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_WK_AP: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_AP_WK_MD; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_AP_WK_MD: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_EXP; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_EXP: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_DUMP; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_DUMP: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); #ifndef GPIO_EXT_USB_SW2 pin=GPIO_EXT_MD_META; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_META: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); #endif }
// ccci_user_ready_to_reset: ready to reset and request to reset md // @handle: a user handle gotten from ccci_reset_register() // return 0 if emd is reset; return negative value for failure int emd_user_ready_to_reset(int handle) { int i,ret; int reset_ready = 1; if( 0==atomic_read(&rst_on_going) ){ EMD_MSG_INF("chr", "Ignore reset request\n"); mutex_lock(&emd_reset_mutex); emd_reset_sta[handle].is_allocate = 0; emd_reset_sta[handle].is_reset = 0; mutex_unlock(&emd_reset_mutex); return 0; } if (handle >= NR_EMD_RESET_USER) { EMD_MSG_INF("chr", "reset_request: invalid handle:%d \n", handle); return -1; } if (emd_reset_sta[handle].is_allocate == 0) { EMD_MSG_INF("chr", "reset_request: handle(%d) not alloc: alloc=%d \n", handle, emd_reset_sta[handle].is_allocate); return -1; } EMD_MSG_INF("chr", "%s (%d) call reset request \n",current->comm, handle); mutex_lock(&emd_reset_mutex); emd_reset_sta[handle].is_allocate = 0; emd_reset_sta[handle].is_reset = 1; EMD_MSG_INF("chr", "Dump not ready list++++\n"); for (i = 0; i < NR_EMD_RESET_USER; i++) { if (emd_reset_sta[i].is_allocate && (emd_reset_sta[i].is_reset == 0)) { reset_ready = 0; EMD_MSG_INF("chr", " ==> %s\n", emd_reset_sta[i].name); } } EMD_MSG_INF("chr", "Dump not ready list----\n"); mutex_unlock(&emd_reset_mutex); if (reset_ready == 0) return -1; // All service ready, send reset request EMD_MSG_INF("chr", "Reset MD by %s(%d) \n", current->comm, handle); if(emd_status != EMD_STATE_NOT_READY) { emd_power_off(); } msleep(EMD_RST_LOW_TIME); check_drv_rdy_to_rst(); EMD_MSG_INF("chr","send wait done message\n"); ret = send_message_to_user(&drv_client[0], EMD_MSG_WAIT_DONE); if( ret!=0 ) EMD_MSG_INF("chr","send wait done message fail\n"); return 0; }
void cm_hold_rst_signal(void) { EMD_MSG_INF("chr","cm_hold_rst_signal1:GPIO_EXT_MD_RST(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); mt_set_gpio_dir(GPIO_EXT_MD_RST, 1); #ifdef GPIO_EXT_USB_SW2 mt_set_gpio_out(GPIO_EXT_MD_RST, 0); EMD_MSG_INF("chr","cm_hold_rst_signal2:set evb GPIO_EXT_MD_RST(out)=%d!\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); #else mt_set_gpio_out(GPIO_EXT_MD_RST, 1); EMD_MSG_INF("chr","cm_hold_rst_signal2:set phone GPIO_EXT_MD_RST(out)=%d!\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); #endif }
static int emd_ctl_drv_suspend(struct platform_device *dev, pm_message_t state) { EMD_MSG_INF("chr","client:%d suspend!!\n", dev->id); if( (dev->id < 0)||(dev->id >= EMD_CHR_CLIENT_NUM) ) EMD_MSG_INF("chr","invalid id%d!!\n", dev->id); else{ if(0 == dev->id){ emd_spm_suspend(emd_status==EMD_STATE_NOT_READY); } } return 0; }
static int emd_ctl_drv_resume(struct platform_device *dev) { EMD_MSG_INF("chr","client:%d resume!!\n", dev->id); if( (dev->id < 0)||(dev->id >= EMD_CHR_CLIENT_NUM) ) EMD_MSG_INF("chr","invalid id%d!!\n", dev->id); else{ if(0 == dev->id){ emd_spm_resume(); } } return 0; }
static int emd_send_enter_flight_mode(void) { int ret=0; if(emd_status!=EMD_STATE_READY) { EMD_MSG_INF("chr","emd_send_enter_flight_mode:ext md not ready!\n"); return -ENODEV; } EMD_MSG_INF("chr","emd_send_enter_flight_mode\n"); emd_power_off(); send_message_to_user(&drv_client[0], EMD_MSG_ENTER_FLIGHT_MODE); return ret; }
static int push_data(emd_dev_client_t *client, int data) { int size, ret; if(kfifo_is_full(&client->fifo)){ ret=-ENOMEM; EMD_MSG_INF("chr","sub_dev%d kfifo full\n",client->sub_dev_id); }else{ EMD_MSG_INF("chr","push data=0x%08x into sub_dev%d kfifo\n",data,client->sub_dev_id); size=kfifo_in(&client->fifo,&data,sizeof(int)); WARN_ON(size!=sizeof(int)); ret=sizeof(int); } return ret; }
static void emd_aseert_log_work_func(struct work_struct *data) { #if defined (CONFIG_MTK_AEE_FEATURE) char log[]="ExtMD exception\nMD:G*MT6261_S01*11C.unknown*0000/00/00 00:00\nAP:WG*MT6595_S00\n(MD)Debug"; EMD_MSG_INF("chr","Ext MD exception,%s\n",log); emd_aseert_log_wait_timeout = 1; wake_up_interruptible(&emd_aseert_log_wait); aed_md_exception((int *)log, sizeof(log), (int *)log, sizeof(log), log); #else EMD_MSG_INF("chr","Ext MD ASSERT -> RESET\n"); emd_aseert_log_wait_timeout = 1; wake_up_interruptible(&emd_aseert_log_wait); emd_request_reset(); #endif }
int request_ext_md_reset() { int ret = 0; if(atomic_add_return(1, &rst_on_going) == 1){ ret = send_message_to_user(&drv_client[0], EMD_MSG_REQUEST_RST); if(ret!=0){ EMD_MSG_INF("chr","request_ext_md_reset fail, msg does not send\n"); atomic_dec(&rst_on_going); } }else{ EMD_MSG_INF("chr","reset is on-going\n"); } return ret; }
static int emd_cfifo_release(struct inode *inode, struct file *file) { cfifo_instance_t *cfifo_instance = (cfifo_instance_t *)file->private_data; int md_id; cfifo_ctl_block_t *ctlb = NULL; md_id = cfifo_instance->m_md_id; ctlb = emd_cfifo_ctlb[md_id]; mutex_lock(&cfifo_instance->emd_cfifo_mutex); cfifo_instance->count--; EMD_MSG_INF("cfifo","[cfifo_close]Port%d count %d \n", cfifo_instance->idx, cfifo_instance->count); if (cfifo_instance->count == 0) { write_lock_bh(&cfifo_instance->emd_cfifo_rwlock); cfifo_instance->ready = 0; write_unlock_bh(&cfifo_instance->emd_cfifo_rwlock); if(cfifo_instance->reset_handle!=-1) { emd_user_ready_to_reset(cfifo_instance->reset_handle); } } mutex_unlock(&cfifo_instance->emd_cfifo_mutex); return 0; }
void cm_relese_rst_signal(void) { EMD_MSG_INF("chr","cm_relese_rst_signal1:GPIO_EXT_MD_RST(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); mt_set_gpio_dir(GPIO_EXT_MD_RST, 1); #ifdef GPIO_EXT_USB_SW2 mt_set_gpio_out(GPIO_EXT_MD_RST, 1); EMD_MSG_INF("chr","cm_relese_rst_signal2:GPIO_EXT_MD_RST(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); mt_set_gpio_pull_enable(GPIO_EXT_MD_RST, 1); mt_set_gpio_dir(GPIO_EXT_MD_RST, 0); mt_set_gpio_pull_select(GPIO_EXT_MD_RST, 1); EMD_MSG_INF("chr","cm_relese_rst_signal3:set evb GPIO_EXT_MD_RST(in)=%d!\n",mt_get_gpio_in(GPIO_EXT_MD_RST)); #else mt_set_gpio_out(GPIO_EXT_MD_RST, 0); EMD_MSG_INF("chr","cm_relese_rst_signal3:set phoneGPIO_EXT_MD_RST(in)=%d!\n",mt_get_gpio_in(GPIO_EXT_MD_RST)); #endif }
int cm_get_assertlog_status(void) { int val; mt_set_gpio_dir(GPIO_EXT_MD_DUMP, 0); val = mt_get_gpio_in(GPIO_EXT_MD_DUMP); EMD_MSG_INF("chr","cm_get_assertlog_status:GPIO_EXT_MD_EXP(in)=%d!\n",val); return val; }
int emd_md_exception(void) { emd_status=EMD_STATE_EXCEPTION; EMD_MSG_INF("chr","emd_md_exception happened!\n"); schedule_work(&emd_aseert_log_work); return 0; }
int eint_var_init(void) { memset(&ext_md_exp_eint, 0, sizeof(ext_md_exp_eint)); spin_lock_init(&ext_md_exp_eint.lock); memset(&ext_md_wdt_eint, 0, sizeof(ext_md_wdt_eint)); spin_lock_init(&ext_md_wdt_eint.lock); memset(&ext_md_wk_eint, 0, sizeof(ext_md_wk_eint)); spin_lock_init(&ext_md_wk_eint.lock); #ifdef CONFIG_OF EMD_MSG_INF("chr","%s: CONFIG_OF en\n", __func__); if(get_eint_info("DT_EXT_MD_EXP", &ext_md_exp_eint) != 0) return -1; if(get_eint_info("DT_EXT_MD_WDT", &ext_md_wdt_eint) != 0) return -1; if(get_eint_info("DT_EXT_MD_WK_UP", &ext_md_wk_eint) != 0) return -1; #else EMD_MSG_INF("chr","%s: CONFIG_OF dis\n", __func__); // For exp ext_md_exp_eint.gpio_id = GPIO_EXT_MD_EXP; ext_md_exp_eint.debounce_time = CUST_EINT_DT_EXT_MD_EXP_DEBOUNCE_CN; ext_md_exp_eint.irq_id = CUST_EINT_DT_EXT_MD_EXP_NUM; ext_md_exp_eint.intr_flag = CUST_EINT_DT_EXT_MD_EXP_TYPE; // For wdt ext_md_wdt_eint.gpio_id = GPIO_EXT_MD_WD; ext_md_wdt_eint.debounce_time = CUST_EINT_DT_EXT_MD_WDT_DEBOUNCE_CN; ext_md_wdt_eint.irq_id = CUST_EINT_DT_EXT_MD_WDT_NUM; ext_md_wdt_eint.intr_flag = CUST_EINT_DT_EXT_MD_WDT_TYPE; // For wakeup ext_md_wk_eint.gpio_id = GPIO_EXT_MD_WK_AP; ext_md_wk_eint.debounce_time = CUST_EINT_DT_EXT_MD_WK_UP_DEBOUNCE_CN; ext_md_wk_eint.irq_id = CUST_EINT_DT_EXT_MD_WK_UP_NUM; ext_md_wk_eint.intr_flag = CUST_EINT_DT_EXT_MD_WK_UP_TYPE; #endif EMD_MSG_INF("chr","%s: Eint-EXP(%d,%d,%d,%x)\n", __func__, ext_md_exp_eint.gpio_id, ext_md_exp_eint.debounce_time, \ ext_md_exp_eint.irq_id, ext_md_exp_eint.intr_flag); EMD_MSG_INF("chr","%s: Eint-WDT(%d,%d,%d,%x)\n", __func__, ext_md_wdt_eint.gpio_id, ext_md_wdt_eint.debounce_time, \ ext_md_wdt_eint.irq_id, ext_md_wdt_eint.intr_flag); EMD_MSG_INF("chr","%s: Eint-WK UP(%d,%d,%d,%x)\n", __func__, ext_md_wk_eint.gpio_id, ext_md_wk_eint.debounce_time, \ ext_md_wk_eint.irq_id, ext_md_wk_eint.intr_flag); return 0; }
static int emd_power_on(int bootmode) { EMD_MSG_INF("chr","emd_power_on, bootmode=%d\n",bootmode); #ifdef CONFIG_MTK_DT_USB_SUPPORT #ifdef CONFIG_PM_RUNTIME /* make sure usb device tree is waked up so that usb is ready */ usb11_auto_resume(); #endif #endif cm_do_md_power_on(bootmode); cm_register_irq_cb(0,ext_md_wdt_irq_cb); cm_register_irq_cb(1,ext_md_wakeup_irq_cb); cm_register_irq_cb(2,ext_md_exception_irq_cb); EMD_MSG_INF("chr","let_ext_md_go...\n"); let_ext_md_go(); return 0; }
static int let_ext_md_go(void) { int ret=0; int retry; ret = send_message_to_user(&drv_client[0], EMD_MSG_READY); atomic_set(&rst_on_going, 0); if( ret==0 ){ retry = cm_do_md_go(); EMD_MSG_INF("chr","cm_do_md_go, ret=%d\n", retry); emd_status = EMD_STATE_READY; }else{ EMD_MSG_INF("chr","let_ext_md_go fail, msg does not send\n"); ret = -1; } return ret; }
int cm_do_md_go(void) { int ret = -1; if (is_hold_rst) { is_hold_rst=0; unsigned int retry = 100; EMD_MSG_INF("chr","cm_do_md_go:1\n"); EMD_MSG_INF("chr","cm_do_md_go2:GPIO_EXT_MD_RST(out)=%d,GPIO_EXT_MD_WD(in)=%d\n",mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_in(GPIO_EXT_MD_WD)); cm_relese_rst_signal(); EMD_MSG_INF("chr","cm_do_md_go3:GPIO_EXT_MD_RST(out)=%d,GPIO_EXT_MD_WD(in)=%d\n",mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_in(GPIO_EXT_MD_WD)); // Check WDT pin to high while(retry>0){ retry--; if(mt_get_gpio_in(GPIO_EXT_MD_WD)==0) { msleep(10); } else { ret=100-retry; break; } } atomic_set(&traffic_on, 1); msleep(1000); // for use AP_WK_MD as EXT_MD_META, give 6261 bootloader sometime to read boot mode atomic_set(&allow_wk_md, 1); cm_hold_wakeup_md_signal(); EMD_MSG_INF("chr","cm_do_md_go4:GPIO_EXT_MD_RST(out)=%d,GPIO_EXT_MD_WD(in)=%d\n",mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_in(GPIO_EXT_MD_WD)); msleep(POWER_ON_HOLD_TIME); mt_set_gpio_out(GPIO_EXT_MD_PWR_KEY, 0); } mt_set_gpio_dir(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_WK_AP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WK_AP, 1); cm_enable_ext_md_wdt_irq(); cm_enable_ext_md_wakeup_irq(); cm_enable_ext_md_exp_irq(); //msleep(50); // WDT IRQ is level triggered now, no need this debounce ignore_wdt_interrupt = 0; return ret; }
void check_drv_rdy_to_rst(void) { int check_count = 0; // Max 10 seconds while(check_count<MAX_CHK_RDY_TIMES){ if(usb_h_acm_all_clear()) return; msleep(200); check_count++; } EMD_MSG_INF("chr","Wait drv rdy to rst timeout!!\n"); }
static int emd_send_leave_flight_mode(void) { int ret=0; if(emd_status==EMD_STATE_READY) { EMD_MSG_INF("chr","emd_send_leave_flight_mode:ext md is ready,cannot leave flight mode!\n"); return -EPERM; } if(atomic_add_return(1, &rst_on_going) == 1){ ret = send_message_to_user(&drv_client[0], EMD_MSG_LEAVE_FLIGHT_MODE); if(ret!=0){ EMD_MSG_INF("chr","emd_send_leave_flight_mode fail, msg does not send\n"); atomic_dec(&rst_on_going); } }else{ EMD_MSG_INF("chr","emd_send_leave_flight_mode:reset is on-going\n"); } return ret; }
static void emd_power_off(void) { EMD_MSG_INF("chr","emd_power_off\n"); #if defined(MTK_DT_SUPPORT) && !defined(EVDO_DT_SUPPORT) #ifdef CONFIG_PM_RUNTIME /* make sure usb device tree is waked up so that usb is ready */ usb11_auto_resume(); #endif #endif cm_do_md_power_off(); emd_status = EMD_STATE_NOT_READY; }
static int pop_data(emd_dev_client_t *client, int *buf) { int ret = 0; if(!kfifo_is_empty(&client->fifo)) { ret = kfifo_out(&client->fifo, buf, sizeof(int)); EMD_MSG_INF("chr","pop data=0x%08x from sub_dev%d kfifo.\n",*buf,client->sub_dev_id); } return ret; }
static int emd_dev_release(struct inode *inode, struct file *file) { int ret=0; emd_dev_client_t *client=(emd_dev_client_t *)file->private_data; EMD_MSG_INF("chr","client %d call release\n", client->sub_dev_id); mutex_lock(&client->emd_mutex); client->user_num--; mutex_unlock(&client->emd_mutex); return 0; }
int cm_do_md_go(void) { int ret = -1; if (is_hold_rst) { is_hold_rst=0; unsigned int retry = 100; EMD_MSG_INF("chr","cm_do_md_go:1\n"); EMD_MSG_INF("chr","cm_do_md_go2:GPIO_EXT_MD_RST(out)=%d,GPIO_EXT_MD_WD(in)=%d\n",mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_in(GPIO_EXT_MD_WD)); cm_relese_rst_signal(); atomic_set(&traffic_on, 1); EMD_MSG_INF("chr","cm_do_md_go3:GPIO_EXT_MD_RST(out)=%d,GPIO_EXT_MD_WD(in)=%d\n",mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_in(GPIO_EXT_MD_WD)); // Check WDT pin to high while(retry>0){ retry--; if(mt_get_gpio_in(GPIO_EXT_MD_WD)==0) { msleep(10); } else { ret=100-retry; break; } } EMD_MSG_INF("chr","cm_do_md_go4:GPIO_EXT_MD_RST(out)=%d,GPIO_EXT_MD_WD(in)=%d\n",mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_in(GPIO_EXT_MD_WD)); msleep(POWER_ON_HOLD_TIME); mt_set_gpio_out(GPIO_EXT_MD_PWR_KEY, 0); } mt_set_gpio_dir(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_WK_AP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WK_AP, 1); cm_enable_ext_md_wdt_irq(); cm_enable_ext_md_wakeup_irq(); cm_enable_ext_md_exp_irq(); msleep(50); ignore_wdt_interrupt = 0; return ret; }