All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans Verkuil <hverkuil@xs4all.nl>
To: Neil Armstrong <narmstrong@baylibre.com>
Cc: linux-media@vger.kernel.org, linux-amlogic@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 2/4] media: meson: Add M2M driver for the Amlogic GE2D Accelerator Unit
Date: Wed, 2 Dec 2020 16:14:31 +0100	[thread overview]
Message-ID: <540b95ef-5815-d400-9214-87667c3b3777@xs4all.nl> (raw)
In-Reply-To: <81cd2c1b-cfc9-0167-0e72-9f47b0887369@baylibre.com>

On 02/12/2020 15:56, Neil Armstrong wrote:
> Hi Hans,
> 
> On 02/12/2020 13:40, Hans Verkuil wrote:
>> On 17/11/2020 09:44, Neil Armstrong wrote:
>>> The GE2D is a 2D accelerator with various features like configurable blitter
>>> with alpha blending, frame rotation, scaling, format conversion and colorspace
>>> conversion.
>>>
>>> The driver implements a Memory2Memory VB2 V4L2 streaming device permitting:
>>> - 0, 90, 180, 270deg rotation
>>> - horizontal/vertical flipping
>>> - source cropping
>>> - destination compositing
>>> - 32bit/24bit/16bit format conversion
>>>
>>> This adds the support for the GE2D version found in the AXG SoCs Family.
>>>
>>> The missing features are:
>>> - Source scaling
>>> - Colorspace conversion
>>> - Advanced alpha blending & blitting options
>>>
>>> Is passes v4l2-compliance SHA: ea16a7ef13a902793a5c2626b0cefc4d956147f3, 64 bits, 64-bit time_t
>>>
>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>> ---
>>>  drivers/media/platform/Kconfig                |   13 +
>>>  drivers/media/platform/Makefile               |    2 +
>>>  drivers/media/platform/meson/ge2d/Makefile    |    3 +
>>>  drivers/media/platform/meson/ge2d/ge2d-regs.h |  360 ++++++
>>>  drivers/media/platform/meson/ge2d/ge2d.c      | 1091 +++++++++++++++++
>>>  5 files changed, 1469 insertions(+)
>>>  create mode 100644 drivers/media/platform/meson/ge2d/Makefile
>>>  create mode 100644 drivers/media/platform/meson/ge2d/ge2d-regs.h
>>>  create mode 100644 drivers/media/platform/meson/ge2d/ge2d.c
>>>
> 
> [...]
> 
>>> +
>>> +#define DEFAULT_WIDTH	100
>>> +#define DEFAULT_HEIGHT	100
>>
>> That's a weird default value. I would expect to see some multiple of 8 here.
> 
> Sure, whatever the HW is quite flexible, I took 100x100 from the other 2D accelerator drivers actually.
> 
> [...]
> 
>>> +
>>> +static void ge2d_stop_streaming(struct vb2_queue *vq)
>>> +{
>>> +	struct ge2d_ctx *ctx = vb2_get_drv_priv(vq);
>>> +	struct vb2_v4l2_buffer *vbuf;
>>> +
>>> +	if (V4L2_TYPE_IS_OUTPUT(vq->type))
>>> +		ctx->streamon_out = false;
>>> +	else
>>> +		ctx->streamon_cap = false;
>>
>> Do you need streamon_out/cap? Can't you use vb2_start_streaming_called() instead?
> 
> Indeed, I'll switch to vb2_start_streaming_called & co.
> 
> [...]
> 
>>> +
>>> +static int vidioc_try_fmt_out(struct file *file, void *priv, struct v4l2_format *f)
>>> +{
>>> +	const struct ge2d_fmt *fmt = find_fmt(f);
>>> +
>>> +	f->fmt.pix.field = V4L2_FIELD_NONE;
>>> +	f->fmt.pix.pixelformat = fmt->fourcc;
>>> +
>>> +	if (f->fmt.pix.width > MAX_WIDTH)
>>> +		f->fmt.pix.width = MAX_WIDTH;
>>> +	if (f->fmt.pix.height > MAX_HEIGHT)
>>> +		f->fmt.pix.height = MAX_HEIGHT;
>>> +
>>> +	if (f->fmt.pix.width < 0)
>>> +		f->fmt.pix.width = 0;
>>> +	if (f->fmt.pix.height < 0)
>>> +		f->fmt.pix.height = 0;
>>
>> width and height are unsigned, so this check is not needed.
> 
> Ok
> 
> [...]
> 
>>> +
>>> +static int ge2d_s_ctrl(struct v4l2_ctrl *ctrl)
>>> +{
>>> +	struct ge2d_ctx *ctx = container_of(ctrl->handler, struct ge2d_ctx,
>>> +					   ctrl_handler);
>>> +	struct v4l2_pix_format fmt;
>>> +	struct vb2_queue *vq;
>>> +	unsigned long flags;
>>> +
>>> +	spin_lock_irqsave(&ctx->ge2d->ctrl_lock, flags);
>>> +	switch (ctrl->id) {
>>> +	case V4L2_CID_HFLIP:
>>> +		ctx->hflip = ctrl->val;
>>> +		break;
>>> +	case V4L2_CID_VFLIP:
>>> +		ctx->vflip = ctrl->val;
>>> +		break;
>>> +	case V4L2_CID_ROTATE:
>>> +		vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
>>> +		if (vb2_is_busy(vq))
>>> +			return -EBUSY;
>>
>> This doesn't call spin_unlock_irqrestore()!
>>
>> Do you need the spinlock at all? This function is already called with a mutex
>> for ctrl->handler held. It's unusual to see a spinlock here.
> 
> Is device_run also called with ctrl->handler held ?
> 
> The spinlock is used to protect against concurrent re-config & run.

Ah, I see. I think it would help to add some more comments.

BTW, do you need to save the irq state? This function definitely can't
be called from interrupt context, and I suspect that's also true of the
other place where this spinlock is used.

> 
> [...]
> 
>>> +
>>> +	platform_set_drvdata(pdev, ge2d);
>>> +	ge2d->m2m_dev = v4l2_m2m_init(&ge2d_m2m_ops);
>>> +	if (IS_ERR(ge2d->m2m_dev)) {
>>> +		v4l2_err(&ge2d->v4l2_dev, "Failed to init mem2mem device\n");
>>> +		ret = PTR_ERR(ge2d->m2m_dev);
>>> +		goto unreg_video_dev;
>>
>> This should be goto rel_vdev.
>>
>>> +	}
>>> +
>>> +	ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
>>> +	if (ret) {
>>> +		v4l2_err(&ge2d->v4l2_dev, "Failed to register video device\n");
>>> +		goto rel_vdev;
>>> +	}
>>> +
>>> +	v4l2_info(&ge2d->v4l2_dev, "Registered %s as /dev/%s\n",
>>> +		  vfd->name, video_device_node_name(vfd));
>>> +
>>> +	return 0;
>>> +
>>> +rel_vdev:
>>> +	video_device_release(vfd);
>>> +unreg_video_dev:
>>> +	video_unregister_device(ge2d->vfd);
>>
>> This makes no sense. If video_register_device() fails, then you
>> call video_device_release(vfd), not video_unregister_device().
>>
>> Just drop these two lines.
> 
> ok
> 
>>
>>> +unreg_v4l2_dev:
>>> +	v4l2_device_unregister(&ge2d->v4l2_dev);
>>> +disable_clks:
>>> +	clk_disable_unprepare(ge2d->clk);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static int ge2d_remove(struct platform_device *pdev)
>>> +{
>>> +	struct meson_ge2d *ge2d = platform_get_drvdata(pdev);
>>> +
>>> +	v4l2_m2m_release(ge2d->m2m_dev);
>>> +	video_unregister_device(ge2d->vfd);
>>> +	v4l2_device_unregister(&ge2d->v4l2_dev);
>>> +
>>> +	clk_disable_unprepare(ge2d->clk);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static const struct of_device_id meson_ge2d_match[] = {
>>> +	{
>>> +		.compatible = "amlogic,axg-ge2d",
>>> +	},
>>> +	{},
>>> +};
>>> +
>>> +MODULE_DEVICE_TABLE(of, meson_ge2d_match);
>>> +
>>> +static struct platform_driver ge2d_drv = {
>>> +	.probe = ge2d_probe,
>>> +	.remove = ge2d_remove,
>>> +	.driver = {
>>> +		.name = "meson-ge2d",
>>> +		.of_match_table = meson_ge2d_match,
>>> +	},
>>> +};
>>> +
>>> +module_platform_driver(ge2d_drv);
>>> +
>>> +MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
>>> +MODULE_DESCRIPTION("Amlogic 2D Graphic Acceleration Unit");
>>> +MODULE_LICENSE("GPL");
>>>
>>
>> Regards,
>>
>> 	Hans
>>
> 
> Thanks,
> Neil
> 

Regards,

	Hans

WARNING: multiple messages have this Message-ID (diff)
From: Hans Verkuil <hverkuil@xs4all.nl>
To: Neil Armstrong <narmstrong@baylibre.com>
Cc: linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-media@vger.kernel.org
Subject: Re: [PATCH v3 2/4] media: meson: Add M2M driver for the Amlogic GE2D Accelerator Unit
Date: Wed, 2 Dec 2020 16:14:31 +0100	[thread overview]
Message-ID: <540b95ef-5815-d400-9214-87667c3b3777@xs4all.nl> (raw)
In-Reply-To: <81cd2c1b-cfc9-0167-0e72-9f47b0887369@baylibre.com>

On 02/12/2020 15:56, Neil Armstrong wrote:
> Hi Hans,
> 
> On 02/12/2020 13:40, Hans Verkuil wrote:
>> On 17/11/2020 09:44, Neil Armstrong wrote:
>>> The GE2D is a 2D accelerator with various features like configurable blitter
>>> with alpha blending, frame rotation, scaling, format conversion and colorspace
>>> conversion.
>>>
>>> The driver implements a Memory2Memory VB2 V4L2 streaming device permitting:
>>> - 0, 90, 180, 270deg rotation
>>> - horizontal/vertical flipping
>>> - source cropping
>>> - destination compositing
>>> - 32bit/24bit/16bit format conversion
>>>
>>> This adds the support for the GE2D version found in the AXG SoCs Family.
>>>
>>> The missing features are:
>>> - Source scaling
>>> - Colorspace conversion
>>> - Advanced alpha blending & blitting options
>>>
>>> Is passes v4l2-compliance SHA: ea16a7ef13a902793a5c2626b0cefc4d956147f3, 64 bits, 64-bit time_t
>>>
>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>> ---
>>>  drivers/media/platform/Kconfig                |   13 +
>>>  drivers/media/platform/Makefile               |    2 +
>>>  drivers/media/platform/meson/ge2d/Makefile    |    3 +
>>>  drivers/media/platform/meson/ge2d/ge2d-regs.h |  360 ++++++
>>>  drivers/media/platform/meson/ge2d/ge2d.c      | 1091 +++++++++++++++++
>>>  5 files changed, 1469 insertions(+)
>>>  create mode 100644 drivers/media/platform/meson/ge2d/Makefile
>>>  create mode 100644 drivers/media/platform/meson/ge2d/ge2d-regs.h
>>>  create mode 100644 drivers/media/platform/meson/ge2d/ge2d.c
>>>
> 
> [...]
> 
>>> +
>>> +#define DEFAULT_WIDTH	100
>>> +#define DEFAULT_HEIGHT	100
>>
>> That's a weird default value. I would expect to see some multiple of 8 here.
> 
> Sure, whatever the HW is quite flexible, I took 100x100 from the other 2D accelerator drivers actually.
> 
> [...]
> 
>>> +
>>> +static void ge2d_stop_streaming(struct vb2_queue *vq)
>>> +{
>>> +	struct ge2d_ctx *ctx = vb2_get_drv_priv(vq);
>>> +	struct vb2_v4l2_buffer *vbuf;
>>> +
>>> +	if (V4L2_TYPE_IS_OUTPUT(vq->type))
>>> +		ctx->streamon_out = false;
>>> +	else
>>> +		ctx->streamon_cap = false;
>>
>> Do you need streamon_out/cap? Can't you use vb2_start_streaming_called() instead?
> 
> Indeed, I'll switch to vb2_start_streaming_called & co.
> 
> [...]
> 
>>> +
>>> +static int vidioc_try_fmt_out(struct file *file, void *priv, struct v4l2_format *f)
>>> +{
>>> +	const struct ge2d_fmt *fmt = find_fmt(f);
>>> +
>>> +	f->fmt.pix.field = V4L2_FIELD_NONE;
>>> +	f->fmt.pix.pixelformat = fmt->fourcc;
>>> +
>>> +	if (f->fmt.pix.width > MAX_WIDTH)
>>> +		f->fmt.pix.width = MAX_WIDTH;
>>> +	if (f->fmt.pix.height > MAX_HEIGHT)
>>> +		f->fmt.pix.height = MAX_HEIGHT;
>>> +
>>> +	if (f->fmt.pix.width < 0)
>>> +		f->fmt.pix.width = 0;
>>> +	if (f->fmt.pix.height < 0)
>>> +		f->fmt.pix.height = 0;
>>
>> width and height are unsigned, so this check is not needed.
> 
> Ok
> 
> [...]
> 
>>> +
>>> +static int ge2d_s_ctrl(struct v4l2_ctrl *ctrl)
>>> +{
>>> +	struct ge2d_ctx *ctx = container_of(ctrl->handler, struct ge2d_ctx,
>>> +					   ctrl_handler);
>>> +	struct v4l2_pix_format fmt;
>>> +	struct vb2_queue *vq;
>>> +	unsigned long flags;
>>> +
>>> +	spin_lock_irqsave(&ctx->ge2d->ctrl_lock, flags);
>>> +	switch (ctrl->id) {
>>> +	case V4L2_CID_HFLIP:
>>> +		ctx->hflip = ctrl->val;
>>> +		break;
>>> +	case V4L2_CID_VFLIP:
>>> +		ctx->vflip = ctrl->val;
>>> +		break;
>>> +	case V4L2_CID_ROTATE:
>>> +		vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
>>> +		if (vb2_is_busy(vq))
>>> +			return -EBUSY;
>>
>> This doesn't call spin_unlock_irqrestore()!
>>
>> Do you need the spinlock at all? This function is already called with a mutex
>> for ctrl->handler held. It's unusual to see a spinlock here.
> 
> Is device_run also called with ctrl->handler held ?
> 
> The spinlock is used to protect against concurrent re-config & run.

Ah, I see. I think it would help to add some more comments.

BTW, do you need to save the irq state? This function definitely can't
be called from interrupt context, and I suspect that's also true of the
other place where this spinlock is used.

> 
> [...]
> 
>>> +
>>> +	platform_set_drvdata(pdev, ge2d);
>>> +	ge2d->m2m_dev = v4l2_m2m_init(&ge2d_m2m_ops);
>>> +	if (IS_ERR(ge2d->m2m_dev)) {
>>> +		v4l2_err(&ge2d->v4l2_dev, "Failed to init mem2mem device\n");
>>> +		ret = PTR_ERR(ge2d->m2m_dev);
>>> +		goto unreg_video_dev;
>>
>> This should be goto rel_vdev.
>>
>>> +	}
>>> +
>>> +	ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
>>> +	if (ret) {
>>> +		v4l2_err(&ge2d->v4l2_dev, "Failed to register video device\n");
>>> +		goto rel_vdev;
>>> +	}
>>> +
>>> +	v4l2_info(&ge2d->v4l2_dev, "Registered %s as /dev/%s\n",
>>> +		  vfd->name, video_device_node_name(vfd));
>>> +
>>> +	return 0;
>>> +
>>> +rel_vdev:
>>> +	video_device_release(vfd);
>>> +unreg_video_dev:
>>> +	video_unregister_device(ge2d->vfd);
>>
>> This makes no sense. If video_register_device() fails, then you
>> call video_device_release(vfd), not video_unregister_device().
>>
>> Just drop these two lines.
> 
> ok
> 
>>
>>> +unreg_v4l2_dev:
>>> +	v4l2_device_unregister(&ge2d->v4l2_dev);
>>> +disable_clks:
>>> +	clk_disable_unprepare(ge2d->clk);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static int ge2d_remove(struct platform_device *pdev)
>>> +{
>>> +	struct meson_ge2d *ge2d = platform_get_drvdata(pdev);
>>> +
>>> +	v4l2_m2m_release(ge2d->m2m_dev);
>>> +	video_unregister_device(ge2d->vfd);
>>> +	v4l2_device_unregister(&ge2d->v4l2_dev);
>>> +
>>> +	clk_disable_unprepare(ge2d->clk);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static const struct of_device_id meson_ge2d_match[] = {
>>> +	{
>>> +		.compatible = "amlogic,axg-ge2d",
>>> +	},
>>> +	{},
>>> +};
>>> +
>>> +MODULE_DEVICE_TABLE(of, meson_ge2d_match);
>>> +
>>> +static struct platform_driver ge2d_drv = {
>>> +	.probe = ge2d_probe,
>>> +	.remove = ge2d_remove,
>>> +	.driver = {
>>> +		.name = "meson-ge2d",
>>> +		.of_match_table = meson_ge2d_match,
>>> +	},
>>> +};
>>> +
>>> +module_platform_driver(ge2d_drv);
>>> +
>>> +MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
>>> +MODULE_DESCRIPTION("Amlogic 2D Graphic Acceleration Unit");
>>> +MODULE_LICENSE("GPL");
>>>
>>
>> Regards,
>>
>> 	Hans
>>
> 
> Thanks,
> Neil
> 

Regards,

	Hans

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

WARNING: multiple messages have this Message-ID (diff)
From: Hans Verkuil <hverkuil@xs4all.nl>
To: Neil Armstrong <narmstrong@baylibre.com>
Cc: linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-media@vger.kernel.org
Subject: Re: [PATCH v3 2/4] media: meson: Add M2M driver for the Amlogic GE2D Accelerator Unit
Date: Wed, 2 Dec 2020 16:14:31 +0100	[thread overview]
Message-ID: <540b95ef-5815-d400-9214-87667c3b3777@xs4all.nl> (raw)
In-Reply-To: <81cd2c1b-cfc9-0167-0e72-9f47b0887369@baylibre.com>

On 02/12/2020 15:56, Neil Armstrong wrote:
> Hi Hans,
> 
> On 02/12/2020 13:40, Hans Verkuil wrote:
>> On 17/11/2020 09:44, Neil Armstrong wrote:
>>> The GE2D is a 2D accelerator with various features like configurable blitter
>>> with alpha blending, frame rotation, scaling, format conversion and colorspace
>>> conversion.
>>>
>>> The driver implements a Memory2Memory VB2 V4L2 streaming device permitting:
>>> - 0, 90, 180, 270deg rotation
>>> - horizontal/vertical flipping
>>> - source cropping
>>> - destination compositing
>>> - 32bit/24bit/16bit format conversion
>>>
>>> This adds the support for the GE2D version found in the AXG SoCs Family.
>>>
>>> The missing features are:
>>> - Source scaling
>>> - Colorspace conversion
>>> - Advanced alpha blending & blitting options
>>>
>>> Is passes v4l2-compliance SHA: ea16a7ef13a902793a5c2626b0cefc4d956147f3, 64 bits, 64-bit time_t
>>>
>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>> ---
>>>  drivers/media/platform/Kconfig                |   13 +
>>>  drivers/media/platform/Makefile               |    2 +
>>>  drivers/media/platform/meson/ge2d/Makefile    |    3 +
>>>  drivers/media/platform/meson/ge2d/ge2d-regs.h |  360 ++++++
>>>  drivers/media/platform/meson/ge2d/ge2d.c      | 1091 +++++++++++++++++
>>>  5 files changed, 1469 insertions(+)
>>>  create mode 100644 drivers/media/platform/meson/ge2d/Makefile
>>>  create mode 100644 drivers/media/platform/meson/ge2d/ge2d-regs.h
>>>  create mode 100644 drivers/media/platform/meson/ge2d/ge2d.c
>>>
> 
> [...]
> 
>>> +
>>> +#define DEFAULT_WIDTH	100
>>> +#define DEFAULT_HEIGHT	100
>>
>> That's a weird default value. I would expect to see some multiple of 8 here.
> 
> Sure, whatever the HW is quite flexible, I took 100x100 from the other 2D accelerator drivers actually.
> 
> [...]
> 
>>> +
>>> +static void ge2d_stop_streaming(struct vb2_queue *vq)
>>> +{
>>> +	struct ge2d_ctx *ctx = vb2_get_drv_priv(vq);
>>> +	struct vb2_v4l2_buffer *vbuf;
>>> +
>>> +	if (V4L2_TYPE_IS_OUTPUT(vq->type))
>>> +		ctx->streamon_out = false;
>>> +	else
>>> +		ctx->streamon_cap = false;
>>
>> Do you need streamon_out/cap? Can't you use vb2_start_streaming_called() instead?
> 
> Indeed, I'll switch to vb2_start_streaming_called & co.
> 
> [...]
> 
>>> +
>>> +static int vidioc_try_fmt_out(struct file *file, void *priv, struct v4l2_format *f)
>>> +{
>>> +	const struct ge2d_fmt *fmt = find_fmt(f);
>>> +
>>> +	f->fmt.pix.field = V4L2_FIELD_NONE;
>>> +	f->fmt.pix.pixelformat = fmt->fourcc;
>>> +
>>> +	if (f->fmt.pix.width > MAX_WIDTH)
>>> +		f->fmt.pix.width = MAX_WIDTH;
>>> +	if (f->fmt.pix.height > MAX_HEIGHT)
>>> +		f->fmt.pix.height = MAX_HEIGHT;
>>> +
>>> +	if (f->fmt.pix.width < 0)
>>> +		f->fmt.pix.width = 0;
>>> +	if (f->fmt.pix.height < 0)
>>> +		f->fmt.pix.height = 0;
>>
>> width and height are unsigned, so this check is not needed.
> 
> Ok
> 
> [...]
> 
>>> +
>>> +static int ge2d_s_ctrl(struct v4l2_ctrl *ctrl)
>>> +{
>>> +	struct ge2d_ctx *ctx = container_of(ctrl->handler, struct ge2d_ctx,
>>> +					   ctrl_handler);
>>> +	struct v4l2_pix_format fmt;
>>> +	struct vb2_queue *vq;
>>> +	unsigned long flags;
>>> +
>>> +	spin_lock_irqsave(&ctx->ge2d->ctrl_lock, flags);
>>> +	switch (ctrl->id) {
>>> +	case V4L2_CID_HFLIP:
>>> +		ctx->hflip = ctrl->val;
>>> +		break;
>>> +	case V4L2_CID_VFLIP:
>>> +		ctx->vflip = ctrl->val;
>>> +		break;
>>> +	case V4L2_CID_ROTATE:
>>> +		vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
>>> +		if (vb2_is_busy(vq))
>>> +			return -EBUSY;
>>
>> This doesn't call spin_unlock_irqrestore()!
>>
>> Do you need the spinlock at all? This function is already called with a mutex
>> for ctrl->handler held. It's unusual to see a spinlock here.
> 
> Is device_run also called with ctrl->handler held ?
> 
> The spinlock is used to protect against concurrent re-config & run.

Ah, I see. I think it would help to add some more comments.

BTW, do you need to save the irq state? This function definitely can't
be called from interrupt context, and I suspect that's also true of the
other place where this spinlock is used.

> 
> [...]
> 
>>> +
>>> +	platform_set_drvdata(pdev, ge2d);
>>> +	ge2d->m2m_dev = v4l2_m2m_init(&ge2d_m2m_ops);
>>> +	if (IS_ERR(ge2d->m2m_dev)) {
>>> +		v4l2_err(&ge2d->v4l2_dev, "Failed to init mem2mem device\n");
>>> +		ret = PTR_ERR(ge2d->m2m_dev);
>>> +		goto unreg_video_dev;
>>
>> This should be goto rel_vdev.
>>
>>> +	}
>>> +
>>> +	ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
>>> +	if (ret) {
>>> +		v4l2_err(&ge2d->v4l2_dev, "Failed to register video device\n");
>>> +		goto rel_vdev;
>>> +	}
>>> +
>>> +	v4l2_info(&ge2d->v4l2_dev, "Registered %s as /dev/%s\n",
>>> +		  vfd->name, video_device_node_name(vfd));
>>> +
>>> +	return 0;
>>> +
>>> +rel_vdev:
>>> +	video_device_release(vfd);
>>> +unreg_video_dev:
>>> +	video_unregister_device(ge2d->vfd);
>>
>> This makes no sense. If video_register_device() fails, then you
>> call video_device_release(vfd), not video_unregister_device().
>>
>> Just drop these two lines.
> 
> ok
> 
>>
>>> +unreg_v4l2_dev:
>>> +	v4l2_device_unregister(&ge2d->v4l2_dev);
>>> +disable_clks:
>>> +	clk_disable_unprepare(ge2d->clk);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static int ge2d_remove(struct platform_device *pdev)
>>> +{
>>> +	struct meson_ge2d *ge2d = platform_get_drvdata(pdev);
>>> +
>>> +	v4l2_m2m_release(ge2d->m2m_dev);
>>> +	video_unregister_device(ge2d->vfd);
>>> +	v4l2_device_unregister(&ge2d->v4l2_dev);
>>> +
>>> +	clk_disable_unprepare(ge2d->clk);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static const struct of_device_id meson_ge2d_match[] = {
>>> +	{
>>> +		.compatible = "amlogic,axg-ge2d",
>>> +	},
>>> +	{},
>>> +};
>>> +
>>> +MODULE_DEVICE_TABLE(of, meson_ge2d_match);
>>> +
>>> +static struct platform_driver ge2d_drv = {
>>> +	.probe = ge2d_probe,
>>> +	.remove = ge2d_remove,
>>> +	.driver = {
>>> +		.name = "meson-ge2d",
>>> +		.of_match_table = meson_ge2d_match,
>>> +	},
>>> +};
>>> +
>>> +module_platform_driver(ge2d_drv);
>>> +
>>> +MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
>>> +MODULE_DESCRIPTION("Amlogic 2D Graphic Acceleration Unit");
>>> +MODULE_LICENSE("GPL");
>>>
>>
>> Regards,
>>
>> 	Hans
>>
> 
> Thanks,
> Neil
> 

Regards,

	Hans

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

  reply	other threads:[~2020-12-02 15:15 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-17  8:44 [PATCH v3 0/4] media: meson: Add support for the Amlogic GE2D Accelerator Unit Neil Armstrong
2020-11-17  8:44 ` Neil Armstrong
2020-11-17  8:44 ` Neil Armstrong
2020-11-17  8:44 ` [PATCH v3 1/4] dt-bindings: media: Add bindings " Neil Armstrong
2020-11-17  8:44   ` Neil Armstrong
2020-11-17  8:44   ` Neil Armstrong
2020-11-17  8:44 ` [PATCH v3 2/4] media: meson: Add M2M driver " Neil Armstrong
2020-11-17  8:44   ` Neil Armstrong
2020-11-17  8:44   ` Neil Armstrong
2020-12-02 12:40   ` Hans Verkuil
2020-12-02 12:40     ` Hans Verkuil
2020-12-02 12:40     ` Hans Verkuil
2020-12-02 14:56     ` Neil Armstrong
2020-12-02 14:56       ` Neil Armstrong
2020-12-02 14:56       ` Neil Armstrong
2020-12-02 15:14       ` Hans Verkuil [this message]
2020-12-02 15:14         ` Hans Verkuil
2020-12-02 15:14         ` Hans Verkuil
2020-11-17  8:44 ` [PATCH v3 3/4] MAINTAINERS: Add myself as maintainer of the Amlogic GE2D driver Neil Armstrong
2020-11-17  8:44   ` Neil Armstrong
2020-11-17  8:44   ` Neil Armstrong
2020-11-17  8:44 ` [PATCH v3 4/4] arm64: dts: meson-axg: add GE2D node Neil Armstrong
2020-11-17  8:44   ` Neil Armstrong
2020-11-17  8:44   ` Neil Armstrong
2020-11-18  7:35   ` kernel test robot
2020-12-02 12:27 ` [PATCH v3 0/4] media: meson: Add support for the Amlogic GE2D Accelerator Unit Hans Verkuil
2020-12-02 12:27   ` Hans Verkuil
2020-12-02 12:27   ` Hans Verkuil
2020-12-02 12:40   ` Neil Armstrong
2020-12-02 12:40     ` Neil Armstrong
2020-12-02 12:40     ` Neil Armstrong
2020-12-08 16:54 ` Nicolas Dufresne
2020-12-08 16:54   ` Nicolas Dufresne
2020-12-08 16:54   ` Nicolas Dufresne
2020-12-08 17:22   ` Neil Armstrong
2020-12-08 17:22     ` Neil Armstrong
2020-12-08 17:22     ` Neil Armstrong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=540b95ef-5815-d400-9214-87667c3b3777@xs4all.nl \
    --to=hverkuil@xs4all.nl \
    --cc=linux-amlogic@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=narmstrong@baylibre.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.