Skip to content

Commit d330767

Browse files
authored
acquire & release sensor fixes (#49) (#55) (#5)
* 1).acq & rel sensor fix for HSD 15015753611 2).release_firmware fix for HSD 14022301639 3).vid/pid mismatch fix for HSD 15015491881 * Revert testapp to use external acq/rel. --------- Signed-off-by: Srinivas Alla <alla.srinivas@intel.com>
1 parent b1dbe7d commit d330767

File tree

3 files changed

+64
-53
lines changed

3 files changed

+64
-53
lines changed

drivers/misc/icvs/intel_cvs.c

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ static void cvs_wdt_reset_thread(struct work_struct *work)
7272

7373
if (icvs->rst_retry--) {
7474
icvs->owner = CVS_CAMERA_NONE;
75+
icvs->ref_count = 0;
76+
icvs->int_ref_count = 0;
77+
7578
msleep(RST_TIME);
7679
gpiod_set_value_cansleep(icvs->rst, 1);
7780
hrtimer_start(&icvs->wdt, ms_to_ktime(WDT_TIMEOUT),
@@ -267,7 +270,6 @@ static void cvs_i2c_remove(struct i2c_client *i2c)
267270
dev_info(&i2c->dev, "%s\n", __func__);
268271
icvs = i2c_get_clientdata(i2c);
269272
if (icvs) {
270-
release_firmware(cvs->file);
271273
cvs->close_fw_dl_task = true;
272274

273275
while (cvs->ref_count) {
@@ -328,7 +330,7 @@ int cvs_acquire_camera_sensor_internal(void)
328330
if (!cvs)
329331
return -EINVAL;
330332

331-
if (cvs->icvs_state == CV_FW_DOWNLOADING_STATE)
333+
if (cvs->icvs_state == CV_FW_DOWNLOADING_STATE || cvs->icvs_state == CV_FW_FLASHING_STATE)
332334
return -EBUSY;
333335

334336
if (cvs->owner != CVS_CAMERA_IPU) {
@@ -341,6 +343,8 @@ int cvs_acquire_camera_sensor_internal(void)
341343
if (val != 0)
342344
goto err_out;
343345
}
346+
347+
cvs->owner = CVS_CAMERA_IPU;
344348
cvs->int_ref_count++;
345349
return 0;
346350

@@ -359,7 +363,10 @@ int cvs_release_camera_sensor_internal(void)
359363
if (cvs->icvs_state == CV_FW_DOWNLOADING_STATE)
360364
return -EBUSY;
361365

362-
if (cvs->owner != CVS_CAMERA_CVS) {
366+
if (cvs->int_ref_count == 0)
367+
return 0;
368+
369+
if (cvs->owner != CVS_CAMERA_CVS && cvs->int_ref_count == 1) {
363370
do {
364371
gpiod_set_value_cansleep(cvs->req, 1);
365372
mdelay(GPIO_READ_DELAY_MS);
@@ -369,8 +376,12 @@ int cvs_release_camera_sensor_internal(void)
369376
if (val != 1)
370377
goto err_out;
371378
}
379+
372380
cvs->int_ref_count--;
381+
cvs->owner = (cvs->int_ref_count == 0) ? CVS_CAMERA_CVS :
382+
CVS_CAMERA_IPU;
373383
return 0;
384+
374385
err_out:
375386
dev_err(cvs->dev, "%s:error! val %d (!=1)\n", __func__, val);
376387
return -EIO;
@@ -388,10 +399,7 @@ int cvs_acquire_camera_sensor(struct cvs_mipi_config *config,
388399
ret = cvs_acquire_camera_sensor_internal();
389400
if (!ret) {
390401
spin_lock(&cvs->lock);
391-
cvs->owner = (cvs->ref_count <= 0) ? CVS_CAMERA_IPU :
392-
cvs->owner;
393-
cvs->ref_count = (cvs->ref_count <= 0) ? 1 :
394-
(cvs->ref_count + 1);
402+
cvs->ref_count++;
395403
spin_unlock(&cvs->lock);
396404
}
397405
return (ret) ? ret : 0;
@@ -408,33 +416,16 @@ int cvs_release_camera_sensor(struct cvs_camera_status *status)
408416
ret = cvs_release_camera_sensor_internal();
409417
if (!ret) {
410418
spin_lock(&cvs->lock);
411-
cvs->ref_count = (cvs->ref_count > 0) ? (cvs->ref_count - 1) :
412-
0;
419+
cvs->ref_count = (cvs->ref_count > 0) ? (cvs->ref_count - 1) : 0;
413420
cvs->owner = (cvs->ref_count == 0) ? CVS_CAMERA_CVS :
414-
cvs->owner;
421+
CVS_CAMERA_IPU;
415422
spin_unlock(&cvs->lock);
416423
}
417424
return (ret) ? ret : 0;
418425
}
419426
EXPORT_SYMBOL_GPL(cvs_release_camera_sensor);
420427

421428
#ifdef DEBUG_CVS
422-
int cvs_get_state()
423-
{
424-
if (!cvs)
425-
return -EINVAL;
426-
427-
if (cvs_acquire_camera_sensor_internal())
428-
return -EINVAL;
429-
430-
if (cvs_read_i2c(GET_DEVICE_STATE, (char *)&cvs->cvs_state,
431-
sizeof(char)) <= 0)
432-
return -EIO;
433-
434-
cvs_release_camera_sensor_internal();
435-
return 0;
436-
}
437-
438429
int cvs_exec_cmd(enum cvs_command command)
439430
{
440431
int rc;
@@ -448,20 +439,34 @@ int cvs_exec_cmd(enum cvs_command command)
448439

449440
switch (command) {
450441
case GET_DEVICE_STATE:
442+
if(cvs->icvs_state == CV_FW_FLASHING_STATE) {
443+
dev_dbg(cvs->dev, "%s: Device Busy. State can't be queried now", __func__);
444+
return -EBUSY;
445+
}
451446
rc = cvs_read_i2c(GET_DEVICE_STATE, (char *)&cvs->cvs_state,
452447
sizeof(char));
453448
if (rc <= 0)
454449
goto err_out;
455450
break;
456451

457452
case GET_FW_VERSION:
453+
if(cvs->icvs_state == CV_FW_DOWNLOADING_STATE || cvs->icvs_state == CV_FW_FLASHING_STATE) {
454+
dev_dbg(cvs->dev, "%s: Device Busy. Version can't be queried now", __func__);
455+
return -EBUSY;
456+
}
457+
458458
rc = cvs_read_i2c(GET_FW_VERSION, (char *)&cvs->ver,
459459
sizeof(struct cvs_fw));
460460
if (rc <= 0)
461461
goto err_out;
462462
break;
463463

464464
case GET_VID_PID:
465+
if(cvs->icvs_state == CV_FW_DOWNLOADING_STATE || cvs->icvs_state == CV_FW_FLASHING_STATE) {
466+
dev_dbg(cvs->dev, "%s: Device Busy. ID can't be queried now", __func__);
467+
return -EBUSY;
468+
}
469+
465470
rc = cvs_read_i2c(GET_VID_PID, (char *)&cvs->id,
466471
sizeof(struct cvs_id));
467472
if (rc <= 0)
@@ -482,7 +487,6 @@ int cvs_exec_cmd(enum cvs_command command)
482487
if (cvs->i2c_shared && cvs->icvs_state != CV_FW_DOWNLOADING_STATE)
483488
cvs_release_camera_sensor_internal();
484489

485-
486490
pr_err("%s:CVs command 0x%x failed, cvs_read_i2c: %d\n", __func__,
487491
command, rc);
488492
return -EIO;
@@ -532,30 +536,27 @@ static ssize_t coredump_show(struct device *dev, struct device_attribute *attr,
532536
cvs->ver.hotfix, cvs->ver.build, cvs->ver.major, cvs->ver.minor,
533537
cvs->ver.hotfix, cvs->ver.build, cvs->cvs_state, stat_name,
534538
cvs->ref_count, cvs->int_ref_count,
535-
(cvs->owner == CVS_CAMERA_CVS) ?
536-
"CVS" :
537-
((cvs->owner == CVS_CAMERA_IPU) ? "IPU" : "none"),
539+
((cvs->owner == CVS_CAMERA_NONE) ? "NONE" :
540+
(cvs->owner == CVS_CAMERA_CVS) ? "CVS" :
541+
(cvs->owner == CVS_CAMERA_IPU && cvs->ref_count) ? "IPU" :
542+
(cvs->owner == CVS_CAMERA_IPU && cvs->int_ref_count) ? "VDRV" : "UNKNOWN"),
538543
cvs->i2c_shared);
539544
}
540545
static DEVICE_ATTR_RO(coredump);
541546

542547
static ssize_t cmd_store(struct device *dev, struct device_attribute *attr,
543548
const char *buf, size_t count)
544549
{
545-
if (sysfs_streq(buf, "reset"))
546-
schedule_work(&cvs->rst_task);
547-
else if (sysfs_streq(buf, "acquire"))
550+
if (sysfs_streq(buf, "acquire"))
548551
cvs_acquire_camera_sensor(NULL, NULL, NULL, NULL);
549552
else if (sysfs_streq(buf, "release"))
550553
cvs_release_camera_sensor(NULL);
551554
else if (sysfs_streq(buf, "state"))
552-
cvs_get_state();
555+
cvs_exec_cmd(GET_DEVICE_STATE);
553556
else if (sysfs_streq(buf, "version"))
554557
cvs_exec_cmd(GET_FW_VERSION);
555558
else if (sysfs_streq(buf, "id"))
556559
cvs_exec_cmd(GET_VID_PID);
557-
else if (sysfs_streq(buf, "update"))
558-
pr_err("%s:update not implemented\n", __func__);
559560
else
560561
pr_err("%s:invalid %s command\n", __func__, buf);
561562

@@ -567,7 +568,7 @@ static ssize_t cmd_show(struct device *dev, struct device_attribute *attr,
567568
{
568569
return sysfs_emit(
569570
buf, "command: %s\n",
570-
"[coredump, reset, acquire, release, state, version, id, update]");
571+
"[coredump, acquire, release, state, version, id]");
571572
}
572573
static DEVICE_ATTR_RW(cmd);
573574

@@ -587,6 +588,7 @@ static int cvs_suspend(struct device *dev)
587588
int ret = 0;
588589
u64 timeout;
589590

591+
dev_info(icvs->dev, "%s entered\n", __func__);
590592
/* Wait for FW update complete */
591593
if (icvs->cap == ICVS_FULLCAP && cvs->fw_dl_task_finished != true) {
592594
cvs->close_fw_dl_task = true;
@@ -601,6 +603,7 @@ static int cvs_suspend(struct device *dev)
601603
ret = -EAGAIN;
602604
}
603605
}
606+
604607
if (icvs->cap == ICVS_FULLCAP) {
605608
/* Disable wdt & IRQ */
606609
hrtimer_cancel(&icvs->wdt);
@@ -617,6 +620,7 @@ static int cvs_resume(struct device *dev)
617620
struct intel_cvs *icvs = i2c_get_clientdata(i2c);
618621
int val = -1, retry = FW_MAX_RETRY;
619622

623+
dev_info(icvs->dev, "%s entered\n", __func__);
620624
/* Wait for bridge ready */
621625
while (val < 0 && retry--) {
622626
val = gpiod_get_value_cansleep(cvs->resp);

drivers/misc/icvs/intel_cvs_update.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ int cvs_get_dev_state(void)
106106
}
107107

108108
if (ctx->i2c_shared) {
109-
if (ctx->icvs_sensor_state != CV_SENSOR_IPU_ACQUIRED_STATE) {
109+
if (ctx->icvs_sensor_state == CV_SENSOR_RELEASED_STATE) {
110110
if (cvs_acquire_camera_sensor_internal()) {
111111
dev_err(cvs->dev, "%s:Acquire sensor fail",__func__);
112112
return -EIO;
@@ -293,6 +293,7 @@ int cvs_dev_fw_dl_end(void)
293293

294294
ctx->icvs_state = CV_FW_FLASHING_STATE;
295295
status = cvs_get_device_state(&fw_state);
296+
ctx->cv_fw_state = fw_state;
296297
return status;
297298
}
298299

@@ -351,6 +352,12 @@ int cvs_dev_fw_dl(void)
351352

352353
do {
353354
status = cvs_wait_for_host_wake(ctx->max_flashtime_ms);
355+
if (status) {
356+
dev_err(cvs->dev, "%s: FW flash hostwake error",
357+
__func__);
358+
return -ETIMEDOUT;
359+
}
360+
ctx->icvs_state = CV_INIT_STATE;
354361
status = cvs_get_dev_state();
355362
} while ((!ctx->cv_fw_state) ||
356363
(ctx->cv_fw_state & DEVICE_DWNLD_BUSY_MASK));
@@ -434,6 +441,13 @@ static int cvs_fw_parse(void)
434441
return -EINVAL;
435442
}
436443

444+
if ((ptr_fw_header->vid_pid.vid != cvs->id.vid) ||
445+
(ptr_fw_header->vid_pid.pid != cvs->id.pid)) {
446+
dev_err(cvs->dev, "%s:dev & lib vid, pid mismatch",
447+
__func__);
448+
return -EINVAL;
449+
}
450+
437451
dev_info(cvs->dev, "%s:Lib FW version is %d.%d.%d.%d",
438452
__func__, ptr_fw_header->fw_ver.major,
439453
ptr_fw_header->fw_ver.minor,
@@ -501,8 +515,8 @@ static bool evaluate_fw(void)
501515
devm_kzalloc(cvs->dev, cvs->fw_buffer_size, GFP_KERNEL);
502516
if (IS_ERR_OR_NULL(cvs->fw_buffer)) {
503517
dev_err(cvs->dev, "%s:No memory for fw_buffer", __func__);
504-
status = -ENOMEM;
505-
goto err_fw_release;
518+
release_firmware(cvs->file);
519+
return -ENOMEM;
506520
}
507521

508522
dev_dbg(cvs->dev, "%s:fw_buff:%p size:0x%x, out_buf:%p",
@@ -513,15 +527,9 @@ static bool evaluate_fw(void)
513527
wmb(); /* Flush WC buffers after writing fw_buffer */
514528

515529
status = cvs_fw_parse();
516-
if (status) {
530+
if (status)
517531
dev_err(cvs->dev, "%s: FW bin file is invalid", __func__);
518-
goto err_fw_release;
519-
}
520532

521-
return 0;
522-
523-
err_fw_release:
524-
dev_err(cvs->dev, "%s:Calling release_firmware()\n", __func__);
525533
release_firmware(cvs->file);
526534
return status;
527535
}
@@ -555,7 +563,7 @@ void cvs_fw_dl_thread(struct work_struct *arg)
555563
ctx->fw_update_retries = CV_FW_DL_MAX_TRY_DEFAULT;
556564

557565
if (cvs->i2c_shared &&
558-
ctx->icvs_sensor_state != CV_SENSOR_IPU_ACQUIRED_STATE) {
566+
ctx->icvs_sensor_state == CV_SENSOR_RELEASED_STATE) {
559567
if (cvs_acquire_camera_sensor_internal())
560568
goto err_exit;
561569
}
@@ -565,14 +573,15 @@ void cvs_fw_dl_thread(struct work_struct *arg)
565573
dev_info(cvs->dev, "%s:Device FW version is %d.%d.%d.%d",
566574
__func__, cvs->ver.major, cvs->ver.minor,
567575
cvs->ver.hotfix, cvs->ver.build);
576+
568577
if (evaluate_fw()) {
569578
dev_err(cvs->dev, "%s:FW file not found",
570579
__func__);
571580
goto err_exit;
572581
}
573582
}
574583
else {
575-
dev_info(cvs->dev, "%s:I2C error. Not able to read vid/pid",
584+
dev_err(cvs->dev, "%s:I2C error. Not able to read vid/pid",
576585
__func__);
577586
goto err_exit;
578587
}
@@ -597,9 +606,8 @@ void cvs_fw_dl_thread(struct work_struct *arg)
597606
goto err_exit;
598607
}
599608

600-
if (ctx->icvs_sensor_state !=
601-
CV_SENSOR_IPU_ACQUIRED_STATE &&
602-
ctx->i2c_shared) {
609+
if (ctx->icvs_sensor_state == CV_SENSOR_RELEASED_STATE &&
610+
ctx->i2c_shared) {
603611
status = cvs_acquire_camera_sensor_internal();
604612
if (status) {
605613
dev_err(cvs->dev,

include/linux/intel_cvs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ int cvs_release_camera_sensor(struct cvs_camera_status *status);
201201
#ifdef DEBUG_CVS
202202
int cvs_sysfs_dump(char *buf);
203203
int cvs_exec_cmd(enum cvs_command command);
204-
int cvs_get_state(void);
205204
#endif
206205

207206
#endif // __INTEL_CVS_H__

0 commit comments

Comments
 (0)