void msm_jpeg_subdev_release(struct v4l2_subdev *jpeg_sd)
{
	int rc;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *)jpeg_sd->host_priv;
	JPEG_DBG("%s:pgmn_dev=0x%lx", __func__, (unsigned long)pgmn_dev);
	rc = __msm_jpeg_release(pgmn_dev);
	JPEG_DBG("%s:rc=%d", __func__, rc);
}
/*
 * msm_jpeg_set_init_dt_parms() - get device tree config and write to registers.
 * @pgmn_dev: Pointer to jpeg device.
 * @dt_prop_name: Device tree property name.
 * @base: Base address.
 *
 * This function reads register offsets and values from dtsi based on
 * device tree property name and writes to jpeg registers.
 *
 * Return: 0 on success and negative error on failure.
 */
static int32_t msm_jpeg_set_init_dt_parms(struct msm_jpeg_device *pgmn_dev,
	const char *dt_prop_name,
	void *base)
{
	struct device_node *of_node;
	int32_t i = 0 , rc = 0;
	uint32_t *dt_reg_settings = NULL;
	uint32_t dt_count = 0;

	of_node = pgmn_dev->pdev->dev.of_node;
	JPEG_DBG("%s:%d E\n", __func__, __LINE__);

	if (!of_get_property(of_node, dt_prop_name,
				&dt_count)) {
		JPEG_DBG("%s: Error property does not exist\n",
				__func__);
		return -ENOENT;
	}
	if (dt_count % 8) {
		JPEG_PR_ERR("%s: Error invalid entries\n",
				__func__);
		return -EINVAL;
	}
	dt_count /= 4;
	if (dt_count != 0) {
		dt_reg_settings = kcalloc(dt_count, sizeof(uint32_t),
			GFP_KERNEL);
		if (!dt_reg_settings) {
			JPEG_PR_ERR("%s:%d No memory\n",
				__func__, __LINE__);
			return -ENOMEM;
		}
		rc = of_property_read_u32_array(of_node,
				dt_prop_name,
				dt_reg_settings,
				dt_count);
		if (rc < 0) {
			JPEG_PR_ERR("%s: No reg info\n",
				__func__);
			kfree(dt_reg_settings);
			return -EINVAL;
		}
		for (i = 0; i < dt_count; i = i + 2) {
			JPEG_DBG("%s:%d] %p %08x\n",
					__func__, __LINE__,
					base + dt_reg_settings[i],
					dt_reg_settings[i + 1]);
			msm_camera_io_w(dt_reg_settings[i + 1],
					base + dt_reg_settings[i]);
		}
		kfree(dt_reg_settings);
	}
	return 0;
}
Exemple #3
0
int msm_jpeg_subdev_init(struct v4l2_subdev *jpeg_sd)
{
	int rc;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *)jpeg_sd->host_priv;

	JPEG_DBG("%s:%d: jpeg_sd=0x%x pgmn_dev=0x%x\n",
		__func__, __LINE__, (uint32_t)jpeg_sd, (uint32_t)pgmn_dev);
	rc = __msm_jpeg_open(pgmn_dev);
	JPEG_DBG("%s:%d: rc=%d\n",
		__func__, __LINE__, rc);
	return rc;
}
Exemple #4
0
static long msm_jpeg_ioctl(struct file *filp, unsigned int cmd,
	unsigned long arg)
{
	int rc;
	struct msm_jpeg_device *pgmn_dev = filp->private_data;

	JPEG_DBG("%s:%d] cmd=%d pgmn_dev=0x%x arg=0x%x\n", __func__,
		__LINE__, _IOC_NR(cmd), (uint32_t)pgmn_dev, (uint32_t)arg);

	rc = __msm_jpeg_ioctl(pgmn_dev, cmd, arg);

	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
	return rc;
}
Exemple #5
0
static int msm_jpeg_release(struct inode *inode, struct file *filp)
{
	int rc;

	struct msm_jpeg_device *pgmn_dev = filp->private_data;

	JPEG_DBG(KERN_INFO "%s:%d]\n", __func__, __LINE__);

	rc = __msm_jpeg_release(pgmn_dev);

	JPEG_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
	return rc;
}
static int msm_jpeg_get_clk_info(struct msm_jpeg_device *jpeg_dev,
	struct platform_device *pdev)
{
	uint32_t count;
	int i, rc;
	uint32_t rates[JPEG_CLK_INFO_MAX];

	struct device_node *of_node;
	of_node = pdev->dev.of_node;

	count = of_property_count_strings(of_node, "clock-names");

	JPEG_DBG("count = %d\n", count);
	if (count == 0) {
		pr_err("no clocks found in device tree, count=%d", count);
		return 0;
	}

	if (count > JPEG_CLK_INFO_MAX) {
		pr_err("invalid count=%d, max is %d\n", count,
			JPEG_CLK_INFO_MAX);
		return -EINVAL;
	}

	for (i = 0; i < count; i++) {
		rc = of_property_read_string_index(of_node, "clock-names",
				i, &(jpeg_8x_clk_info[i].clk_name));
		JPEG_DBG("clock-names[%d] = %s\n",
			 i, jpeg_8x_clk_info[i].clk_name);
		if (rc < 0) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			return rc;
		}
	}
	rc = of_property_read_u32_array(of_node, "qcom,clock-rates",
		rates, count);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		return rc;
	}
	for (i = 0; i < count; i++) {
		jpeg_8x_clk_info[i].clk_rate =
			(rates[i] == 0) ? -1 : rates[i];
		JPEG_DBG("clk_rate[%d] = %ld\n",
			i, jpeg_8x_clk_info[i].clk_rate);
	}
	jpeg_dev->num_clk = count;
	return 0;
}
static int msm_jpeg_detach_iommu(struct msm_jpeg_device *pgmn_dev)
{
	JPEG_DBG("%s:%d] handle %d detach\n",
			__func__, __LINE__, pgmn_dev->iommu_hdl);
	cam_smmu_ops(pgmn_dev->iommu_hdl, CAM_SMMU_DETACH);
	return 0;
}
Exemple #8
0
uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
	uint32_t len, struct file **file_p, struct ion_handle **ionhandle,
	int domain_num) {
	unsigned long paddr;
	unsigned long size;
	int rc;
	*ionhandle = ion_import_dma_buf(pgmn_dev->jpeg_client, fd);
	if (IS_ERR_OR_NULL(*ionhandle))
		return 0;

	rc = ion_map_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0,
		SZ_4K, 0, &paddr, (unsigned long *)&size, 0, 0);
	JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
		(uint32_t)paddr, size);

	if (rc < 0) {
		JPEG_PR_ERR("%s: ion_map_iommu fd %d error %d\n", __func__, fd,
			rc);
		goto error1;
	}

	/* validate user input */
	if (len > size) {
		JPEG_PR_ERR("%s: invalid offset + len\n", __func__);
		goto error1;
	}

	return paddr;
error1:
	ion_free(pgmn_dev->jpeg_client, *ionhandle);
	return 0;
}
Exemple #9
0
void msm_jpeg_hw_irq_clear(uint32_t mask, uint32_t data, void *base)
{
	JPEG_DBG("%s:%d] mask %0x data %0x", __func__, __LINE__, mask, data);
	hw_cmd_irq_clear[0].mask = mask;
	hw_cmd_irq_clear[0].data = data;
	msm_jpeg_hw_write(&hw_cmd_irq_clear[0], base);
}
uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
	uint32_t len, int iommu_hdl)
{
	dma_addr_t paddr;
	size_t size;
	int rc;

	rc = cam_smmu_get_phy_addr(pgmn_dev->iommu_hdl, fd, CAM_SMMU_MAP_RW,
			&paddr, &size);
	JPEG_DBG("%s:%d] addr 0x%x size %zu", __func__, __LINE__,
		(uint32_t)paddr, size);

	if (rc < 0) {
		JPEG_PR_ERR("%s: fd %d got phy addr error %d\n", __func__, fd,
			rc);
		goto err_get_phy;
	}

	/* validate user input */
	if (len > size) {
		JPEG_PR_ERR("%s: invalid offset + len\n", __func__);
		goto err_size;
	}

	return paddr;
err_size:
	cam_smmu_put_phy_addr(pgmn_dev->iommu_hdl, fd);
err_get_phy:
	return 0;
}
int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev,
		long clk_rate)
{
	int rc = 0;
	struct clk *jpeg_clk;

	jpeg_clk = clk_get(&pgmn_dev->pdev->dev, "core_clk");
	if (IS_ERR(jpeg_clk)) {
		JPEG_PR_ERR("%s get failed\n", "core_clk");
		rc = PTR_ERR(jpeg_clk);
		goto error;
	}

	clk_rate = clk_round_rate(jpeg_clk, clk_rate);
	if (clk_rate < 0) {
		JPEG_PR_ERR("%s:%d] round rate failed", __func__, __LINE__);
		rc = -EINVAL;
		goto error;
	}
	JPEG_DBG("%s:%d] jpeg clk rate %ld", __func__, __LINE__, clk_rate);

	rc = clk_set_rate(jpeg_clk, clk_rate);

error:
	return rc;
}
static long msm_jpeg_subdev_ioctl(struct v4l2_subdev *sd,
	unsigned int cmd, void *arg)
{
	long rc;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *)sd->host_priv;

	JPEG_DBG("%s: cmd=%d\n", __func__, cmd);

	JPEG_DBG("%s: pgmn_dev 0x%lx", __func__, (unsigned long)pgmn_dev);

	JPEG_DBG("%s: Calling __msm_jpeg_ioctl\n", __func__);

	rc = __msm_jpeg_ioctl(pgmn_dev, cmd, (unsigned long)arg);
	pr_debug("%s: X\n", __func__);
	return rc;
}
Exemple #13
0
static int msm_jpeg_open(struct inode *inode, struct file *filp)
{
	int rc = 0;

	struct msm_jpeg_device *pgmn_dev = container_of(inode->i_cdev,
		struct msm_jpeg_device, cdev);
	filp->private_data = pgmn_dev;

	JPEG_DBG("%s:%d]\n", __func__, __LINE__);

	rc = __msm_jpeg_open(pgmn_dev);

	JPEG_DBG(KERN_INFO "%s:%d] %s open_count = %d\n", __func__, __LINE__,
		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);

	return rc;
}
inline void msm_jpeg_q_init(char const *name, struct msm_jpeg_q *q_p)
{
	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, name);
	q_p->name = name;
	spin_lock_init(&q_p->lck);
	INIT_LIST_HEAD(&q_p->q);
	init_waitqueue_head(&q_p->wait);
	q_p->unblck = 0;
}
int msm_jpeg_platform_release(struct resource *mem, void *base, int irq,
	void *context)
{
	int result = 0;
	int i = 0;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;

	free_irq(irq, context);

#ifdef CONFIG_MSM_IOMMU
	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
		iommu_detach_device(pgmn_dev->domain,
				pgmn_dev->iommu_ctx_arr[i]);
		JPEG_DBG("%s:%d]", __func__, __LINE__);
	}
#endif
	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, ARRAY_SIZE(jpeg_8x_clk_info), 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;
}
static int msm_jpeg_attach_iommu(struct msm_jpeg_device *pgmn_dev)
{
	int rc;
	rc = cam_smmu_ops(pgmn_dev->iommu_hdl, CAM_SMMU_ATTACH);
	if (rc < 0) {
		JPEG_PR_ERR("%s: Device attach failed\n", __func__);
		return -ENODEV;
	}
	JPEG_DBG("%s:%d] handle %d attach\n",
			__func__, __LINE__, pgmn_dev->iommu_hdl);
	return 0;
}
void msm_jpegdma_hw_irq_clear(uint32_t mask, uint32_t data, void *base)
{
    struct msm_jpeg_hw_cmd cmd_irq_clear;

    cmd_irq_clear.type = MSM_JPEG_HW_CMD_TYPE_WRITE;
    cmd_irq_clear.n = 1;
    cmd_irq_clear.offset = JPEGDMA_IRQ_CLEAR_ADDR;
    cmd_irq_clear.mask = mask;
    cmd_irq_clear.data = data;
    JPEG_DBG("%s:%d] mask %0x data %0x", __func__, __LINE__, mask, data);
    msm_jpeg_hw_write(&cmd_irq_clear, base);
}
static int msm_jpeg_detach_iommu(struct msm_jpeg_device *pgmn_dev)
{
	int i;

	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
		JPEG_DBG("%s:%d] dom 0x%lx ctx 0x%lx", __func__, __LINE__,
				(unsigned long)pgmn_dev->domain,
				(unsigned long)pgmn_dev->iommu_ctx_arr[i]);
		iommu_detach_device(pgmn_dev->domain,
				pgmn_dev->iommu_ctx_arr[i]);
	}
	return 0;
}
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, pgmn_dev->jpeg_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;
}
inline void *msm_jpeg_q_out(struct msm_jpeg_q *q_p)
{
	unsigned long flags;
	struct msm_jpeg_q_entry *q_entry_p = NULL;
	void *data = NULL;

	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
	spin_lock_irqsave(&q_p->lck, flags);
	if (!list_empty(&q_p->q)) {
		q_entry_p = list_first_entry(&q_p->q, struct msm_jpeg_q_entry,
			list);
		list_del_init(&q_entry_p->list);
	}
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;
}
static int msm_jpeg_attach_iommu(struct msm_jpeg_device *pgmn_dev)
{
	int i;

	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
		int rc = iommu_attach_device(pgmn_dev->domain,
				pgmn_dev->iommu_ctx_arr[i]);
		if (rc < 0) {
			JPEG_PR_ERR("%s: Device attach failed\n", __func__);
			return -ENODEV;
		}
		JPEG_DBG("%s:%d] dom 0x%lx ctx 0x%lx", __func__, __LINE__,
				(unsigned long)pgmn_dev->domain,
				(unsigned long)pgmn_dev->iommu_ctx_arr[i]);
	}
	return 0;
}
/*
 * msm_jpeg_platform_set_dt_config() - set jpeg device tree configuration.
 * @pgmn_dev: Pointer to jpeg device.
 *
 * This function holds an array of device tree property names and calls
 * msm_jpeg_set_init_dt_parms() for each property.
 *
 * Return: 0 on success and negative error on failure.
 */
int msm_jpeg_platform_set_dt_config(struct msm_jpeg_device *pgmn_dev)
{
	int rc = 0;
	uint8_t dt_prop_cnt = JPEG_DT_PROP_CNT;
	char *dt_prop_name[JPEG_DT_PROP_CNT] = {"qcom,qos-reg-settings",
		"qcom,prefetch-reg-settings"};

	while (dt_prop_cnt) {
		dt_prop_cnt--;
		rc = msm_jpeg_set_init_dt_parms(pgmn_dev,
			dt_prop_name[dt_prop_cnt],
			pgmn_dev->base);
		if (rc == -ENOENT) {
			JPEG_DBG("%s: No %s property\n", __func__,
				dt_prop_name[dt_prop_cnt]);
		} else if (rc < 0) {
			JPEG_PR_ERR("%s: %s params set fail\n", __func__,
				dt_prop_name[dt_prop_cnt]);
			return rc;
		}
	}
	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;
}
Exemple #25
0
static int msm_jpeg_init_dev(struct platform_device *pdev)
{
	int rc = -1;
	struct device *dev;
	struct msm_jpeg_device *msm_jpeg_device_p;
	char devname[10];

	msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
	if (!msm_jpeg_device_p) {
		JPEG_PR_ERR("%s: no mem\n", __func__);
		return -EFAULT;
	}

	msm_jpeg_device_p->pdev = pdev;

	if (pdev->dev.of_node)
		of_property_read_u32((&pdev->dev)->of_node, "cell-index",
								&pdev->id);

	snprintf(devname, sizeof(devname), "%s%d", MSM_JPEG_NAME, pdev->id);

	rc = __msm_jpeg_init(msm_jpeg_device_p);
	if (rc < -1) {
		JPEG_PR_ERR("%s: initialization failed\n", __func__);
		goto fail;
	}

	v4l2_subdev_init(&msm_jpeg_device_p->subdev, &msm_jpeg_subdev_ops);
	v4l2_set_subdev_hostdata(&msm_jpeg_device_p->subdev, msm_jpeg_device_p);
	JPEG_DBG("%s: msm_jpeg_device_p 0x%x", __func__,
			(uint32_t)msm_jpeg_device_p);

	rc = alloc_chrdev_region(&msm_jpeg_device_p->msm_jpeg_devno, 0, 1,
				devname);
	if (rc < 0) {
		JPEG_PR_ERR("%s: failed to allocate chrdev\n", __func__);
		goto fail_1;
	}

	if (!msm_jpeg_device_p->msm_jpeg_class) {
		msm_jpeg_device_p->msm_jpeg_class =
				class_create(THIS_MODULE, devname);
		if (IS_ERR(msm_jpeg_device_p->msm_jpeg_class)) {
			rc = PTR_ERR(msm_jpeg_device_p->msm_jpeg_class);
			JPEG_PR_ERR("%s: create device class failed\n",
				__func__);
			goto fail_2;
		}
	}

	dev = device_create(msm_jpeg_device_p->msm_jpeg_class, NULL,
		MKDEV(MAJOR(msm_jpeg_device_p->msm_jpeg_devno),
		MINOR(msm_jpeg_device_p->msm_jpeg_devno)), NULL,
		"%s%d", MSM_JPEG_NAME, pdev->id);
	if (IS_ERR(dev)) {
		JPEG_PR_ERR("%s: error creating device\n", __func__);
		rc = -ENODEV;
		goto fail_3;
	}

	cdev_init(&msm_jpeg_device_p->cdev, &msm_jpeg_fops);
	msm_jpeg_device_p->cdev.owner = THIS_MODULE;
	msm_jpeg_device_p->cdev.ops	 =
		(const struct file_operations *) &msm_jpeg_fops;
	rc = cdev_add(&msm_jpeg_device_p->cdev,
			msm_jpeg_device_p->msm_jpeg_devno, 1);
	if (rc < 0) {
		JPEG_PR_ERR("%s: error adding cdev\n", __func__);
		rc = -ENODEV;
		goto fail_4;
	}

	platform_set_drvdata(pdev, &msm_jpeg_device_p);

	JPEG_DBG("%s %s%d: success\n", __func__, MSM_JPEG_NAME, pdev->id);

	return rc;

fail_4:
	device_destroy(msm_jpeg_device_p->msm_jpeg_class,
			msm_jpeg_device_p->msm_jpeg_devno);

fail_3:
	class_destroy(msm_jpeg_device_p->msm_jpeg_class);

fail_2:
	unregister_chrdev_region(msm_jpeg_device_p->msm_jpeg_devno, 1);

fail_1:
	__msm_jpeg_exit(msm_jpeg_device_p);

fail:
	kfree(msm_jpeg_device_p);
	return rc;

}
Exemple #26
0
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 i = 0;
	int jpeg_irq;
	struct resource *jpeg_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: 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;
	}

	rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
	 pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 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_BASE_ADDRESS, VBIF_REGION_SIZE);
	if (!pgmn_dev->jpeg_vbif) {
		rc = -ENOMEM;
		JPEG_PR_ERR("%s:%d] ioremap failed\n", __func__, __LINE__);
		goto fail_vbif;
	}
	JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__,
		(uint32_t)pgmn_dev->jpeg_vbif);

#ifdef CONFIG_MSM_IOMMU
	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
		rc = iommu_attach_device(pgmn_dev->domain,
				pgmn_dev->iommu_ctx_arr[i]);
		if (rc < 0) {
			rc = -ENODEV;
			JPEG_PR_ERR("%s: Device attach failed\n", __func__);
			goto fail_iommu;
		}
		JPEG_DBG("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__,
					(uint32_t)pgmn_dev->domain,
					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
	}
#endif
	set_vbif_params(pgmn_dev, pgmn_dev->jpeg_vbif);

#ifdef CONFIG_MACH_LGE
	*mem  = jpeg_mem;
	*base = jpeg_base;
#endif

	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;
	}

#ifndef CONFIG_MACH_LGE /* QCT origin */
	*mem  = jpeg_mem;
	*base = jpeg_base;
#endif
	*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:
#ifdef CONFIG_MACH_LGE
	*mem  = NULL;
	*base = NULL;
#endif

#ifdef CONFIG_MSM_IOMMU
	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
		JPEG_PR_ERR("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__,
					(uint32_t)pgmn_dev->domain,
					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
		iommu_detach_device(pgmn_dev->domain,
					pgmn_dev->iommu_ctx_arr[i]);
	}
#endif

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, ARRAY_SIZE(jpeg_8x_clk_info), 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(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;
}