static void __exit msm_sensor_exit_module(void) { msm_sd_unregister(&s_init->msm_sd); mutex_destroy(&s_init->imutex); kfree(s_init); return; }
static int ispif_remove (struct platform_device *pdev) { struct v4l2_subdev* subdev; struct ispif_device *ispif; subdev = (struct v4l2_subdev*) platform_get_drvdata(pdev); ispif = (struct ispif_device *)v4l2_get_subdevdata(subdev); msm_sd_unregister(&ispif->msm_sd); mutex_destroy(&ispif->mutex); mutex_destroy(&ispif->fem.sync_mutex); kfree(ispif); return 0; }
static int __devinit ispif_probe(struct platform_device *pdev) { int rc; struct ispif_device *ispif; ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL); if (!ispif) { pr_err("%s: no enough memory\n", __func__); return -ENOMEM; } add_debugfs_entry(ispif); INIT_WORK(&ispif->fem.async_work, async_frame_event_do_work); mutex_init(&ispif->fem.sync_mutex); v4l2_subdev_init(&ispif->msm_sd.sd, &msm_ispif_subdev_ops); ispif->msm_sd.sd.internal_ops = &msm_ispif_internal_ops; ispif->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(ispif->msm_sd.sd.name, ARRAY_SIZE(ispif->msm_sd.sd.name), MSM_ISPIF_DRV_NAME); v4l2_set_subdevdata(&ispif->msm_sd.sd, ispif); platform_set_drvdata(pdev, &ispif->msm_sd.sd); mutex_init(&ispif->mutex); media_entity_init(&ispif->msm_sd.sd.entity, 0, NULL, 0); ispif->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; ispif->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ISPIF; ispif->msm_sd.sd.entity.name = pdev->name; ispif->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x1; rc = msm_sd_register(&ispif->msm_sd); if (rc) { pr_err("%s: msm_sd_register error = %d\n", __func__, rc); goto error_sd_register; } if (pdev->dev.of_node) { of_property_read_u32((&pdev->dev)->of_node, "cell-index", &pdev->id); rc = of_property_read_u32((&pdev->dev)->of_node, "qcom,num-isps", &ispif->hw_num_isps); if (rc) /* backward compatibility */ ispif->hw_num_isps = 1; /* not an error condition */ rc = 0; } ispif->mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ispif"); if (!ispif->mem) { pr_err("%s: no mem resource?\n", __func__); rc = -ENODEV; goto error; } ispif->irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ispif"); if (!ispif->irq) { pr_err("%s: no irq resource?\n", __func__); rc = -ENODEV; goto error; } ispif->io = request_mem_region(ispif->mem->start, resource_size(ispif->mem), pdev->name); if (!ispif->io) { pr_err("%s: no valid mem region\n", __func__); rc = -EBUSY; goto error; } ispif->clk_mux_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csi_clk_mux"); if (ispif->clk_mux_mem) { ispif->clk_mux_io = request_mem_region( ispif->clk_mux_mem->start, resource_size(ispif->clk_mux_mem), ispif->clk_mux_mem->name); if (!ispif->clk_mux_io) pr_err("%s: no valid csi_mux region\n", __func__); } ispif->pdev = pdev; ispif->ispif_state = ISPIF_POWER_DOWN; ispif->open_cnt = 0; return 0; error: msm_sd_unregister(&ispif->msm_sd); error_sd_register: mutex_destroy(&ispif->mutex); mutex_destroy(&ispif->fem.sync_mutex); kfree(ispif); return rc; }
static int vfe_probe(struct platform_device *pdev) { struct vfe_device *vfe_dev; /*struct msm_cam_subdev_info sd_info;*/ const struct of_device_id *match_dev; int rc = 0; struct msm_iova_partition vfe_partition = { .start = SZ_128K, .size = SZ_2G - SZ_128K, }; struct msm_iova_layout vfe_layout = { .partitions = &vfe_partition, .npartitions = 1, .client_name = "vfe", .domain_flags = 0, }; vfe_dev = kzalloc(sizeof(struct vfe_device), GFP_KERNEL); if (!vfe_dev) { pr_err("%s: no enough memory\n", __func__); rc = -ENOMEM; goto end; } vfe_dev->stats = kzalloc(sizeof(struct msm_isp_statistics), GFP_KERNEL); if (!vfe_dev->stats) { pr_err("%s: no enough memory\n", __func__); rc = -ENOMEM; goto probe_fail1; } vfe_dev->ub_info = kzalloc(sizeof(struct msm_isp_ub_info), GFP_KERNEL); if (!vfe_dev->ub_info) { pr_err("%s: no enough memory\n", __func__); rc = -ENOMEM; goto probe_fail2; } if (pdev->dev.of_node) { of_property_read_u32((&pdev->dev)->of_node, "cell-index", &pdev->id); match_dev = of_match_device(msm_vfe_dt_match, &pdev->dev); if (!match_dev) { pr_err("%s: No vfe hardware info\n", __func__); rc = -EINVAL; goto probe_fail3; } vfe_dev->hw_info = (struct msm_vfe_hardware_info *) match_dev->data; } else { vfe_dev->hw_info = (struct msm_vfe_hardware_info *) platform_get_device_id(pdev)->driver_data; } if (!vfe_dev->hw_info) { pr_err("%s: No vfe hardware info\n", __func__); rc = -EINVAL; goto probe_fail3; } ISP_DBG("%s: device id = %d\n", __func__, pdev->id); vfe_dev->pdev = pdev; vfe_dev->dual_vfe_res = &dualvfe; vfe_dev->dual_vfe_res->axi_data[vfe_dev->pdev->id] = &vfe_dev->axi_data; vfe_dev->dual_vfe_res->stats_data[vfe_dev->pdev->id] = &vfe_dev->stats_data; rc = vfe_dev->hw_info->vfe_ops.core_ops.get_platform_data(vfe_dev); if (rc < 0) { pr_err("%s: failed to get platform resources\n", __func__); rc = -ENOMEM; goto probe_fail3; } INIT_LIST_HEAD(&vfe_dev->tasklet_q); tasklet_init(&vfe_dev->vfe_tasklet, msm_isp_do_tasklet, (unsigned long)vfe_dev); /* init hardware will enable it back */ tasklet_disable(&vfe_dev->vfe_tasklet); v4l2_subdev_init(&vfe_dev->subdev.sd, vfe_dev->hw_info->subdev_ops); vfe_dev->subdev.sd.internal_ops = vfe_dev->hw_info->subdev_internal_ops; snprintf(vfe_dev->subdev.sd.name, ARRAY_SIZE(vfe_dev->subdev.sd.name), "vfe"); vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS; v4l2_set_subdevdata(&vfe_dev->subdev.sd, vfe_dev); platform_set_drvdata(pdev, &vfe_dev->subdev.sd); mutex_init(&vfe_dev->realtime_mutex); mutex_init(&vfe_dev->core_mutex); mutex_init(&vfe_dev->buf_mgr_mutex); spin_lock_init(&vfe_dev->tasklet_lock); spin_lock_init(&vfe_dev->shared_data_lock); spin_lock_init(&vfe_dev->reg_update_lock); spin_lock_init(&vfe_dev->shared_cfg_reg_lock); //LGE_CHANGE, 20150609, Change spin_lock for watchodog case using shard_data_lock, changhwan.kang.kang spin_lock_init(&req_history_lock); media_entity_init(&vfe_dev->subdev.sd.entity, 0, NULL, 0); vfe_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE; vfe_dev->subdev.sd.entity.name = pdev->name; vfe_dev->subdev.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x2; rc = msm_sd_register(&vfe_dev->subdev); if (rc != 0) { pr_err("%s: msm_sd_register error = %d\n", __func__, rc); goto probe_fail3; } msm_isp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner; msm_isp_v4l2_subdev_fops.open = v4l2_subdev_fops.open; msm_isp_v4l2_subdev_fops.release = v4l2_subdev_fops.release; msm_isp_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll; vfe_dev->subdev.sd.devnode->fops = &msm_isp_v4l2_subdev_fops; vfe_dev->buf_mgr = &vfe_buf_mgr; v4l2_subdev_notify(&vfe_dev->subdev.sd, MSM_SD_NOTIFY_REQ_CB, &vfe_vb2_ops); rc = msm_isp_create_isp_buf_mgr(vfe_dev->buf_mgr, &vfe_vb2_ops, &vfe_layout); if (rc < 0) { pr_err("%s: Unable to create buffer manager\n", __func__); rc = -EINVAL; goto probe_fail3; } /* create secure context banks*/ if (vfe_dev->hw_info->num_iommu_secure_ctx) { /*secure vfe layout*/ struct msm_iova_layout vfe_secure_layout = { .partitions = &vfe_partition, .npartitions = 1, .client_name = "vfe_secure", .domain_flags = 0, .is_secure = MSM_IOMMU_DOMAIN_SECURE, }; rc = msm_isp_create_secure_domain(vfe_dev->buf_mgr, &vfe_secure_layout); if (rc < 0) { pr_err("%s: fail to create secure domain\n", __func__); msm_sd_unregister(&vfe_dev->subdev); rc = -EINVAL; goto probe_fail3; } } msm_isp_enable_debugfs(vfe_dev, msm_isp_bw_request_history); vfe_dev->buf_mgr->ops->register_ctx(vfe_dev->buf_mgr, &vfe_dev->iommu_ctx[0], &vfe_dev->iommu_secure_ctx[0], vfe_dev->hw_info->num_iommu_ctx, vfe_dev->hw_info->num_iommu_secure_ctx); vfe_dev->buf_mgr->init_done = 1; vfe_dev->vfe_open_cnt = 0; return rc; probe_fail3: kfree(vfe_dev->ub_info); probe_fail2: kfree(vfe_dev->stats); probe_fail1: kfree(vfe_dev); end: return rc; } static struct platform_driver vfe_driver = { .probe = vfe_probe, .driver = { .name = "msm_vfe", .owner = THIS_MODULE, .of_match_table = msm_vfe_dt_match, }, .id_table = msm_vfe_dev_id, }; static int __init msm_vfe_init_module(void) { return platform_driver_register(&vfe_driver); } static void __exit msm_vfe_exit_module(void) { platform_driver_unregister(&vfe_driver); } module_init(msm_vfe_init_module); module_exit(msm_vfe_exit_module); MODULE_DESCRIPTION("MSM VFE driver"); MODULE_LICENSE("GPL v2");
static int __init msm_sensor_init_module(void) { struct msm_sensor_init_t *s_init = NULL; struct device *cam_dev_back; struct device *cam_dev_front; int rc = 0; camera_class = class_create(THIS_MODULE, "camera"); if (IS_ERR(camera_class)) pr_err("failed to create device cam_dev_rear!\n"); /* Allocate memory for msm_sensor_init control structure */ s_init = kzalloc(sizeof(struct msm_sensor_init_t), GFP_KERNEL); if (!s_init) { class_destroy(camera_class); pr_err("failed: no memory s_init %p", NULL); return -ENOMEM; } pr_err("MSM_SENSOR_INIT_MODULE %p", NULL); /* Initialize mutex */ mutex_init(&s_init->imutex); /* Create /dev/v4l-subdevX for msm_sensor_init */ v4l2_subdev_init(&s_init->msm_sd.sd, &msm_sensor_init_subdev_ops); snprintf(s_init->msm_sd.sd.name, sizeof(s_init->msm_sd.sd.name), "%s", "msm_sensor_init"); v4l2_set_subdevdata(&s_init->msm_sd.sd, s_init); s_init->msm_sd.sd.internal_ops = &msm_sensor_init_internal_ops; s_init->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; rc = media_entity_init(&s_init->msm_sd.sd.entity, 0, NULL, 0); if (rc < 0) goto entity_fail; s_init->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; s_init->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR_INIT; s_init->msm_sd.sd.entity.name = s_init->msm_sd.sd.name; s_init->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6; rc = msm_sd_register(&s_init->msm_sd); if (rc < 0) goto msm_sd_register_fail; cam_dev_back = device_create(camera_class, NULL, 1, NULL, "rear"); if (IS_ERR(cam_dev_back)) { printk("Failed to create cam_dev_back device!\n"); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_camtype) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camtype.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_camfw) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_checkfw_user) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_checkfw_user.attr.name); rc = -ENODEV; goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_checkfw_factory) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_checkfw_factory.attr.name); rc = -ENODEV; goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_isp_core) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_isp_core.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_camfw_load) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw_load.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_camfw_full) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw_full.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_vendorid) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_vendorid.attr.name); goto device_create_fail; } cam_dev_front = device_create(camera_class, NULL, 2, NULL, "front"); if (IS_ERR(cam_dev_front)) { printk("Failed to create cam_dev_front device!"); goto device_create_fail; } if (device_create_file(cam_dev_front, &dev_attr_front_camtype) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_front_camtype.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_front, &dev_attr_front_camfw) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_front_camfw.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_front, &dev_attr_front_camfw_load) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw_load.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_front, &dev_attr_front_camfw_full) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw_full.attr.name); goto device_create_fail; } init_waitqueue_head(&s_init->state_wait); return 0; device_create_fail: msm_sd_unregister(&s_init->msm_sd); msm_sd_register_fail: media_entity_cleanup(&s_init->msm_sd.sd.entity); entity_fail: mutex_destroy(&s_init->imutex); kfree(s_init); class_destroy(camera_class); return rc; }
static int __devinit vfe_probe(struct platform_device *pdev) { struct vfe_device *vfe_dev; /*struct msm_cam_subdev_info sd_info;*/ const struct of_device_id *match_dev; int rc = 0; struct msm_iova_partition vfe_partition = { .start = SZ_128K, .size = SZ_2G - SZ_128K, }; struct msm_iova_layout vfe_layout = { .partitions = &vfe_partition, .npartitions = 1, .client_name = "vfe", .domain_flags = 0, }; vfe_dev = kzalloc(sizeof(struct vfe_device), GFP_KERNEL); vfe_dev->stats = kzalloc(sizeof(struct msm_isp_statistics), GFP_KERNEL); if (!vfe_dev) { pr_err("%s: no enough memory\n", __func__); return -ENOMEM; } if (pdev->dev.of_node) { of_property_read_u32((&pdev->dev)->of_node, "cell-index", &pdev->id); match_dev = of_match_device(msm_vfe_dt_match, &pdev->dev); /*LGE_CHANGE_E, beacuse of WBT.517790, it may casue Kernel Panic or Fatal Error with NULL of Match_dev, [email protected], 2013-10-17 */ if(!match_dev){ pr_err("%s: no match dev found\n", __func__); return -EINVAL; } /*LGE_CHANGE_X, beacuse of WBT.517790, it may casue Kernel Panic or Fatal Error with NULL of Match_dev, [email protected], 2013-10-17 */ vfe_dev->hw_info = (struct msm_vfe_hardware_info *) match_dev->data; } else { vfe_dev->hw_info = (struct msm_vfe_hardware_info *) platform_get_device_id(pdev)->driver_data; } if (!vfe_dev->hw_info) { pr_err("%s: No vfe hardware info\n", __func__); return -EINVAL; } ISP_DBG("%s: device id = %d\n", __func__, pdev->id); vfe_dev->pdev = pdev; rc = vfe_dev->hw_info->vfe_ops.core_ops.get_platform_data(vfe_dev); if (rc < 0) { pr_err("%s: failed to get platform resources\n", __func__); kfree(vfe_dev); return -ENOMEM; } INIT_LIST_HEAD(&vfe_dev->tasklet_q); tasklet_init(&vfe_dev->vfe_tasklet, msm_isp_do_tasklet, (unsigned long)vfe_dev); v4l2_subdev_init(&vfe_dev->subdev.sd, vfe_dev->hw_info->subdev_ops); vfe_dev->subdev.sd.internal_ops = vfe_dev->hw_info->subdev_internal_ops; snprintf(vfe_dev->subdev.sd.name, ARRAY_SIZE(vfe_dev->subdev.sd.name), "vfe"); vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS; v4l2_set_subdevdata(&vfe_dev->subdev.sd, vfe_dev); platform_set_drvdata(pdev, &vfe_dev->subdev.sd); mutex_init(&vfe_dev->realtime_mutex); mutex_init(&vfe_dev->core_mutex); spin_lock_init(&vfe_dev->tasklet_lock); spin_lock_init(&vfe_dev->shared_data_lock); media_entity_init(&vfe_dev->subdev.sd.entity, 0, NULL, 0); vfe_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE; vfe_dev->subdev.sd.entity.name = pdev->name; vfe_dev->subdev.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x2; rc = msm_sd_register(&vfe_dev->subdev); if (rc != 0) { pr_err("%s: msm_sd_register error = %d\n", __func__, rc); kfree(vfe_dev); goto end; } vfe_dev->buf_mgr = &vfe_buf_mgr; v4l2_subdev_notify(&vfe_dev->subdev.sd, MSM_SD_NOTIFY_REQ_CB, &vfe_vb2_ops); rc = msm_isp_create_isp_buf_mgr(vfe_dev->buf_mgr, &vfe_vb2_ops, &vfe_layout); if (rc < 0) { pr_err("%s: Unable to create buffer manager\n", __func__); msm_sd_unregister(&vfe_dev->subdev); kfree(vfe_dev); return -EINVAL; } msm_isp_enable_debugfs(vfe_dev->stats); vfe_dev->buf_mgr->ops->register_ctx(vfe_dev->buf_mgr, &vfe_dev->iommu_ctx[0], vfe_dev->hw_info->num_iommu_ctx); vfe_dev->vfe_open_cnt = 0; end: return rc; } static struct platform_driver vfe_driver = { .probe = vfe_probe, .driver = { .name = "msm_vfe", .owner = THIS_MODULE, .of_match_table = msm_vfe_dt_match, }, .id_table = msm_vfe_dev_id, }; static int __init msm_vfe_init_module(void) { return platform_driver_register(&vfe_driver); } static void __exit msm_vfe_exit_module(void) { platform_driver_unregister(&vfe_driver); }
static int __devinit ispif_probe(struct platform_device *pdev) { int rc; struct ispif_device *ispif; ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL); if (!ispif) { pr_err("%s: no enough memory\n", __func__); return -ENOMEM; } v4l2_subdev_init(&ispif->msm_sd.sd, &msm_ispif_subdev_ops); ispif->msm_sd.sd.internal_ops = &msm_ispif_internal_ops; ispif->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(ispif->msm_sd.sd.name, ARRAY_SIZE(ispif->msm_sd.sd.name), MSM_ISPIF_DRV_NAME); v4l2_set_subdevdata(&ispif->msm_sd.sd, ispif); platform_set_drvdata(pdev, &ispif->msm_sd.sd); mutex_init(&ispif->mutex); media_entity_init(&ispif->msm_sd.sd.entity, 0, NULL, 0); ispif->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; ispif->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ISPIF; ispif->msm_sd.sd.entity.name = pdev->name; ispif->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x1; rc = msm_sd_register(&ispif->msm_sd); if (rc) { pr_err("%s: msm_sd_register error = %d\n", __func__, rc); goto error_sd_register; } if (pdev->dev.of_node) of_property_read_u32((&pdev->dev)->of_node, "cell-index", &pdev->id); ispif->mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ispif"); if (!ispif->mem) { pr_err("%s: no mem resource?\n", __func__); rc = -ENODEV; goto error; } ispif->irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ispif"); if (!ispif->irq) { pr_err("%s: no irq resource?\n", __func__); rc = -ENODEV; goto error; } ispif->io = request_mem_region(ispif->mem->start, resource_size(ispif->mem), pdev->name); if (!ispif->io) { pr_err("%s: no valid mem region\n", __func__); rc = -EBUSY; goto error; } ispif->clk_mux_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csi_clk_mux"); if (ispif->clk_mux_mem) { ispif->clk_mux_io = request_mem_region( ispif->clk_mux_mem->start, resource_size(ispif->clk_mux_mem), ispif->clk_mux_mem->name); if (!ispif->clk_mux_io) pr_err("%s: no valid csi_mux region\n", __func__); } ispif->pdev = pdev; ispif->ispif_state = ISPIF_POWER_DOWN; ispif->open_cnt = 0; pr_err(" %s:%d ISPIF_POWER_DOWN %d \n",__func__,__LINE__,ispif->ispif_state); /* */ wake_lock_init(&ispif->camera_wake_lock, WAKE_LOCK_SUSPEND, "camera_wake_lock"); /* */ return 0; error: msm_sd_unregister(&ispif->msm_sd); error_sd_register: mutex_destroy(&ispif->mutex); kfree(ispif); return rc; }