Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f43f125b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: fd: Add CPP VBIF error handling"

parents 8a98936a e3cda116
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
GCC_VERSION      := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
ccflags-y += -Idrivers/media/video/msm
ccflags-y += -Idrivers/media/platform/msm/camera_v2/common
ccflags-y += -Idrivers/media/platform/msm/camera_v2
ccflags-y += -Idrivers/media/platform/msm/camera_v2/pproc/cpp

obj-$(CONFIG_MSM_FD) += msm_fd_dev.o msm_fd_hw.o
+80 −0
Original line number Diff line number Diff line
@@ -264,8 +264,10 @@ static void msm_fd_stop_streaming(struct vb2_queue *q)
{
	struct fd_ctx *ctx = vb2_get_drv_priv(q);

	mutex_lock(&ctx->fd_device->recovery_lock);
	msm_fd_hw_remove_buffers_from_queue(ctx->fd_device, q);
	msm_fd_hw_put(ctx->fd_device);
	mutex_unlock(&ctx->fd_device->recovery_lock);
}

/* Videobuf2 queue callbacks. */
@@ -325,6 +327,69 @@ static struct vb2_mem_ops msm_fd_vb2_mem_ops = {
	.put_userptr = msm_fd_put_userptr,
};

/*
 * msm_fd_vbif_error_handler - FD VBIF Error handler
 * @handle: FD Device handle
 * @error: CPP-VBIF Error code
 */
static int msm_fd_vbif_error_handler(void *handle, uint32_t error)
{
	struct fd_ctx *ctx;
	struct msm_fd_device *fd;
	struct msm_fd_buffer *active_buf;
	int ret;

	if (NULL == handle) {
		dev_err(fd->dev, "FD Ctx is null, Cannot recover\n");
		return 0;
	}
	ctx = (struct fd_ctx *)handle;
	fd = (struct msm_fd_device *)ctx->fd_device;

	if (error == CPP_VBIF_ERROR_HANG) {
		mutex_lock(&fd->recovery_lock);
		dev_err(fd->dev, "Handling FD VBIF Hang\n");
		if (fd->state != MSM_FD_DEVICE_RUNNING) {
			dev_err(fd->dev, "FD is not FD_DEVICE_RUNNING, %d\n",
				fd->state);
			mutex_unlock(&fd->recovery_lock);
			return 0;
		}
		fd->recovery_mode = 1;

		/* Halt and reset */
		msm_fd_hw_put(fd);
		msm_fd_hw_get(fd, ctx->settings.speed);

		/* Get active buffer */
		active_buf = msm_fd_hw_get_active_buffer(fd);

		if (active_buf == NULL) {
			dev_dbg(fd->dev, "no active buffer, return\n");
			fd->recovery_mode = 0;
			mutex_unlock(&fd->recovery_lock);
			return 0;
		}

		dev_dbg(fd->dev, "Active Buffer present.. Start re-schedule\n");

		/* Queue the buffer again */
		msm_fd_hw_add_buffer(fd, active_buf);

		/* Schedule and restart */
		ret = msm_fd_hw_schedule_next_buffer(fd);
		if (ret) {
			dev_err(fd->dev, "Cannot reschedule buffer, recovery failed\n");
			fd->recovery_mode = 0;
			mutex_unlock(&fd->recovery_lock);
			return ret;
		}
		dev_dbg(fd->dev, "Restarted FD after VBIF HAng\n");
		mutex_unlock(&fd->recovery_lock);
	}
	return 0;
}

/*
 * msm_fd_open - Fd device open method.
 * @file: Pointer to file struct.
@@ -388,6 +453,10 @@ static int msm_fd_open(struct file *file)
		goto error_ahb_config;
	}

	/* Register with CPP VBIF error handler */
	msm_cpp_vbif_register_error_handler((void *)ctx,
		VBIF_CLIENT_FD, msm_fd_vbif_error_handler);

	return 0;

error_ahb_config:
@@ -409,6 +478,10 @@ static int msm_fd_release(struct file *file)
{
	struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data);

	/* Un-register with CPP VBIF error handler */
	msm_cpp_vbif_register_error_handler((void *)ctx,
		VBIF_CLIENT_FD, NULL);

	vb2_queue_release(&ctx->vb2_q);

	vfree(ctx->stats);
@@ -1173,6 +1246,12 @@ static void msm_fd_wq_handler(struct work_struct *work)
	/* Stats are ready, set correct frame id */
	atomic_set(&stats->frame_id, ctx->sequence);

	/* If Recovery mode is on, we got IRQ after recovery, reset it */
	if (fd->recovery_mode) {
		fd->recovery_mode = 0;
		dev_dbg(fd->dev, "Got IRQ after Recovery\n");
	}

	/* We have the data from fd hw, we can start next processing */
	msm_fd_hw_schedule_next_buffer(fd);

@@ -1209,6 +1288,7 @@ static int fd_probe(struct platform_device *pdev)

	mutex_init(&fd->lock);
	spin_lock_init(&fd->slock);
	mutex_init(&fd->recovery_lock);
	init_completion(&fd->hw_halt_completion);
	INIT_LIST_HEAD(&fd->buf_queue);
	fd->pdev = pdev;
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include <linux/msm_ion.h>
#include "cam_soc_api.h"
#include "cam_hw_ops.h"
#include "msm_cpp.h"

/* Maximum number of result buffers */
#define MSM_FD_MAX_RESULT_BUFS 5
/* Max number of clocks defined in device tree */
@@ -213,12 +215,14 @@ enum msm_fd_mem_resources {
 * @work_queue: Pointer to FD device IRQ bottom half workqueue.
 * @work: IRQ bottom half work struct.
 * @hw_halt_completion: Completes when face detection hw halt completes.
 * @recovery_mode: Indicates if FD is in recovery mode
 */
struct msm_fd_device {
	u32 hw_revision;

	struct mutex lock;
	spinlock_t slock;
	struct mutex recovery_lock;
	int ref_count;

	int irq_num;
@@ -247,6 +251,7 @@ struct msm_fd_device {
	struct workqueue_struct *work_queue;
	struct work_struct work;
	struct completion hw_halt_completion;
	int recovery_mode;
};

#endif /* __MSM_FD_DEV_H__ */
+4 −0
Original line number Diff line number Diff line
@@ -1058,6 +1058,8 @@ static int msm_fd_hw_enable(struct msm_fd_device *fd,
	msm_fd_hw_set_direction_angle(fd, buffer->settings.direction_index,
		buffer->settings.angle_index);
	msm_fd_hw_run(fd);
	if (fd->recovery_mode)
		dev_err(fd->dev, "Scheduled buffer in recovery mode\n");
	return 1;
}

@@ -1259,6 +1261,8 @@ int msm_fd_hw_schedule_next_buffer(struct msm_fd_device *fd)
		}
	} else {
		fd->state = MSM_FD_DEVICE_IDLE;
		if (fd->recovery_mode)
			dev_err(fd->dev, "No Buffer in recovery mode.Device Idle\n");
	}
	spin_unlock(&fd->slock);