int msm_vfe47_enable_clks(struct vfe_device *vfe_dev, int enable)
{
- return msm_camera_clk_enable(&vfe_dev->pdev->dev,
+ unsigned long flags;
+ int rc;
+
+ if (!enable) {
+ spin_lock_irqsave(&vfe_dev->tasklet_lock, flags);
+ vfe_dev->clk_enabled = false;
+ spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
+ }
+
+ rc = msm_camera_clk_enable(&vfe_dev->pdev->dev,
vfe_dev->vfe_clk_info,
vfe_dev->vfe_clk, vfe_dev->num_clk, enable);
+ if (rc < 0) {
+ pr_err("%s: clk set %d failed %d\n", __func__, enable, rc);
+ return rc;
+ }
+
+ if (enable) {
+ spin_lock_irqsave(&vfe_dev->tasklet_lock, flags);
+ vfe_dev->clk_enabled = true;
+ spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
+ }
+
+ return rc;
}
int msm_vfe47_set_clk_rate(struct vfe_device *vfe_dev, long *rate)
{
long rc = 0;
long rc2 = 0;
+ unsigned long flags;
struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
if (!vfe_dev || !vfe_dev->vfe_base) {
while (vfe_dev->vfe_open_cnt != 0)
msm_isp_close_node(sd, NULL);
break;
+ case VIDIOC_MSM_ISP_SET_CLK_STATUS:
+ spin_lock_irqsave(&vfe_dev->tasklet_lock, flags);
+ vfe_dev->clk_enabled = *((unsigned int *)arg);
+ spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
+ break;
default:
pr_err_ratelimited("%s: Invalid ISP command %d\n", __func__,
}
atomic_sub(1, &vfe_dev->irq_cnt);
list_del(&queue_cmd->list);
+
+ if (!vfe_dev->clk_enabled) {
+ /* client closed, delayed task should exit directly */
+ spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
+ return;
+ }
+
queue_cmd->cmd_used = 0;
irq_status0 = queue_cmd->vfeInterruptStatus0;
irq_status1 = queue_cmd->vfeInterruptStatus1;
pingpong_status = queue_cmd->vfePingPongStatus;
ts = queue_cmd->ts;
+ /* related to rw reg, need to be protected */
+ irq_ops->process_halt_irq(vfe_dev,
+ irq_status0, irq_status1);
spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
ISP_DBG("%s: vfe_id %d status0: 0x%x status1: 0x%x\n",
__func__, vfe_dev->pdev->id, irq_status0, irq_status1);
}
irq_ops->process_reset_irq(vfe_dev,
irq_status0, irq_status1);
- irq_ops->process_halt_irq(vfe_dev,
- irq_status0, irq_status1);
if (atomic_read(&vfe_dev->error_info.overflow_state)
!= NO_OVERFLOW) {
ISP_DBG("%s: Recovery in processing, Ignore IRQs!!!\n",
MSM_ISP_AXI_OUTPUT_CFG,
MSM_ISP_START,
MSM_ISP_STOP,
+
+ MSM_ISP_SET_CLK_STATUS,
};
_IOWR('V', MSM_ISP_CAMIF_CFG, \
struct msm_vfe_camif_cfg)
+#define VIDIOC_MSM_ISP_SET_CLK_STATUS \
+ _IOWR('V', MSM_ISP_SET_CLK_STATUS, \
+ unsigned int)
#endif /* __UAPI_MSM_AIS_ISP__ */