//static int __devexit cbp_remove(struct platform_device *pdev) static int cbp_remove(struct platform_device *pdev) { struct cbp_platform_data *plat = pdev->dev.platform_data; if((GPIO_C2K_VALID(plat->gpio_sd_select)) && (GPIO_C2K_VALID(plat->gpio_mc3_enable))){ } if(plat->data_ack_enable && (GPIO_C2K_VALID(plat->gpio_data_ack))){ free_irq(c2k_gpio_to_irq(plat->gpio_data_ack), cbp_data_ack); kfree(cbp_data_ack); } if(plat->flow_ctrl_enable && (GPIO_C2K_VALID(plat->gpio_flow_ctrl))){ free_irq(c2k_gpio_to_irq(plat->gpio_flow_ctrl), cbp_flow_ctrl); kfree(cbp_flow_ctrl); } if(plat->rst_ind_enable && (GPIO_C2K_VALID(plat->gpio_rst_ind))){ free_irq(c2k_gpio_to_irq(plat->gpio_rst_ind), cbp_rst_ind); destroy_workqueue(cbp_rst_ind->reset_wq); kfree(cbp_rst_ind); } destroy_workqueue(cbp_excp_ind->excp_wq); kfree(cbp_excp_ind); plat->cbp_destroy(); sysfs_remove_group(cbp_power_kobj, &g_power_attr_group); kobject_put(cbp_power_kobj); LOGPRT(LOG_INFO, " cbp removed on host %s, bus is %s!\n", plat->host_id, plat->bus); return 0; }
int c2k_gpio_set_irq_type(int gpio, unsigned int type) { int irq, level; irq = c2k_gpio_to_irq(gpio); if (irq < 0) return irq; level = c2k_gpio_get_value(gpio); if (type == IRQ_TYPE_EDGE_BOTH) { if (level) type = IRQ_TYPE_EDGE_FALLING; else type = IRQ_TYPE_EDGE_RISING; } if (type == IRQ_TYPE_LEVEL_MASK) { if (level) type = IRQ_TYPE_LEVEL_LOW; else type = IRQ_TYPE_LEVEL_HIGH; } #ifndef CONFIG_EVDO_DT_VIA_SUPPORT c2k_irq_set_type(irq, type); #endif #if defined(CONFIG_MTK_LEGACY) mt_eint_set_hw_debounce(irq, 0); switch (type) { case IRQ_TYPE_EDGE_RISING: mt_eint_set_sens(irq, MT_EDGE_SENSITIVE); mt_eint_set_polarity(irq, MT_POLARITY_HIGH); break; case IRQ_TYPE_EDGE_FALLING: mt_eint_set_sens(irq, MT_EDGE_SENSITIVE); mt_eint_set_polarity(irq, MT_POLARITY_LOW); break; case IRQ_TYPE_LEVEL_HIGH: mt_eint_set_sens(irq, MT_LEVEL_SENSITIVE); mt_eint_set_polarity(irq, MT_POLARITY_HIGH); break; case IRQ_TYPE_LEVEL_LOW: mt_eint_set_sens(irq, MT_LEVEL_SENSITIVE); mt_eint_set_polarity(irq, MT_POLARITY_LOW); break; default: return -EINVAL; } #else gpio_set_debounce(gpio, 0); irq_set_irq_type(irq, type); #endif /*pr_debug("[C2K]set irq(%d) type(%d) done\n", irq, type); */ return 0; }
void c2k_gpio_irq_unmask(int gpio) { int irq; irq = c2k_gpio_to_irq(gpio); if(irq < 0){ return ; } mt_eint_unmask(irq); }
void c2k_gpio_irq_unmask(int gpio) { int irq; irq = c2k_gpio_to_irq(gpio); if (irq < 0) return; #if defined(CONFIG_MTK_LEGACY) mt_eint_unmask(irq); #else enable_irq(irq); #endif }
//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; }