int fimc_is_resource_put(struct fimc_is_resourcemgr *resourcemgr)
{
	int ret = 0;
	struct fimc_is_core *core;

	BUG_ON(!resourcemgr);

	core = (struct fimc_is_core *)resourcemgr->private_data;

	if ((atomic_read(&core->rsccount) == 0) ||
		(atomic_read(&core->rsccount) > 5)) {
		err("[RSC] %s: Invalid rsccount(%d)\n", __func__,
			atomic_read(&core->rsccount));
		ret = -EMFILE;

		goto exit;
	}

	atomic_dec(&core->rsccount);

	 pr_info("[RSC] %s: rsccount = %d\n",
               __func__, atomic_read(&core->rsccount));

	if (!atomic_read(&core->rsccount)) {
		if (test_bit(FIMC_IS_ISCHAIN_POWER_ON, &core->state)) {
			/* 1. Stop a5 and other devices operation */
			ret = fimc_is_itf_power_down(&core->interface);
			if (ret)
				err("power down is failed, retry forcelly");

			/* 2. Power down */
			ret = fimc_is_ischain_power(&core->ischain[0], 0);
			if (ret)
				err("fimc_is_ischain_power is failed");
		}

		/* 3. Deinit variables */
		ret = fimc_is_interface_close(&core->interface);
		if (ret)
			err("fimc_is_interface_close is failed");

#ifndef RESERVED_MEM
		/* 5. Dealloc memroy */
		fimc_is_ishcain_deinitmem(&core->ischain[0]);
#endif
	}

exit:
	return ret;
}
int fimc_is_resource_get(struct fimc_is_resourcemgr *resourcemgr, u32 rsc_type)
{
	int ret = 0;
	u32 rsccount;
	struct fimc_is_resource *resource;
	struct fimc_is_core *core;

	BUG_ON(!resourcemgr);
	BUG_ON(!resourcemgr->private_data);
	BUG_ON(rsc_type >= RESOURCE_TYPE_MAX);

	resource = GET_RESOURCE(resourcemgr, rsc_type);
	core = (struct fimc_is_core *)resourcemgr->private_data;
	rsccount = atomic_read(&core->rsccount);

	if (rsccount >= 5) {
		err("[RSC] Invalid rsccount(%d)", rsccount);
		ret = -EMFILE;
		goto p_err;
	}

	if (rsccount == 0) {
#ifdef ENABLE_DVFS
		/* dvfs controller init */
		ret = fimc_is_dvfs_init(resourcemgr);
		if (ret) {
			err("%s: fimc_is_dvfs_init failed!\n", __func__);
			goto p_err;
		}
#endif
	}

	if (atomic_read(&resource->rsccount) == 0) {
		switch (rsc_type) {
		case RESOURCE_TYPE_SENSOR0:
			break;
		case RESOURCE_TYPE_SENSOR1:
			break;
		case RESOURCE_TYPE_ISCHAIN:
			core->debug_cnt = 0;

			ret = fimc_is_interface_open(&core->interface);
			if (ret) {
				err("fimc_is_interface_open is fail(%d)", ret);
				goto p_err;
			}

			ret = fimc_is_ischain_power(&core->ischain[0], 1);
			if (ret) {
				err("fimc_is_ischain_power is fail (%d)", ret);
				goto p_err;
			}

			/* W/A for a lower version MCUCTL */
			fimc_is_interface_reset(&core->interface);

#ifdef ENABLE_CLOCK_GATE
			if (sysfs_debug.en_clk_gate &&
					sysfs_debug.clk_gate_mode == CLOCK_GATE_MODE_HOST)
				fimc_is_clk_gate_init(core);
#endif
			break;
		default:
			err("[RSC] resource type(%d) is invalid", rsc_type);
			BUG();
			break;
		}
	}

	atomic_inc(&resource->rsccount);
	atomic_inc(&core->rsccount);

p_err:
	info("[RSC] rsctype : %d, rsccount : %d\n", rsc_type, rsccount);
	return ret;
}
int fimc_is_resource_put(struct fimc_is_resourcemgr *resourcemgr, u32 rsc_type)
{
	int ret = 0;
	u32 rsccount;
	struct fimc_is_resource *resource;
	struct fimc_is_core *core;

	BUG_ON(!resourcemgr);
	BUG_ON(!resourcemgr->private_data);
	BUG_ON(rsc_type >= RESOURCE_TYPE_MAX);

	resource = GET_RESOURCE(resourcemgr, rsc_type);
	core = (struct fimc_is_core *)resourcemgr->private_data;
	rsccount = atomic_read(&core->rsccount);

	if (rsccount == 0) {
		err("[RSC] Invalid rsccount(%d)\n", rsccount);
		ret = -EMFILE;
		goto p_err;
	}

	if (atomic_read(&resource->rsccount) == 1) {
		switch (rsc_type) {
		case RESOURCE_TYPE_SENSOR0:
			break;
		case RESOURCE_TYPE_SENSOR1:
			break;
		case RESOURCE_TYPE_ISCHAIN:
			ret = fimc_is_itf_power_down(&core->interface);
			if (ret)
				err("power down cmd is fail(%d)", ret);

			ret = fimc_is_ischain_power(&core->ischain[0], 0);
			if (ret)
				err("fimc_is_ischain_power is fail(%d)", ret);

			ret = fimc_is_interface_close(&core->interface);
			if (ret)
				err("fimc_is_interface_close is fail(%d)", ret);
#ifndef RESERVED_MEM
			/* 5. Dealloc memroy */
			ret = fimc_is_ishcain_deinitmem(&core->ischain[0]);
			if (ret)
				err("fimc_is_ishcain_deinitmem is fail(%d)", ret);
#endif
			break;

		default:
			err("[RSC] resource type(%d) is invalid", rsc_type);
			BUG();
			break;
		}
	}

	atomic_dec(&resource->rsccount);
	atomic_dec(&core->rsccount);

p_err:
	info("[RSC] rsctype : %d, rsccount : %d\n", rsc_type, rsccount);
	return ret;
}
int fimc_is_resource_put(struct fimc_is_resourcemgr *resourcemgr, u32 rsc_type)
{
	int ret = 0;
	u32 rsccount;
	struct fimc_is_resource *resource;
	struct fimc_is_core *core;

	BUG_ON(!resourcemgr);
	BUG_ON(!resourcemgr->private_data);
	BUG_ON(rsc_type >= RESOURCE_TYPE_MAX);

	resource = GET_RESOURCE(resourcemgr, rsc_type);
	core = (struct fimc_is_core *)resourcemgr->private_data;
	rsccount = atomic_read(&core->rsccount);

	if (!core->pdev) {
		err("[RSC] pdev is NULL");
		ret = -EMFILE;
		goto p_err;
	}

	if (rsccount == 0) {
		err("[RSC] Invalid rsccount(%d)\n", rsccount);
		ret = -EMFILE;
		goto p_err;
	}

	/* local update */
	if (atomic_read(&resource->rsccount) == 1) {
		/* clear hal version, default 1.0 */
		resourcemgr->hal_version = IS_HAL_VER_1_0;

		switch (rsc_type) {
		case RESOURCE_TYPE_COMPANION:
#if defined(CONFIG_PM_RUNTIME)
			pm_runtime_put_sync(&resource->pdev->dev);
#else
			fimc_is_companion_runtime_suspend(&resource->pdev->dev);
#endif
			clear_bit(FIMC_IS_RM_COM_POWER_ON, &resourcemgr->state);
			break;
		case RESOURCE_TYPE_SENSOR0:
#if defined(CONFIG_PM_RUNTIME)
			pm_runtime_put_sync(&resource->pdev->dev);
#else
			fimc_is_sensor_runtime_suspend(&resource->pdev->dev);
#endif
			clear_bit(FIMC_IS_RM_SS0_POWER_ON, &resourcemgr->state);
			break;
		case RESOURCE_TYPE_SENSOR1:
#if defined(CONFIG_PM_RUNTIME)
			pm_runtime_put_sync(&resource->pdev->dev);
#else
			fimc_is_sensor_runtime_suspend(&resource->pdev->dev);
#endif
			clear_bit(FIMC_IS_RM_SS1_POWER_ON, &resourcemgr->state);
			break;
		case RESOURCE_TYPE_ISCHAIN:
			ret = fimc_is_itf_power_down(&core->interface);
			if (ret)
				err("power down cmd is fail(%d)", ret);

			ret = fimc_is_ischain_power(&core->ischain[0], 0);
			if (ret)
				err("fimc_is_ischain_power is fail(%d)", ret);

			ret = fimc_is_interface_close(&core->interface);
			if (ret)
				err("fimc_is_interface_close is fail(%d)", ret);

			ret = fimc_is_debug_close();
			if (ret)
				err("fimc_is_debug_close is fail(%d)", ret);

#ifndef ENABLE_RESERVED_MEM
			ret = fimc_is_resourcemgr_deinitmem(resourcemgr);
			if (ret)
				err("fimc_is_resourcemgr_deinitmem is fail(%d)", ret);
#endif

			clear_bit(FIMC_IS_RM_ISC_POWER_ON, &resourcemgr->state);
			break;
		default:
			err("[RSC] resource type(%d) is invalid", rsc_type);
			BUG();
			break;
		}
	}

	/* global update */
	if (atomic_read(&core->rsccount) == 1) {
		u32 current_min, current_max;

		current_min = (resourcemgr->cluster0 & CLUSTER_MIN_MASK) >> CLUSTER_MIN_SHIFT;
		current_max = (resourcemgr->cluster0 & CLUSTER_MAX_MASK) >> CLUSTER_MAX_SHIFT;
		if (current_min) {
			C0MIN_QOS_DEL();
			warn("[RSC] cluster0 minfreq is not removed(%dMhz)\n", current_min);
		}

		if (current_max) {
			C0MAX_QOS_DEL();
			warn("[RSC] cluster0 maxfreq is not removed(%dMhz)\n", current_max);
		}

		current_min = (resourcemgr->cluster1 & CLUSTER_MIN_MASK) >> CLUSTER_MIN_SHIFT;
		current_max = (resourcemgr->cluster1 & CLUSTER_MAX_MASK) >> CLUSTER_MAX_SHIFT;
		if (current_min) {
			C1MIN_QOS_DEL();
			warn("[RSC] cluster1 minfreq is not removed(%dMhz)\n", current_min);
		}

		if (current_max) {
			C1MAX_QOS_DEL();
			warn("[RSC] cluster1 maxfreq is not removed(%dMhz)\n", current_max);
		}

		resourcemgr->cluster0 = 0;
		resourcemgr->cluster1 = 0;

		ret = fimc_is_runtime_suspend_post(NULL);
		if (ret)
			err("fimc_is_runtime_suspend_post is fail(%d)", ret);

		pm_relax(&core->pdev->dev);

		clear_bit(FIMC_IS_RM_POWER_ON, &resourcemgr->state);
	}
int fimc_is_resource_get(struct fimc_is_resourcemgr *resourcemgr, u32 rsc_type)
{
	int ret = 0;
	u32 rsccount;
	struct fimc_is_resource *resource;
	struct fimc_is_core *core;

	BUG_ON(!resourcemgr);
	BUG_ON(!resourcemgr->private_data);
	BUG_ON(rsc_type >= RESOURCE_TYPE_MAX);

	resource = GET_RESOURCE(resourcemgr, rsc_type);
	core = (struct fimc_is_core *)resourcemgr->private_data;
	rsccount = atomic_read(&core->rsccount);

	if (!core->pdev) {
		err("[RSC] pdev is NULL");
		ret = -EMFILE;
		goto p_err;
	}

	if (rsccount >= (FIMC_IS_STREAM_COUNT + FIMC_IS_VIDEO_SS3_NUM)) {
		err("[RSC] Invalid rsccount(%d)", rsccount);
		ret = -EMFILE;
		goto p_err;
	}

	if (rsccount == 0) {
		pm_stay_awake(&core->pdev->dev);

		resourcemgr->cluster0 = 0;
		resourcemgr->cluster1 = 0;

#ifdef ENABLE_DVFS
		/* dvfs controller init */
		ret = fimc_is_dvfs_init(resourcemgr);
		if (ret) {
			err("%s: fimc_is_dvfs_init failed!\n", __func__);
			goto p_err;
		}
#endif
	}

	if (atomic_read(&resource->rsccount) == 0) {
		switch (rsc_type) {
		case RESOURCE_TYPE_COMPANION:
#if defined(CONFIG_PM_RUNTIME)
			pm_runtime_get_sync(&resource->pdev->dev);
#else
			fimc_is_companion_runtime_resume(&resource->pdev->dev);
#endif
			set_bit(FIMC_IS_RM_COM_POWER_ON, &resourcemgr->state);
			break;
		case RESOURCE_TYPE_SENSOR0:
#ifdef CONFIG_PM_RUNTIME
			pm_runtime_get_sync(&resource->pdev->dev);
#else
			fimc_is_sensor_runtime_resume(&resource->pdev->dev);
#endif
			set_bit(FIMC_IS_RM_SS0_POWER_ON, &resourcemgr->state);
			break;
		case RESOURCE_TYPE_SENSOR1:
#ifdef CONFIG_PM_RUNTIME
			pm_runtime_get_sync(&resource->pdev->dev);
#else
			fimc_is_sensor_runtime_resume(&resource->pdev->dev);
#endif
			set_bit(FIMC_IS_RM_SS1_POWER_ON, &resourcemgr->state);
			break;
		case RESOURCE_TYPE_ISCHAIN:
			if (test_bit(FIMC_IS_RM_POWER_ON, &resourcemgr->state)) {
				err("all resource is not power off(%lX)", resourcemgr->state);
				ret = -EINVAL;
				goto p_err;
			}

#ifndef ENABLE_RESERVED_MEM
			ret = fimc_is_resourcemgr_initmem(resourcemgr);
			if (ret) {
				err("fimc_is_resourcemgr_initmem is fail(%d)\n", ret);
				goto p_err;
			}
#endif

			ret = fimc_is_debug_open(&resourcemgr->minfo);
			if (ret) {
				err("fimc_is_debug_open is fail(%d)", ret);
				goto p_err;
			}

			ret = fimc_is_interface_open(&core->interface);
			if (ret) {
				err("fimc_is_interface_open is fail(%d)", ret);
				goto p_err;
			}

			ret = fimc_is_ischain_power(&core->ischain[0], 1);
			if (ret) {
				err("fimc_is_ischain_power is fail(%d)", ret);
				fimc_is_ischain_power(&core->ischain[0], 0);
				goto p_err;
			}

			/* W/A for a lower version MCUCTL */
			fimc_is_interface_reset(&core->interface);

#ifdef ENABLE_CLOCK_GATE
			if (sysfs_debug.en_clk_gate &&
					sysfs_debug.clk_gate_mode == CLOCK_GATE_MODE_HOST)
				fimc_is_clk_gate_init(core);
#endif

			set_bit(FIMC_IS_RM_ISC_POWER_ON, &resourcemgr->state);
			set_bit(FIMC_IS_RM_POWER_ON, &resourcemgr->state);
			break;
		default:
			err("[RSC] resource type(%d) is invalid", rsc_type);
			BUG();
			break;
		}
	}

	atomic_inc(&resource->rsccount);
	atomic_inc(&core->rsccount);

p_err:
	info("[RSC] rsctype : %d, rsccount : %d\n", rsc_type, rsccount + 1);
	return ret;
}
Exemplo n.º 6
0
int fimc_is_resource_put(struct fimc_is_resourcemgr *resourcemgr, u32 rsc_type)
{
	int ret = 0;
	u32 rsccount;
	struct fimc_is_resource *resource;
	struct fimc_is_core *core;

	BUG_ON(!resourcemgr);
	BUG_ON(!resourcemgr->private_data);
	BUG_ON(rsc_type >= RESOURCE_TYPE_MAX);

	resource = GET_RESOURCE(resourcemgr, rsc_type);
	core = (struct fimc_is_core *)resourcemgr->private_data;
	rsccount = atomic_read(&core->rsccount);

	if (rsccount == 0) {
		err("[RSC] Invalid rsccount(%d)\n", rsccount);
		ret = -EMFILE;
		goto p_err;
	}

	/* local update */
	if (atomic_read(&resource->rsccount) == 1) {
		/* clear hal version, default 1.0 */
		resourcemgr->hal_version = IS_HAL_VER_1_0;

		switch (rsc_type) {
		case RESOURCE_TYPE_COMPANION:
#if defined(CONFIG_PM_RUNTIME)
			pm_runtime_put_sync(&resource->pdev->dev);
#else
#if defined(CONFIG_COMPANION_USE)
			fimc_is_companion_runtime_suspend(&resource->pdev->dev);
#endif
#endif
			clear_bit(FIMC_IS_RM_COM_POWER_ON, &resourcemgr->state);
			break;
		case RESOURCE_TYPE_SENSOR0:
#if defined(CONFIG_PM_RUNTIME)
			pm_runtime_put_sync(&resource->pdev->dev);
#else
			fimc_is_sensor_runtime_suspend(&resource->pdev->dev);
#endif
			clear_bit(FIMC_IS_RM_SS0_POWER_ON, &resourcemgr->state);
			break;
		case RESOURCE_TYPE_SENSOR1:
#if defined(CONFIG_PM_RUNTIME)
			pm_runtime_put_sync(&resource->pdev->dev);
#else
			fimc_is_sensor_runtime_suspend(&resource->pdev->dev);
#endif
			clear_bit(FIMC_IS_RM_SS1_POWER_ON, &resourcemgr->state);
			break;
		case RESOURCE_TYPE_ISCHAIN:
			ret = fimc_is_itf_power_down(&core->interface);
			if (ret)
				err("power down cmd is fail(%d)", ret);

			ret = fimc_is_ischain_power(&core->ischain[0], 0);
			if (ret)
				err("fimc_is_ischain_power is fail(%d)", ret);

			ret = fimc_is_interface_close(&core->interface);
			if (ret)
				err("fimc_is_interface_close is fail(%d)", ret);

			ret = fimc_is_debug_close();
			if (ret)
				err("fimc_is_debug_close is fail(%d)", ret);

#ifndef ENABLE_RESERVED_MEM
			ret = fimc_is_resourcemgr_deinitmem(resourcemgr);
			if (ret)
				err("fimc_is_resourcemgr_deinitmem is fail(%d)", ret);
#endif

			clear_bit(FIMC_IS_RM_ISC_POWER_ON, &resourcemgr->state);
			break;
		default:
			err("[RSC] resource type(%d) is invalid", rsc_type);
			BUG();
			break;
		}
	}

	/* global update */
	if (atomic_read(&core->rsccount) == 1) {
		ret = fimc_is_runtime_suspend_post(NULL);
		if (ret)
			err("fimc_is_runtime_suspend_post is fail(%d)", ret);

		clear_bit(FIMC_IS_RM_POWER_ON, &resourcemgr->state);
	}

	atomic_dec(&resource->rsccount);
	atomic_dec(&core->rsccount);

p_err:
	info("[RSC] rsctype : %d, rsccount : %d\n", rsc_type, rsccount - 1);
	return ret;
}