Commit 97a48d1a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull media fixes from Mauro Carvalho Chehab:

 - rkvdec: fix stack usage with clang and improve handling missing
   short/long term RPS

 - synopsys: fix a Kconfig issue and an out-of-bounds check

 - verisilicon: Fix kernel panic due to __initconst misuse

 - media core: serialize REINIT and REQBUFS with req_queue_mutex

* tag 'media/v7.0-5' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  media: verisilicon: Fix kernel panic due to __initconst misuse
  media: rkvdec: reduce stack usage in rkvdec_init_v4l2_vp9_count_tbl()
  media: rkvdec: reduce excessive stack usage in assemble_hw_pps()
  media: rkvdec: Improve handling missing short/long term RPS
  media: mc, v4l2: serialize REINIT and REQBUFS with req_queue_mutex
  media: synopsys: csi2rx: add missing kconfig dependency
  media: synopsys: csi2rx: fix out-of-bounds check for formats array
parents a0124352 e8d97c27
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -192,6 +192,8 @@ static long media_request_ioctl_reinit(struct media_request *req)
	struct media_device *mdev = req->mdev;
	unsigned long flags;

	mutex_lock(&mdev->req_queue_mutex);

	spin_lock_irqsave(&req->lock, flags);
	if (req->state != MEDIA_REQUEST_STATE_IDLE &&
	    req->state != MEDIA_REQUEST_STATE_COMPLETE) {
@@ -199,6 +201,7 @@ static long media_request_ioctl_reinit(struct media_request *req)
			"request: %s not in idle or complete state, cannot reinit\n",
			req->debug_str);
		spin_unlock_irqrestore(&req->lock, flags);
		mutex_unlock(&mdev->req_queue_mutex);
		return -EBUSY;
	}
	if (req->access_count) {
@@ -206,6 +209,7 @@ static long media_request_ioctl_reinit(struct media_request *req)
			"request: %s is being accessed, cannot reinit\n",
			req->debug_str);
		spin_unlock_irqrestore(&req->lock, flags);
		mutex_unlock(&mdev->req_queue_mutex);
		return -EBUSY;
	}
	req->state = MEDIA_REQUEST_STATE_CLEANING;
@@ -216,6 +220,7 @@ static long media_request_ioctl_reinit(struct media_request *req)
	spin_lock_irqsave(&req->lock, flags);
	req->state = MEDIA_REQUEST_STATE_IDLE;
	spin_unlock_irqrestore(&req->lock, flags);
	mutex_unlock(&mdev->req_queue_mutex);

	return 0;
}
+4 −0
Original line number Diff line number Diff line
@@ -500,11 +500,15 @@ void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx,
		ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
				      V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS);
		run->ext_sps_st_rps = ctrl ? ctrl->p_cur.p : NULL;
	} else {
		run->ext_sps_st_rps = NULL;
	}
	if (ctx->has_sps_lt_rps) {
		ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
				      V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS);
		run->ext_sps_lt_rps = ctrl ? ctrl->p_cur.p : NULL;
	} else {
		run->ext_sps_lt_rps = NULL;
	}

	rkvdec_run_preamble(ctx, &run->base);
+27 −23
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ struct rkvdec_h264_ctx {
	struct vdpu383_regs_h26x regs;
};

static void set_field_order_cnt(struct rkvdec_pps *pps, const struct v4l2_h264_dpb_entry *dpb)
static noinline_for_stack void set_field_order_cnt(struct rkvdec_pps *pps, const struct v4l2_h264_dpb_entry *dpb)
{
	pps->top_field_order_cnt0 = dpb[0].top_field_order_cnt;
	pps->bot_field_order_cnt0 = dpb[0].bottom_field_order_cnt;
@@ -166,6 +166,31 @@ static void set_field_order_cnt(struct rkvdec_pps *pps, const struct v4l2_h264_d
	pps->bot_field_order_cnt15 = dpb[15].bottom_field_order_cnt;
}

static noinline_for_stack void set_dec_params(struct rkvdec_pps *pps, const struct v4l2_ctrl_h264_decode_params *dec_params)
{
	const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;

	for (int i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
			pps->is_longterm |= (1 << i);
		pps->ref_field_flags |=
		 (!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) << i;
		pps->ref_colmv_use_flag |=
		 (!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) << i;
		pps->ref_topfield_used |=
		 (!!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF)) << i;
		pps->ref_botfield_used |=
			(!!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)) << i;
	}
	pps->pic_field_flag =
		!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC);
	pps->pic_associated_flag =
		!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD);

	pps->cur_top_field = dec_params->top_field_order_cnt;
	pps->cur_bot_field = dec_params->bottom_field_order_cnt;
}

static void assemble_hw_pps(struct rkvdec_ctx *ctx,
			    struct rkvdec_h264_run *run)
{
@@ -177,7 +202,6 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
	struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
	struct rkvdec_sps_pps *hw_ps;
	u32 pic_width, pic_height;
	u32 i;

	/*
	 * HW read the SPS/PPS information from PPS packet index by PPS id.
@@ -261,28 +285,8 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
		!!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);

	set_field_order_cnt(&hw_ps->pps, dpb);
	set_dec_params(&hw_ps->pps, dec_params);

	for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
			hw_ps->pps.is_longterm |= (1 << i);

		hw_ps->pps.ref_field_flags |=
			(!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) << i;
		hw_ps->pps.ref_colmv_use_flag |=
			(!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) << i;
		hw_ps->pps.ref_topfield_used |=
			(!!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF)) << i;
		hw_ps->pps.ref_botfield_used |=
			(!!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)) << i;
	}

	hw_ps->pps.pic_field_flag =
		!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC);
	hw_ps->pps.pic_associated_flag =
		!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD);

	hw_ps->pps.cur_top_field = dec_params->top_field_order_cnt;
	hw_ps->pps.cur_bot_field = dec_params->bottom_field_order_cnt;
}

static void rkvdec_write_regs(struct rkvdec_ctx *ctx)
+2 −1
Original line number Diff line number Diff line
@@ -893,7 +893,8 @@ static void rkvdec_vp9_done(struct rkvdec_ctx *ctx,
	update_ctx_last_info(vp9_ctx);
}

static void rkvdec_init_v4l2_vp9_count_tbl(struct rkvdec_ctx *ctx)
static noinline_for_stack void
rkvdec_init_v4l2_vp9_count_tbl(struct rkvdec_ctx *ctx)
{
	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
	struct rkvdec_vp9_intra_frame_symbol_counts *intra_cnts = vp9_ctx->count_tbl.cpu;
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ config VIDEO_DW_MIPI_CSI2RX
	depends on VIDEO_DEV
	depends on V4L_PLATFORM_DRIVERS
	depends on PM && COMMON_CLK
	select GENERIC_PHY_MIPI_DPHY
	select MEDIA_CONTROLLER
	select V4L2_FWNODE
	select VIDEO_V4L2_SUBDEV_API
Loading