int msm_jpeg_platform_release(struct resource *mem, void *base, int irq,
	void *context)
{
	int result = 0;

	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;

	free_irq(irq, context);

	msm_jpeg_detach_iommu(pgmn_dev);

	if (pgmn_dev->jpeg_bus_client) {
		msm_bus_scale_client_update_request(
			pgmn_dev->jpeg_bus_client, 0);
		msm_bus_scale_unregister_client(pgmn_dev->jpeg_bus_client);
	}

	msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
	pgmn_dev->jpeg_clk, pgmn_dev->num_clk, 0);
	JPEG_DBG("%s:%d] clock disbale done", __func__, __LINE__);

	if (pgmn_dev->jpeg_fs) {
		result = regulator_disable(pgmn_dev->jpeg_fs);
		if (!result)
			regulator_put(pgmn_dev->jpeg_fs);
		else
			JPEG_PR_ERR("%s:%d] regulator disable failed %d",
				__func__, __LINE__, result);
		pgmn_dev->jpeg_fs = NULL;
	}
	iounmap(pgmn_dev->jpeg_vbif);
	iounmap(base);
	release_mem_region(mem->start, resource_size(mem));
	ion_client_destroy(pgmn_dev->jpeg_client);
	pgmn_dev->state = MSM_JPEG_IDLE;
	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
	return result;
}
int msm_jpeg_platform_release(void *context)
{
	int result = 0;

	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;

	/* release the irq */
	msm_camera_unregister_irq(pgmn_dev->pdev,
		pgmn_dev->jpeg_irq_res, context);

	msm_jpeg_detach_iommu(pgmn_dev);

	if (pgmn_dev->bus_client) {
		if (pgmn_dev->jpeg_bus_vote) {
			/* update the bw with zeroth vector */
			msm_camera_update_bus_vector(pgmn_dev->bus_client, 0);
			JPEG_BUS_UNVOTED(pgmn_dev);
			JPEG_DBG("%s:%d] Bus unvoted\n", __func__, __LINE__);
		}
	}

	/* disable all the clocks */
	msm_camera_clk_enable(&pgmn_dev->pdev->dev, pgmn_dev->jpeg_clk_info,
		pgmn_dev->jpeg_clk, pgmn_dev->num_clk, false);
	JPEG_DBG("%s:%d] clock disbale done", __func__, __LINE__);

	/* disable all the regulators */
	msm_camera_regulator_enable(pgmn_dev->jpeg_vdd,
		pgmn_dev->num_reg, false);
	JPEG_DBG("%s:%d] regulator disable done", __func__, __LINE__);

	pgmn_dev->state = MSM_JPEG_IDLE;
	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
	return result;
}
int msm_jpeg_platform_init(struct platform_device *pdev,
	struct resource **mem,
	void **base,
	int *irq,
	irqreturn_t (*handler) (int, void *),
	void *context)
{
	int rc = -1;
	int jpeg_irq;
	struct resource *jpeg_mem, *vbif_mem, *jpeg_io, *jpeg_irq_res;
	void *jpeg_base;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;

	pgmn_dev->state = MSM_JPEG_IDLE;

	jpeg_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!jpeg_mem) {
		JPEG_PR_ERR("%s: jpeg no mem resource?\n", __func__);
		return -ENODEV;
	}

	vbif_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!vbif_mem) {
		JPEG_PR_ERR("%s: vbif no mem resource?\n", __func__);
		return -ENODEV;
	}

	jpeg_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!jpeg_irq_res) {
		JPEG_PR_ERR("no irq resource?\n");
		return -ENODEV;
	}
	jpeg_irq = jpeg_irq_res->start;
	JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__,
		jpeg_mem->start, jpeg_irq);

	pgmn_dev->jpeg_bus_client =
		msm_bus_scale_register_client(&msm_jpeg_bus_client_pdata);
	if (!pgmn_dev->jpeg_bus_client) {
		JPEG_PR_ERR("%s: Registration Failed!\n", __func__);
		pgmn_dev->jpeg_bus_client = 0;
		return -EINVAL;
	}
	msm_bus_scale_client_update_request(
		pgmn_dev->jpeg_bus_client, 1);

	jpeg_io = request_mem_region(jpeg_mem->start,
		resource_size(jpeg_mem), pdev->name);
	if (!jpeg_io) {
		JPEG_PR_ERR("%s: region already claimed\n", __func__);
		return -EBUSY;
	}

	jpeg_base = ioremap(jpeg_mem->start, resource_size(jpeg_mem));
	if (!jpeg_base) {
		rc = -ENOMEM;
		JPEG_PR_ERR("%s: ioremap failed\n", __func__);
		goto fail_remap;
	}

	pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd");
	rc = regulator_enable(pgmn_dev->jpeg_fs);
	if (rc) {
		JPEG_PR_ERR("%s:%d]jpeg regulator get failed\n",
				__func__, __LINE__);
		goto fail_fs;
	}

	if (msm_jpeg_get_clk_info(pgmn_dev, pgmn_dev->pdev) < 0) {
		JPEG_PR_ERR("%s:%d]jpeg clock get failed\n",
				__func__, __LINE__);
		goto fail_fs;
	}

	rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
	 pgmn_dev->jpeg_clk, pgmn_dev->num_clk, 1);
	if (rc < 0) {
		JPEG_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
		goto fail_clk;
	}

	pgmn_dev->hw_version = readl_relaxed(jpeg_base +
		JPEG_HW_VERSION);
	JPEG_DBG_HIGH("%s:%d] jpeg HW version 0x%x", __func__, __LINE__,
		pgmn_dev->hw_version);

	pgmn_dev->jpeg_vbif = ioremap(vbif_mem->start, resource_size(vbif_mem));
	if (!pgmn_dev->jpeg_vbif) {
		rc = -ENOMEM;
		JPEG_PR_ERR("%s: ioremap failed\n", __func__);
		goto fail_vbif;
	}

	JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__,
		(uint32_t)pgmn_dev->jpeg_vbif);

	rc = msm_jpeg_attach_iommu(pgmn_dev);
	if (rc < 0)
		goto fail_iommu;

	set_vbif_params(pgmn_dev, pgmn_dev->jpeg_vbif);

	if (pgmn_dev->hw_version == JPEG_8939) {
		writel_relaxed(0x0000550e,
				jpeg_base + JPEG_FE_QOS_CFG);
		writel_relaxed(0x00005555,
				jpeg_base + JPEG_WE_QOS_CFG);
	}

	rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg",
		context);
	if (rc) {
		JPEG_PR_ERR("%s: request_irq failed, %d\n", __func__,
			jpeg_irq);
		goto fail_request_irq;
	}

	*mem  = jpeg_mem;
	*base = jpeg_base;
	*irq  = jpeg_irq;

	pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);

	pgmn_dev->state = MSM_JPEG_INIT;
	return rc;

fail_request_irq:
	msm_jpeg_detach_iommu(pgmn_dev);

fail_iommu:
	iounmap(pgmn_dev->jpeg_vbif);


fail_vbif:
	msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
	pgmn_dev->jpeg_clk, pgmn_dev->num_clk, 0);

fail_clk:
	rc = regulator_disable(pgmn_dev->jpeg_fs);
	if (!rc)
		regulator_put(pgmn_dev->jpeg_fs);
	else
		JPEG_PR_ERR("%s:%d] regulator disable failed %d",
			__func__, __LINE__, rc);
	pgmn_dev->jpeg_fs = NULL;

fail_fs:
	iounmap(jpeg_base);

fail_remap:
	release_mem_region(jpeg_mem->start, resource_size(jpeg_mem));
	JPEG_DBG("%s:%d] fail\n", __func__, __LINE__);
	return rc;
}
int msm_jpeg_platform_init(irqreturn_t (*handler)(int, void *),
	void *context)
{
	int rc = -1;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;
	struct platform_device *pdev = pgmn_dev->pdev;

	pgmn_dev->state = MSM_JPEG_IDLE;

	/* enable all regulators */
	rc = msm_camera_regulator_enable(pgmn_dev->jpeg_vdd,
		pgmn_dev->num_reg, true);
	if (rc < 0) {
		JPEG_PR_ERR("%s: failed to enable regulators\n", __func__);
		goto err_reg_enable;
	}

	/* enable all clocks */
	rc = msm_camera_clk_enable(&pgmn_dev->pdev->dev,
			pgmn_dev->jpeg_clk_info, pgmn_dev->jpeg_clk,
			pgmn_dev->num_clk, true);
	if (rc < 0) {
		JPEG_PR_ERR("%s: clk enable failed\n", __func__);
		goto err_clk_enable;
	}

	/* attach the smmu context banks */
	rc = msm_jpeg_attach_iommu(pgmn_dev);
	if (rc < 0) {
		JPEG_PR_ERR("%s: iommu attach failed\n", __func__);
		goto err_fail_iommu;
	}
	rc = msm_jpeg_set_init_dt_parms(pgmn_dev, "qcom,vbif-reg-settings",
		pgmn_dev->vbif_base);
	if (rc == -ENOENT) {
		JPEG_DBG("%s: No qcom,vbif-reg-settings property\n", __func__);
		set_vbif_params(pgmn_dev, pgmn_dev->vbif_base);
	} else if (rc < 0) {
		JPEG_PR_ERR("%s: vbif params set fail\n", __func__);
		goto err_fail_set_vbif;
	}

	/* register the interrupt handler */
	rc = msm_camera_register_irq(pgmn_dev->pdev,
		pgmn_dev->jpeg_irq_res, handler, IRQF_TRIGGER_RISING,
		"jpeg", context);
	if (rc < 0) {
		JPEG_PR_ERR("%s: irq request fail\n", __func__);
		goto err_reg_irq_fail;
	}

	pgmn_dev->hw_version = msm_camera_io_r(pgmn_dev->base +
		JPEG_HW_VERSION);
	JPEG_DBG_HIGH("%s:%d] jpeg HW version 0x%x", __func__, __LINE__,
		pgmn_dev->hw_version);
	pgmn_dev->state = MSM_JPEG_INIT;

	return 0;
err_reg_irq_fail:
err_fail_set_vbif:
	msm_jpeg_detach_iommu(pgmn_dev);
err_fail_iommu:
	msm_camera_clk_enable(&pdev->dev, pgmn_dev->jpeg_clk_info,
		pgmn_dev->jpeg_clk, pgmn_dev->num_clk, false);
err_clk_enable:
	msm_camera_regulator_enable(pgmn_dev->jpeg_vdd,
		pgmn_dev->num_reg, false);
err_reg_enable:
	return rc;
}