static ssize_t cbp_reset_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { unsigned long val; if (strict_strtoul(buf, 10, &val)) return -EINVAL; if (val < 0) return -EINVAL; if (val){ //sys_reset_cbp(); //c2k_modem_reset_platform(); c2k_reset_modem(); LOGPRT(LOG_INFO, "AP reset CBP.\n"); } else{ LOGPRT(LOG_ERR, "%s: reset cbp use value 1.\n", __func__); } return n; }
static int modem_detect_host(const char *host_id) { /* HACK!!! * Rely on mmc->class_dev.class set in mmc_alloc_host * Tricky part: a new mmc hook is being (temporary) created * to discover mmc_host class. * Do you know more elegant way how to enumerate mmc_hosts? */ struct mmc_host *mmc = NULL; struct class_dev_iter iter; struct device *dev; int ret = -1; #if 1 printk("[C2K] before alloc host\n"); mmc = mmc_alloc_host(0, NULL); if (!mmc){ printk("[C2K] mmc_aloc_host error\n"); ret = -ENOMEM; goto out; } printk("[C2K] mmc_aloc_host success\n"); BUG_ON(!mmc->class_dev.class); class_dev_iter_init(&iter, mmc->class_dev.class, NULL, NULL); for (;;) { dev = class_dev_iter_next(&iter); if (!dev) { printk("[C2K] class dev iter next failed\n"); LOGPRT(LOG_ERR, "%s: %d\n", __func__, __LINE__); break; } else { struct mmc_host *host = container_of(dev, struct mmc_host, class_dev); if (dev_name(&host->class_dev) && strcmp(dev_name(&host->class_dev), host_id)) continue; ret = 0; break; } } mmc_free_host(mmc); #endif //ret = 0; out: return ret; }
static void modem_detect(struct work_struct *work) { struct cbp_reset *cbp_rst_ind = NULL; int ret; int level = 0; LOGPRT(LOG_NOTICE, "%s %d .\n",__func__,__LINE__); cbp_rst_ind = container_of(work, struct cbp_reset, reset_work); #ifdef CONFIG_EVDO_DT_VIA_SUPPORT if((cbp_rst_ind->host == NULL)){/*for first detection and ipoh*/ LOGPRT(LOG_NOTICE, "%s %d modem_detect_card.\n",__func__,__LINE__); ret = modem_detect_card(cbp_rst_ind); if (ret){ LOGPRT(LOG_ERR, "%s: modem detect failed.\n", __func__); } } else{/*for device reset*/ level = !!c2k_gpio_get_value(cbp_rst_ind->rst_ind_gpio); if(level == cbp_rst_ind->rst_ind_polar){ LOGPRT(LOG_NOTICE, "%s %d power on sdio host\n", __func__, __LINE__); c2k_wake_host(0); c2k_wake_host(1); } else{ LOGPRT(LOG_NOTICE, "%s %d power off sdio host\n", __func__, __LINE__); //c2k_gpio_direction_output(GPIO_C2K_MDM_PWR_EN, 1); modem_reset_handler(); c2k_wake_host(0); } } #else level = !!c2k_gpio_get_value(cbp_rst_ind->rst_ind_gpio); if(level == cbp_rst_ind->rst_ind_polar){ LOGPRT(LOG_NOTICE, "%s %d power on sdio host\n", __func__, __LINE__); c2k_wake_host(0); c2k_wake_host(1); } else{ LOGPRT(LOG_NOTICE, "%s %d power off sdio host\n", __func__, __LINE__); //c2k_gpio_direction_output(GPIO_C2K_MDM_PWR_EN, 1); modem_reset_handler(); c2k_wake_host(0); } #endif }
static irqreturn_t c2k_wdt_isr(int irq, void *data) { unsigned long flags; struct cbp_platform_data *cdata = &cbp_data; LOGPRT(LOG_ERR, "%s: receive c2k wdt interrupt, prepare to reset c2k...!\n", __func__); dump_c2k_iram(); //wake_lock_timeout(&cmdata->wlock, MDM_RST_LOCK_TIME * HZ); modem_notify_event(MDM_EVT_NOTIFY_WDT); spin_lock_irqsave(&cdata->modem->status_lock, flags); cdata->modem->status = MD_OFF; spin_unlock_irqrestore(&cdata->modem->status_lock, flags); atomic_set(&cdata->modem->tx_fifo_cnt, TX_FIFO_SZ); wake_up(&cdata->modem->wait_tx_done_q); return IRQ_HANDLED; }
static ssize_t cbp_jtag_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { unsigned long val; if (strict_strtoul(buf, 10, &val)) return -EINVAL; if (val < 0) return -EINVAL; if (val){ //sys_reset_cbp(); //c2k_modem_reset_platform(); jtag_mode = val; enable_c2k_jtag(val); LOGPRT(LOG_INFO, "set cbp jtag to mode %d.\n", jtag_mode); } return n; }
void gpio_irq_cbp_rst_ind(void) { int level = 0; unsigned long flags; struct cbp_platform_data *cdata = &cbp_data; level = !!c2k_gpio_get_value(cbp_rst_ind->rst_ind_gpio); if(level != cbp_rst_ind->rst_ind_polar){/*1:cbp reset happened*/ if (cdata->modem){ LOGPRT(LOG_INFO, "%s: set md off.\n", __func__); spin_lock_irqsave(&cdata->modem->status_lock, flags); cdata->modem->status = MD_OFF; spin_unlock_irqrestore(&cdata->modem->status_lock, flags); } #ifdef CONFIG_EVDO_DT_VIA_SUPPORT wake_up(&cbp_flow_ctrl->wait_q); wake_up(&cbp_data_ack->wait_q); #else atomic_set(&cdata->modem->tx_fifo_cnt, TX_FIFO_SZ); wake_up(&cdata->modem->wait_tx_done_q); #endif } queue_work(cbp_rst_ind->reset_wq, &cbp_rst_ind->reset_work); }
//static int __devinit cbp_probe(struct platform_device *pdev) static int cbp_probe(struct platform_device *pdev) { struct cbp_platform_data *plat = pdev->dev.platform_data; int ret = -1; /* must have platform data */ if (!plat) { LOGPRT(LOG_ERR, "%s: no platform data!\n", __func__); ret = -EINVAL; goto out; } #if 0 if(plat->bus && !strcmp(plat->bus,"sdio")){ if(plat->detect_host){ ret = plat->detect_host(plat->host_id); if(ret){ LOGPRT(LOG_ERR, "%s: host %s dectect failed!\n", __func__, plat->host_id); goto out; } } else{ LOGPRT(LOG_ERR, "%s: bus %s have no dectect function!\n", __func__, plat->bus); goto out; } } else{ LOGPRT(LOG_ERR, "%s: unknow bus!\n", __func__); goto out; } #endif if(GPIO_C2K_VALID(plat->gpio_data_ack)){ cbp_data_ack = kzalloc(sizeof(struct cbp_wait_event), GFP_KERNEL); if (!cbp_data_ack){ ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d kzalloc cbp_data_ack failed \n",__func__, __LINE__); goto err_kzalloc_cbp_data_ack; } init_waitqueue_head(&cbp_data_ack->wait_q); atomic_set(&cbp_data_ack->state, MODEM_ST_UNKNOW); cbp_data_ack->wait_gpio = plat->gpio_data_ack; cbp_data_ack->wait_polar = plat->gpio_data_ack_polar; LOGPRT(LOG_ERR, "cbp_data_ack->wait_gpio=%d\n",cbp_data_ack->wait_gpio); LOGPRT(LOG_ERR, "cbp_data_ack->wait_polar=%d\n",cbp_data_ack->wait_polar); c2k_gpio_irq_mask(plat->gpio_data_ack); c2k_gpio_direction_input_for_irq(plat->gpio_data_ack); c2k_gpio_set_irq_type(plat->gpio_data_ack, IRQF_TRIGGER_FALLING); ret = c2k_gpio_request_irq(plat->gpio_data_ack, gpio_irq_data_ack, IRQF_SHARED | IRQF_TRIGGER_FALLING, DRIVER_NAME "(data_ack)", cbp_data_ack); c2k_gpio_irq_unmask(plat->gpio_data_ack); if (ret < 0) { LOGPRT(LOG_ERR, "%s: %d fail to request irq for data_ack!!\n", __func__, __LINE__); goto err_req_irq_data_ack; } plat->cbp_data_ack = cbp_data_ack; plat->data_ack_wait_event = data_ack_wait_event; plat->data_ack_enable =true; } if(GPIO_C2K_VALID(plat->gpio_flow_ctrl)){ cbp_flow_ctrl = kzalloc(sizeof(struct cbp_wait_event), GFP_KERNEL); if (!cbp_flow_ctrl){ ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d kzalloc cbp_flow_ctrl failed \n",__func__, __LINE__); goto err_kzalloc_cbp_flow_ctrl; } init_waitqueue_head(&cbp_flow_ctrl->wait_q); atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_DISABLE); cbp_flow_ctrl->wait_gpio = plat->gpio_flow_ctrl; cbp_flow_ctrl->wait_polar = plat->gpio_flow_ctrl_polar; LOGPRT(LOG_ERR, "cbp_flow_ctrl->wait_gpio=%d\n",cbp_flow_ctrl->wait_gpio); LOGPRT(LOG_ERR, "cbp_flow_ctrl->wait_polar=%d\n",cbp_flow_ctrl->wait_polar); c2k_gpio_irq_mask(plat->gpio_flow_ctrl); c2k_gpio_direction_input_for_irq(plat->gpio_flow_ctrl); //c2k_gpio_set_irq_type(plat->gpio_flow_ctrl, IRQ_TYPE_LEVEL_LOW |IRQ_TYPE_LEVEL_HIGH); c2k_gpio_set_irq_type(plat->gpio_flow_ctrl, IRQF_TRIGGER_FALLING); ret = c2k_gpio_request_irq(plat->gpio_flow_ctrl, gpio_irq_flow_ctrl, IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRIVER_NAME "(flow_ctrl)", cbp_flow_ctrl); c2k_gpio_irq_unmask(plat->gpio_flow_ctrl); if (ret < 0) { LOGPRT(LOG_ERR, "%s: %d fail to request irq for flow_ctrl!!\n", __func__, __LINE__); goto err_req_irq_flow_ctrl; } plat->cbp_flow_ctrl= cbp_flow_ctrl; plat->flow_ctrl_wait_event = flow_ctrl_wait_event; plat->flow_ctrl_enable = true; } if(GPIO_C2K_VALID(plat->gpio_rst_ind)){ cbp_rst_ind = kzalloc(sizeof(struct cbp_reset), GFP_KERNEL); if (!cbp_rst_ind){ ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d kzalloc cbp_rst_ind failed \n",__func__, __LINE__); goto err_kzalloc_cbp_rst_ind; } cbp_rst_ind->name = "cbp_rst_ind_wq"; cbp_rst_ind->reset_wq = create_singlethread_workqueue(cbp_rst_ind->name); if (cbp_rst_ind->reset_wq == NULL) { ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d error creat rst_ind_workqueue \n",__func__, __LINE__); goto err_create_work_queue; } INIT_WORK(&cbp_rst_ind->reset_work, modem_detect); cbp_rst_ind->rst_ind_gpio = plat->gpio_rst_ind; cbp_rst_ind->rst_ind_polar = plat->gpio_rst_ind_polar; cbp_rst_ind->host = NULL; #if 0 c2k_gpio_irq_mask(plat->gpio_rst_ind); c2k_gpio_direction_input_for_irq(plat->gpio_rst_ind); c2k_gpio_set_irq_type(plat->gpio_rst_ind, IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING); ret = c2k_gpio_request_irq(plat->gpio_rst_ind, gpio_irq_cbp_rst_ind, IRQF_SHARED |IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING, DRIVER_NAME "(rst_ind)", cbp_rst_ind); c2k_gpio_irq_unmask(plat->gpio_rst_ind); if (ret < 0) { LOGPRT(LOG_ERR, "%s: %d fail to request irq for rst_ind!!\n", __func__, __LINE__); goto err_req_irq_rst_ind; } #endif plat->rst_ind_enable = true; } cbp_excp_ind = kzalloc(sizeof(struct cbp_exception), GFP_KERNEL); if (!cbp_excp_ind){ ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d kzalloc cbp_rst_ind failed \n",__func__, __LINE__); goto err_kzalloc_cbp_excp_ind; } cbp_excp_ind->name = "cbp_excp_ind_wq"; cbp_excp_ind->excp_wq = create_singlethread_workqueue(cbp_excp_ind->name); if (cbp_excp_ind->excp_wq == NULL) { ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d error creat rst_ind_workqueue \n",__func__, __LINE__); goto err_create_excp_work_queue; } //Todo: workqueue function need to be implemented //INIT_WORK(&cbp_excp_ind->excp_work, modem_detect); INIT_WORK(&cbp_excp_ind->excp_work, modem_detect_for_excp); cbp_excp_ind->host = NULL; #ifndef CONFIG_EVDO_DT_VIA_SUPPORT if (GPIO_C2K_VALID(plat->gpio_cp_exception)){ cbp_excp_ind->excp_ind_gpio = plat->gpio_cp_exception; c2k_gpio_irq_mask(plat->gpio_cp_exception); c2k_gpio_set_irq_type(plat->gpio_cp_exception, IRQF_TRIGGER_FALLING); ret = c2k_gpio_request_irq(plat->gpio_cp_exception, gpio_irq_cbp_excp_ind, IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRIVER_NAME "(c2k EE)", cbp_excp_ind); c2k_gpio_irq_unmask(plat->gpio_cp_exception); if (ret < 0) { LOGPRT(LOG_ERR, "%s: %d fail to request irq for flow_ctrl!!\n", __func__, __LINE__); goto err_req_irq_excp; } } plat->c2k_wdt_irq_id = get_c2k_wdt_irq_id(); LOGPRT(LOG_INFO, "get c2k wdt irq id %d\n", plat->c2k_wdt_irq_id); #if 1 if (plat->c2k_wdt_irq_id) ret = request_irq(plat->c2k_wdt_irq_id, c2k_wdt_isr, IRQF_TRIGGER_NONE, "C2K_CCCI", plat); else LOGPRT(LOG_ERR, "%s: %d fail to get wdt irq id!!\n", __func__, __LINE__); #endif #endif if((GPIO_C2K_VALID(plat->gpio_ap_wkup_cp)) && (GPIO_C2K_VALID(plat->gpio_cp_ready)) && (GPIO_C2K_VALID(plat->gpio_cp_wkup_ap)) && (GPIO_C2K_VALID(plat->gpio_ap_ready))){ sdio_tx_handle.gpio_wake = plat->gpio_ap_wkup_cp; sdio_tx_handle.gpio_ready = plat->gpio_cp_ready; sdio_tx_handle.polar = plat->gpio_sync_polar; ret = asc_tx_register_handle(&sdio_tx_handle); if(ret){ LOGPRT(LOG_ERR, "%s %d asc_tx_register_handle failed.\n",__FUNCTION__,__LINE__); goto err_ipc; } ret = asc_tx_add_user(sdio_tx_handle.name, &sdio_tx_user); if(ret){ LOGPRT(LOG_ERR, "%s %d asc_tx_add_user failed.\n",__FUNCTION__,__LINE__); goto err_ipc; } sdio_rx_handle.gpio_wake = plat->gpio_cp_wkup_ap; sdio_rx_handle.gpio_ready = plat->gpio_ap_ready; sdio_rx_handle.polar = plat->gpio_sync_polar; ret = asc_rx_register_handle(&sdio_rx_handle); if(ret){ LOGPRT(LOG_ERR, "%s %d asc_rx_register_handle failed.\n",__FUNCTION__,__LINE__); goto err_ipc; } ret = asc_rx_add_user(sdio_rx_handle.name, &sdio_rx_user); if(ret){ LOGPRT(LOG_ERR, "%s %d asc_rx_add_user failed.\n",__FUNCTION__,__LINE__); goto err_ipc; } plat->ipc_enable = true; plat->tx_handle = &sdio_tx_handle; } ret = plat->cbp_setup(plat); if(ret){ LOGPRT(LOG_ERR, "%s: host %s setup failed!\n", __func__, plat->host_id); goto err_ipc; } cbp_power_kobj = c2k_kobject_add("power"); if (!cbp_power_kobj){ LOGPRT(LOG_ERR, "error c2k_kobject_add!\n"); ret = -ENOMEM; goto err_create_kobj; } LOGPRT(LOG_INFO, " cbp initialized on host %s successfully, bus is %s !\n", plat->host_id, plat->bus); return sysfs_create_group(cbp_power_kobj, &g_power_attr_group); err_create_kobj: plat->cbp_destroy(); err_ipc: #if 0 if(GPIO_C2K_VALID(plat->gpio_rst_ind)){ free_irq(c2k_gpio_to_irq(plat->gpio_rst_ind), cbp_rst_ind); } err_req_irq_rst_ind: if(GPIO_C2K_VALID(plat->gpio_rst_ind)){ } #endif #ifndef CONFIG_EVDO_DT_VIA_SUPPORT err_req_irq_excp: if(GPIO_C2K_VALID(plat->gpio_cp_exception)){ destroy_workqueue(cbp_excp_ind->excp_wq); } #endif err_create_excp_work_queue: kfree(cbp_excp_ind); err_kzalloc_cbp_excp_ind: if(GPIO_C2K_VALID(plat->gpio_rst_ind)){ destroy_workqueue(cbp_rst_ind->reset_wq); } err_create_work_queue: if(GPIO_C2K_VALID(plat->gpio_rst_ind)){ kfree(cbp_rst_ind); } err_kzalloc_cbp_rst_ind: if(GPIO_C2K_VALID(plat->gpio_flow_ctrl)){ free_irq(c2k_gpio_to_irq(plat->gpio_flow_ctrl), cbp_flow_ctrl); } err_req_irq_flow_ctrl: if(GPIO_C2K_VALID(plat->gpio_flow_ctrl)){ kfree(cbp_flow_ctrl); } err_kzalloc_cbp_flow_ctrl: if(GPIO_C2K_VALID(plat->gpio_data_ack)){ free_irq(c2k_gpio_to_irq(plat->gpio_data_ack), cbp_data_ack); } err_req_irq_data_ack: if(GPIO_C2K_VALID(plat->gpio_data_ack)){ kfree(cbp_data_ack); } err_kzalloc_cbp_data_ack: out: return ret; }
//static int __devinit cbp_probe(struct platform_device *pdev) static int cbp_probe(struct platform_device *pdev) { struct cbp_platform_data *plat = pdev->dev.platform_data; int ret = -1; /* must have platform data */ if (!plat) { LOGPRT(LOG_ERR, "%s: no platform data!\n", __func__); ret = -EINVAL; goto out; } if(plat->bus && !strcmp(plat->bus,"sdio")){ if(plat->detect_host){ ret = plat->detect_host(plat->host_id); if(ret){ LOGPRT(LOG_ERR, "%s: host %s dectect failed!\n", __func__, plat->host_id); goto out; } } else{ LOGPRT(LOG_ERR, "%s: bus %s have no dectect function!\n", __func__, plat->bus); goto out; } } else{ LOGPRT(LOG_ERR, "%s: unknow bus!\n", __func__); goto out; } if((GPIO_OEM_VALID(plat->gpio_sd_select)) && (GPIO_OEM_VALID(plat->gpio_mc3_enable))){ ret = oem_gpio_request(plat->gpio_mc3_enable, DRIVER_NAME"(MC3_EN_N)"); if(ret < 0){ LOGPRT(LOG_ERR, "%s: %d fail to requset MC3_EN_N gpio %d ret =%d!!\n", __func__, __LINE__, plat->gpio_mc3_enable,ret); goto out; } ret = oem_gpio_request(plat->gpio_sd_select, DRIVER_NAME"(SD_SEL_N)"); if(ret < 0){ LOGPRT(LOG_ERR, "%s: %d fail to requset SD_SEL_N gpio %d ret =%d!!\n", __func__, __LINE__, plat->gpio_sd_select,ret); goto err_req_sd_sel; } oem_gpio_direction_output(GPIO_VIATEL_MC3_EN_N, 0); //MC3_EN_N oem_gpio_direction_output(GPIO_VIATEL_SD_SEL_N, 0); //SD_SEL_N } if(GPIO_OEM_VALID(plat->gpio_data_ack)){ cbp_data_ack = kzalloc(sizeof(struct cbp_wait_event), GFP_KERNEL); if (!cbp_data_ack){ ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d kzalloc cbp_data_ack failed \n",__func__, __LINE__); goto err_kzalloc_cbp_data_ack; } init_waitqueue_head(&cbp_data_ack->wait_q); atomic_set(&cbp_data_ack->state, MODEM_ST_UNKNOW); cbp_data_ack->wait_gpio = plat->gpio_data_ack; cbp_data_ack->wait_polar = plat->gpio_data_ack_polar; LOGPRT(LOG_ERR, "cbp_data_ack->wait_gpio=%d\n",cbp_data_ack->wait_gpio); LOGPRT(LOG_ERR, "cbp_data_ack->wait_polar=%d\n",cbp_data_ack->wait_polar); ret = oem_gpio_request(plat->gpio_data_ack, DRIVER_NAME "(data_ack)"); if(ret < 0){ LOGPRT(LOG_ERR, "%s: %d fail to requset data_ack gpio %d ret =%d!!\n", __func__, __LINE__, plat->gpio_data_ack, ret); goto err_req_data_ack; } oem_gpio_irq_mask(plat->gpio_data_ack); oem_gpio_direction_input_for_irq(plat->gpio_data_ack); oem_gpio_set_irq_type(plat->gpio_data_ack, IRQF_TRIGGER_FALLING); ret = oem_gpio_request_irq(plat->gpio_data_ack, gpio_irq_data_ack, IRQF_SHARED | IRQF_TRIGGER_FALLING, DRIVER_NAME "(data_ack)", cbp_data_ack); oem_gpio_irq_unmask(plat->gpio_data_ack); if (ret < 0) { LOGPRT(LOG_ERR, "%s: %d fail to request irq for data_ack!!\n", __func__, __LINE__); goto err_req_irq_data_ack; } plat->cbp_data_ack = cbp_data_ack; plat->data_ack_wait_event = data_ack_wait_event; plat->data_ack_enable =true; } if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){ cbp_flow_ctrl = kzalloc(sizeof(struct cbp_wait_event), GFP_KERNEL); if (!cbp_flow_ctrl){ ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d kzalloc cbp_flow_ctrl failed \n",__func__, __LINE__); goto err_kzalloc_cbp_flow_ctrl; } init_waitqueue_head(&cbp_flow_ctrl->wait_q); atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_DISABLE); cbp_flow_ctrl->wait_gpio = plat->gpio_flow_ctrl; cbp_flow_ctrl->wait_polar = plat->gpio_flow_ctrl_polar; LOGPRT(LOG_ERR, "cbp_flow_ctrl->wait_gpio=%d\n",cbp_flow_ctrl->wait_gpio); LOGPRT(LOG_ERR, "cbp_flow_ctrl->wait_polar=%d\n",cbp_flow_ctrl->wait_polar); ret = oem_gpio_request(plat->gpio_flow_ctrl, DRIVER_NAME "(flow_ctrl)"); if(ret < 0){ LOGPRT(LOG_ERR, "%s: %d fail to requset flow_ctrl gpio %d ret =%d!!\n", __func__, __LINE__, plat->gpio_flow_ctrl, ret); goto err_req_flow_ctrl; } oem_gpio_irq_mask(plat->gpio_flow_ctrl); oem_gpio_direction_input_for_irq(plat->gpio_flow_ctrl); //oem_gpio_set_irq_type(plat->gpio_flow_ctrl, IRQ_TYPE_LEVEL_LOW |IRQ_TYPE_LEVEL_HIGH); oem_gpio_set_irq_type(plat->gpio_flow_ctrl, IRQF_TRIGGER_FALLING); ret = oem_gpio_request_irq(plat->gpio_flow_ctrl, gpio_irq_flow_ctrl, IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRIVER_NAME "(flow_ctrl)", cbp_flow_ctrl); oem_gpio_irq_unmask(plat->gpio_flow_ctrl); if (ret < 0) { LOGPRT(LOG_ERR, "%s: %d fail to request irq for flow_ctrl!!\n", __func__, __LINE__); goto err_req_irq_flow_ctrl; } plat->cbp_flow_ctrl= cbp_flow_ctrl; plat->flow_ctrl_wait_event = flow_ctrl_wait_event; plat->flow_ctrl_enable = true; } if(GPIO_OEM_VALID(plat->gpio_rst_ind)){ cbp_rst_ind = kzalloc(sizeof(struct cbp_reset), GFP_KERNEL); if (!cbp_rst_ind){ ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d kzalloc cbp_rst_ind failed \n",__func__, __LINE__); goto err_kzalloc_cbp_rst_ind; } cbp_rst_ind->name = "cbp_rst_ind_wq"; cbp_rst_ind->reset_wq = create_singlethread_workqueue(cbp_rst_ind->name); if (cbp_rst_ind->reset_wq == NULL) { ret = -ENOMEM; LOGPRT(LOG_ERR, "%s %d error creat rst_ind_workqueue \n",__func__, __LINE__); goto err_create_work_queue; } INIT_WORK(&cbp_rst_ind->reset_work, modem_detect); cbp_rst_ind->rst_ind_gpio = plat->gpio_rst_ind; cbp_rst_ind->rst_ind_polar = plat->gpio_rst_ind_polar; cbp_rst_ind->host = NULL; #if 0 ret = oem_gpio_request(plat->gpio_rst_ind, DRIVER_NAME "(rst_ind)"); if(ret < 0){ LOGPRT(LOG_ERR, "%s: %d fail to requset rst_ind gpio %d ret =%d!!\n", __func__, __LINE__, plat->gpio_rst_ind, ret); goto err_req_rst_ind; } oem_gpio_irq_mask(plat->gpio_rst_ind); oem_gpio_direction_input_for_irq(plat->gpio_rst_ind); oem_gpio_set_irq_type(plat->gpio_rst_ind, IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING); ret = oem_gpio_request_irq(plat->gpio_rst_ind, gpio_irq_cbp_rst_ind, IRQF_SHARED |IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING, DRIVER_NAME "(rst_ind)", cbp_rst_ind); oem_gpio_irq_unmask(plat->gpio_rst_ind); if (ret < 0) { LOGPRT(LOG_ERR, "%s: %d fail to request irq for rst_ind!!\n", __func__, __LINE__); goto err_req_irq_rst_ind; } #endif plat->rst_ind_enable = true; } if((GPIO_OEM_VALID(plat->gpio_ap_wkup_cp)) && (GPIO_OEM_VALID(plat->gpio_cp_ready)) && (GPIO_OEM_VALID(plat->gpio_cp_wkup_ap)) && (GPIO_OEM_VALID(plat->gpio_ap_ready))){ sdio_tx_handle.gpio_wake = plat->gpio_ap_wkup_cp; sdio_tx_handle.gpio_ready = plat->gpio_cp_ready; sdio_tx_handle.polar = plat->gpio_sync_polar; ret = asc_tx_register_handle(&sdio_tx_handle); if(ret){ LOGPRT(LOG_ERR, "%s %d asc_tx_register_handle failed.\n",__FUNCTION__,__LINE__); goto err_ipc; } ret = asc_tx_add_user(sdio_tx_handle.name, &sdio_tx_user); if(ret){ LOGPRT(LOG_ERR, "%s %d asc_tx_add_user failed.\n",__FUNCTION__,__LINE__); goto err_ipc; } sdio_rx_handle.gpio_wake = plat->gpio_cp_wkup_ap; sdio_rx_handle.gpio_ready = plat->gpio_ap_ready; sdio_rx_handle.polar = plat->gpio_sync_polar; ret = asc_rx_register_handle(&sdio_rx_handle); if(ret){ LOGPRT(LOG_ERR, "%s %d asc_rx_register_handle failed.\n",__FUNCTION__,__LINE__); goto err_ipc; } ret = asc_rx_add_user(sdio_rx_handle.name, &sdio_rx_user); if(ret){ LOGPRT(LOG_ERR, "%s %d asc_rx_add_user failed.\n",__FUNCTION__,__LINE__); goto err_ipc; } plat->ipc_enable = true; plat->tx_handle = &sdio_tx_handle; } ret = plat->cbp_setup(plat); if(ret){ LOGPRT(LOG_ERR, "%s: host %s setup failed!\n", __func__, plat->host_id); goto err_ipc; } cbp_power_kobj = viatel_kobject_add("power"); if (!cbp_power_kobj){ LOGPRT(LOG_ERR, "error viatel_kobject_add!\n"); ret = -ENOMEM; goto err_create_kobj; } LOGPRT(LOG_INFO, " cbp initialized on host %s successfully, bus is %s !\n", plat->host_id, plat->bus); return sysfs_create_group(cbp_power_kobj, &g_power_attr_group); err_create_kobj: plat->cbp_destroy(); err_ipc: #if 0 if(GPIO_OEM_VALID(plat->gpio_rst_ind)){ free_irq(oem_gpio_to_irq(plat->gpio_rst_ind), cbp_rst_ind); } err_req_irq_rst_ind: if(GPIO_OEM_VALID(plat->gpio_rst_ind)){ oem_gpio_free(plat->gpio_rst_ind); } #endif err_req_rst_ind: if(GPIO_OEM_VALID(plat->gpio_rst_ind)){ destroy_workqueue(cbp_rst_ind->reset_wq); } err_create_work_queue: if(GPIO_OEM_VALID(plat->gpio_rst_ind)){ kfree(cbp_rst_ind); } err_kzalloc_cbp_rst_ind: if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){ free_irq(oem_gpio_to_irq(plat->gpio_flow_ctrl), cbp_flow_ctrl); } err_req_irq_flow_ctrl: if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){ oem_gpio_free(plat->gpio_flow_ctrl); } err_req_flow_ctrl: if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){ kfree(cbp_flow_ctrl); } err_kzalloc_cbp_flow_ctrl: if(GPIO_OEM_VALID(plat->gpio_data_ack)){ free_irq(oem_gpio_to_irq(plat->gpio_data_ack), cbp_data_ack); } err_req_irq_data_ack: if(GPIO_OEM_VALID(plat->gpio_data_ack)){ oem_gpio_free(plat->gpio_data_ack); } err_req_data_ack: if(GPIO_OEM_VALID(plat->gpio_data_ack)){ kfree(cbp_data_ack); } err_kzalloc_cbp_data_ack: if((GPIO_OEM_VALID(plat->gpio_sd_select)) && (GPIO_OEM_VALID(plat->gpio_mc3_enable))){ oem_gpio_free(plat->gpio_sd_select); } err_req_sd_sel: if((GPIO_OEM_VALID(plat->gpio_sd_select)) && (GPIO_OEM_VALID(plat->gpio_mc3_enable))){ oem_gpio_free(plat->gpio_mc3_enable); } out: return ret; }