mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
media: rockchip: isp: fix resource release if user crashes
Change-Id: I3587300198b4896f28278812651b38d08fdce2bf Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -304,7 +304,6 @@ static void rkisp_params_vb2_stop_streaming(struct vb2_queue *vq)
|
||||
params_vdev->first_cfg_params = true;
|
||||
return;
|
||||
}
|
||||
rkisp_params_disable_isp(params_vdev);
|
||||
/* clean module params */
|
||||
params_vdev->ops->clear_first_param(params_vdev);
|
||||
params_vdev->rdbk_times = 0;
|
||||
@@ -566,9 +565,12 @@ void rkisp_params_meshbuf_free(struct rkisp_isp_params_vdev *params_vdev, u64 id
|
||||
|
||||
void rkisp_params_stream_stop(struct rkisp_isp_params_vdev *params_vdev)
|
||||
{
|
||||
rkisp_params_disable_isp(params_vdev);
|
||||
/* isp stop to free buf */
|
||||
if (params_vdev->ops->stream_stop)
|
||||
params_vdev->ops->stream_stop(params_vdev);
|
||||
if (!atomic_read(¶ms_vdev->open_cnt) && params_vdev->ops->fop_release)
|
||||
params_vdev->ops->fop_release(params_vdev);
|
||||
}
|
||||
|
||||
bool rkisp_params_check_bigmode(struct rkisp_isp_params_vdev *params_vdev)
|
||||
|
||||
@@ -5066,9 +5066,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
rkisp_free_buffer(params_vdev->dev, buf);
|
||||
} else {
|
||||
is_alloc = false;
|
||||
buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
|
||||
if (buf->dma_fd < 0)
|
||||
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
|
||||
goto err;
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
}
|
||||
}
|
||||
if (is_alloc) {
|
||||
@@ -5079,9 +5079,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
goto err;
|
||||
}
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
mesh_head->stat = MESH_BUF_INIT;
|
||||
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
|
||||
}
|
||||
mesh_head->stat = MESH_BUF_INIT;
|
||||
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
|
||||
buf++;
|
||||
}
|
||||
|
||||
|
||||
@@ -4055,9 +4055,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
rkisp_free_buffer(params_vdev->dev, buf);
|
||||
} else {
|
||||
is_alloc = false;
|
||||
buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
|
||||
if (buf->dma_fd < 0)
|
||||
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
|
||||
goto err;
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
}
|
||||
}
|
||||
if (is_alloc) {
|
||||
@@ -4068,9 +4068,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
goto err;
|
||||
}
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
mesh_head->stat = MESH_BUF_INIT;
|
||||
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
|
||||
}
|
||||
mesh_head->stat = MESH_BUF_INIT;
|
||||
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
|
||||
buf++;
|
||||
}
|
||||
|
||||
|
||||
@@ -4988,9 +4988,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
rkisp_free_buffer(params_vdev->dev, buf);
|
||||
} else {
|
||||
is_alloc = false;
|
||||
buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
|
||||
if (buf->dma_fd < 0)
|
||||
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
|
||||
goto err;
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
}
|
||||
}
|
||||
if (is_alloc) {
|
||||
@@ -5001,11 +5001,12 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
goto err;
|
||||
}
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
mesh_head->stat = MESH_BUF_INIT;
|
||||
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
|
||||
}
|
||||
mesh_head->stat = MESH_BUF_INIT;
|
||||
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
|
||||
if (meshsize->module_id == ISP35_MODULE_BAY3D)
|
||||
mesh_head->data1_oft = mesh_head->data_oft +
|
||||
ALIGN(priv->b3dldc_hsize * 4 * priv->b3dldch_vsize, 16);
|
||||
}
|
||||
buf++;
|
||||
}
|
||||
|
||||
|
||||
@@ -4430,9 +4430,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
rkisp_free_buffer(params_vdev->dev, buf);
|
||||
} else {
|
||||
is_alloc = false;
|
||||
buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC);
|
||||
if (buf->dma_fd < 0)
|
||||
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
|
||||
goto err;
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
}
|
||||
}
|
||||
if (is_alloc) {
|
||||
@@ -4443,9 +4443,9 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
goto err;
|
||||
}
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
mesh_head->stat = MESH_BUF_INIT;
|
||||
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
|
||||
}
|
||||
mesh_head->stat = MESH_BUF_INIT;
|
||||
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
|
||||
buf++;
|
||||
}
|
||||
|
||||
|
||||
@@ -4497,6 +4497,7 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
u32 mesh_size, buf_size;
|
||||
int i, ret, id = meshsize->unite_isp_id;
|
||||
int buf_cnt = meshsize->buf_cnt;
|
||||
bool is_alloc;
|
||||
|
||||
priv_val = params_vdev->priv_val;
|
||||
if (!priv_val) {
|
||||
@@ -4529,14 +4530,26 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
buf->is_need_vaddr = true;
|
||||
buf->is_need_dbuf = true;
|
||||
buf->is_need_dmafd = true;
|
||||
buf->size = buf_size;
|
||||
ret = rkisp_alloc_buffer(params_vdev->dev, buf);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s failed\n", __func__);
|
||||
goto err;
|
||||
is_alloc = true;
|
||||
if (buf->mem_priv) {
|
||||
if (buf_size > buf->size) {
|
||||
rkisp_free_buffer(params_vdev->dev, buf);
|
||||
} else {
|
||||
is_alloc = false;
|
||||
if (rkisp_buf_get_fd(ispdev, buf, false) < 0)
|
||||
goto err;
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
}
|
||||
}
|
||||
if (is_alloc) {
|
||||
buf->size = buf_size;
|
||||
ret = rkisp_alloc_buffer(params_vdev->dev, buf);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s failed\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
}
|
||||
|
||||
mesh_head = (struct isp2x_mesh_head *)buf->vaddr;
|
||||
mesh_head->stat = MESH_BUF_INIT;
|
||||
mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16);
|
||||
buf++;
|
||||
|
||||
@@ -219,6 +219,8 @@ static void rkisp_stats_vb2_stop_streaming(struct vb2_queue *vq)
|
||||
|
||||
stats_vdev->ae_meas_done_next = false;
|
||||
stats_vdev->af_meas_done_next = false;
|
||||
if (stats_vdev->ops->stats_stop)
|
||||
stats_vdev->ops->stats_stop(stats_vdev);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -38,6 +38,7 @@ struct rkisp_isp_stats_ops {
|
||||
void (*first_ddr_cfg)(struct rkisp_isp_stats_vdev *stats_vdev);
|
||||
void (*next_ddr_cfg)(struct rkisp_isp_stats_vdev *stats_vdev);
|
||||
int (*stats_tb)(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp_buffer *stats_buf);
|
||||
void (*stats_stop)(struct rkisp_isp_stats_vdev *stats_vdev);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -1146,6 +1146,21 @@ rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
rkisp_stats_update_buf(stats_vdev);
|
||||
}
|
||||
|
||||
static void rkisp_stats_stop_v32(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
{
|
||||
struct rkisp_device *dev = stats_vdev->dev;
|
||||
u32 val, addr;
|
||||
|
||||
/* aiq crash or exit first */
|
||||
if (dev->isp_state & ISP_START &&
|
||||
stats_vdev->stats_buf[0].mem_priv) {
|
||||
rkisp_stats_update_buf(stats_vdev);
|
||||
addr = stats_vdev->stats_buf[0].dma_addr;
|
||||
readl_poll_timeout(dev->hw_dev->base_addr + ISP3X_MI_3A_WR_BASE,
|
||||
val, val == addr, 5000, 50000);
|
||||
}
|
||||
}
|
||||
|
||||
static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
|
||||
.isr_hdl = rkisp_stats_isr_v32,
|
||||
.send_meas = rkisp_stats_send_meas_v32,
|
||||
@@ -1154,6 +1169,7 @@ static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
|
||||
.stats_tb = rkisp_stats_tb_v32,
|
||||
.first_ddr_cfg = rkisp_stats_first_ddr_config_v32,
|
||||
.next_ddr_cfg = rkisp_stats_next_ddr_config_v32,
|
||||
.stats_stop = rkisp_stats_stop_v32,
|
||||
};
|
||||
|
||||
void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
@@ -1167,6 +1183,7 @@ void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
rkisp_isp_stats_ops_tbl.stats_tb = NULL;
|
||||
rkisp_isp_stats_ops_tbl.first_ddr_cfg = NULL;
|
||||
rkisp_isp_stats_ops_tbl.next_ddr_cfg = NULL;
|
||||
rkisp_isp_stats_ops_tbl.stats_stop = NULL;
|
||||
}
|
||||
stats_vdev->ops = &rkisp_isp_stats_ops_tbl;
|
||||
}
|
||||
|
||||
@@ -568,6 +568,21 @@ rkisp_stats_next_ddr_config_v33(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
rkisp_stats_update_buf(stats_vdev);
|
||||
}
|
||||
|
||||
static void rkisp_stats_stop_v33(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
{
|
||||
struct rkisp_device *dev = stats_vdev->dev;
|
||||
u32 val, addr;
|
||||
|
||||
/* aiq crash or exit first */
|
||||
if (dev->isp_state & ISP_START &&
|
||||
stats_vdev->stats_buf[0].mem_priv) {
|
||||
rkisp_stats_update_buf(stats_vdev);
|
||||
addr = stats_vdev->stats_buf[0].dma_addr;
|
||||
readl_poll_timeout(dev->hw_dev->base_addr + ISP39_W3A_AEBIG_ADDR_SHD,
|
||||
val, val == addr, 5000, 50000);
|
||||
}
|
||||
}
|
||||
|
||||
static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
|
||||
.isr_hdl = rkisp_stats_isr_v33,
|
||||
.send_meas = rkisp_stats_send_meas_v33,
|
||||
@@ -575,6 +590,7 @@ static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
|
||||
.stats_tb = rkisp_stats_tb_v33,
|
||||
.first_ddr_cfg = rkisp_stats_first_ddr_config_v33,
|
||||
.next_ddr_cfg = rkisp_stats_next_ddr_config_v33,
|
||||
.stats_stop = rkisp_stats_stop_v33,
|
||||
};
|
||||
|
||||
void rkisp_init_stats_vdev_v33(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
|
||||
@@ -862,12 +862,28 @@ rkisp_stats_next_ddr_config_v35(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
}
|
||||
}
|
||||
|
||||
static void rkisp_stats_stop_v35(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
{
|
||||
struct rkisp_device *dev = stats_vdev->dev;
|
||||
u32 val, addr;
|
||||
|
||||
/* aiq crash or exit first */
|
||||
if (dev->isp_state & ISP_START &&
|
||||
stats_vdev->stats_buf[0].mem_priv) {
|
||||
rkisp_stats_update_buf(stats_vdev);
|
||||
addr = stats_vdev->stats_buf[0].dma_addr;
|
||||
readl_poll_timeout(dev->hw_dev->base_addr + ISP39_W3A_AEBIG_ADDR_SHD,
|
||||
val, val == addr, 5000, 50000);
|
||||
}
|
||||
}
|
||||
|
||||
static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
|
||||
.isr_hdl = rkisp_stats_isr_v35,
|
||||
.get_stat_size = rkisp_get_stat_size_v35,
|
||||
.stats_tb = rkisp_stats_tb_v35,
|
||||
.first_ddr_cfg = rkisp_stats_first_ddr_config_v35,
|
||||
.next_ddr_cfg = rkisp_stats_next_ddr_config_v35,
|
||||
.stats_stop = rkisp_stats_stop_v35,
|
||||
};
|
||||
|
||||
void rkisp_init_stats_vdev_v35(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
|
||||
@@ -536,11 +536,27 @@ rkisp_stats_next_ddr_config_v39(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
}
|
||||
}
|
||||
|
||||
static void rkisp_stats_stop_v39(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
{
|
||||
struct rkisp_device *dev = stats_vdev->dev;
|
||||
u32 val, addr;
|
||||
|
||||
/* aiq crash or exit first */
|
||||
if (dev->isp_state & ISP_START &&
|
||||
stats_vdev->stats_buf[0].mem_priv) {
|
||||
rkisp_stats_update_buf(stats_vdev);
|
||||
addr = stats_vdev->stats_buf[0].dma_addr;
|
||||
readl_poll_timeout(dev->hw_dev->base_addr + ISP39_W3A_AEBIG_ADDR_SHD,
|
||||
val, val == addr, 5000, 50000);
|
||||
}
|
||||
}
|
||||
|
||||
static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = {
|
||||
.isr_hdl = rkisp_stats_isr_v39,
|
||||
.get_stat_size = rkisp_get_stat_size_v39,
|
||||
.first_ddr_cfg = rkisp_stats_first_ddr_config_v39,
|
||||
.next_ddr_cfg = rkisp_stats_next_ddr_config_v39,
|
||||
.stats_stop = rkisp_stats_stop_v39,
|
||||
};
|
||||
|
||||
void rkisp_init_stats_vdev_v39(struct rkisp_isp_stats_vdev *stats_vdev)
|
||||
|
||||
Reference in New Issue
Block a user