static int __devinit snd_saudio_probe(struct platform_device *devptr) { struct snd_saudio *saudio = NULL; static pid_t thread_id = (pid_t) -1; struct saudio_init_data *init_data = devptr->dev.platform_data; ADEBUG(); if (!(saudio = saudio_card_probe(init_data))) { return -1; } saudio->pdev = devptr; saudio->queue=create_singlethread_workqueue("saudio"); if(!saudio->queue) { printk("saudio:workqueue create error %d",saudio->queue); if(saudio) { kfree(saudio); saudio = NULL; } return -1; } printk("saudio:workqueue create ok"); INIT_WORK(&saudio->card_free_work,saudio_work_card_free_handler); platform_set_drvdata(devptr, saudio); thread_id = kernel_thread(saudio_ctrl_thread, saudio, 0); if (thread_id < 0) { ETRACE("virtual audio cmd kernel thread creation failure \n"); destroy_workqueue(saudio->queue); saudio->queue = NULL; kfree(saudio); platform_set_drvdata(devptr, NULL); return thread_id; } return 0; }
static int snd_saudio_probe(struct platform_device *devptr) { struct snd_saudio *saudio = NULL; static pid_t thread_id = (pid_t) - 1; #ifdef CONFIG_OF int ret, id; const char *name = NULL; struct saudio_init_data snd_init_data = {0}; const char *saudio_names = "sprd,saudio-names"; const char *saudio_dst_id = "sprd,saudio-dst-id"; struct saudio_init_data *init_data = &snd_init_data; #else struct saudio_init_data *init_data = devptr->dev.platform_data; #endif ADEBUG(); #ifdef CONFIG_OF ret = of_property_read_u32(devptr->dev.of_node, saudio_dst_id, &id); if (ret) { printk("saudio: %s: missing %s in dt node\n", __func__, saudio_dst_id); return ret; } else { if ((id == SIPC_ID_CPT) || (id == SIPC_ID_CPW)) { printk("saudio: %s: %s is %d\n", __func__, __func__, saudio_dst_id, id); } else { printk("saudio: %s: %s is %d and only support 1,2\n", __func__, saudio_dst_id, id); return ret; } } ret = of_property_read_string(devptr->dev.of_node, saudio_names, &name); if (ret) { printk("saudio: %s: missing %s in dt node\n", __func__, saudio_names); return ret; } else { printk("saudio: %s: %s is %s\n", __func__, __func__, saudio_names, name); } if (!strcmp(name, "saudio_voip")) { init_data->name = "saudiovoip"; init_data->dst = id; init_data->ctrl_channel = SMSG_CH_CTRL_VOIP; init_data->playback_channel = SMSG_CH_PLAYBACK_VOIP; init_data->capture_channel = SMSG_CH_CAPTURE_VOIP; init_data->monitor_channel = SMSG_CH_MONITOR_VOIP; } else if(id == SIPC_ID_CPT) { init_data->name = "VIRTUAL AUDIO"; init_data->dst = id; init_data->ctrl_channel = SMSG_CH_VBC; init_data->playback_channel = SMSG_CH_PLAYBACK; init_data->capture_channel = SMSG_CH_CAPTURE; init_data->monitor_channel = SMSG_CH_MONITOR_AUDIO; } else if(id == SIPC_ID_CPW) { init_data->name = "VIRTUAL AUDIO W"; init_data->dst = id; init_data->ctrl_channel = SMSG_CH_VBC; init_data->playback_channel = SMSG_CH_PLAYBACK; init_data->capture_channel = SMSG_CH_CAPTURE; init_data->monitor_channel = SMSG_CH_MONITOR_AUDIO; } else { printk("saudio: %s: get data in dt node failed\n", __func__); } #endif if (!(saudio = saudio_card_probe(init_data))) { return -1; } saudio->pdev = devptr; saudio->queue = create_singlethread_workqueue("saudio"); if (!saudio->queue) { printk("saudio:workqueue create error %d\n", (int)saudio->queue); if (saudio) { kfree(saudio); saudio = NULL; } return -1; } printk("saudio:workqueue create ok"); INIT_WORK(&saudio->card_free_work, saudio_work_card_free_handler); platform_set_drvdata(devptr, saudio); saudio->thread_id = kthread_create(saudio_ctrl_thread, saudio, "saudio-%d-%d",saudio->dst,saudio->channel); if (IS_ERR(saudio->thread_id)) { ETRACE("virtual audio cmd kernel thread creation failure \n"); destroy_workqueue(saudio->queue); saudio->queue = NULL; saudio->thread_id = NULL; kfree(saudio); platform_set_drvdata(devptr, NULL); return -1; } wake_up_process(saudio->thread_id); return 0; }