Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +35 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ static int32_t cam_cci_validate_queue(struct cci_device *cci_dev, struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; read_val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset); Loading @@ -110,12 +111,16 @@ static int32_t cam_cci_validate_queue(struct cci_device *cci_dev, CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); reg_val = 1 << ((master * 2) + queue); CAM_DBG(CAM_CCI, "CCI_QUEUE_START_ADDR"); spin_lock_irqsave( &cci_dev->cci_master_info[master].lock_q[queue], flags); atomic_set(&cci_dev->cci_master_info[master]. done_pending[queue], 1); cam_io_w_mb(reg_val, base + CCI_QUEUE_START_ADDR); CAM_DBG(CAM_CCI, "wait_for_completion_timeout"); 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-> cci_master_info[master].report_q[queue], CCI_TIMEOUT); if (rc <= 0) { Loading Loading @@ -290,6 +295,7 @@ static int32_t cam_cci_wait_report_cmd(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) { unsigned long flags; struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; Loading @@ -297,8 +303,12 @@ static int32_t cam_cci_wait_report_cmd(struct cci_device *cci_dev, uint32_t reg_val = 1 << ((master * 2) + queue); cam_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].done_pending[queue], 1); spin_unlock_irqrestore( &cci_dev->cci_master_info[master].lock_q[queue], flags); cam_io_w_mb(reg_val, base + CCI_QUEUE_START_ADDR); Loading @@ -310,8 +320,13 @@ static int32_t cam_cci_transfer_end(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) { int32_t rc = 0; unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 0) { spin_unlock_irqrestore( &cci_dev->cci_master_info[master].lock_q[queue], flags); rc = cam_cci_lock_queue(cci_dev, master, queue, 0); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc: %d", rc); Loading @@ -325,6 +340,8 @@ static int32_t cam_cci_transfer_end(struct cci_device *cci_dev, } else { 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); rc = cam_cci_wait(cci_dev, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc %d", rc); Loading Loading @@ -372,13 +389,18 @@ static void cam_cci_process_half_q(struct cci_device *cci_dev, &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; uint32_t reg_val = 1 << ((master * 2) + queue); unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master].lock_q[queue], flags); if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 0) { cam_cci_load_report_cmd(cci_dev, master, queue); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); cam_io_w_mb(reg_val, base + CCI_QUEUE_START_ADDR); } spin_unlock_irqrestore(&cci_dev->cci_master_info[master].lock_q[queue], flags); } static int32_t cam_cci_process_full_q(struct cci_device *cci_dev, Loading @@ -386,16 +408,24 @@ static int32_t cam_cci_process_full_q(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) { int32_t rc = 0; unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master].lock_q[queue], flags); if (atomic_read(&cci_dev->cci_master_info[master].q_free[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); rc = cam_cci_wait(cci_dev, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc %d", rc); return rc; } } else { spin_unlock_irqrestore( &cci_dev->cci_master_info[master].lock_q[queue], flags); rc = cam_cci_wait_report_cmd(cci_dev, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc %d", rc); Loading Loading @@ -599,6 +629,7 @@ static int32_t cam_cci_data_queue(struct cci_device *cci_dev, struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; if (i2c_cmd == NULL) { CAM_ERR(CAM_CCI, "Failed: i2c cmd is NULL"); Loading Loading @@ -641,7 +672,11 @@ static int32_t cam_cci_data_queue(struct cci_device *cci_dev, cam_io_w_mb(val, base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + 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); 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; Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +26 −1 Original line number Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * 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 Loading Loading @@ -64,6 +64,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; irq = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR); cam_io_w_mb(irq, base + CCI_IRQ_CLEAR_0_ADDR); Loading Loading @@ -91,23 +92,35 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) struct cam_cci_master_info *cci_master_info; 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); cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { complete(&cci_master_info->report_q[QUEUE_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) { struct cam_cci_master_info *cci_master_info; 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); cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { complete(&cci_master_info->report_q[QUEUE_1]); 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) { cci_dev->cci_master_info[MASTER_1].status = 0; Loading @@ -117,23 +130,35 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) struct cam_cci_master_info *cci_master_info; 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); cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { complete(&cci_master_info->report_q[QUEUE_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) { struct cam_cci_master_info *cci_master_info; 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); cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { complete(&cci_master_info->report_q[QUEUE_1]); 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) { cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * 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 Loading Loading @@ -144,6 +144,7 @@ struct cam_cci_master_info { struct mutex mutex_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; spinlock_t lock_q[NUM_QUEUES]; }; struct cam_cci_clk_params_t { Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +3 −1 Original line number Diff line number Diff line Loading @@ -198,6 +198,8 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); init_completion(&new_cci_dev-> cci_master_info[i].report_q[j]); spin_lock_init( &new_cci_dev->cci_master_info[i].lock_q[j]); } } } Loading Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +35 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ static int32_t cam_cci_validate_queue(struct cci_device *cci_dev, struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; read_val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset); Loading @@ -110,12 +111,16 @@ static int32_t cam_cci_validate_queue(struct cci_device *cci_dev, CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); reg_val = 1 << ((master * 2) + queue); CAM_DBG(CAM_CCI, "CCI_QUEUE_START_ADDR"); spin_lock_irqsave( &cci_dev->cci_master_info[master].lock_q[queue], flags); atomic_set(&cci_dev->cci_master_info[master]. done_pending[queue], 1); cam_io_w_mb(reg_val, base + CCI_QUEUE_START_ADDR); CAM_DBG(CAM_CCI, "wait_for_completion_timeout"); 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-> cci_master_info[master].report_q[queue], CCI_TIMEOUT); if (rc <= 0) { Loading Loading @@ -290,6 +295,7 @@ static int32_t cam_cci_wait_report_cmd(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) { unsigned long flags; struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; Loading @@ -297,8 +303,12 @@ static int32_t cam_cci_wait_report_cmd(struct cci_device *cci_dev, uint32_t reg_val = 1 << ((master * 2) + queue); cam_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].done_pending[queue], 1); spin_unlock_irqrestore( &cci_dev->cci_master_info[master].lock_q[queue], flags); cam_io_w_mb(reg_val, base + CCI_QUEUE_START_ADDR); Loading @@ -310,8 +320,13 @@ static int32_t cam_cci_transfer_end(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) { int32_t rc = 0; unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master]. lock_q[queue], flags); if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 0) { spin_unlock_irqrestore( &cci_dev->cci_master_info[master].lock_q[queue], flags); rc = cam_cci_lock_queue(cci_dev, master, queue, 0); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc: %d", rc); Loading @@ -325,6 +340,8 @@ static int32_t cam_cci_transfer_end(struct cci_device *cci_dev, } else { 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); rc = cam_cci_wait(cci_dev, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc %d", rc); Loading Loading @@ -372,13 +389,18 @@ static void cam_cci_process_half_q(struct cci_device *cci_dev, &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; uint32_t reg_val = 1 << ((master * 2) + queue); unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master].lock_q[queue], flags); if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 0) { cam_cci_load_report_cmd(cci_dev, master, queue); atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); cam_io_w_mb(reg_val, base + CCI_QUEUE_START_ADDR); } spin_unlock_irqrestore(&cci_dev->cci_master_info[master].lock_q[queue], flags); } static int32_t cam_cci_process_full_q(struct cci_device *cci_dev, Loading @@ -386,16 +408,24 @@ static int32_t cam_cci_process_full_q(struct cci_device *cci_dev, enum cci_i2c_queue_t queue) { int32_t rc = 0; unsigned long flags; spin_lock_irqsave(&cci_dev->cci_master_info[master].lock_q[queue], flags); if (atomic_read(&cci_dev->cci_master_info[master].q_free[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); rc = cam_cci_wait(cci_dev, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc %d", rc); return rc; } } else { spin_unlock_irqrestore( &cci_dev->cci_master_info[master].lock_q[queue], flags); rc = cam_cci_wait_report_cmd(cci_dev, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc %d", rc); Loading Loading @@ -599,6 +629,7 @@ static int32_t cam_cci_data_queue(struct cci_device *cci_dev, struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; if (i2c_cmd == NULL) { CAM_ERR(CAM_CCI, "Failed: i2c cmd is NULL"); Loading Loading @@ -641,7 +672,11 @@ static int32_t cam_cci_data_queue(struct cci_device *cci_dev, cam_io_w_mb(val, base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + 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); 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; Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +26 −1 Original line number Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * 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 Loading Loading @@ -64,6 +64,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; irq = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR); cam_io_w_mb(irq, base + CCI_IRQ_CLEAR_0_ADDR); Loading Loading @@ -91,23 +92,35 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) struct cam_cci_master_info *cci_master_info; 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); cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { complete(&cci_master_info->report_q[QUEUE_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) { struct cam_cci_master_info *cci_master_info; 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); cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { complete(&cci_master_info->report_q[QUEUE_1]); 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) { cci_dev->cci_master_info[MASTER_1].status = 0; Loading @@ -117,23 +130,35 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) struct cam_cci_master_info *cci_master_info; 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); cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { complete(&cci_master_info->report_q[QUEUE_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) { struct cam_cci_master_info *cci_master_info; 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); cci_master_info->status = 0; if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { complete(&cci_master_info->report_q[QUEUE_1]); 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) { cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * 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 Loading Loading @@ -144,6 +144,7 @@ struct cam_cci_master_info { struct mutex mutex_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; spinlock_t lock_q[NUM_QUEUES]; }; struct cam_cci_clk_params_t { Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +3 −1 Original line number Diff line number Diff line Loading @@ -198,6 +198,8 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); init_completion(&new_cci_dev-> cci_master_info[i].report_q[j]); spin_lock_init( &new_cci_dev->cci_master_info[i].lock_q[j]); } } } Loading