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