summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Liao <rogerliao@google.com>2020-10-20 17:04:23 +0800
committerRoger Liao <rogerliao@google.com>2020-10-21 00:23:06 +0800
commit4b50ea998f28018f9ca54a980085e0e2f4d49724 (patch)
treeaab73c21daab1c2d29f8f1f52638f34c3efc2b59
parentb122fe6046966c53653e37e38cb296dd661f9d81 (diff)
parent21437ea878416dad4e3364033a7886e899de5bf3 (diff)
downloadcamera-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.c46
-rw-r--r--drivers/cam_req_mgr/cam_req_mgr_workq.h12
-rw-r--r--drivers/cam_sensor_module/cam_ois/cam_ois_core.c12
-rw-r--r--drivers/cam_sensor_module/cam_ois/cam_ois_dev.c38
-rw-r--r--drivers/cam_sensor_module/cam_ois/cam_ois_dev.h8
-rw-r--r--drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c26
-rw-r--r--drivers/cam_sensor_module/cam_sensor_vsync/cam_sensor_vsync.h4
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,
+ &param);
+ 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, &param) != 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