diff options
author | Roger Liao <rogerliao@google.com> | 2020-10-20 17:04:23 +0800 |
---|---|---|
committer | Roger Liao <rogerliao@google.com> | 2020-10-21 00:23:06 +0800 |
commit | 4b50ea998f28018f9ca54a980085e0e2f4d49724 (patch) | |
tree | aab73c21daab1c2d29f8f1f52638f34c3efc2b59 | |
parent | b122fe6046966c53653e37e38cb296dd661f9d81 (diff) | |
parent | 21437ea878416dad4e3364033a7886e899de5bf3 (diff) | |
download | camera-kernel-4b50ea998f28018f9ca54a980085e0e2f4d49724.tar.gz |
Merge branch 'android-msm-pixel-4.19-rvc-qpr1' into android-msm-barbet-4.19
Merge from build 6891367
Bug: 162288636
Signed-off-by: Roger Liao <rogerliao@google.com>
Change-Id: I2b6739a69e02e73a08f150563ae033b3af187f83
-rw-r--r-- | drivers/cam_req_mgr/cam_req_mgr_workq.c | 46 | ||||
-rw-r--r-- | drivers/cam_req_mgr/cam_req_mgr_workq.h | 12 | ||||
-rw-r--r-- | drivers/cam_sensor_module/cam_ois/cam_ois_core.c | 12 | ||||
-rw-r--r-- | drivers/cam_sensor_module/cam_ois/cam_ois_dev.c | 38 | ||||
-rw-r--r-- | drivers/cam_sensor_module/cam_ois/cam_ois_dev.h | 8 | ||||
-rw-r--r-- | drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c | 26 | ||||
-rw-r--r-- | drivers/cam_sensor_module/cam_sensor_vsync/cam_sensor_vsync.h | 4 |
7 files changed, 101 insertions, 45 deletions
diff --git a/drivers/cam_req_mgr/cam_req_mgr_workq.c b/drivers/cam_req_mgr/cam_req_mgr_workq.c index 1e4da21..a14465d 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_workq.c +++ b/drivers/cam_req_mgr/cam_req_mgr_workq.c @@ -89,7 +89,7 @@ static int cam_req_mgr_process_task(struct crm_workq_task *task) * cam_req_mgr_process_workq() - main loop handling * @w: workqueue task pointer */ -static void cam_req_mgr_process_workq(struct work_struct *w) +static void cam_req_mgr_process_workq(struct kthread_work *w) { struct cam_req_mgr_core_workq *workq = NULL; struct crm_workq_task *task; @@ -152,11 +152,6 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task, ? prio : CRM_TASK_PRIORITY_0; WORKQ_ACQUIRE_LOCK(workq, flags); - if (!workq->job) { - rc = -EINVAL; - WORKQ_RELEASE_LOCK(workq, flags); - goto end; - } list_add_tail(&task->entry, &workq->task.process_head[task->priority]); @@ -165,7 +160,7 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task, CAM_DBG(CAM_CRM, "enq task %pK pending_cnt %d", task, atomic_read(&workq->task.pending_cnt)); - queue_work(workq->job, &workq->work); + kthread_queue_work(&workq->job_worker, &workq->work); WORKQ_RELEASE_LOCK(workq, flags); end: return rc; @@ -176,10 +171,12 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks, struct cam_req_mgr_core_workq **workq, enum crm_workq_context in_irq, int flags) { - int32_t i, wq_flags = 0, max_active_tasks = 0; + int32_t i, max_active_tasks = 0; struct crm_workq_task *task; struct cam_req_mgr_core_workq *crm_workq = NULL; char buf[128] = "crm_workq-"; + struct sched_param param = { .sched_priority = 1 }; + int error; if (!*workq) { crm_workq = kzalloc(sizeof(struct cam_req_mgr_core_workq), @@ -187,24 +184,31 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks, if (crm_workq == NULL) return -ENOMEM; - wq_flags |= WQ_UNBOUND; - if (flags & CAM_WORKQ_FLAG_HIGH_PRIORITY) - wq_flags |= WQ_HIGHPRI; - if (flags & CAM_WORKQ_FLAG_SERIAL) max_active_tasks = 1; strlcat(buf, name, sizeof(buf)); CAM_DBG(CAM_CRM, "create workque crm_workq-%s", name); - crm_workq->job = alloc_workqueue(buf, - wq_flags, max_active_tasks, NULL); - if (!crm_workq->job) { + kthread_init_worker(&crm_workq->job_worker); + crm_workq->job_worker_thread = kthread_run(kthread_worker_fn, + &crm_workq->job_worker, + buf); + if (IS_ERR(crm_workq->job_worker_thread)) { kfree(crm_workq); return -ENOMEM; } + /* non-fatal error, ignore if occurs */ + error = sched_setscheduler(crm_workq->job_worker_thread, + SCHED_FIFO, + ¶m); + if (error){ + CAM_WARN(CAM_CRM, "Unable to set SCHED_FIFO, error %d", + error); + } + /* Workq attributes initialization */ - INIT_WORK(&crm_workq->work, cam_req_mgr_process_workq); + kthread_init_work(&crm_workq->work, cam_req_mgr_process_workq); spin_lock_init(&crm_workq->lock_bh); CAM_DBG(CAM_CRM, "LOCK_DBG workq %s lock %pK", name, &crm_workq->lock_bh); @@ -246,16 +250,16 @@ EXPORT_SYMBOL_GPL(cam_req_mgr_workq_create); void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **crm_workq) { unsigned long flags = 0; - struct workqueue_struct *job; + struct task_struct *job; CAM_DBG(CAM_CRM, "destroy workque %pK", crm_workq); if (*crm_workq) { WORKQ_ACQUIRE_LOCK(*crm_workq, flags); - if ((*crm_workq)->job) { - job = (*crm_workq)->job; - (*crm_workq)->job = NULL; + if ((*crm_workq)->job_worker_thread) { + job = (*crm_workq)->job_worker_thread; + (*crm_workq)->job_worker_thread = NULL; WORKQ_RELEASE_LOCK(*crm_workq, flags); - destroy_workqueue(job); + kthread_stop(job); } else { WORKQ_RELEASE_LOCK(*crm_workq, flags); } diff --git a/drivers/cam_req_mgr/cam_req_mgr_workq.h b/drivers/cam_req_mgr/cam_req_mgr_workq.h index f938710..60254c2 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_workq.h +++ b/drivers/cam_req_mgr/cam_req_mgr_workq.h @@ -11,6 +11,8 @@ #include<linux/init.h> #include<linux/sched.h> #include <linux/workqueue.h> +#include <linux/kthread.h> +#include <uapi/linux/sched/types.h> #include <linux/slab.h> #include <linux/timer.h> @@ -65,8 +67,9 @@ struct crm_workq_task { }; /** struct cam_req_mgr_core_workq - * @work : work token used by workqueue - * @job : workqueue internal job struct + * @work : work token used by kthread + * @job_worker : kthread internal struct + * @job_worker_thread : kthread task_struct * task - * @lock_bh : lock for task structs * @in_irq : set true if workque can be used in irq context @@ -78,8 +81,9 @@ struct crm_workq_task { * - */ struct cam_req_mgr_core_workq { - struct work_struct work; - struct workqueue_struct *job; + struct kthread_work work; + struct kthread_worker job_worker; + struct task_struct *job_worker_thread; spinlock_t lock_bh; uint32_t in_irq; diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c index 2f2b8b4..d286ea9 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -477,7 +477,7 @@ static int cam_ois_shift_data_enqueue(struct cam_ois_shift *o_shift_data, * * Returns success or failure */ -static void cam_ois_read_work(struct work_struct *work) +static void cam_ois_read_work(struct kthread_work *work) { uint8_t buf[10] = { 0 }; int32_t rc = 0; @@ -570,7 +570,7 @@ static enum hrtimer_restart cam_ois_shift_timer(struct hrtimer *timer) return HRTIMER_NORESTART; } - queue_work(ois_timer_in->ois_wq, &ois_timer_in->g_work); + kthread_queue_work(&ois_timer_in->o_ctrl->worker, &ois_timer_in->g_work); currtime = ktime_get(); interval = ktime_set(0, READ_OUT_TIME); hrtimer_forward(timer, currtime, interval); @@ -593,7 +593,6 @@ static int cam_ois_stop_shift_reader(struct cam_ois_ctrl_t *o_ctrl) return -EFAULT; } hrtimer_cancel(&o_ctrl->timer.hr_timer); - destroy_workqueue(o_ctrl->timer.ois_wq); o_ctrl->timer.ois_timer_state = CAM_OIS_TIME_INACTIVE; CAM_INFO(CAM_OIS, "Successfully stopped OIS shift reader."); return 0; @@ -628,12 +627,7 @@ static int cam_ois_start_shift_reader(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->timer.o_ctrl = o_ctrl; // set worker function and work queue - INIT_WORK(&o_ctrl->timer.g_work, cam_ois_read_work); - o_ctrl->timer.ois_wq = alloc_workqueue("ois_wq", WQ_HIGHPRI, 1); - if (!o_ctrl->timer.ois_wq) { - CAM_ERR(CAM_OIS, "ois_wq create failed."); - return -EFAULT; - } + kthread_init_work(&o_ctrl->timer.g_work, cam_ois_read_work); // set timer ktime = ktime_set(0, READ_OUT_TIME); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 58cb877..37b12b4 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -9,6 +9,29 @@ #include "cam_ois_core.h" #include "cam_debug_util.h" +static long cam_ois_create_thread(struct cam_ois_ctrl_t *o_ctrl) +{ + struct sched_param param = { .sched_priority = 15 }; + kthread_init_worker(&o_ctrl->worker); + o_ctrl->worker_thread = kthread_run(kthread_worker_fn, &o_ctrl->worker, + "ois_worker"); + if (IS_ERR(o_ctrl->worker_thread)) { + return -EFAULT; + } + if (sched_setscheduler(o_ctrl->worker_thread, + SCHED_FIFO, ¶m) != 0) { + CAM_ERR(CAM_OIS, "sched_setscheduler failed on ois_worker"); + } + return 0; +} + +static long cam_ois_destroy_thread(struct cam_ois_ctrl_t *o_ctrl) +{ + kthread_stop(o_ctrl->worker_thread); + o_ctrl->worker_thread = NULL; + return 0; +} + static long cam_ois_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { @@ -197,6 +220,11 @@ static int cam_ois_i2c_driver_probe(struct i2c_client *client, if (rc) goto soc_free; + rc = cam_ois_create_thread(o_ctrl); + if (rc) { + CAM_ERR(CAM_OIS, "failed: couldn't create ois worker %d", rc); + goto soc_free; + } o_ctrl->cam_ois_state = CAM_OIS_INIT; return rc; @@ -233,6 +261,8 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client) mutex_unlock(&(o_ctrl->ois_mutex)); cam_unregister_subdev(&(o_ctrl->v4l2_dev_str)); + cam_ois_destroy_thread(o_ctrl); + soc_private = (struct cam_ois_soc_private *)soc_info->soc_private; power_info = &soc_private->power_info; @@ -299,6 +329,12 @@ static int32_t cam_ois_platform_driver_probe( } o_ctrl->bridge_intf.device_hdl = -1; + rc = cam_ois_create_thread(o_ctrl); + if (rc) { + CAM_ERR(CAM_OIS, "failed: couldn't create ois worker %d", rc); + goto unreg_subdev; + } + platform_set_drvdata(pdev, o_ctrl); o_ctrl->cam_ois_state = CAM_OIS_INIT; @@ -347,6 +383,8 @@ static int cam_ois_platform_driver_remove(struct platform_device *pdev) kfree(o_ctrl->io_master_info.cci_client); platform_set_drvdata(pdev, NULL); v4l2_set_subdevdata(&o_ctrl->v4l2_dev_str.sd, NULL); + cam_ois_destroy_thread(o_ctrl); + mutex_destroy(&o_ctrl->ois_shift_mutex); kfree(o_ctrl); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h index 10a07cd..e46ee03 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -7,6 +7,9 @@ #include <linux/i2c.h> #include <linux/gpio.h> +#include <uapi/linux/sched/types.h> +#include <linux/sched.h> +#include <linux/kthread.h> #include <media/v4l2-event.h> #include <media/v4l2-subdev.h> #include <media/v4l2-ioctl.h> @@ -117,8 +120,7 @@ struct cam_ois_shift_buffer { */ struct cam_ois_timer_t { struct hrtimer hr_timer; - struct workqueue_struct *ois_wq; - struct work_struct g_work; + struct kthread_work g_work; enum cam_ois_timer_state_t ois_timer_state; struct cam_ois_ctrl_t *o_ctrl; int i2c_fail_count; @@ -169,6 +171,8 @@ struct cam_ois_ctrl_t { struct cam_ois_shift_buffer buf; struct cam_ois_timer_t timer; struct mutex ois_shift_mutex; + struct kthread_worker worker; + struct task_struct *worker_thread; }; #endif /*_CAM_OIS_DEV_H_ */ diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 20db229..c0b7850 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -774,6 +774,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, void *arg) { int rc = 0, pkt_opcode = 0; + int8_t retries = 3; struct cam_control *cmd = (struct cam_control *)arg; struct cam_sensor_power_ctrl_t *power_info = &s_ctrl->sensordata->power_info; @@ -959,10 +960,26 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, goto release_mutex; } + s_ctrl->sensor_state = CAM_SENSOR_ACQUIRE; + s_ctrl->last_flush_req = 0; + CAM_INFO(CAM_SENSOR, + "CAM_ACQUIRE_DEV Success, sensor_id:0x%x,sensor_slave_addr:0x%x", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensordata->slave_info.sensor_slave_addr); + #if IS_ENABLED(CONFIG_CAMERA_GYRO) if (s_ctrl->sensordata->slave_info.sensor_id == 0x363 && s_ctrl->custom_gyro_support) { - rc = enable_cam_gyro(); + /* From vendor spec, we need to add at least 10 ms delay time + * to pacify the first writing of gyro settings after turning + * the camera power on. Use the retry mechanism to fulfill this purpose. + */ + while ((rc = enable_cam_gyro()) && (retries > 0)) { + CAM_ERR(CAM_SENSOR, "CAM_GYRO_ENABLE failure, wait and retry"); + retries--; + /* TBD: Delay 1 ms for each retry */ + usleep_range(1000, 3000); + } if (rc < 0) { CAM_ERR(CAM_SENSOR, "CAM_GYRO_ENABLE failure"); cam_sensor_power_down(s_ctrl); @@ -971,13 +988,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, CAM_INFO(CAM_SENSOR, "CAM_GYRO_ENABLE success"); } #endif - - s_ctrl->sensor_state = CAM_SENSOR_ACQUIRE; - s_ctrl->last_flush_req = 0; - CAM_INFO(CAM_SENSOR, - "CAM_ACQUIRE_DEV Success, sensor_id:0x%x,sensor_slave_addr:0x%x", - s_ctrl->sensordata->slave_info.sensor_id, - s_ctrl->sensordata->slave_info.sensor_slave_addr); } break; case CAM_RELEASE_DEV: { diff --git a/drivers/cam_sensor_module/cam_sensor_vsync/cam_sensor_vsync.h b/drivers/cam_sensor_module/cam_sensor_vsync/cam_sensor_vsync.h index c755a35..d6283a6 100644 --- a/drivers/cam_sensor_module/cam_sensor_vsync/cam_sensor_vsync.h +++ b/drivers/cam_sensor_module/cam_sensor_vsync/cam_sensor_vsync.h @@ -30,7 +30,9 @@ #define CAM_VSYNC_REQ_MSG_ID_V01 0x20 #define CAM_VSYNC_RESP_MSG_ID_V01 0x20 -#define CAM_VSYNC_REQ_MAX_MSG_LEN_V01 520 +/** The recv_buf_size should be at least the size of the largest qmi msg used by the + client/service, which in this case, it's sns_client_report_ind_msg_v01. */ +#define CAM_VSYNC_REQ_MAX_MSG_LEN_V01 sizeof(struct sns_client_report_ind_msg_v01) /** QMI Service ID for this Sensors Service */ #define SNS_CLIENT_SVC_ID_V01 400 |