Loading drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +58 −1 Original line number Original line Diff line number Diff line Loading @@ -201,6 +201,7 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { int32_t rc = 0; int32_t rc = 0; unsigned long flags; uint32_t read_val = 0; uint32_t read_val = 0; uint32_t reg_offset = master * 0x200 + queue * 0x100; uint32_t reg_offset = master * 0x200 + queue * 0x100; read_val = msm_camera_io_r_mb(cci_dev->base + read_val = msm_camera_io_r_mb(cci_dev->base + Loading @@ -223,6 +224,8 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); reg_val = 1 << ((master * 2) + queue); reg_val = 1 << ((master * 2) + queue); CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__); CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__); spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); atomic_set(&cci_dev->cci_master_info[master]. atomic_set(&cci_dev->cci_master_info[master]. done_pending[queue], 1); done_pending[queue], 1); msm_camera_io_w_mb(reg_val, cci_dev->base + msm_camera_io_w_mb(reg_val, cci_dev->base + Loading @@ -230,6 +233,8 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, CDBG("%s line %d wait_for_completion_timeout\n", CDBG("%s line %d wait_for_completion_timeout\n", __func__, __LINE__); __func__, __LINE__); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = wait_for_completion_timeout(&cci_dev-> rc = wait_for_completion_timeout(&cci_dev-> cci_master_info[master].report_q[queue], CCI_TIMEOUT); cci_master_info[master].report_q[queue], CCI_TIMEOUT); if (rc <= 0) { if (rc <= 0) { Loading Loading @@ -438,10 +443,17 @@ static int32_t msm_cci_wait_report_cmd(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { unsigned long flags; uint32_t reg_val = 1 << ((master * 2) + queue); uint32_t reg_val = 1 << ((master * 2) + queue); msm_cci_load_report_cmd(cci_dev, master, queue); msm_cci_load_report_cmd(cci_dev, master, queue); spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); atomic_set(&cci_dev->cci_master_info[master].done_pending[queue], 1); atomic_set(&cci_dev->cci_master_info[master].done_pending[queue], 1); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); msm_camera_io_w_mb(reg_val, cci_dev->base + msm_camera_io_w_mb(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR); CCI_QUEUE_START_ADDR); return msm_cci_wait(cci_dev, master, queue); return msm_cci_wait(cci_dev, master, queue); Loading @@ -451,13 +463,19 @@ static void msm_cci_process_half_q(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { unsigned long flags; uint32_t reg_val = 1 << ((master * 2) + queue); uint32_t reg_val = 1 << ((master * 2) + queue); spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { msm_cci_load_report_cmd(cci_dev, master, queue); msm_cci_load_report_cmd(cci_dev, master, queue); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); msm_camera_io_w_mb(reg_val, cci_dev->base + msm_camera_io_w_mb(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR); CCI_QUEUE_START_ADDR); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); } } static int32_t msm_cci_process_full_q(struct cci_device *cci_dev, static int32_t msm_cci_process_full_q(struct cci_device *cci_dev, Loading @@ -465,15 +483,23 @@ static int32_t msm_cci_process_full_q(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { int32_t rc = 0; int32_t rc = 0; unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); if (1 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { if (1 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { atomic_set(&cci_dev->cci_master_info[master]. atomic_set(&cci_dev->cci_master_info[master]. done_pending[queue], 1); done_pending[queue], 1); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = msm_cci_wait(cci_dev, master, queue); rc = msm_cci_wait(cci_dev, master, queue); if (rc < 0) { if (rc < 0) { pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); return rc; return rc; } } } else { } else { spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = msm_cci_wait_report_cmd(cci_dev, master, queue); rc = msm_cci_wait_report_cmd(cci_dev, master, queue); if (rc < 0) { if (rc < 0) { pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); Loading Loading @@ -501,8 +527,13 @@ static int32_t msm_cci_transfer_end(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { int32_t rc = 0; int32_t rc = 0; unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = msm_cci_lock_queue(cci_dev, master, queue, 0); rc = msm_cci_lock_queue(cci_dev, master, queue, 0); if (rc < 0) { if (rc < 0) { pr_err("%s failed line %d\n", __func__, __LINE__); pr_err("%s failed line %d\n", __func__, __LINE__); Loading @@ -516,6 +547,8 @@ static int32_t msm_cci_transfer_end(struct cci_device *cci_dev, } else { } else { atomic_set(&cci_dev->cci_master_info[master]. atomic_set(&cci_dev->cci_master_info[master]. done_pending[queue], 1); done_pending[queue], 1); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = msm_cci_wait(cci_dev, master, queue); rc = msm_cci_wait(cci_dev, master, queue); if (rc < 0) { if (rc < 0) { pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); Loading Loading @@ -570,6 +603,7 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, uint32_t reg_offset; uint32_t reg_offset; uint32_t val = 0; uint32_t val = 0; uint32_t max_queue_size; uint32_t max_queue_size; unsigned long flags; if (i2c_cmd == NULL) { if (i2c_cmd == NULL) { pr_err("%s:%d Failed line\n", __func__, pr_err("%s:%d Failed line\n", __func__, Loading Loading @@ -613,7 +647,11 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, msm_camera_io_w_mb(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + msm_camera_io_w_mb(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + reg_offset); reg_offset); spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 0); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 0); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); max_queue_size = cci_dev->cci_i2c_queue_info[master][queue]. max_queue_size = cci_dev->cci_i2c_queue_info[master][queue]. max_queue_size; max_queue_size; Loading Loading @@ -1641,6 +1679,7 @@ static int32_t msm_cci_config(struct v4l2_subdev *sd, static irqreturn_t msm_cci_irq(int irq_num, void *data) static irqreturn_t msm_cci_irq(int irq_num, void *data) { { uint32_t irq; uint32_t irq; unsigned long flags; struct cci_device *cci_dev = data; struct cci_device *cci_dev = data; irq = msm_camera_io_r_mb(cci_dev->base + CCI_IRQ_STATUS_0_ADDR); irq = msm_camera_io_r_mb(cci_dev->base + CCI_IRQ_STATUS_0_ADDR); msm_camera_io_w_mb(irq, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR); msm_camera_io_w_mb(irq, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR); Loading @@ -1667,22 +1706,30 @@ static irqreturn_t msm_cci_irq(int irq_num, void *data) if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { struct msm_camera_cci_master_info *cci_master_info; struct msm_camera_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; spin_lock_irqsave(&cci_dev->cci_master_info[MASTER_0]. lock_q[QUEUE_0], flags); atomic_set(&cci_master_info->q_free[QUEUE_0], 0); atomic_set(&cci_master_info->q_free[QUEUE_0], 0); cci_master_info->status = 0; cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { complete(&cci_master_info->report_q[QUEUE_0]); complete(&cci_master_info->report_q[QUEUE_0]); atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[MASTER_0]. lock_q[QUEUE_0], flags); } } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK) { struct msm_camera_cci_master_info *cci_master_info; struct msm_camera_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; spin_lock_irqsave(&cci_dev->cci_master_info[MASTER_0]. lock_q[QUEUE_1], flags); atomic_set(&cci_master_info->q_free[QUEUE_1], 0); atomic_set(&cci_master_info->q_free[QUEUE_1], 0); cci_master_info->status = 0; cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { complete(&cci_master_info->report_q[QUEUE_1]); complete(&cci_master_info->report_q[QUEUE_1]); atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[MASTER_0]. lock_q[QUEUE_1], flags); } } if (irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) { cci_dev->cci_master_info[MASTER_1].status = 0; cci_dev->cci_master_info[MASTER_1].status = 0; Loading @@ -1691,22 +1738,30 @@ static irqreturn_t msm_cci_irq(int irq_num, void *data) if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { struct msm_camera_cci_master_info *cci_master_info; struct msm_camera_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; spin_lock_irqsave(&cci_dev->cci_master_info[MASTER_1]. lock_q[QUEUE_0], flags); atomic_set(&cci_master_info->q_free[QUEUE_0], 0); atomic_set(&cci_master_info->q_free[QUEUE_0], 0); cci_master_info->status = 0; cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { complete(&cci_master_info->report_q[QUEUE_0]); complete(&cci_master_info->report_q[QUEUE_0]); atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[MASTER_1]. lock_q[QUEUE_0], flags); } } if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK) { struct msm_camera_cci_master_info *cci_master_info; struct msm_camera_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; spin_lock_irqsave(&cci_dev->cci_master_info[MASTER_1]. lock_q[QUEUE_1], flags); atomic_set(&cci_master_info->q_free[QUEUE_1], 0); atomic_set(&cci_master_info->q_free[QUEUE_1], 0); cci_master_info->status = 0; cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { complete(&cci_master_info->report_q[QUEUE_1]); complete(&cci_master_info->report_q[QUEUE_1]); atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[MASTER_1]. lock_q[QUEUE_1], flags); } } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; Loading Loading @@ -1795,6 +1850,8 @@ static void msm_cci_init_cci_params(struct cci_device *new_cci_dev) mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); init_completion(&new_cci_dev-> init_completion(&new_cci_dev-> cci_master_info[i].report_q[j]); cci_master_info[i].report_q[j]); spin_lock_init(&new_cci_dev-> cci_master_info[i].lock_q[j]); } } } } return; return; Loading drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h +2 −1 Original line number Original line Diff line number Diff line /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -125,6 +125,7 @@ struct msm_camera_cci_master_info { struct mutex mutex_q[NUM_QUEUES]; struct mutex mutex_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; spinlock_t lock_q[NUM_QUEUES]; }; }; struct msm_cci_clk_params_t { struct msm_cci_clk_params_t { Loading Loading
drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +58 −1 Original line number Original line Diff line number Diff line Loading @@ -201,6 +201,7 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { int32_t rc = 0; int32_t rc = 0; unsigned long flags; uint32_t read_val = 0; uint32_t read_val = 0; uint32_t reg_offset = master * 0x200 + queue * 0x100; uint32_t reg_offset = master * 0x200 + queue * 0x100; read_val = msm_camera_io_r_mb(cci_dev->base + read_val = msm_camera_io_r_mb(cci_dev->base + Loading @@ -223,6 +224,8 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); reg_val = 1 << ((master * 2) + queue); reg_val = 1 << ((master * 2) + queue); CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__); CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__); spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); atomic_set(&cci_dev->cci_master_info[master]. atomic_set(&cci_dev->cci_master_info[master]. done_pending[queue], 1); done_pending[queue], 1); msm_camera_io_w_mb(reg_val, cci_dev->base + msm_camera_io_w_mb(reg_val, cci_dev->base + Loading @@ -230,6 +233,8 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, CDBG("%s line %d wait_for_completion_timeout\n", CDBG("%s line %d wait_for_completion_timeout\n", __func__, __LINE__); __func__, __LINE__); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = wait_for_completion_timeout(&cci_dev-> rc = wait_for_completion_timeout(&cci_dev-> cci_master_info[master].report_q[queue], CCI_TIMEOUT); cci_master_info[master].report_q[queue], CCI_TIMEOUT); if (rc <= 0) { if (rc <= 0) { Loading Loading @@ -438,10 +443,17 @@ static int32_t msm_cci_wait_report_cmd(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { unsigned long flags; uint32_t reg_val = 1 << ((master * 2) + queue); uint32_t reg_val = 1 << ((master * 2) + queue); msm_cci_load_report_cmd(cci_dev, master, queue); msm_cci_load_report_cmd(cci_dev, master, queue); spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); atomic_set(&cci_dev->cci_master_info[master].done_pending[queue], 1); atomic_set(&cci_dev->cci_master_info[master].done_pending[queue], 1); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); msm_camera_io_w_mb(reg_val, cci_dev->base + msm_camera_io_w_mb(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR); CCI_QUEUE_START_ADDR); return msm_cci_wait(cci_dev, master, queue); return msm_cci_wait(cci_dev, master, queue); Loading @@ -451,13 +463,19 @@ static void msm_cci_process_half_q(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { unsigned long flags; uint32_t reg_val = 1 << ((master * 2) + queue); uint32_t reg_val = 1 << ((master * 2) + queue); spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { msm_cci_load_report_cmd(cci_dev, master, queue); msm_cci_load_report_cmd(cci_dev, master, queue); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); msm_camera_io_w_mb(reg_val, cci_dev->base + msm_camera_io_w_mb(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR); CCI_QUEUE_START_ADDR); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); } } static int32_t msm_cci_process_full_q(struct cci_device *cci_dev, static int32_t msm_cci_process_full_q(struct cci_device *cci_dev, Loading @@ -465,15 +483,23 @@ static int32_t msm_cci_process_full_q(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { int32_t rc = 0; int32_t rc = 0; unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); if (1 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { if (1 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { atomic_set(&cci_dev->cci_master_info[master]. atomic_set(&cci_dev->cci_master_info[master]. done_pending[queue], 1); done_pending[queue], 1); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = msm_cci_wait(cci_dev, master, queue); rc = msm_cci_wait(cci_dev, master, queue); if (rc < 0) { if (rc < 0) { pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); return rc; return rc; } } } else { } else { spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = msm_cci_wait_report_cmd(cci_dev, master, queue); rc = msm_cci_wait_report_cmd(cci_dev, master, queue); if (rc < 0) { if (rc < 0) { pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); Loading Loading @@ -501,8 +527,13 @@ static int32_t msm_cci_transfer_end(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) enum cci_i2c_queue_t queue) { { int32_t rc = 0; int32_t rc = 0; unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = msm_cci_lock_queue(cci_dev, master, queue, 0); rc = msm_cci_lock_queue(cci_dev, master, queue, 0); if (rc < 0) { if (rc < 0) { pr_err("%s failed line %d\n", __func__, __LINE__); pr_err("%s failed line %d\n", __func__, __LINE__); Loading @@ -516,6 +547,8 @@ static int32_t msm_cci_transfer_end(struct cci_device *cci_dev, } else { } else { atomic_set(&cci_dev->cci_master_info[master]. atomic_set(&cci_dev->cci_master_info[master]. done_pending[queue], 1); done_pending[queue], 1); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); rc = msm_cci_wait(cci_dev, master, queue); rc = msm_cci_wait(cci_dev, master, queue); if (rc < 0) { if (rc < 0) { pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); Loading Loading @@ -570,6 +603,7 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, uint32_t reg_offset; uint32_t reg_offset; uint32_t val = 0; uint32_t val = 0; uint32_t max_queue_size; uint32_t max_queue_size; unsigned long flags; if (i2c_cmd == NULL) { if (i2c_cmd == NULL) { pr_err("%s:%d Failed line\n", __func__, pr_err("%s:%d Failed line\n", __func__, Loading Loading @@ -613,7 +647,11 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, msm_camera_io_w_mb(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + msm_camera_io_w_mb(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + reg_offset); reg_offset); spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 0); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 0); spin_unlock_irqrestore(&cci_dev->cci_master_info[master]. lock_q[queue], flags); max_queue_size = cci_dev->cci_i2c_queue_info[master][queue]. max_queue_size = cci_dev->cci_i2c_queue_info[master][queue]. max_queue_size; max_queue_size; Loading Loading @@ -1641,6 +1679,7 @@ static int32_t msm_cci_config(struct v4l2_subdev *sd, static irqreturn_t msm_cci_irq(int irq_num, void *data) static irqreturn_t msm_cci_irq(int irq_num, void *data) { { uint32_t irq; uint32_t irq; unsigned long flags; struct cci_device *cci_dev = data; struct cci_device *cci_dev = data; irq = msm_camera_io_r_mb(cci_dev->base + CCI_IRQ_STATUS_0_ADDR); irq = msm_camera_io_r_mb(cci_dev->base + CCI_IRQ_STATUS_0_ADDR); msm_camera_io_w_mb(irq, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR); msm_camera_io_w_mb(irq, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR); Loading @@ -1667,22 +1706,30 @@ static irqreturn_t msm_cci_irq(int irq_num, void *data) if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { struct msm_camera_cci_master_info *cci_master_info; struct msm_camera_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; spin_lock_irqsave(&cci_dev->cci_master_info[MASTER_0]. lock_q[QUEUE_0], flags); atomic_set(&cci_master_info->q_free[QUEUE_0], 0); atomic_set(&cci_master_info->q_free[QUEUE_0], 0); cci_master_info->status = 0; cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { complete(&cci_master_info->report_q[QUEUE_0]); complete(&cci_master_info->report_q[QUEUE_0]); atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[MASTER_0]. lock_q[QUEUE_0], flags); } } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK) { struct msm_camera_cci_master_info *cci_master_info; struct msm_camera_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; spin_lock_irqsave(&cci_dev->cci_master_info[MASTER_0]. lock_q[QUEUE_1], flags); atomic_set(&cci_master_info->q_free[QUEUE_1], 0); atomic_set(&cci_master_info->q_free[QUEUE_1], 0); cci_master_info->status = 0; cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { complete(&cci_master_info->report_q[QUEUE_1]); complete(&cci_master_info->report_q[QUEUE_1]); atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[MASTER_0]. lock_q[QUEUE_1], flags); } } if (irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) { cci_dev->cci_master_info[MASTER_1].status = 0; cci_dev->cci_master_info[MASTER_1].status = 0; Loading @@ -1691,22 +1738,30 @@ static irqreturn_t msm_cci_irq(int irq_num, void *data) if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { struct msm_camera_cci_master_info *cci_master_info; struct msm_camera_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; spin_lock_irqsave(&cci_dev->cci_master_info[MASTER_1]. lock_q[QUEUE_0], flags); atomic_set(&cci_master_info->q_free[QUEUE_0], 0); atomic_set(&cci_master_info->q_free[QUEUE_0], 0); cci_master_info->status = 0; cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { complete(&cci_master_info->report_q[QUEUE_0]); complete(&cci_master_info->report_q[QUEUE_0]); atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[MASTER_1]. lock_q[QUEUE_0], flags); } } if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK) { struct msm_camera_cci_master_info *cci_master_info; struct msm_camera_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; spin_lock_irqsave(&cci_dev->cci_master_info[MASTER_1]. lock_q[QUEUE_1], flags); atomic_set(&cci_master_info->q_free[QUEUE_1], 0); atomic_set(&cci_master_info->q_free[QUEUE_1], 0); cci_master_info->status = 0; cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { complete(&cci_master_info->report_q[QUEUE_1]); complete(&cci_master_info->report_q[QUEUE_1]); atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); } } spin_unlock_irqrestore(&cci_dev->cci_master_info[MASTER_1]. lock_q[QUEUE_1], flags); } } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; Loading Loading @@ -1795,6 +1850,8 @@ static void msm_cci_init_cci_params(struct cci_device *new_cci_dev) mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); init_completion(&new_cci_dev-> init_completion(&new_cci_dev-> cci_master_info[i].report_q[j]); cci_master_info[i].report_q[j]); spin_lock_init(&new_cci_dev-> cci_master_info[i].lock_q[j]); } } } } return; return; Loading
drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h +2 −1 Original line number Original line Diff line number Diff line /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -125,6 +125,7 @@ struct msm_camera_cci_master_info { struct mutex mutex_q[NUM_QUEUES]; struct mutex mutex_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; spinlock_t lock_q[NUM_QUEUES]; }; }; struct msm_cci_clk_params_t { struct msm_cci_clk_params_t { Loading