Merge "msm: camera: Modify interrupt handler for CCI" into dev/msm-4.9-camx

This commit is contained in:
Jeyaprakash Soundrapandian 2018-10-19 15:47:23 -07:00 • committed by Gerrit - the friendly Code Review server
commit ab61fb5849
3 changed files with 75 additions and 17 deletions

View file

@ -870,7 +870,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
struct cam_cci_ctrl *c_ctrl)
{
int32_t rc = 0;
uint32_t val = 0, i = 0, j = 0;
uint32_t val = 0, i = 0, j = 0, irq_mask_update = 0;
unsigned long rem_jiffies, flags;
int32_t read_words = 0, exp_words = 0;
int32_t index = 0, first_byte = 0, total_read_words = 0;
@ -1049,13 +1049,20 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
j, total_read_words);
spin_lock_irqsave(&cci_dev->lock_status, flags);
if (cci_dev->irq_status1) {
CAM_DBG(CAM_CCI, "clear irq_status1:%x",
cci_dev->irq_status1);
cam_io_w_mb(cci_dev->irq_status1,
base + CCI_IRQ_CLEAR_1_ADDR);
cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
cci_dev->irq_status1 = 0;
if (cci_dev->irqs_disabled) {
irq_mask_update =
cam_io_r_mb(base + CCI_IRQ_MASK_1_ADDR) |
CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD;
if (master == MASTER_0 && cci_dev->irqs_disabled &
CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD)
irq_mask_update |=
CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD;
else if (master == MASTER_1 && cci_dev->irqs_disabled &
CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD)
irq_mask_update |=
CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD;
cam_io_w_mb(irq_mask_update,
base + CCI_IRQ_MASK_1_ADDR);
}
spin_unlock_irqrestore(&cci_dev->lock_status, flags);

View file

@ -58,8 +58,8 @@ static long cam_cci_subdev_compat_ioctl(struct v4l2_subdev *sd,
irqreturn_t cam_cci_irq(int irq_num, void *data)
{
uint32_t irq_status0 = 0;
uint32_t irq_status1 = 0;
uint32_t irq_status0, irq_status1, reg_bmsk;
uint32_t irq_update_rd_done = 0;
struct cci_device *cci_dev = data;
struct cam_hw_soc_info *soc_info =
&cci_dev->soc_info;
@ -141,6 +141,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
&cci_dev->cci_master_info[MASTER_0].lock_q[QUEUE_1],
flags);
}
rd_done_th_assert = false;
if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) &&
(irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD)) {
cci_dev->cci_master_info[MASTER_1].status = 0;
@ -223,19 +224,67 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
cam_io_w_mb(CCI_M1_HALT_REQ_RMSK,
base + CCI_HALT_REQ_ADDR);
CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0);
}
if ((rd_done_th_assert) || (!cci_dev->is_burst_read)) {
cam_io_w_mb(irq_status1, base + CCI_IRQ_CLEAR_1_ADDR);
CAM_DBG(CAM_CCI, "clear irq_status0:%x irq_status1:%x",
irq_status0, irq_status1);
} else {
spin_lock_irqsave(&cci_dev->lock_status, flags);
cci_dev->irq_status1 |= irq_status1;
spin_unlock_irqrestore(&cci_dev->lock_status, flags);
}
cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR);
reg_bmsk = CCI_IRQ_MASK_1_RMSK;
if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) &&
!(irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK)) {
reg_bmsk &= ~CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD;
spin_lock_irqsave(&cci_dev->lock_status, flags);
cci_dev->irqs_disabled |=
CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD;
spin_unlock_irqrestore(&cci_dev->lock_status, flags);
}
if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) &&
!(irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK)) {
reg_bmsk &= ~CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD;
spin_lock_irqsave(&cci_dev->lock_status, flags);
cci_dev->irqs_disabled |=
CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD;
spin_unlock_irqrestore(&cci_dev->lock_status, flags);
}
if (reg_bmsk != CCI_IRQ_MASK_1_RMSK) {
cam_io_w_mb(reg_bmsk, base + CCI_IRQ_MASK_1_ADDR);
CAM_DBG(CAM_CCI, "Updating the reg mask for irq1: 0x%x",
reg_bmsk);
} else if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK ||
irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) {
if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) {
spin_lock_irqsave(&cci_dev->lock_status, flags);
if (cci_dev->irqs_disabled &
CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) {
irq_update_rd_done |=
CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD;
cci_dev->irqs_disabled &=
~CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD;
}
spin_unlock_irqrestore(&cci_dev->lock_status, flags);
}
if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) {
spin_lock_irqsave(&cci_dev->lock_status, flags);
if (cci_dev->irqs_disabled &
CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) {
irq_update_rd_done |=
CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD;
cci_dev->irqs_disabled &=
~CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD;
}
spin_unlock_irqrestore(&cci_dev->lock_status, flags);
}
}
if (irq_update_rd_done != 0) {
irq_update_rd_done |= cam_io_r_mb(base + CCI_IRQ_MASK_1_ADDR);
cam_io_w_mb(irq_update_rd_done, base + CCI_IRQ_MASK_1_ADDR);
}
cam_io_w_mb(irq_status1, base + CCI_IRQ_CLEAR_1_ADDR);
cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
return IRQ_HANDLED;
}

View file

@ -198,6 +198,7 @@ enum cam_cci_state_t {
* @lock_status: to protect changes to irq_status1
* @is_burst_read: Flag to determine if we are performing
* a burst read operation or not
* @irqs_disabled: Mask for IRQs that are disabled
*/
struct cci_device {
struct v4l2_subdev subdev;
@ -225,6 +226,7 @@ struct cci_device {
uint32_t irq_status1;
spinlock_t lock_status;
bool is_burst_read;
uint32_t irqs_disabled;
};
enum cam_cci_i2c_cmd_type {