From 87f9ed85d0f93fcc810dd7081e5f1a883940fab6 Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Tue, 21 Mar 2017 07:49:17 -0400 Subject: media: v4l2-dv-timings: Introduce v4l2_calc_timeperframe helper A new helper function was introduced to facilitate the calculation of time per frame value whenever we have access to the full v4l2_dv_timings structure. This should be used only for receivers and only when there is enough accuracy in the measured pixel clock value as well as in the horizontal/vertical values. Signed-off-by: Jose Abreu Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-dv-timings.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/media') diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h index 17cb27df1b81..fb355d9577a4 100644 --- a/include/media/v4l2-dv-timings.h +++ b/include/media/v4l2-dv-timings.h @@ -10,6 +10,17 @@ #include +/** + * v4l2_calc_timeperframe - helper function to calculate timeperframe based + * v4l2_dv_timings fields. + * @t: Timings for the video mode. + * + * Calculates the expected timeperframe using the pixel clock value and + * horizontal/vertical measures. This means that v4l2_dv_timings structure + * must be correctly and fully filled. + */ +struct v4l2_fract v4l2_calc_timeperframe(const struct v4l2_dv_timings *t); + /* * v4l2_dv_timings_presets: list of all dv_timings presets. */ -- cgit v1.2.3 From 5f628053e28bcca6d06c321a5b71ed55d6332a6f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 5 Aug 2018 23:16:40 -0400 Subject: media: vsp1: convert to SPDX identifiers Signed-off-by: Kuninori Morimoto Reviewed-by: Simon Horman Signed-off-by: Mauro Carvalho Chehab --- include/media/vsp1.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'include/media') diff --git a/include/media/vsp1.h b/include/media/vsp1.h index 3093b9cb9067..dbe64dcb356a 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -1,14 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * vsp1.h -- R-Car VSP1 API * * Copyright (C) 2015 Renesas Electronics Corporation * * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef __MEDIA_VSP1_H__ #define __MEDIA_VSP1_H__ -- cgit v1.2.3 From 1de2e6b34bbf691900cd3c50ae244fa32db430d0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 5 Aug 2018 23:17:01 -0400 Subject: media: rcar-fcp: convert to SPDX identifiers Signed-off-by: Kuninori Morimoto Reviewed-by: Simon Horman Signed-off-by: Mauro Carvalho Chehab --- include/media/rcar-fcp.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'include/media') diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h index b60a7b176c37..179240fb163b 100644 --- a/include/media/rcar-fcp.h +++ b/include/media/rcar-fcp.h @@ -1,14 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * rcar-fcp.h -- R-Car Frame Compression Processor Driver * * Copyright (C) 2016 Renesas Electronics Corporation * * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef __MEDIA_RCAR_FCP_H__ #define __MEDIA_RCAR_FCP_H__ -- cgit v1.2.3 From 092a37875a22fbb75098e834fb1cc1c6220f0eaa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 31 Jul 2018 12:48:05 -0400 Subject: media: v4l2: remove VBI output pad The signal there is the same as the video output (well, except for sliced VBI, but let's simplify the model and ignore it, at least for now - as it is routed together with raw VBI). Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/au8522_decoder.c | 1 - drivers/media/i2c/saa7115.c | 1 - drivers/media/i2c/tvp5150.c | 1 - drivers/media/pci/saa7134/saa7134-core.c | 1 - drivers/media/v4l2-core/v4l2-mc.c | 2 +- include/media/v4l2-mc.h | 2 -- 6 files changed, 1 insertion(+), 7 deletions(-) (limited to 'include/media') diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index f285096a48f0..198dd2b6f326 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -720,7 +720,6 @@ static int au8522_probe(struct i2c_client *client, state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; - state->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[DEMOD_PAD_AUDIO_OUT].flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_ATV_DECODER; diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index 7bc3b721831e..471d1b7af164 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -1836,7 +1836,6 @@ static int saa711x_probe(struct i2c_client *client, #if defined(CONFIG_MEDIA_CONTROLLER) state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; - state->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_ATV_DECODER; diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 57b2102586bc..93c373c20efd 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -1501,7 +1501,6 @@ static int tvp5150_probe(struct i2c_client *c, #if defined(CONFIG_MEDIA_CONTROLLER) core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; - core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_ATV_DECODER; diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 9e76de2411ae..267d143c3a48 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -847,7 +847,6 @@ static void saa7134_create_entities(struct saa7134_dev *dev) dev->demod.name = "saa713x"; dev->demod_pad[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; dev->demod_pad[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; - dev->demod_pad[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; dev->demod.function = MEDIA_ENT_F_ATV_DECODER; ret = media_entity_pads_init(&dev->demod, DEMOD_NUM_PADS, diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index 0fc185a2ce90..982bab3530f6 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c @@ -147,7 +147,7 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) } if (io_vbi) { - ret = media_create_pad_link(decoder, DEMOD_PAD_VBI_OUT, + ret = media_create_pad_link(decoder, DEMOD_PAD_VID_OUT, io_vbi, 0, MEDIA_LNK_FL_ENABLED); if (ret) diff --git a/include/media/v4l2-mc.h b/include/media/v4l2-mc.h index 2634d9dc9916..7c9c781b16a9 100644 --- a/include/media/v4l2-mc.h +++ b/include/media/v4l2-mc.h @@ -89,14 +89,12 @@ enum if_aud_dec_pad_index { * * @DEMOD_PAD_IF_INPUT: IF input sink pad. * @DEMOD_PAD_VID_OUT: Video output source pad. - * @DEMOD_PAD_VBI_OUT: Vertical Blank Interface (VBI) output source pad. * @DEMOD_PAD_AUDIO_OUT: Audio output source pad. * @DEMOD_NUM_PADS: Maximum number of output pads. */ enum demod_pad_index { DEMOD_PAD_IF_INPUT, DEMOD_PAD_VID_OUT, - DEMOD_PAD_VBI_OUT, DEMOD_PAD_AUDIO_OUT, DEMOD_NUM_PADS }; -- cgit v1.2.3 From c1a37dd5e87dc6a4c37e5fc68d7b26fb4a3ef097 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 31 Jul 2018 08:03:48 -0400 Subject: media: v4l2: taint pads with the signal types for consumer devices Consumer devices are provided with a wide different range of types supported by the same driver, allowing different configutations. In order to make easier to setup media controller links, "taint" pads with the signal type it carries. While here, get rid of DEMOD_PAD_VBI_OUT, as the signal it carries is actually the same as the normal video output. The difference happens at the video/VBI interface: - for VBI, only the hidden lines are streamed; - for video, the stream is usually cropped to hide the vbi lines. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/au8522_decoder.c | 3 +++ drivers/media/i2c/msp3400-driver.c | 2 ++ drivers/media/i2c/saa7115.c | 2 ++ drivers/media/i2c/tvp5150.c | 2 ++ drivers/media/pci/saa7134/saa7134-core.c | 2 ++ drivers/media/tuners/si2157.c | 4 +++- drivers/media/usb/dvb-usb-v2/mxl111sf.c | 2 ++ drivers/media/v4l2-core/tuner-core.c | 5 +++++ include/media/media-entity.h | 30 ++++++++++++++++++++++++++++ 9 files changed, 51 insertions(+), 1 deletion(-) (limited to 'include/media') diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 198dd2b6f326..583fdaa7339f 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -719,8 +719,11 @@ static int au8522_probe(struct i2c_client *client, #if defined(CONFIG_MEDIA_CONTROLLER) state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; + state->pads[DEMOD_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG; state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; + state->pads[DEMOD_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV; state->pads[DEMOD_PAD_AUDIO_OUT].flags = MEDIA_PAD_FL_SOURCE; + state->pads[DEMOD_PAD_AUDIO_OUT].sig_type = PAD_SIGNAL_AUDIO; sd->entity.function = MEDIA_ENT_F_ATV_DECODER; ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads), diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c index 98d20479b651..226854ccbd19 100644 --- a/drivers/media/i2c/msp3400-driver.c +++ b/drivers/media/i2c/msp3400-driver.c @@ -704,7 +704,9 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) #if defined(CONFIG_MEDIA_CONTROLLER) state->pads[IF_AUD_DEC_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; + state->pads[IF_AUD_DEC_PAD_IF_INPUT].sig_type = PAD_SIGNAL_AUDIO; state->pads[IF_AUD_DEC_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; + state->pads[IF_AUD_DEC_PAD_OUT].sig_type = PAD_SIGNAL_AUDIO; sd->entity.function = MEDIA_ENT_F_IF_AUD_DECODER; diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index 471d1b7af164..7b2dbe7c59b2 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -1835,7 +1835,9 @@ static int saa711x_probe(struct i2c_client *client, #if defined(CONFIG_MEDIA_CONTROLLER) state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; + state->pads[DEMOD_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG; state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; + state->pads[DEMOD_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV; sd->entity.function = MEDIA_ENT_F_ATV_DECODER; diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 93c373c20efd..94841cf81a7d 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -1500,7 +1500,9 @@ static int tvp5150_probe(struct i2c_client *c, #if defined(CONFIG_MEDIA_CONTROLLER) core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; + core->pads[DEMOD_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG; core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; + core->pads[DEMOD_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV; sd->entity.function = MEDIA_ENT_F_ATV_DECODER; diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 267d143c3a48..c4e2df197bf9 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -846,7 +846,9 @@ static void saa7134_create_entities(struct saa7134_dev *dev) if (!decoder) { dev->demod.name = "saa713x"; dev->demod_pad[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; + dev->demod_pad[DEMOD_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG; dev->demod_pad[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; + dev->demod_pad[DEMOD_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV; dev->demod.function = MEDIA_ENT_F_ATV_DECODER; ret = media_entity_pads_init(&dev->demod, DEMOD_NUM_PADS, diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index a08d8fe2bb1b..0e39810922fc 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -467,10 +467,12 @@ static int si2157_probe(struct i2c_client *client, dev->ent.name = KBUILD_MODNAME; dev->ent.function = MEDIA_ENT_F_TUNER; - dev->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; + dev->pad[TUNER_PAD_RF_INPUT].sig_type = PAD_SIGNAL_ANALOG; dev->pad[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; + dev->pad[TUNER_PAD_OUTPUT].sig_type = PAD_SIGNAL_ANALOG; dev->pad[TUNER_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE; + dev->pad[TUNER_PAD_AUD_OUT].sig_type = PAD_SIGNAL_AUDIO; ret = media_entity_pads_init(&dev->ent, TUNER_NUM_PADS, &dev->pad[0]); diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c index 4713ba65e1c2..ecd758388745 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c @@ -893,7 +893,9 @@ static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap) state->tuner.function = MEDIA_ENT_F_TUNER; state->tuner.name = "mxl111sf tuner"; state->tuner_pads[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; + state->tuner_pads[TUNER_PAD_RF_INPUT].sig_type = PAD_SIGNAL_ANALOG; state->tuner_pads[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; + state->tuner_pads[TUNER_PAD_OUTPUT].sig_type = PAD_SIGNAL_ANALOG; ret = media_entity_pads_init(&state->tuner, TUNER_NUM_PADS, state->tuner_pads); diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 7f858c39753c..2f3b7fb092b9 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -685,15 +685,20 @@ register_client: */ if (t->type == TUNER_TDA9887) { t->pad[IF_VID_DEC_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; + t->pad[IF_VID_DEC_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG; t->pad[IF_VID_DEC_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; + t->pad[IF_VID_DEC_PAD_OUT].sig_type = PAD_SIGNAL_ANALOG; ret = media_entity_pads_init(&t->sd.entity, IF_VID_DEC_PAD_NUM_PADS, &t->pad[0]); t->sd.entity.function = MEDIA_ENT_F_IF_VID_DECODER; } else { t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; + t->pad[TUNER_PAD_RF_INPUT].sig_type = PAD_SIGNAL_ANALOG; t->pad[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; + t->pad[TUNER_PAD_OUTPUT].sig_type = PAD_SIGNAL_ANALOG; t->pad[TUNER_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE; + t->pad[TUNER_PAD_AUD_OUT].sig_type = PAD_SIGNAL_AUDIO; ret = media_entity_pads_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); t->sd.entity.function = MEDIA_ENT_F_TUNER; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 3aa3d58d1d58..b7a53f5d3e12 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -155,12 +155,41 @@ struct media_link { bool is_backlink; }; +/** + * enum media_pad_signal_type - type of the signal inside a media pad + * + * @PAD_SIGNAL_DEFAULT: + * Default signal. Use this when all inputs or all outputs are + * uniquely identified by the pad number. + * @PAD_SIGNAL_ANALOG: + * The pad contains an analog signal. It can be Radio Frequency, + * Intermediate Frequency, a baseband signal or sub-cariers. + * Tuner inputs, IF-PLL demodulators, composite and s-video signals + * should use it. + * @PAD_SIGNAL_DV: + * Contains a digital video signal, with can be a bitstream of samples + * taken from an analog TV video source. On such case, it usually + * contains the VBI data on it. + * @PAD_SIGNAL_AUDIO: + * Contains an Intermediate Frequency analog signal from an audio + * sub-carrier or an audio bitstream. IF signals are provided by tuners + * and consumed by audio AM/FM decoders. Bitstream audio is provided by + * an audio decoder. + */ +enum media_pad_signal_type { + PAD_SIGNAL_DEFAULT = 0, + PAD_SIGNAL_ANALOG, + PAD_SIGNAL_DV, + PAD_SIGNAL_AUDIO, +}; + /** * struct media_pad - A media pad graph object. * * @graph_obj: Embedded structure containing the media object common data * @entity: Entity this pad belongs to * @index: Pad index in the entity pads array, numbered from 0 to n + * @sig_type: Type of the signal inside a media pad * @flags: Pad flags, as defined in * :ref:`include/uapi/linux/media.h ` * (seek for ``MEDIA_PAD_FL_*``) @@ -169,6 +198,7 @@ struct media_pad { struct media_gobj graph_obj; /* must be first field in struct */ struct media_entity *entity; u16 index; + enum media_pad_signal_type sig_type; unsigned long flags; }; -- cgit v1.2.3 From 9d6d20e652c0d304f98de30d51805658f98ba27d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 31 Jul 2018 09:22:40 -0400 Subject: media: v4l2-mc: switch it to use the new approach to setup pipelines Instead of relying on a static map for pids, use the new sig_type "taint" type to setup the pipelines with the same tipe between different entities. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 26 ++++++++++++ drivers/media/v4l2-core/v4l2-mc.c | 85 ++++++++++++++++++++++++++++----------- include/media/media-entity.h | 18 +++++++++ 3 files changed, 106 insertions(+), 23 deletions(-) (limited to 'include/media') diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 3498551e618e..0b1cb3559140 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -662,6 +662,32 @@ static void __media_entity_remove_link(struct media_entity *entity, kfree(link); } +int media_get_pad_index(struct media_entity *entity, bool is_sink, + enum media_pad_signal_type sig_type) +{ + int i; + bool pad_is_sink; + + if (!entity) + return -EINVAL; + + for (i = 0; i < entity->num_pads; i++) { + if (entity->pads[i].flags == MEDIA_PAD_FL_SINK) + pad_is_sink = true; + else if (entity->pads[i].flags == MEDIA_PAD_FL_SOURCE) + pad_is_sink = false; + else + continue; /* This is an error! */ + + if (pad_is_sink != is_sink) + continue; + if (entity->pads[i].sig_type == sig_type) + return i; + } + return -EINVAL; +} +EXPORT_SYMBOL_GPL(media_get_pad_index); + int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags) diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index 982bab3530f6..d9f3397abf2f 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c @@ -28,7 +28,7 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) struct media_entity *io_v4l = NULL, *io_vbi = NULL, *io_swradio = NULL; bool is_webcam = false; u32 flags; - int ret; + int ret, pad_sink, pad_source; if (!mdev) return 0; @@ -97,29 +97,52 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) /* Link the tuner and IF video output pads */ if (tuner) { if (if_vid) { - ret = media_create_pad_link(tuner, TUNER_PAD_OUTPUT, - if_vid, - IF_VID_DEC_PAD_IF_INPUT, + pad_source = media_get_pad_index(tuner, false, + PAD_SIGNAL_ANALOG); + pad_sink = media_get_pad_index(if_vid, true, + PAD_SIGNAL_ANALOG); + if (pad_source < 0 || pad_sink < 0) + return -EINVAL; + ret = media_create_pad_link(tuner, pad_source, + if_vid, pad_sink, MEDIA_LNK_FL_ENABLED); if (ret) return ret; - ret = media_create_pad_link(if_vid, IF_VID_DEC_PAD_OUT, - decoder, DEMOD_PAD_IF_INPUT, - MEDIA_LNK_FL_ENABLED); + + pad_source = media_get_pad_index(if_vid, false, + PAD_SIGNAL_ANALOG); + pad_sink = media_get_pad_index(decoder, true, + PAD_SIGNAL_ANALOG); + if (pad_source < 0 || pad_sink < 0) + return -EINVAL; + ret = media_create_pad_link(if_vid, pad_source, + decoder, pad_sink, + MEDIA_LNK_FL_ENABLED); if (ret) return ret; } else { - ret = media_create_pad_link(tuner, TUNER_PAD_OUTPUT, - decoder, DEMOD_PAD_IF_INPUT, - MEDIA_LNK_FL_ENABLED); + pad_source = media_get_pad_index(tuner, false, + PAD_SIGNAL_ANALOG); + pad_sink = media_get_pad_index(decoder, true, + PAD_SIGNAL_ANALOG); + if (pad_source < 0 || pad_sink < 0) + return -EINVAL; + ret = media_create_pad_link(tuner, pad_source, + decoder, pad_sink, + MEDIA_LNK_FL_ENABLED); if (ret) return ret; } if (if_aud) { - ret = media_create_pad_link(tuner, TUNER_PAD_AUD_OUT, - if_aud, - IF_AUD_DEC_PAD_IF_INPUT, + pad_source = media_get_pad_index(tuner, false, + PAD_SIGNAL_AUDIO); + pad_sink = media_get_pad_index(if_aud, true, + PAD_SIGNAL_AUDIO); + if (pad_source < 0 || pad_sink < 0) + return -EINVAL; + ret = media_create_pad_link(tuner, pad_source, + if_aud, pad_sink, MEDIA_LNK_FL_ENABLED); if (ret) return ret; @@ -131,23 +154,32 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) /* Create demod to V4L, VBI and SDR radio links */ if (io_v4l) { - ret = media_create_pad_link(decoder, DEMOD_PAD_VID_OUT, - io_v4l, 0, - MEDIA_LNK_FL_ENABLED); + pad_source = media_get_pad_index(decoder, false, PAD_SIGNAL_DV); + if (pad_source < 0) + return -EINVAL; + ret = media_create_pad_link(decoder, pad_source, + io_v4l, 0, + MEDIA_LNK_FL_ENABLED); if (ret) return ret; } if (io_swradio) { - ret = media_create_pad_link(decoder, DEMOD_PAD_VID_OUT, - io_swradio, 0, - MEDIA_LNK_FL_ENABLED); + pad_source = media_get_pad_index(decoder, false, PAD_SIGNAL_DV); + if (pad_source < 0) + return -EINVAL; + ret = media_create_pad_link(decoder, pad_source, + io_swradio, 0, + MEDIA_LNK_FL_ENABLED); if (ret) return ret; } if (io_vbi) { - ret = media_create_pad_link(decoder, DEMOD_PAD_VID_OUT, + pad_source = media_get_pad_index(decoder, false, PAD_SIGNAL_DV); + if (pad_source < 0) + return -EINVAL; + ret = media_create_pad_link(decoder, pad_source, io_vbi, 0, MEDIA_LNK_FL_ENABLED); if (ret) @@ -161,15 +193,22 @@ int v4l2_mc_create_media_graph(struct media_device *mdev) case MEDIA_ENT_F_CONN_RF: if (!tuner) continue; - + pad_sink = media_get_pad_index(tuner, true, + PAD_SIGNAL_ANALOG); + if (pad_sink < 0) + return -EINVAL; ret = media_create_pad_link(entity, 0, tuner, - TUNER_PAD_RF_INPUT, + pad_sink, flags); break; case MEDIA_ENT_F_CONN_SVIDEO: case MEDIA_ENT_F_CONN_COMPOSITE: + pad_sink = media_get_pad_index(decoder, true, + PAD_SIGNAL_ANALOG); + if (pad_sink < 0) + return -EINVAL; ret = media_create_pad_link(entity, 0, decoder, - DEMOD_PAD_IF_INPUT, + pad_sink, flags); break; default: diff --git a/include/media/media-entity.h b/include/media/media-entity.h index b7a53f5d3e12..e5f6960d92f6 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -670,6 +670,24 @@ static inline void media_entity_cleanup(struct media_entity *entity) {} #define media_entity_cleanup(entity) do { } while (false) #endif +/** + * media_get_pad_index() - retrieves a pad index from an entity + * + * @entity: entity where the pads belong + * @is_sink: true if the pad is a sink, false if it is a source + * @sig_type: type of signal of the pad to be search + * + * This helper function finds the first pad index inside an entity that + * satisfies both @is_sink and @sig_type conditions. + * + * Return: + * + * On success, return the pad number. If the pad was not found or the media + * entity is a NULL pointer, return -EINVAL. + */ +int media_get_pad_index(struct media_entity *entity, bool is_sink, + enum media_pad_signal_type sig_type); + /** * media_create_pad_link() - creates a link between two entities. * -- cgit v1.2.3 From 65e83fb00b2df3eadc23d71aacf626af3700f337 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 1 Aug 2018 06:58:38 -0400 Subject: media: v4l2-mc: get rid of global pad indexes Now that all drivers are using pad signal types, we can get rid of the global static definition, as routes are stablished using the pad signal type. The tuner and IF-PLL pads are now used only by the tuner core, so move the definitions to be there. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/tuner-core.c | 49 ++++++++++++++++++++++- include/media/v4l2-mc.h | 76 ------------------------------------ 2 files changed, 48 insertions(+), 77 deletions(-) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 2f3b7fb092b9..03a340cb5a9b 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -94,9 +94,56 @@ static const struct v4l2_subdev_ops tuner_ops; } while (0) /* - * Internal struct used inside the driver + * Internal enums/struct used inside the driver */ +/** + * enum tuner_pad_index - tuner pad index for MEDIA_ENT_F_TUNER + * + * @TUNER_PAD_RF_INPUT: + * Radiofrequency (RF) sink pad, usually linked to a RF connector entity. + * @TUNER_PAD_OUTPUT: + * tuner video output source pad. Contains the video chrominance + * and luminance or the hole bandwidth of the signal converted to + * an Intermediate Frequency (IF) or to baseband (on zero-IF tuners). + * @TUNER_PAD_AUD_OUT: + * Tuner audio output source pad. Tuners used to decode analog TV + * signals have an extra pad for audio output. Old tuners use an + * analog stage with a saw filter for the audio IF frequency. The + * output of the pad is, in this case, the audio IF, with should be + * decoded either by the bridge chipset (that's the case of cx2388x + * chipsets) or may require an external IF sound processor, like + * msp34xx. On modern silicon tuners, the audio IF decoder is usually + * incorporated at the tuner. On such case, the output of this pad + * is an audio sampled data. + * @TUNER_NUM_PADS: + * Number of pads of the tuner. + */ +enum tuner_pad_index { + TUNER_PAD_RF_INPUT, + TUNER_PAD_OUTPUT, + TUNER_PAD_AUD_OUT, + TUNER_NUM_PADS +}; + +/** + * enum if_vid_dec_pad_index - video IF-PLL pad index + * for MEDIA_ENT_F_IF_VID_DECODER + * + * @IF_VID_DEC_PAD_IF_INPUT: + * video Intermediate Frequency (IF) sink pad + * @IF_VID_DEC_PAD_OUT: + * IF-PLL video output source pad. Contains the video chrominance + * and luminance IF signals. + * @IF_VID_DEC_PAD_NUM_PADS: + * Number of pads of the video IF-PLL. + */ +enum if_vid_dec_pad_index { + IF_VID_DEC_PAD_IF_INPUT, + IF_VID_DEC_PAD_OUT, + IF_VID_DEC_PAD_NUM_PADS +}; + struct tuner { /* device */ struct dvb_frontend fe; diff --git a/include/media/v4l2-mc.h b/include/media/v4l2-mc.h index 7c9c781b16a9..bf5043c1ab6b 100644 --- a/include/media/v4l2-mc.h +++ b/include/media/v4l2-mc.h @@ -23,82 +23,6 @@ #include #include -/** - * enum tuner_pad_index - tuner pad index for MEDIA_ENT_F_TUNER - * - * @TUNER_PAD_RF_INPUT: Radiofrequency (RF) sink pad, usually linked to a - * RF connector entity. - * @TUNER_PAD_OUTPUT: Tuner video output source pad. Contains the video - * chrominance and luminance or the hole bandwidth - * of the signal converted to an Intermediate Frequency - * (IF) or to baseband (on zero-IF tuners). - * @TUNER_PAD_AUD_OUT: Tuner audio output source pad. Tuners used to decode - * analog TV signals have an extra pad for audio output. - * Old tuners use an analog stage with a saw filter for - * the audio IF frequency. The output of the pad is, in - * this case, the audio IF, with should be decoded either - * by the bridge chipset (that's the case of cx2388x - * chipsets) or may require an external IF sound - * processor, like msp34xx. On modern silicon tuners, - * the audio IF decoder is usually incorporated at the - * tuner. On such case, the output of this pad is an - * audio sampled data. - * @TUNER_NUM_PADS: Number of pads of the tuner. - */ -enum tuner_pad_index { - TUNER_PAD_RF_INPUT, - TUNER_PAD_OUTPUT, - TUNER_PAD_AUD_OUT, - TUNER_NUM_PADS -}; - -/** - * enum if_vid_dec_pad_index - video IF-PLL pad index for - * MEDIA_ENT_F_IF_VID_DECODER - * - * @IF_VID_DEC_PAD_IF_INPUT: video Intermediate Frequency (IF) sink pad - * @IF_VID_DEC_PAD_OUT: IF-PLL video output source pad. Contains the - * video chrominance and luminance IF signals. - * @IF_VID_DEC_PAD_NUM_PADS: Number of pads of the video IF-PLL. - */ -enum if_vid_dec_pad_index { - IF_VID_DEC_PAD_IF_INPUT, - IF_VID_DEC_PAD_OUT, - IF_VID_DEC_PAD_NUM_PADS -}; - -/** - * enum if_aud_dec_pad_index - audio/sound IF-PLL pad index for - * MEDIA_ENT_F_IF_AUD_DECODER - * - * @IF_AUD_DEC_PAD_IF_INPUT: audio Intermediate Frequency (IF) sink pad - * @IF_AUD_DEC_PAD_OUT: IF-PLL audio output source pad. Contains the - * audio sampled stream data, usually connected - * to the bridge bus via an Inter-IC Sound (I2S) - * bus. - * @IF_AUD_DEC_PAD_NUM_PADS: Number of pads of the audio IF-PLL. - */ -enum if_aud_dec_pad_index { - IF_AUD_DEC_PAD_IF_INPUT, - IF_AUD_DEC_PAD_OUT, - IF_AUD_DEC_PAD_NUM_PADS -}; - -/** - * enum demod_pad_index - analog TV pad index for MEDIA_ENT_F_ATV_DECODER - * - * @DEMOD_PAD_IF_INPUT: IF input sink pad. - * @DEMOD_PAD_VID_OUT: Video output source pad. - * @DEMOD_PAD_AUDIO_OUT: Audio output source pad. - * @DEMOD_NUM_PADS: Maximum number of output pads. - */ -enum demod_pad_index { - DEMOD_PAD_IF_INPUT, - DEMOD_PAD_VID_OUT, - DEMOD_PAD_AUDIO_OUT, - DEMOD_NUM_PADS -}; - /* We don't need to include pci.h or usb.h here */ struct pci_dev; struct usb_device; -- cgit v1.2.3 From e62fdbb24c342f78e431e05925097165cc0e05e9 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Thu, 28 Jun 2018 12:20:37 -0400 Subject: media: v4l2-rect.h: add position and equal helpers Add two helper functions to check if two rectangles have the same position (top/left) and if two rectangles equals (same size and same position). Signed-off-by: Marco Felsch Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-rect.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include/media') diff --git a/include/media/v4l2-rect.h b/include/media/v4l2-rect.h index 595c3ba05f23..c86474dc7b55 100644 --- a/include/media/v4l2-rect.h +++ b/include/media/v4l2-rect.h @@ -82,6 +82,32 @@ static inline bool v4l2_rect_same_size(const struct v4l2_rect *r1, return r1->width == r2->width && r1->height == r2->height; } +/** + * v4l2_rect_same_position() - return true if r1 has the same position as r2 + * @r1: rectangle. + * @r2: rectangle. + * + * Return true if both rectangles have the same position + */ +static inline bool v4l2_rect_same_position(const struct v4l2_rect *r1, + const struct v4l2_rect *r2) +{ + return r1->top == r2->top && r1->left == r2->left; +} + +/** + * v4l2_rect_equal() - return true if r1 equals r2 + * @r1: rectangle. + * @r2: rectangle. + * + * Return true if both rectangles have the same size and position. + */ +static inline bool v4l2_rect_equal(const struct v4l2_rect *r1, + const struct v4l2_rect *r2) +{ + return v4l2_rect_same_size(r1, r2) && v4l2_rect_same_position(r1, r2); +} + /** * v4l2_rect_intersect() - calculate the intersection of two rects. * @r: intersection of @r1 and @r2. -- cgit v1.2.3 From 9b2798d5b71c50f64c41a40f0cbcae47c3fbd067 Mon Sep 17 00:00:00 2001 From: Koji Matsuoka Date: Thu, 26 Oct 2017 02:27:51 -0400 Subject: media: vsp1: Fix YCbCr planar formats pitch calculation YCbCr planar formats can have different pitch values for the luma and chroma planes. This isn't taken into account in the driver. Fix it. Based on a BSP patch from Koji Matsuoka . Fixes: 7863ac504bc5 ("drm: rcar-du: Add tri-planar memory formats support") [Updated documentation of the struct vsp1_du_atomic_config pitch field] Signed-off-by: Koji Matsuoka Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_drm.c | 11 ++++++++++- include/media/vsp1.h | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'include/media') diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index b9c0f695d002..8d86f618ec77 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -770,6 +770,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index, struct vsp1_device *vsp1 = dev_get_drvdata(dev); struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index]; const struct vsp1_format_info *fmtinfo; + unsigned int chroma_hsub; struct vsp1_rwpf *rpf; if (rpf_index >= vsp1->info->rpf_count) @@ -810,10 +811,18 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index, return -EINVAL; } + /* + * Only formats with three planes can affect the chroma planes pitch. + * All formats with two planes have a horizontal subsampling value of 2, + * but combine U and V in a single chroma plane, which thus results in + * the luma plane and chroma plane having the same pitch. + */ + chroma_hsub = (fmtinfo->planes == 3) ? fmtinfo->hsub : 1; + rpf->fmtinfo = fmtinfo; rpf->format.num_planes = fmtinfo->planes; rpf->format.plane_fmt[0].bytesperline = cfg->pitch; - rpf->format.plane_fmt[1].bytesperline = cfg->pitch; + rpf->format.plane_fmt[1].bytesperline = cfg->pitch / chroma_hsub; rpf->alpha = cfg->alpha; rpf->mem.addr[0] = cfg->mem[0]; diff --git a/include/media/vsp1.h b/include/media/vsp1.h index dbe64dcb356a..1cf868360701 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -42,7 +42,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, /** * struct vsp1_du_atomic_config - VSP atomic configuration parameters * @pixelformat: plane pixel format (V4L2 4CC) - * @pitch: line pitch in bytes, for all planes + * @pitch: line pitch in bytes for the first plane * @mem: DMA memory address for each plane of the frame buffer * @src: source rectangle in the frame buffer (integer coordinates) * @dst: destination rectangle on the display (integer coordinates) -- cgit v1.2.3 From 0658293012af1e69d8bb8a25e71781470f9b2ac6 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 29 Aug 2018 05:52:46 -0400 Subject: media: v4l: subdev: Add a function to set an I²C sub-device's name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v4l2_i2c_subdev_set_name() can be used to assign a name to a sub-device. This way uniform names can be formed easily without having to resort to things such as snprintf in drivers. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-common.c | 18 ++++++++++++++---- include/media/v4l2-common.h | 12 ++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index 7c755952398f..50763fb42a1b 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -109,6 +109,19 @@ EXPORT_SYMBOL(v4l2_ctrl_query_fill); #if IS_ENABLED(CONFIG_I2C) +void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client, + const char *devname, const char *postfix) +{ + if (!devname) + devname = client->dev.driver->name; + if (!postfix) + postfix = ""; + + snprintf(sd->name, sizeof(sd->name), "%s%s %d-%04x", devname, postfix, + i2c_adapter_id(client->adapter), client->addr); +} +EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_set_name); + void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, const struct v4l2_subdev_ops *ops) { @@ -120,10 +133,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, /* i2c_client and v4l2_subdev point to one another */ v4l2_set_subdevdata(sd, client); i2c_set_clientdata(client, sd); - /* initialize name */ - snprintf(sd->name, sizeof(sd->name), "%s %d-%04x", - client->dev.driver->name, i2c_adapter_id(client->adapter), - client->addr); + v4l2_i2c_subdev_set_name(sd, client, NULL, NULL); } EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init); diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index cdc87ec61e54..bd880a909ecf 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -154,6 +154,18 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, struct i2c_adapter *adapter, struct i2c_board_info *info, const unsigned short *probe_addrs); +/** + * v4l2_i2c_subdev_set_name - Set name for an I²C sub-device + * + * @sd: pointer to &struct v4l2_subdev + * @client: pointer to struct i2c_client + * @devname: the name of the device; if NULL, the I²C device's name will be used + * @postfix: sub-device specific string to put right after the I²C device name; + * may be NULL + */ +void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client, + const char *devname, const char *postfix); + /** * v4l2_i2c_subdev_init - Initializes a &struct v4l2_subdev with data from * an i2c_client struct. -- cgit v1.2.3 From b915bf575d5b7774d0f22d57d6c143e07dcaade2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 13 Sep 2018 03:25:59 -0400 Subject: media: cec: make cec_get_edid_spa_location() an inline function This function is needed by both V4L2 and CEC, so move this to cec.h as a static inline since there are no obvious shared modules between the two subsystems. This patch, together with the following ones, fixes a dependency bug: if CEC_CORE is disabled, then building adv7604 (and other HDMI receivers) will fail because an essential function is now stubbed out. Signed-off-by: Hans Verkuil Cc: # for v4.17 and up Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-edid.c | 60 ------------------------------------- include/media/cec.h | 70 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 60 deletions(-) (limited to 'include/media') diff --git a/drivers/media/cec/cec-edid.c b/drivers/media/cec/cec-edid.c index ec72ac1c0b91..f587e8eaefd8 100644 --- a/drivers/media/cec/cec-edid.c +++ b/drivers/media/cec/cec-edid.c @@ -10,66 +10,6 @@ #include #include -/* - * This EDID is expected to be a CEA-861 compliant, which means that there are - * at least two blocks and one or more of the extensions blocks are CEA-861 - * blocks. - * - * The returned location is guaranteed to be < size - 1. - */ -static unsigned int cec_get_edid_spa_location(const u8 *edid, unsigned int size) -{ - unsigned int blocks = size / 128; - unsigned int block; - u8 d; - - /* Sanity check: at least 2 blocks and a multiple of the block size */ - if (blocks < 2 || size % 128) - return 0; - - /* - * If there are fewer extension blocks than the size, then update - * 'blocks'. It is allowed to have more extension blocks than the size, - * since some hardware can only read e.g. 256 bytes of the EDID, even - * though more blocks are present. The first CEA-861 extension block - * should normally be in block 1 anyway. - */ - if (edid[0x7e] + 1 < blocks) - blocks = edid[0x7e] + 1; - - for (block = 1; block < blocks; block++) { - unsigned int offset = block * 128; - - /* Skip any non-CEA-861 extension blocks */ - if (edid[offset] != 0x02 || edid[offset + 1] != 0x03) - continue; - - /* search Vendor Specific Data Block (tag 3) */ - d = edid[offset + 2] & 0x7f; - /* Check if there are Data Blocks */ - if (d <= 4) - continue; - if (d > 4) { - unsigned int i = offset + 4; - unsigned int end = offset + d; - - /* Note: 'end' is always < 'size' */ - do { - u8 tag = edid[i] >> 5; - u8 len = edid[i] & 0x1f; - - if (tag == 3 && len >= 5 && i + len <= end && - edid[i + 1] == 0x03 && - edid[i + 2] == 0x0c && - edid[i + 3] == 0x00) - return i + 4; - i += len + 1; - } while (i < end); - } - } - return 0; -} - u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, unsigned int *offset) { diff --git a/include/media/cec.h b/include/media/cec.h index ff9847f7f99d..603f2fa08f62 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -461,4 +461,74 @@ static inline void cec_phys_addr_invalidate(struct cec_adapter *adap) cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); } +/** + * cec_get_edid_spa_location() - find location of the Source Physical Address + * + * @edid: the EDID + * @size: the size of the EDID + * + * This EDID is expected to be a CEA-861 compliant, which means that there are + * at least two blocks and one or more of the extensions blocks are CEA-861 + * blocks. + * + * The returned location is guaranteed to be <= size-2. + * + * This is an inline function since it is used by both CEC and V4L2. + * Ideally this would go in a module shared by both, but it is overkill to do + * that for just a single function. + */ +static inline unsigned int cec_get_edid_spa_location(const u8 *edid, + unsigned int size) +{ + unsigned int blocks = size / 128; + unsigned int block; + u8 d; + + /* Sanity check: at least 2 blocks and a multiple of the block size */ + if (blocks < 2 || size % 128) + return 0; + + /* + * If there are fewer extension blocks than the size, then update + * 'blocks'. It is allowed to have more extension blocks than the size, + * since some hardware can only read e.g. 256 bytes of the EDID, even + * though more blocks are present. The first CEA-861 extension block + * should normally be in block 1 anyway. + */ + if (edid[0x7e] + 1 < blocks) + blocks = edid[0x7e] + 1; + + for (block = 1; block < blocks; block++) { + unsigned int offset = block * 128; + + /* Skip any non-CEA-861 extension blocks */ + if (edid[offset] != 0x02 || edid[offset + 1] != 0x03) + continue; + + /* search Vendor Specific Data Block (tag 3) */ + d = edid[offset + 2] & 0x7f; + /* Check if there are Data Blocks */ + if (d <= 4) + continue; + if (d > 4) { + unsigned int i = offset + 4; + unsigned int end = offset + d; + + /* Note: 'end' is always < 'size' */ + do { + u8 tag = edid[i] >> 5; + u8 len = edid[i] & 0x1f; + + if (tag == 3 && len >= 5 && i + len <= end && + edid[i + 1] == 0x03 && + edid[i + 2] == 0x0c && + edid[i + 3] == 0x00) + return i + 4; + i += len + 1; + } while (i < end); + } + } + return 0; +} + #endif /* _MEDIA_CEC_H */ -- cgit v1.2.3 From 9cfd2753f8f3923f89cbb15f940f3aa0e7202d3e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 13 Sep 2018 03:40:56 -0400 Subject: media: cec/v4l2: move V4L2 specific CEC functions to V4L2 Several CEC functions are actually specific for use with receivers, i.e. they should be part of the V4L2 subsystem, not CEC. These functions deal with validating and modifying EDIDs for (HDMI) receivers, and they do not actually have anything to do with the CEC subsystem and whether or not CEC is enabled. The problem was that if the CEC_CORE config option was not set, then these functions would become stubs, but that's not right: they should always be valid. So replace the cec_ prefix by v4l2_ and move them to v4l2-dv-timings.c. Update all drivers that call these accordingly. Signed-off-by: Hans Verkuil Reported-by: Lars-Peter Clausen Cc: # for v4.17 and up Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-edid.c | 71 ----------- drivers/media/i2c/adv7604.c | 4 +- drivers/media/i2c/adv7842.c | 4 +- drivers/media/i2c/tc358743.c | 2 +- drivers/media/platform/vivid/vivid-vid-cap.c | 4 +- drivers/media/platform/vivid/vivid-vid-common.c | 2 +- drivers/media/v4l2-core/v4l2-dv-timings.c | 151 ++++++++++++++++++++++++ include/media/cec.h | 80 ------------- include/media/v4l2-dv-timings.h | 6 + 9 files changed, 165 insertions(+), 159 deletions(-) (limited to 'include/media') diff --git a/drivers/media/cec/cec-edid.c b/drivers/media/cec/cec-edid.c index f587e8eaefd8..e2f54eec0829 100644 --- a/drivers/media/cec/cec-edid.c +++ b/drivers/media/cec/cec-edid.c @@ -22,74 +22,3 @@ u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, return (edid[loc] << 8) | edid[loc + 1]; } EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr); - -void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr) -{ - unsigned int loc = cec_get_edid_spa_location(edid, size); - u8 sum = 0; - unsigned int i; - - if (loc == 0) - return; - edid[loc] = phys_addr >> 8; - edid[loc + 1] = phys_addr & 0xff; - loc &= ~0x7f; - - /* update the checksum */ - for (i = loc; i < loc + 127; i++) - sum += edid[i]; - edid[i] = 256 - sum; -} -EXPORT_SYMBOL_GPL(cec_set_edid_phys_addr); - -u16 cec_phys_addr_for_input(u16 phys_addr, u8 input) -{ - /* Check if input is sane */ - if (WARN_ON(input == 0 || input > 0xf)) - return CEC_PHYS_ADDR_INVALID; - - if (phys_addr == 0) - return input << 12; - - if ((phys_addr & 0x0fff) == 0) - return phys_addr | (input << 8); - - if ((phys_addr & 0x00ff) == 0) - return phys_addr | (input << 4); - - if ((phys_addr & 0x000f) == 0) - return phys_addr | input; - - /* - * All nibbles are used so no valid physical addresses can be assigned - * to the input. - */ - return CEC_PHYS_ADDR_INVALID; -} -EXPORT_SYMBOL_GPL(cec_phys_addr_for_input); - -int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port) -{ - int i; - - if (parent) - *parent = phys_addr; - if (port) - *port = 0; - if (phys_addr == CEC_PHYS_ADDR_INVALID) - return 0; - for (i = 0; i < 16; i += 4) - if (phys_addr & (0xf << i)) - break; - if (i == 16) - return 0; - if (parent) - *parent = phys_addr & (0xfff0 << i); - if (port) - *port = (phys_addr >> i) & 0xf; - for (i += 4; i < 16; i += 4) - if ((phys_addr & (0xf << i)) == 0) - return -EINVAL; - return 0; -} -EXPORT_SYMBOL_GPL(cec_phys_addr_validate); diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 668be2bca57a..c31673fcd5c1 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -2295,8 +2295,8 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) edid->blocks = 2; return -E2BIG; } - pa = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, &spa_loc); - err = cec_phys_addr_validate(pa, &pa, NULL); + pa = v4l2_get_edid_phys_addr(edid->edid, edid->blocks * 128, &spa_loc); + err = v4l2_phys_addr_validate(pa, &pa, NULL); if (err) return err; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index f1c168bfaaa4..cd63cc6564e9 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -789,8 +789,8 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port) if (!state->hdmi_edid.present) return 0; - pa = cec_get_edid_phys_addr(edid, 256, &spa_loc); - err = cec_phys_addr_validate(pa, &pa, NULL); + pa = v4l2_get_edid_phys_addr(edid, 256, &spa_loc); + err = v4l2_phys_addr_validate(pa, &pa, NULL); if (err) return err; diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 44c41933415a..ef4dbac6bb58 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1789,7 +1789,7 @@ static int tc358743_s_edid(struct v4l2_subdev *sd, return -E2BIG; } pa = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL); - err = cec_phys_addr_validate(pa, &pa, NULL); + err = v4l2_phys_addr_validate(pa, &pa, NULL); if (err) return err; diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index f2c37e959bea..58e14dd1dcd3 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -1722,7 +1722,7 @@ int vidioc_s_edid(struct file *file, void *_fh, return -E2BIG; } phys_addr = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL); - ret = cec_phys_addr_validate(phys_addr, &phys_addr, NULL); + ret = v4l2_phys_addr_validate(phys_addr, &phys_addr, NULL); if (ret) return ret; @@ -1738,7 +1738,7 @@ set_phys_addr: for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) cec_s_phys_addr(dev->cec_tx_adap[i], - cec_phys_addr_for_input(phys_addr, i + 1), + v4l2_phys_addr_for_input(phys_addr, i + 1), false); return 0; } diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index be531caa2cdf..27a0000a5973 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -863,7 +863,7 @@ int vidioc_g_edid(struct file *file, void *_fh, if (edid->blocks > dev->edid_blocks - edid->start_block) edid->blocks = dev->edid_blocks - edid->start_block; if (adap) - cec_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); + v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128); return 0; } diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 8f52353b0881..b4e50c5509b7 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -15,6 +15,7 @@ #include #include #include +#include MODULE_AUTHOR("Hans Verkuil"); MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions"); @@ -981,3 +982,153 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi, return c; } EXPORT_SYMBOL_GPL(v4l2_hdmi_rx_colorimetry); + +/** + * v4l2_get_edid_phys_addr() - find and return the physical address + * + * @edid: pointer to the EDID data + * @size: size in bytes of the EDID data + * @offset: If not %NULL then the location of the physical address + * bytes in the EDID will be returned here. This is set to 0 + * if there is no physical address found. + * + * Return: the physical address or CEC_PHYS_ADDR_INVALID if there is none. + */ +u16 v4l2_get_edid_phys_addr(const u8 *edid, unsigned int size, + unsigned int *offset) +{ + unsigned int loc = cec_get_edid_spa_location(edid, size); + + if (offset) + *offset = loc; + if (loc == 0) + return CEC_PHYS_ADDR_INVALID; + return (edid[loc] << 8) | edid[loc + 1]; +} +EXPORT_SYMBOL_GPL(v4l2_get_edid_phys_addr); + +/** + * v4l2_set_edid_phys_addr() - find and set the physical address + * + * @edid: pointer to the EDID data + * @size: size in bytes of the EDID data + * @phys_addr: the new physical address + * + * This function finds the location of the physical address in the EDID + * and fills in the given physical address and updates the checksum + * at the end of the EDID block. It does nothing if the EDID doesn't + * contain a physical address. + */ +void v4l2_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr) +{ + unsigned int loc = cec_get_edid_spa_location(edid, size); + u8 sum = 0; + unsigned int i; + + if (loc == 0) + return; + edid[loc] = phys_addr >> 8; + edid[loc + 1] = phys_addr & 0xff; + loc &= ~0x7f; + + /* update the checksum */ + for (i = loc; i < loc + 127; i++) + sum += edid[i]; + edid[i] = 256 - sum; +} +EXPORT_SYMBOL_GPL(v4l2_set_edid_phys_addr); + +/** + * v4l2_phys_addr_for_input() - calculate the PA for an input + * + * @phys_addr: the physical address of the parent + * @input: the number of the input port, must be between 1 and 15 + * + * This function calculates a new physical address based on the input + * port number. For example: + * + * PA = 0.0.0.0 and input = 2 becomes 2.0.0.0 + * + * PA = 3.0.0.0 and input = 1 becomes 3.1.0.0 + * + * PA = 3.2.1.0 and input = 5 becomes 3.2.1.5 + * + * PA = 3.2.1.3 and input = 5 becomes f.f.f.f since it maxed out the depth. + * + * Return: the new physical address or CEC_PHYS_ADDR_INVALID. + */ +u16 v4l2_phys_addr_for_input(u16 phys_addr, u8 input) +{ + /* Check if input is sane */ + if (WARN_ON(input == 0 || input > 0xf)) + return CEC_PHYS_ADDR_INVALID; + + if (phys_addr == 0) + return input << 12; + + if ((phys_addr & 0x0fff) == 0) + return phys_addr | (input << 8); + + if ((phys_addr & 0x00ff) == 0) + return phys_addr | (input << 4); + + if ((phys_addr & 0x000f) == 0) + return phys_addr | input; + + /* + * All nibbles are used so no valid physical addresses can be assigned + * to the input. + */ + return CEC_PHYS_ADDR_INVALID; +} +EXPORT_SYMBOL_GPL(v4l2_phys_addr_for_input); + +/** + * v4l2_phys_addr_validate() - validate a physical address from an EDID + * + * @phys_addr: the physical address to validate + * @parent: if not %NULL, then this is filled with the parents PA. + * @port: if not %NULL, then this is filled with the input port. + * + * This validates a physical address as read from an EDID. If the + * PA is invalid (such as 1.0.1.0 since '0' is only allowed at the end), + * then it will return -EINVAL. + * + * The parent PA is passed into %parent and the input port is passed into + * %port. For example: + * + * PA = 0.0.0.0: has parent 0.0.0.0 and input port 0. + * + * PA = 1.0.0.0: has parent 0.0.0.0 and input port 1. + * + * PA = 3.2.0.0: has parent 3.0.0.0 and input port 2. + * + * PA = f.f.f.f: has parent f.f.f.f and input port 0. + * + * Return: 0 if the PA is valid, -EINVAL if not. + */ +int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port) +{ + int i; + + if (parent) + *parent = phys_addr; + if (port) + *port = 0; + if (phys_addr == CEC_PHYS_ADDR_INVALID) + return 0; + for (i = 0; i < 16; i += 4) + if (phys_addr & (0xf << i)) + break; + if (i == 16) + return 0; + if (parent) + *parent = phys_addr & (0xfff0 << i); + if (port) + *port = (phys_addr >> i) & 0xf; + for (i += 4; i < 16; i += 4) + if ((phys_addr & (0xf << i)) == 0) + return -EINVAL; + return 0; +} +EXPORT_SYMBOL_GPL(v4l2_phys_addr_validate); diff --git a/include/media/cec.h b/include/media/cec.h index 603f2fa08f62..9f382f0c2970 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -332,67 +332,6 @@ void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts); u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, unsigned int *offset); -/** - * cec_set_edid_phys_addr() - find and set the physical address - * - * @edid: pointer to the EDID data - * @size: size in bytes of the EDID data - * @phys_addr: the new physical address - * - * This function finds the location of the physical address in the EDID - * and fills in the given physical address and updates the checksum - * at the end of the EDID block. It does nothing if the EDID doesn't - * contain a physical address. - */ -void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr); - -/** - * cec_phys_addr_for_input() - calculate the PA for an input - * - * @phys_addr: the physical address of the parent - * @input: the number of the input port, must be between 1 and 15 - * - * This function calculates a new physical address based on the input - * port number. For example: - * - * PA = 0.0.0.0 and input = 2 becomes 2.0.0.0 - * - * PA = 3.0.0.0 and input = 1 becomes 3.1.0.0 - * - * PA = 3.2.1.0 and input = 5 becomes 3.2.1.5 - * - * PA = 3.2.1.3 and input = 5 becomes f.f.f.f since it maxed out the depth. - * - * Return: the new physical address or CEC_PHYS_ADDR_INVALID. - */ -u16 cec_phys_addr_for_input(u16 phys_addr, u8 input); - -/** - * cec_phys_addr_validate() - validate a physical address from an EDID - * - * @phys_addr: the physical address to validate - * @parent: if not %NULL, then this is filled with the parents PA. - * @port: if not %NULL, then this is filled with the input port. - * - * This validates a physical address as read from an EDID. If the - * PA is invalid (such as 1.0.1.0 since '0' is only allowed at the end), - * then it will return -EINVAL. - * - * The parent PA is passed into %parent and the input port is passed into - * %port. For example: - * - * PA = 0.0.0.0: has parent 0.0.0.0 and input port 0. - * - * PA = 1.0.0.0: has parent 0.0.0.0 and input port 1. - * - * PA = 3.2.0.0: has parent 3.0.0.0 and input port 2. - * - * PA = f.f.f.f: has parent f.f.f.f and input port 0. - * - * Return: 0 if the PA is valid, -EINVAL if not. - */ -int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port); - #else static inline int cec_register_adapter(struct cec_adapter *adap, @@ -427,25 +366,6 @@ static inline u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, return CEC_PHYS_ADDR_INVALID; } -static inline void cec_set_edid_phys_addr(u8 *edid, unsigned int size, - u16 phys_addr) -{ -} - -static inline u16 cec_phys_addr_for_input(u16 phys_addr, u8 input) -{ - return CEC_PHYS_ADDR_INVALID; -} - -static inline int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port) -{ - if (parent) - *parent = phys_addr; - if (port) - *port = 0; - return 0; -} - #endif /** diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h index fb355d9577a4..2cc0cabc124f 100644 --- a/include/media/v4l2-dv-timings.h +++ b/include/media/v4l2-dv-timings.h @@ -245,4 +245,10 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi, const struct hdmi_vendor_infoframe *hdmi, unsigned int height); +u16 v4l2_get_edid_phys_addr(const u8 *edid, unsigned int size, + unsigned int *offset); +void v4l2_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr); +u16 v4l2_phys_addr_for_input(u16 phys_addr, u8 input); +int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port); + #endif -- cgit v1.2.3 From ae5a8ca834f9dd0797a2ceb210e71d194431990c Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Wed, 12 Sep 2018 20:07:38 -0400 Subject: media: v4l2-common: fix typo in documentation for v4l_bound_align_image() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niklas Söderlund Acked-by: Sakari Ailus Reviewed-by: Simon Horman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/media') diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index bd880a909ecf..82715645617b 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -295,7 +295,7 @@ struct v4l2_priv_tun_config { * @height: pointer to height that will be adjusted if needed. * @hmin: minimum height. * @hmax: maximum height. - * @halign: least significant bit on width. + * @halign: least significant bit on height. * @salign: least significant bit for the image size (e. g. * :math:`width * height`). * -- cgit v1.2.3 From 183e19f5b9ee18fc7bc4b3983a91b5d0dd6c7871 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 21 Aug 2018 15:57:52 -0400 Subject: media: rc: Remove init_ir_raw_event and DEFINE_IR_RAW_EVENT macros This can be done with c99 initializers, which makes the code cleaner and more transparent. It does require gcc 4.6, because of this bug in earlier versions: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10676 Since commit cafa0010cd51 ("Raise the minimum required gcc version to 4.6"), this is the case. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/hid/hid-picolcd_cir.c | 3 +-- drivers/media/common/siano/smsir.c | 8 ++++---- drivers/media/i2c/cx25840/cx25840-ir.c | 6 ++---- drivers/media/pci/cx23885/cx23888-ir.c | 6 ++---- drivers/media/pci/cx88/cx88-input.c | 3 +-- drivers/media/rc/ene_ir.c | 12 ++++++------ drivers/media/rc/fintek-cir.c | 3 +-- drivers/media/rc/igorplugusb.c | 2 +- drivers/media/rc/iguanair.c | 4 +--- drivers/media/rc/imon_raw.c | 2 +- drivers/media/rc/ir-hix5hd2.c | 2 +- drivers/media/rc/ite-cir.c | 5 +---- drivers/media/rc/mceusb.c | 15 ++++++++------- drivers/media/rc/meson-ir.c | 2 +- drivers/media/rc/mtk-cir.c | 2 +- drivers/media/rc/nuvoton-cir.c | 2 +- drivers/media/rc/rc-core-priv.h | 7 ++++--- drivers/media/rc/rc-ir-raw.c | 12 ++++++------ drivers/media/rc/rc-loopback.c | 2 +- drivers/media/rc/redrat3.c | 10 +++++----- drivers/media/rc/serial_ir.c | 10 +++++----- drivers/media/rc/sir_ir.c | 2 +- drivers/media/rc/st_rc.c | 5 ++--- drivers/media/rc/streamzap.c | 12 ++++++------ drivers/media/rc/sunxi-cir.c | 2 +- drivers/media/rc/ttusbir.c | 4 +--- drivers/media/rc/winbond-cir.c | 12 ++++++------ drivers/media/usb/au0828/au0828-input.c | 5 +---- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 +--- include/media/rc-core.h | 11 +---------- 30 files changed, 74 insertions(+), 101 deletions(-) (limited to 'include/media') diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 32747b7f917e..bf6f29ca3315 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -45,7 +45,7 @@ int picolcd_raw_cir(struct picolcd_data *data, { unsigned long flags; int i, w, sz; - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; /* ignore if rc_dev is NULL or status is shunned */ spin_lock_irqsave(&data->lock, flags); @@ -67,7 +67,6 @@ int picolcd_raw_cir(struct picolcd_data *data, */ sz = size > 0 ? min((int)raw_data[0], size-1) : 0; for (i = 0; i+1 < sz; i += 2) { - init_ir_raw_event(&rawir); w = (raw_data[i] << 8) | (raw_data[i+1]); rawir.pulse = !!(w & 0x8000); rawir.duration = US_TO_NS(rawir.pulse ? (65536 - w) : w); diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index a1cfafba9b4c..79bd627f84b8 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -26,10 +26,10 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) const s32 *samples = (const void *)buf; for (i = 0; i < len >> 2; i++) { - DEFINE_IR_RAW_EVENT(ev); - - ev.duration = abs(samples[i]) * 1000; /* Convert to ns */ - ev.pulse = (samples[i] > 0) ? false : true; + struct ir_raw_event ev = { + .duration = abs(samples[i]) * 1000, /* Convert to ns */ + .pulse = (samples[i] > 0) ? false : true + }; ir_raw_event_store(coredev->ir.dev, &ev); } diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c index ad7f66c7aac8..69cdc09981af 100644 --- a/drivers/media/i2c/cx25840/cx25840-ir.c +++ b/drivers/media/i2c/cx25840/cx25840-ir.c @@ -701,10 +701,8 @@ static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, if (v > IR_MAX_DURATION) v = IR_MAX_DURATION; - init_ir_raw_event(&p->ir_core_data); - p->ir_core_data.pulse = u; - p->ir_core_data.duration = v; - p->ir_core_data.timeout = w; + p->ir_core_data = (struct ir_raw_event) + { .pulse = u, .duration = v, .timeout = w }; v4l2_dbg(2, ir_debug, sd, "rx read: %10u ns %s %s\n", v, u ? "mark" : "space", w ? "(timed out)" : ""); diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index 00329f668b59..1d775c90df51 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -696,10 +696,8 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, if (v > IR_MAX_DURATION) v = IR_MAX_DURATION; - init_ir_raw_event(&p->ir_core_data); - p->ir_core_data.pulse = u; - p->ir_core_data.duration = v; - p->ir_core_data.timeout = w; + p->ir_core_data = (struct ir_raw_event) + { .pulse = u, .duration = v, .timeout = w }; v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns %s %s\n", v, u ? "mark" : "space", w ? "(timed out)" : ""); diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index c5cee71d744d..ca76da04b476 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -535,7 +535,7 @@ void cx88_ir_irq(struct cx88_core *core) struct cx88_IR *ir = core->ir; u32 samples; unsigned int todo, bits; - struct ir_raw_event ev; + struct ir_raw_event ev = {}; if (!ir || !ir->sampling) return; @@ -550,7 +550,6 @@ void cx88_ir_irq(struct cx88_core *core) if (samples == 0xff && ir->dev->idle) return; - init_ir_raw_event(&ev); for (todo = 32; todo > 0; todo -= bits) { ev.pulse = samples & 0x80000000 ? false : true; bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples)); diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 71b8c9bbf6c4..dd2fd307ef85 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -326,8 +326,6 @@ static int ene_rx_get_sample_reg(struct ene_device *dev) /* Sense current received carrier */ static void ene_rx_sense_carrier(struct ene_device *dev) { - DEFINE_IR_RAW_EVENT(ev); - int carrier, duty_cycle; int period = ene_read_reg(dev, ENE_CIRCAR_PRD); int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD); @@ -348,9 +346,11 @@ static void ene_rx_sense_carrier(struct ene_device *dev) dbg("RX: sensed carrier = %d Hz, duty cycle %d%%", carrier, duty_cycle); if (dev->carrier_detect_enabled) { - ev.carrier_report = true; - ev.carrier = carrier; - ev.duty_cycle = duty_cycle; + struct ir_raw_event ev = { + .carrier_report = true, + .carrier = carrier, + .duty_cycle = duty_cycle + }; ir_raw_event_store(dev->rdev, &ev); } } @@ -733,7 +733,7 @@ static irqreturn_t ene_isr(int irq, void *data) unsigned long flags; irqreturn_t retval = IRQ_NONE; struct ene_device *dev = (struct ene_device *)data; - DEFINE_IR_RAW_EVENT(ev); + struct ir_raw_event ev = {}; spin_lock_irqsave(&dev->hw_lock, flags); diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index f2639d0c2fca..601944666b71 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -282,7 +282,7 @@ static int fintek_cmdsize(u8 cmd, u8 subcmd) /* process ir data stored in driver buffer */ static void fintek_process_rx_ir_data(struct fintek_dev *fintek) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; u8 sample; bool event = false; int i; @@ -314,7 +314,6 @@ static void fintek_process_rx_ir_data(struct fintek_dev *fintek) break; case PARSE_IRDATA: fintek->rem--; - init_ir_raw_event(&rawir); rawir.pulse = ((sample & BUF_PULSE_BIT) != 0); rawir.duration = US_TO_NS((sample & BUF_SAMPLE_MASK) * CIR_SAMPLE_PERIOD); diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index f563ddd7f739..ba3f95a97f14 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -56,7 +56,7 @@ static void igorplugusb_cmd(struct igorplugusb *ir, int cmd); static void igorplugusb_irdata(struct igorplugusb *ir, unsigned len) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; unsigned i, start, overflow; dev_dbg(ir->dev, "irdata: %*ph (len=%u)", len, ir->buf_in, len); diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index 7daac8bab83b..fbacb13b614b 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -129,12 +129,10 @@ static void process_ir_data(struct iguanair *ir, unsigned len) break; } } else if (len >= 7) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; unsigned i; bool event = false; - init_ir_raw_event(&rawir); - for (i = 0; i < 7; i++) { if (ir->buf_in[i] == 0x80) { rawir.pulse = false; diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c index 32709f96de14..7796098d9c30 100644 --- a/drivers/media/rc/imon_raw.c +++ b/drivers/media/rc/imon_raw.c @@ -28,7 +28,7 @@ static inline int is_bit_set(const u8 *buf, int bit) static void imon_ir_data(struct imon *imon) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; int offset = 0, size = 5 * 8; int bit; diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index 700ab4c563d0..abc4d6c1b323 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c @@ -175,7 +175,7 @@ static irqreturn_t hix5hd2_ir_rx_interrupt(int irq, void *data) } if ((irq_sr & INTMS_SYMBRCV) || (irq_sr & INTMS_TIMEOUT)) { - DEFINE_IR_RAW_EVENT(ev); + struct ir_raw_event ev = {}; symb_num = readl_relaxed(priv->base + IR_DATAH); for (i = 0; i < symb_num; i++) { diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index de77d22c30a7..cd3c60ba8519 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -173,7 +173,7 @@ static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int u32 sample_period; unsigned long *ldata; unsigned int next_one, next_zero, size; - DEFINE_IR_RAW_EVENT(ev); + struct ir_raw_event ev = {}; if (length == 0) return; @@ -1507,9 +1507,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id /* initialize spinlocks */ spin_lock_init(&itdev->lock); - /* initialize raw event */ - init_ir_raw_event(&itdev->rawir); - /* set driver data into the pnp device */ pnp_set_drvdata(pdev, itdev); itdev->pdev = pdev; diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 7f0fc3e12190..c9293696dc2d 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1078,7 +1078,7 @@ static int mceusb_set_rx_carrier_report(struct rc_dev *dev, int enable) */ static void mceusb_handle_command(struct mceusb_dev *ir, int index) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; u8 hi = ir->buf_in[index + 1] & 0xff; u8 lo = ir->buf_in[index + 2] & 0xff; u32 carrier_cycles; @@ -1152,7 +1152,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index) static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; bool event = false; int i = 0; @@ -1175,7 +1175,6 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) break; case PARSE_IRDATA: ir->rem--; - init_ir_raw_event(&rawir); rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK); if (unlikely(!rawir.duration)) { @@ -1215,11 +1214,13 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) if (ir->rem) { ir->parser_state = PARSE_IRDATA; } else { - init_ir_raw_event(&rawir); - rawir.timeout = 1; - rawir.duration = ir->rc->timeout; + struct ir_raw_event ev = { + .timeout = 1, + .duration = ir->rc->timeout + }; + if (ir_raw_event_store_with_filter(ir->rc, - &rawir)) + &ev)) event = true; ir->pulse_tunit = 0; ir->pulse_count = 0; diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index f449b35d25e7..9914c83fecb9 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c @@ -86,7 +86,7 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id) { struct meson_ir *ir = dev_id; u32 duration, status; - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; spin_lock(&ir->lock); diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c index e42efd9d382e..31b7bb431497 100644 --- a/drivers/media/rc/mtk-cir.c +++ b/drivers/media/rc/mtk-cir.c @@ -212,7 +212,7 @@ static irqreturn_t mtk_ir_irq(int irqno, void *dev_id) struct mtk_ir *ir = dev_id; u8 wid = 0; u32 i, j, val; - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; /* * Reset decoder state machine explicitly is required diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index b8299c9a9744..5c2cd8d2d155 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -737,7 +737,7 @@ static void nvt_dump_rx_buf(struct nvt_dev *nvt) */ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; u8 sample; int i; diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index e847bdad5c51..22b0ec853acc 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -181,9 +181,10 @@ static inline void init_ir_raw_event_duration(struct ir_raw_event *ev, unsigned int pulse, u32 duration) { - init_ir_raw_event(ev); - ev->duration = duration; - ev->pulse = pulse; + *ev = (struct ir_raw_event) { + .duration = duration, + .pulse = pulse + }; } /** diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index e7948908e78c..e10b4644a442 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store); int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse) { ktime_t now; - DEFINE_IR_RAW_EVENT(ev); + struct ir_raw_event ev = {}; if (!dev->raw) return -EINVAL; @@ -210,7 +210,7 @@ void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) if (idle) { dev->raw->this_ev.timeout = true; ir_raw_event_store(dev, &dev->raw->this_ev); - init_ir_raw_event(&dev->raw->this_ev); + dev->raw->this_ev = (struct ir_raw_event) {}; } if (dev->s_idle) @@ -562,10 +562,10 @@ static void ir_raw_edge_handle(struct timer_list *t) spin_lock_irqsave(&dev->raw->edge_spinlock, flags); interval = ktime_sub(ktime_get(), dev->raw->last_event); if (ktime_to_ns(interval) >= dev->timeout) { - DEFINE_IR_RAW_EVENT(ev); - - ev.timeout = true; - ev.duration = ktime_to_ns(interval); + struct ir_raw_event ev = { + .timeout = true, + .duration = ktime_to_ns(interval) + }; ir_raw_event_store(dev, &ev); } else { diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index 3822d9ebcb46..b9f9325b8db1 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -103,7 +103,7 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count) struct loopback_dev *lodev = dev->priv; u32 rxmask; unsigned i; - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; if (lodev->txcarrier < lodev->rxcarriermin || lodev->txcarrier > lodev->rxcarriermax) { diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 6bfc24885b5c..08c51ffd74a0 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -348,7 +348,7 @@ static u32 redrat3_us_to_len(u32 microsec) static void redrat3_process_ir_data(struct redrat3_dev *rr3) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; struct device *dev; unsigned int i, sig_size, single_len, offset, val; u32 mod_freq; @@ -358,10 +358,10 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) mod_freq = redrat3_val_to_mod_freq(&rr3->irdata); dev_dbg(dev, "Got mod_freq of %u\n", mod_freq); if (mod_freq && rr3->wideband) { - DEFINE_IR_RAW_EVENT(ev); - - ev.carrier_report = 1; - ev.carrier = mod_freq; + struct ir_raw_event ev = { + .carrier_report = 1, + .carrier = mod_freq + }; ir_raw_event_store(rr3->rc, &ev); } diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index 8bf5637b3a69..ffe2c672d105 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -273,7 +273,7 @@ static void frbwrite(unsigned int l, bool is_pulse) { /* simple noise filter */ static unsigned int ptr, pulse, space; - DEFINE_IR_RAW_EVENT(ev); + struct ir_raw_event ev = {}; if (ptr > 0 && is_pulse) { pulse += l; @@ -472,10 +472,10 @@ static int hardware_init_port(void) static void serial_ir_timeout(struct timer_list *unused) { - DEFINE_IR_RAW_EVENT(ev); - - ev.timeout = true; - ev.duration = serial_ir.rcdev->timeout; + struct ir_raw_event ev = { + .timeout = true, + .duration = serial_ir.rcdev->timeout + }; ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); ir_raw_event_handle(serial_ir.rcdev); } diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c index 9ee2c9196b4d..c8951650a368 100644 --- a/drivers/media/rc/sir_ir.c +++ b/drivers/media/rc/sir_ir.c @@ -96,7 +96,7 @@ static int sir_tx_ir(struct rc_dev *dev, unsigned int *tx_buf, static void add_read_queue(int flag, unsigned long val) { - DEFINE_IR_RAW_EVENT(ev); + struct ir_raw_event ev = {}; pr_debug("add flag %d with val %lu\n", flag, val); diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index c855b177103c..15de3ae166a2 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -67,8 +67,7 @@ struct st_rc_device { static void st_rc_send_lirc_timeout(struct rc_dev *rdev) { - DEFINE_IR_RAW_EVENT(ev); - ev.timeout = true; + struct ir_raw_event ev = { .timeout = true, .duration = rdev->timeout }; ir_raw_event_store(rdev, &ev); } @@ -101,7 +100,7 @@ static irqreturn_t st_rc_rx_interrupt(int irq, void *data) struct st_rc_device *dev = data; int last_symbol = 0; u32 status, int_status; - DEFINE_IR_RAW_EVENT(ev); + struct ir_raw_event ev = {}; if (dev->irq_wake) pm_wakeup_event(dev->dev, 0); diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index c3e183aabfbe..a490d26bd170 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -130,7 +130,7 @@ static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) static void sz_push_full_pulse(struct streamzap_ir *sz, unsigned char value) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; if (sz->idle) { int delta; @@ -175,7 +175,7 @@ static void sz_push_half_pulse(struct streamzap_ir *sz, static void sz_push_full_space(struct streamzap_ir *sz, unsigned char value) { - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; rawir.pulse = false; rawir.duration = ((int) value) * SZ_RESOLUTION; @@ -249,10 +249,10 @@ static void streamzap_callback(struct urb *urb) break; case FullSpace: if (sz->buf_in[i] == SZ_TIMEOUT) { - DEFINE_IR_RAW_EVENT(rawir); - - rawir.pulse = false; - rawir.duration = sz->rdev->timeout; + struct ir_raw_event rawir = { + .pulse = false, + .duration = sz->rdev->timeout + }; sz->idle = true; if (sz->timeout_enabled) sz_push(sz, rawir); diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index f500cea228a9..307e44714ea0 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c @@ -99,7 +99,7 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id) unsigned char dt; unsigned int cnt, rc; struct sunxi_ir *ir = dev_id; - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; spin_lock(&ir->ir_lock); diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c index aafea3c5170b..8d4b56d057ae 100644 --- a/drivers/media/rc/ttusbir.c +++ b/drivers/media/rc/ttusbir.c @@ -117,12 +117,10 @@ static void ttusbir_bulk_complete(struct urb *urb) */ static void ttusbir_process_ir_data(struct ttusbir *tt, uint8_t *buf) { - struct ir_raw_event rawir; + struct ir_raw_event rawir = {}; unsigned i, v, b; bool event = false; - init_ir_raw_event(&rawir); - for (i = 0; i < 128; i++) { v = buf[i] & 0xfe; switch (v) { diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 851acba9b436..0f07a2c384fa 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -322,11 +322,11 @@ wbcir_carrier_report(struct wbcir_data *data) inb(data->ebase + WBCIR_REG_ECEIR_CNT_HI) << 8; if (counter > 0 && counter < 0xffff) { - DEFINE_IR_RAW_EVENT(ev); - - ev.carrier_report = 1; - ev.carrier = DIV_ROUND_CLOSEST(counter * 1000000u, - data->pulse_duration); + struct ir_raw_event ev = { + .carrier_report = 1, + .carrier = DIV_ROUND_CLOSEST(counter * 1000000u, + data->pulse_duration) + }; ir_raw_event_store(data->dev, &ev); } @@ -362,7 +362,7 @@ static void wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device) { u8 irdata; - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; unsigned duration; /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 832ed9f25784..4befa920246c 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -113,7 +113,7 @@ static int au8522_rc_andor(struct au0828_rc *ir, u16 reg, u8 mask, u8 value) static int au0828_get_key_au8522(struct au0828_rc *ir) { unsigned char buf[40]; - DEFINE_IR_RAW_EVENT(rawir); + struct ir_raw_event rawir = {}; int i, j, rc; int prv_bit, bit, width; bool first = true; @@ -167,7 +167,6 @@ static int au0828_get_key_au8522(struct au0828_rc *ir) if (first) { first = false; - init_ir_raw_event(&rawir); rawir.pulse = true; if (width > NEC_START_SPACE - 2 && width < NEC_START_SPACE + 2) { @@ -186,7 +185,6 @@ static int au0828_get_key_au8522(struct au0828_rc *ir) ir_raw_event_store(ir->rc, &rawir); } - init_ir_raw_event(&rawir); rawir.pulse = prv_bit ? false : true; rawir.duration = AU8522_UNIT * width; dprintk(16, "Storing %s with duration %d", @@ -199,7 +197,6 @@ static int au0828_get_key_au8522(struct au0828_rc *ir) } } - init_ir_raw_event(&rawir); rawir.pulse = prv_bit ? false : true; rawir.duration = AU8522_UNIT * width; dprintk(16, "Storing end %s with duration %d", diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 33f76a347baa..8a83b10e50e0 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1685,7 +1685,7 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) { int ret, i, len; struct rtl28xxu_dev *dev = d->priv; - struct ir_raw_event ev; + struct ir_raw_event ev = {}; u8 buf[128]; static const struct rtl28xxu_reg_val_mask refresh_tab[] = { {IR_RX_IF, 0x03, 0xff}, @@ -1751,8 +1751,6 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) } /* pass data to Kernel IR decoder */ - init_ir_raw_event(&ev); - for (i = 0; i < len; i++) { ev.pulse = buf[i] >> 7; ev.duration = 50800 * (buf[i] & 0x7f); diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 61571773a98d..c0cfbe16a854 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -317,13 +317,6 @@ struct ir_raw_event { unsigned carrier_report:1; }; -#define DEFINE_IR_RAW_EVENT(event) struct ir_raw_event event = {} - -static inline void init_ir_raw_event(struct ir_raw_event *ev) -{ - memset(ev, 0, sizeof(*ev)); -} - #define IR_DEFAULT_TIMEOUT MS_TO_NS(125) #define IR_MAX_DURATION 500000000 /* 500 ms */ #define US_TO_NS(usec) ((usec) * 1000) @@ -344,9 +337,7 @@ int ir_raw_encode_carrier(enum rc_proto protocol); static inline void ir_raw_event_reset(struct rc_dev *dev) { - struct ir_raw_event ev = { .reset = true }; - - ir_raw_event_store(dev, &ev); + ir_raw_event_store(dev, &((struct ir_raw_event) { .reset = true })); dev->idle = true; ir_raw_event_handle(dev); } -- cgit v1.2.3 From b47d7ff1ae8d40eef92abbe718316c8a56558744 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Sat, 29 Sep 2018 15:54:06 -0400 Subject: media: v4l2: async: Add v4l2_async_notifier_add_subdev v4l2_async_notifier_add_subdev() adds an asd to the notifier. It checks that no other equivalent asd's have already been added to this notifier's asd list, or to other registered notifier's waiting or done lists, and increments num_subdevs. v4l2_async_notifier_add_subdev() does not make use of the notifier subdevs array, otherwise it would have to re-allocate the array every time the function was called. In place of the subdevs array, the function adds the newly allocated asd to a new master asd_list. The function will return error with a WARN() if it is ever called with the subdevs array allocated. Drivers are now required to call a v4l2_async_notifier_init(), before the first call to v4l2_async_notifier_add_subdev(), in order to initialize the asd_list. In v4l2_async_notifier_has_async_subdev(), __v4l2_async_notifier_register(), and v4l2_async_notifier_cleanup(), maintain backward compatibility with the subdevs array, by alternatively operate on the subdevs array or a non-empty notifier->asd_list. Signed-off-by: Steve Longerbeam Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-async.c | 191 +++++++++++++++++++++++++++-------- include/media/v4l2-async.h | 34 ++++++- 2 files changed, 182 insertions(+), 43 deletions(-) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index f09d354b96a0..7925875d09b7 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -365,16 +365,26 @@ v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier, struct v4l2_async_subdev *asd, unsigned int this_index) { + struct v4l2_async_subdev *asd_y; unsigned int j; lockdep_assert_held(&list_lock); /* Check that an asd is not being added more than once. */ - for (j = 0; j < this_index; j++) { - struct v4l2_async_subdev *asd_y = notifier->subdevs[j]; - - if (asd_equal(asd, asd_y)) - return true; + if (notifier->subdevs) { + for (j = 0; j < this_index; j++) { + asd_y = notifier->subdevs[j]; + if (asd_equal(asd, asd_y)) + return true; + } + } else { + j = 0; + list_for_each_entry(asd_y, ¬ifier->asd_list, asd_list) { + if (j++ >= this_index) + break; + if (asd_equal(asd, asd_y)) + return true; + } } /* Check that an asd does not exist in other notifiers. */ @@ -385,10 +395,48 @@ v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier, return false; } -static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) +static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier, + struct v4l2_async_subdev *asd, + unsigned int this_index) { struct device *dev = notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL; + + if (!asd) + return -EINVAL; + + switch (asd->match_type) { + case V4L2_ASYNC_MATCH_CUSTOM: + case V4L2_ASYNC_MATCH_DEVNAME: + case V4L2_ASYNC_MATCH_I2C: + case V4L2_ASYNC_MATCH_FWNODE: + if (v4l2_async_notifier_has_async_subdev(notifier, asd, + this_index)) { + dev_dbg(dev, "subdev descriptor already listed in this or other notifiers\n"); + return -EEXIST; + } + break; + default: + dev_err(dev, "Invalid match type %u on %p\n", + asd->match_type, asd); + return -EINVAL; + } + + return 0; +} + +void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier) +{ + mutex_lock(&list_lock); + + INIT_LIST_HEAD(¬ifier->asd_list); + + mutex_unlock(&list_lock); +} +EXPORT_SYMBOL(v4l2_async_notifier_init); + +static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) +{ struct v4l2_async_subdev *asd; int ret; int i; @@ -401,29 +449,25 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) mutex_lock(&list_lock); - for (i = 0; i < notifier->num_subdevs; i++) { - asd = notifier->subdevs[i]; + if (notifier->subdevs) { + for (i = 0; i < notifier->num_subdevs; i++) { + asd = notifier->subdevs[i]; - switch (asd->match_type) { - case V4L2_ASYNC_MATCH_CUSTOM: - case V4L2_ASYNC_MATCH_DEVNAME: - case V4L2_ASYNC_MATCH_I2C: - case V4L2_ASYNC_MATCH_FWNODE: - if (v4l2_async_notifier_has_async_subdev(notifier, - asd, i)) { - dev_err(dev, - "subdev descriptor already listed in this or other notifiers\n"); - ret = -EEXIST; + ret = v4l2_async_notifier_asd_valid(notifier, asd, i); + if (ret) goto err_unlock; - } - break; - default: - dev_err(dev, "Invalid match type %u on %p\n", - asd->match_type, asd); - ret = -EINVAL; - goto err_unlock; + + list_add_tail(&asd->list, ¬ifier->waiting); + } + } else { + i = 0; + list_for_each_entry(asd, ¬ifier->asd_list, asd_list) { + ret = v4l2_async_notifier_asd_valid(notifier, asd, i++); + if (ret) + goto err_unlock; + + list_add_tail(&asd->list, ¬ifier->waiting); } - list_add_tail(&asd->list, ¬ifier->waiting); } ret = v4l2_async_notifier_try_all_subdevs(notifier); @@ -513,36 +557,99 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) } EXPORT_SYMBOL(v4l2_async_notifier_unregister); -void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) +static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) { + struct v4l2_async_subdev *asd, *tmp; unsigned int i; - if (!notifier || !notifier->max_subdevs) + if (!notifier) return; - for (i = 0; i < notifier->num_subdevs; i++) { - struct v4l2_async_subdev *asd = notifier->subdevs[i]; + if (notifier->subdevs) { + if (!notifier->max_subdevs) + return; - switch (asd->match_type) { - case V4L2_ASYNC_MATCH_FWNODE: - fwnode_handle_put(asd->match.fwnode); - break; - default: - WARN_ON_ONCE(true); - break; + for (i = 0; i < notifier->num_subdevs; i++) { + asd = notifier->subdevs[i]; + + switch (asd->match_type) { + case V4L2_ASYNC_MATCH_FWNODE: + fwnode_handle_put(asd->match.fwnode); + break; + default: + break; + } + + kfree(asd); } - kfree(asd); + notifier->max_subdevs = 0; + kvfree(notifier->subdevs); + notifier->subdevs = NULL; + } else { + list_for_each_entry_safe(asd, tmp, + ¬ifier->asd_list, asd_list) { + switch (asd->match_type) { + case V4L2_ASYNC_MATCH_FWNODE: + fwnode_handle_put(asd->match.fwnode); + break; + default: + break; + } + + list_del(&asd->asd_list); + kfree(asd); + } } - notifier->max_subdevs = 0; notifier->num_subdevs = 0; +} + +void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) +{ + mutex_lock(&list_lock); + + __v4l2_async_notifier_cleanup(notifier); - kvfree(notifier->subdevs); - notifier->subdevs = NULL; + mutex_unlock(&list_lock); } EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup); +int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, + struct v4l2_async_subdev *asd) +{ + int ret; + + mutex_lock(&list_lock); + + if (notifier->num_subdevs >= V4L2_MAX_SUBDEVS) { + ret = -EINVAL; + goto unlock; + } + + /* + * If caller uses this function, it cannot also allocate and + * place asd's in the notifier->subdevs array. + */ + if (WARN_ON(notifier->subdevs)) { + ret = -EINVAL; + goto unlock; + } + + ret = v4l2_async_notifier_asd_valid(notifier, asd, + notifier->num_subdevs); + if (ret) + goto unlock; + + list_add_tail(&asd->asd_list, ¬ifier->asd_list); + notifier->num_subdevs++; + +unlock: + mutex_unlock(&list_lock); + return ret; +} +EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev); + int v4l2_async_register_subdev(struct v4l2_subdev *sd) { struct v4l2_async_notifier *subdev_notifier; @@ -616,7 +723,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) mutex_lock(&list_lock); __v4l2_async_notifier_unregister(sd->subdev_notifier); - v4l2_async_notifier_cleanup(sd->subdev_notifier); + __v4l2_async_notifier_cleanup(sd->subdev_notifier); kfree(sd->subdev_notifier); sd->subdev_notifier = NULL; diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 1592d323c577..ab4d7acb7960 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -73,6 +73,8 @@ enum v4l2_async_match_type { * @match.custom.priv: * Driver-specific private struct with match parameters * to be used if %V4L2_ASYNC_MATCH_CUSTOM. + * @asd_list: used to add struct v4l2_async_subdev objects to the + * master notifier @asd_list * @list: used to link struct v4l2_async_subdev objects, waiting to be * probed, to a notifier->waiting list * @@ -98,6 +100,7 @@ struct v4l2_async_subdev { /* v4l2-async core private: not to be used by drivers */ struct list_head list; + struct list_head asd_list; }; /** @@ -127,6 +130,7 @@ struct v4l2_async_notifier_operations { * @v4l2_dev: v4l2_device of the root notifier, NULL otherwise * @sd: sub-device that registered the notifier, NULL otherwise * @parent: parent notifier + * @asd_list: master list of struct v4l2_async_subdev, replaces @subdevs * @waiting: list of struct v4l2_async_subdev, waiting for their drivers * @done: list of struct v4l2_subdev, already probed * @list: member in a global list of notifiers @@ -139,11 +143,37 @@ struct v4l2_async_notifier { struct v4l2_device *v4l2_dev; struct v4l2_subdev *sd; struct v4l2_async_notifier *parent; + struct list_head asd_list; struct list_head waiting; struct list_head done; struct list_head list; }; +/** + * v4l2_async_notifier_init - Initialize a notifier. + * + * @notifier: pointer to &struct v4l2_async_notifier + * + * This function initializes the notifier @asd_list. It must be called + * before the first call to @v4l2_async_notifier_add_subdev. + */ +void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier); + +/** + * v4l2_async_notifier_add_subdev - Add an async subdev to the + * notifier's master asd list. + * + * @notifier: pointer to &struct v4l2_async_notifier + * @asd: pointer to &struct v4l2_async_subdev + * + * This can be used before registering a notifier to add an + * asd to the notifiers @asd_list. If the caller uses this + * method to compose an asd list, it must never allocate + * or place asd's in the @subdevs array. + */ +int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, + struct v4l2_async_subdev *asd); + /** * v4l2_async_notifier_register - registers a subdevice asynchronous notifier * @@ -177,7 +207,9 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); * Release memory resources related to a notifier, including the async * sub-devices allocated for the purposes of the notifier but not the notifier * itself. The user is responsible for calling this function to clean up the - * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints or + * notifier after calling + * @v4l2_async_notifier_add_subdev, + * @v4l2_async_notifier_parse_fwnode_endpoints or * @v4l2_fwnode_reference_parse_sensor_common. * * There is no harm from calling v4l2_async_notifier_cleanup in other -- cgit v1.2.3 From 23989b43f1079fdb90a621cc554a516b3a012981 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Sat, 29 Sep 2018 15:54:07 -0400 Subject: media: v4l2: async: Add convenience functions to allocate and add asd's Add these convenience functions, which allocate an asd of match type fwnode, i2c, or device-name, of size asd_struct_size, and then adds them to the notifier asd_list. Signed-off-by: Steve Longerbeam Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-async.c | 76 ++++++++++++++++++++++++++++++++++++ include/media/v4l2-async.h | 62 +++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 7925875d09b7..196573f4ec48 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -650,6 +650,82 @@ unlock: } EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev); +struct v4l2_async_subdev * +v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, + struct fwnode_handle *fwnode, + unsigned int asd_struct_size) +{ + struct v4l2_async_subdev *asd; + int ret; + + asd = kzalloc(asd_struct_size, GFP_KERNEL); + if (!asd) + return ERR_PTR(-ENOMEM); + + asd->match_type = V4L2_ASYNC_MATCH_FWNODE; + asd->match.fwnode = fwnode; + + ret = v4l2_async_notifier_add_subdev(notifier, asd); + if (ret) { + kfree(asd); + return ERR_PTR(ret); + } + + return asd; +} +EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_subdev); + +struct v4l2_async_subdev * +v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, + int adapter_id, unsigned short address, + unsigned int asd_struct_size) +{ + struct v4l2_async_subdev *asd; + int ret; + + asd = kzalloc(asd_struct_size, GFP_KERNEL); + if (!asd) + return ERR_PTR(-ENOMEM); + + asd->match_type = V4L2_ASYNC_MATCH_I2C; + asd->match.i2c.adapter_id = adapter_id; + asd->match.i2c.address = address; + + ret = v4l2_async_notifier_add_subdev(notifier, asd); + if (ret) { + kfree(asd); + return ERR_PTR(ret); + } + + return asd; +} +EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_i2c_subdev); + +struct v4l2_async_subdev * +v4l2_async_notifier_add_devname_subdev(struct v4l2_async_notifier *notifier, + const char *device_name, + unsigned int asd_struct_size) +{ + struct v4l2_async_subdev *asd; + int ret; + + asd = kzalloc(asd_struct_size, GFP_KERNEL); + if (!asd) + return ERR_PTR(-ENOMEM); + + asd->match_type = V4L2_ASYNC_MATCH_DEVNAME; + asd->match.device_name = device_name; + + ret = v4l2_async_notifier_add_subdev(notifier, asd); + if (ret) { + kfree(asd); + return ERR_PTR(ret); + } + + return asd; +} +EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_devname_subdev); + int v4l2_async_register_subdev(struct v4l2_subdev *sd) { struct v4l2_async_notifier *subdev_notifier; diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index ab4d7acb7960..3489e4ccb29b 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -174,6 +174,68 @@ void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier); int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, struct v4l2_async_subdev *asd); +/** + * v4l2_async_notifier_add_fwnode_subdev - Allocate and add a fwnode async + * subdev to the notifier's master asd_list. + * + * @notifier: pointer to &struct v4l2_async_notifier + * @fwnode: fwnode handle of the sub-device to be matched + * @asd_struct_size: size of the driver's async sub-device struct, including + * sizeof(struct v4l2_async_subdev). The &struct + * v4l2_async_subdev shall be the first member of + * the driver's async sub-device struct, i.e. both + * begin at the same memory address. + * + * This can be used before registering a notifier to add a + * fwnode-matched asd to the notifiers master asd_list. If the caller + * uses this method to compose an asd list, it must never allocate + * or place asd's in the @subdevs array. + */ +struct v4l2_async_subdev * +v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, + struct fwnode_handle *fwnode, + unsigned int asd_struct_size); + +/** + * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async + * subdev to the notifier's master asd_list. + * + * @notifier: pointer to &struct v4l2_async_notifier + * @adapter_id: I2C adapter ID to be matched + * @address: I2C address of sub-device to be matched + * @asd_struct_size: size of the driver's async sub-device struct, including + * sizeof(struct v4l2_async_subdev). The &struct + * v4l2_async_subdev shall be the first member of + * the driver's async sub-device struct, i.e. both + * begin at the same memory address. + * + * Same as above but for I2C matched sub-devices. + */ +struct v4l2_async_subdev * +v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, + int adapter_id, unsigned short address, + unsigned int asd_struct_size); + +/** + * v4l2_async_notifier_add_devname_subdev - Allocate and add a device-name + * async subdev to the notifier's master asd_list. + * + * @notifier: pointer to &struct v4l2_async_notifier + * @device_name: device name string to be matched + * @asd_struct_size: size of the driver's async sub-device struct, including + * sizeof(struct v4l2_async_subdev). The &struct + * v4l2_async_subdev shall be the first member of + * the driver's async sub-device struct, i.e. both + * begin at the same memory address. + * + * Same as above but for device-name matched sub-devices. + */ +struct v4l2_async_subdev * +v4l2_async_notifier_add_devname_subdev(struct v4l2_async_notifier *notifier, + const char *device_name, + unsigned int asd_struct_size); + + /** * v4l2_async_notifier_register - registers a subdevice asynchronous notifier * -- cgit v1.2.3 From eae2aed1eab9bf08146403ac702517d2e4fe932e Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Sat, 29 Sep 2018 15:54:08 -0400 Subject: media: v4l2-fwnode: Switch to v4l2_async_notifier_add_subdev The fwnode endpoint and reference parsing functions in v4l2-fwnode.c are modified to make use of v4l2_async_notifier_add_subdev(). As a result the notifier->subdevs array is no longer allocated or re-allocated, and by extension the max_subdevs value is also no longer needed. Callers of the fwnode endpoint and reference parsing functions must now first initialize the notifier with a call to v4l2_async_notifier_init(). This includes the function v4l2_async_register_subdev_sensor_common(), and the intel-ipu3, omap3isp, and rcar-vin drivers. Since the notifier->subdevs array is no longer allocated in the fwnode endpoint and reference parsing functions, the callers of those functions must never reference that array, since it is now NULL. Of the drivers that make use of the fwnode/ref parsing, only the intel-ipu3 driver references the ->subdevs[] array, (in the notifier completion callback), so that driver has been modified to iterate through the notifier->asd_list instead. Signed-off-by: Steve Longerbeam Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 12 +-- drivers/media/platform/omap3isp/isp.c | 1 + drivers/media/platform/rcar-vin/rcar-core.c | 4 + drivers/media/v4l2-core/v4l2-async.c | 4 - drivers/media/v4l2-core/v4l2-fwnode.c | 132 ++++++---------------------- include/media/v4l2-async.h | 2 - include/media/v4l2-fwnode.h | 22 ++--- 7 files changed, 52 insertions(+), 125 deletions(-) (limited to 'include/media') diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index 08cf4bf00941..d7926c31388f 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -1433,13 +1433,13 @@ static int cio2_notifier_complete(struct v4l2_async_notifier *notifier) struct cio2_device *cio2 = container_of(notifier, struct cio2_device, notifier); struct sensor_async_subdev *s_asd; + struct v4l2_async_subdev *asd; struct cio2_queue *q; - unsigned int i, pad; + unsigned int pad; int ret; - for (i = 0; i < notifier->num_subdevs; i++) { - s_asd = container_of(cio2->notifier.subdevs[i], - struct sensor_async_subdev, asd); + list_for_each_entry(asd, &cio2->notifier.asd_list, asd_list) { + s_asd = container_of(asd, struct sensor_async_subdev, asd); q = &cio2->queue[s_asd->csi2.port]; for (pad = 0; pad < q->sensor->entity.num_pads; pad++) @@ -1461,7 +1461,7 @@ static int cio2_notifier_complete(struct v4l2_async_notifier *notifier) if (ret) { dev_err(&cio2->pci_dev->dev, "failed to create link for %s\n", - cio2->queue[i].sensor->name); + q->sensor->name); return ret; } } @@ -1497,6 +1497,8 @@ static int cio2_notifier_init(struct cio2_device *cio2) { int ret; + v4l2_async_notifier_init(&cio2->notifier); + ret = v4l2_async_notifier_parse_fwnode_endpoints( &cio2->pci_dev->dev, &cio2->notifier, sizeof(struct sensor_async_subdev), diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 93f032a39470..f5dde8774399 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2220,6 +2220,7 @@ static int isp_probe(struct platform_device *pdev) mutex_init(&isp->isp_mutex); spin_lock_init(&isp->stat_lock); + v4l2_async_notifier_init(&isp->notifier); ret = v4l2_async_notifier_parse_fwnode_endpoints( &pdev->dev, &isp->notifier, sizeof(struct isp_async_subdev), diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 01e418c2d4c6..9071b88fa2de 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -610,6 +610,8 @@ static int rvin_parallel_init(struct rvin_dev *vin) { int ret; + v4l2_async_notifier_init(&vin->notifier); + ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port( vin->dev, &vin->notifier, sizeof(struct rvin_parallel_entity), 0, rvin_parallel_parse_v4l2); @@ -802,6 +804,8 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin) return 0; } + v4l2_async_notifier_init(&vin->group->notifier); + /* * Have all VIN's look for CSI-2 subdevices. Some subdevices will * overlap but the parser function can handle it, so each subdevice diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 196573f4ec48..b0eb31efcbfe 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -566,9 +566,6 @@ static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) return; if (notifier->subdevs) { - if (!notifier->max_subdevs) - return; - for (i = 0; i < notifier->num_subdevs; i++) { asd = notifier->subdevs[i]; @@ -583,7 +580,6 @@ static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) kfree(asd); } - notifier->max_subdevs = 0; kvfree(notifier->subdevs); notifier->subdevs = NULL; } else { diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 0b8c736b1606..88383d3d5974 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -320,33 +320,6 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link) } EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link); -static int v4l2_async_notifier_realloc(struct v4l2_async_notifier *notifier, - unsigned int max_subdevs) -{ - struct v4l2_async_subdev **subdevs; - - if (max_subdevs <= notifier->max_subdevs) - return 0; - - subdevs = kvmalloc_array( - max_subdevs, sizeof(*notifier->subdevs), - GFP_KERNEL | __GFP_ZERO); - if (!subdevs) - return -ENOMEM; - - if (notifier->subdevs) { - memcpy(subdevs, notifier->subdevs, - sizeof(*subdevs) * notifier->num_subdevs); - - kvfree(notifier->subdevs); - } - - notifier->subdevs = subdevs; - notifier->max_subdevs = max_subdevs; - - return 0; -} - static int v4l2_async_notifier_fwnode_parse_endpoint( struct device *dev, struct v4l2_async_notifier *notifier, struct fwnode_handle *endpoint, unsigned int asd_struct_size, @@ -391,8 +364,13 @@ static int v4l2_async_notifier_fwnode_parse_endpoint( if (ret < 0) goto out_err; - notifier->subdevs[notifier->num_subdevs] = asd; - notifier->num_subdevs++; + ret = v4l2_async_notifier_add_subdev(notifier, asd); + if (ret < 0) { + /* not an error if asd already exists */ + if (ret == -EEXIST) + ret = 0; + goto out_err; + } return 0; @@ -411,46 +389,11 @@ static int __v4l2_async_notifier_parse_fwnode_endpoints( struct v4l2_async_subdev *asd)) { struct fwnode_handle *fwnode; - unsigned int max_subdevs = notifier->max_subdevs; - int ret; + int ret = 0; if (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev))) return -EINVAL; - for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint( - dev_fwnode(dev), fwnode)); ) { - struct fwnode_handle *dev_fwnode; - bool is_available; - - dev_fwnode = fwnode_graph_get_port_parent(fwnode); - is_available = fwnode_device_is_available(dev_fwnode); - fwnode_handle_put(dev_fwnode); - if (!is_available) - continue; - - if (has_port) { - struct fwnode_endpoint ep; - - ret = fwnode_graph_parse_endpoint(fwnode, &ep); - if (ret) { - fwnode_handle_put(fwnode); - return ret; - } - - if (ep.port != port) - continue; - } - max_subdevs++; - } - - /* No subdevs to add? Return here. */ - if (max_subdevs == notifier->max_subdevs) - return 0; - - ret = v4l2_async_notifier_realloc(notifier, max_subdevs); - if (ret) - return ret; - for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint( dev_fwnode(dev), fwnode)); ) { struct fwnode_handle *dev_fwnode; @@ -473,11 +416,6 @@ static int __v4l2_async_notifier_parse_fwnode_endpoints( continue; } - if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) { - ret = -EINVAL; - break; - } - ret = v4l2_async_notifier_fwnode_parse_endpoint( dev, notifier, fwnode, asd_struct_size, parse_endpoint); if (ret < 0) @@ -548,31 +486,23 @@ static int v4l2_fwnode_reference_parse( if (ret != -ENOENT && ret != -ENODATA) return ret; - ret = v4l2_async_notifier_realloc(notifier, - notifier->num_subdevs + index); - if (ret) - return ret; - for (index = 0; !fwnode_property_get_reference_args( dev_fwnode(dev), prop, NULL, 0, index, &args); index++) { struct v4l2_async_subdev *asd; - if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) { - ret = -EINVAL; - goto error; - } + asd = v4l2_async_notifier_add_fwnode_subdev( + notifier, args.fwnode, sizeof(*asd)); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + /* not an error if asd already exists */ + if (ret == -EEXIST) { + fwnode_handle_put(args.fwnode); + continue; + } - asd = kzalloc(sizeof(*asd), GFP_KERNEL); - if (!asd) { - ret = -ENOMEM; goto error; } - - notifier->subdevs[notifier->num_subdevs] = asd; - asd->match.fwnode = args.fwnode; - asd->match_type = V4L2_ASYNC_MATCH_FWNODE; - notifier->num_subdevs++; } return 0; @@ -843,31 +773,23 @@ static int v4l2_fwnode_reference_parse_int_props( index++; } while (1); - ret = v4l2_async_notifier_realloc(notifier, - notifier->num_subdevs + index); - if (ret) - return -ENOMEM; - for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop( dev_fwnode(dev), prop, index, props, nprops))); index++) { struct v4l2_async_subdev *asd; - if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) { - ret = -EINVAL; - goto error; - } + asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, + sizeof(*asd)); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + /* not an error if asd already exists */ + if (ret == -EEXIST) { + fwnode_handle_put(fwnode); + continue; + } - asd = kzalloc(sizeof(struct v4l2_async_subdev), GFP_KERNEL); - if (!asd) { - ret = -ENOMEM; goto error; } - - notifier->subdevs[notifier->num_subdevs] = asd; - asd->match.fwnode = fwnode; - asd->match_type = V4L2_ASYNC_MATCH_FWNODE; - notifier->num_subdevs++; } return PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode); @@ -924,6 +846,8 @@ int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd) if (!notifier) return -ENOMEM; + v4l2_async_notifier_init(notifier); + ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev, notifier); if (ret < 0) diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 3489e4ccb29b..16b1e2b097c1 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -125,7 +125,6 @@ struct v4l2_async_notifier_operations { * * @ops: notifier operations * @num_subdevs: number of subdevices used in the subdevs array - * @max_subdevs: number of subdevices allocated in the subdevs array * @subdevs: array of pointers to subdevice descriptors * @v4l2_dev: v4l2_device of the root notifier, NULL otherwise * @sd: sub-device that registered the notifier, NULL otherwise @@ -138,7 +137,6 @@ struct v4l2_async_notifier_operations { struct v4l2_async_notifier { const struct v4l2_async_notifier_operations *ops; unsigned int num_subdevs; - unsigned int max_subdevs; struct v4l2_async_subdev **subdevs; struct v4l2_device *v4l2_dev; struct v4l2_subdev *sd; diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 9cccab618b98..ea7a8b247e19 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -247,7 +247,7 @@ typedef int (*parse_endpoint_func)(struct device *dev, * endpoint. Optional. * * Parse the fwnode endpoints of the @dev device and populate the async sub- - * devices array of the notifier. The @parse_endpoint callback function is + * devices list in the notifier. The @parse_endpoint callback function is * called for each endpoint with the corresponding async sub-device pointer to * let the caller initialize the driver-specific part of the async sub-device * structure. @@ -258,10 +258,11 @@ typedef int (*parse_endpoint_func)(struct device *dev, * This function may not be called on a registered notifier and may be called on * a notifier only once. * - * Do not change the notifier's subdevs array, take references to the subdevs - * array itself or change the notifier's num_subdevs field. This is because this - * function allocates and reallocates the subdevs array based on parsing - * endpoints. + * Do not allocate the notifier's subdevs array, or change the notifier's + * num_subdevs field. This is because this function uses + * @v4l2_async_notifier_add_subdev to populate the notifier's asd_list, + * which is in-place-of the subdevs array which must remain unallocated + * and unused. * * The &struct v4l2_fwnode_endpoint passed to the callback function * @parse_endpoint is released once the function is finished. If there is a need @@ -303,7 +304,7 @@ int v4l2_async_notifier_parse_fwnode_endpoints( * devices). In this case the driver must know which ports to parse. * * Parse the fwnode endpoints of the @dev device on a given @port and populate - * the async sub-devices array of the notifier. The @parse_endpoint callback + * the async sub-devices list of the notifier. The @parse_endpoint callback * function is called for each endpoint with the corresponding async sub-device * pointer to let the caller initialize the driver-specific part of the async * sub-device structure. @@ -314,10 +315,11 @@ int v4l2_async_notifier_parse_fwnode_endpoints( * This function may not be called on a registered notifier and may be called on * a notifier only once per port. * - * Do not change the notifier's subdevs array, take references to the subdevs - * array itself or change the notifier's num_subdevs field. This is because this - * function allocates and reallocates the subdevs array based on parsing - * endpoints. + * Do not allocate the notifier's subdevs array, or change the notifier's + * num_subdevs field. This is because this function uses + * @v4l2_async_notifier_add_subdev to populate the notifier's asd_list, + * which is in-place-of the subdevs array which must remain unallocated + * and unused. * * The &struct v4l2_fwnode_endpoint passed to the callback function * @parse_endpoint is released once the function is finished. If there is a need -- cgit v1.2.3 From 1634f0eded87d1f150e823fa56cd782ea0775eb2 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Sat, 29 Sep 2018 15:54:09 -0400 Subject: media: v4l2-fwnode: Add a convenience function for registering subdevs with notifiers Adds v4l2_async_register_fwnode_subdev(), which is a convenience function for parsing a sub-device's fwnode port endpoints for connected remote sub-devices, registering a sub-device notifier, and then registering the sub-device itself. Signed-off-by: Steve Longerbeam Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 64 +++++++++++++++++++++++++++++++++++ include/media/v4l2-fwnode.h | 38 +++++++++++++++++++++ 2 files changed, 102 insertions(+) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 88383d3d5974..be75d9900667 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -876,6 +876,70 @@ out_cleanup: } EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common); +int v4l2_async_register_fwnode_subdev( + struct v4l2_subdev *sd, size_t asd_struct_size, + unsigned int *ports, unsigned int num_ports, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) +{ + struct v4l2_async_notifier *notifier; + struct device *dev = sd->dev; + struct fwnode_handle *fwnode; + int ret; + + if (WARN_ON(!dev)) + return -ENODEV; + + fwnode = dev_fwnode(dev); + if (!fwnode_device_is_available(fwnode)) + return -ENODEV; + + notifier = kzalloc(sizeof(*notifier), GFP_KERNEL); + if (!notifier) + return -ENOMEM; + + v4l2_async_notifier_init(notifier); + + if (!ports) { + ret = v4l2_async_notifier_parse_fwnode_endpoints( + dev, notifier, asd_struct_size, parse_endpoint); + if (ret < 0) + goto out_cleanup; + } else { + unsigned int i; + + for (i = 0; i < num_ports; i++) { + ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port( + dev, notifier, asd_struct_size, + ports[i], parse_endpoint); + if (ret < 0) + goto out_cleanup; + } + } + + ret = v4l2_async_subdev_notifier_register(sd, notifier); + if (ret < 0) + goto out_cleanup; + + ret = v4l2_async_register_subdev(sd); + if (ret < 0) + goto out_unregister; + + sd->subdev_notifier = notifier; + + return 0; + +out_unregister: + v4l2_async_notifier_unregister(notifier); +out_cleanup: + v4l2_async_notifier_cleanup(notifier); + kfree(notifier); + + return ret; +} +EXPORT_SYMBOL_GPL(v4l2_async_register_fwnode_subdev); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Sakari Ailus "); MODULE_AUTHOR("Sylwester Nawrocki "); diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index ea7a8b247e19..031ebb069dcb 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -23,6 +23,7 @@ #include #include +#include struct fwnode_handle; struct v4l2_async_notifier; @@ -360,4 +361,41 @@ int v4l2_async_notifier_parse_fwnode_endpoints_by_port( int v4l2_async_notifier_parse_fwnode_sensor_common( struct device *dev, struct v4l2_async_notifier *notifier); +/** + * v4l2_async_register_fwnode_subdev - registers a sub-device to the + * asynchronous sub-device framework + * and parses fwnode endpoints + * + * @sd: pointer to struct &v4l2_subdev + * @asd_struct_size: size of the driver's async sub-device struct, including + * sizeof(struct v4l2_async_subdev). The &struct + * v4l2_async_subdev shall be the first member of + * the driver's async sub-device struct, i.e. both + * begin at the same memory address. + * @ports: array of port id's to parse for fwnode endpoints. If NULL, will + * parse all ports owned by the sub-device. + * @num_ports: number of ports in @ports array. Ignored if @ports is NULL. + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode + * endpoint. Optional. + * + * This function is just like v4l2_async_register_subdev() with the + * exception that calling it will also allocate a notifier for the + * sub-device, parse the sub-device's firmware node endpoints using + * v4l2_async_notifier_parse_fwnode_endpoints() or + * v4l2_async_notifier_parse_fwnode_endpoints_by_port(), and + * registers the sub-device notifier. The sub-device is similarly + * unregistered by calling v4l2_async_unregister_subdev(). + * + * While registered, the subdev module is marked as in-use. + * + * An error is returned if the module is no longer loaded on any attempts + * to register it. + */ +int v4l2_async_register_fwnode_subdev( + struct v4l2_subdev *sd, size_t asd_struct_size, + unsigned int *ports, unsigned int num_ports, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)); + #endif /* _V4L2_FWNODE_H */ -- cgit v1.2.3 From 66beb323e4a0cef0e1ee1277b609e3e242490bf1 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Sat, 29 Sep 2018 15:54:19 -0400 Subject: media: v4l2: async: Remove notifier subdevs array All platform drivers have been converted to use v4l2_async_notifier_add_subdev(), in place of adding asd's to the notifier subdevs array. So the subdevs array can now be removed from struct v4l2_async_notifier, and remove the backward compatibility support for that array in v4l2-async.c. Signed-off-by: Steve Longerbeam Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-async.c | 114 ++++++++--------------------------- include/media/v4l2-async.h | 21 ++----- include/media/v4l2-fwnode.h | 12 ---- 3 files changed, 30 insertions(+), 117 deletions(-) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index b0eb31efcbfe..70adbd9a01a2 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -359,32 +359,24 @@ __v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier, /* * Find out whether an async sub-device was set up already or * whether it exists in a given notifier before @this_index. + * If @this_index < 0, search the notifier's entire @asd_list. */ static bool v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier, struct v4l2_async_subdev *asd, - unsigned int this_index) + int this_index) { struct v4l2_async_subdev *asd_y; - unsigned int j; + int j = 0; lockdep_assert_held(&list_lock); /* Check that an asd is not being added more than once. */ - if (notifier->subdevs) { - for (j = 0; j < this_index; j++) { - asd_y = notifier->subdevs[j]; - if (asd_equal(asd, asd_y)) - return true; - } - } else { - j = 0; - list_for_each_entry(asd_y, ¬ifier->asd_list, asd_list) { - if (j++ >= this_index) - break; - if (asd_equal(asd, asd_y)) - return true; - } + list_for_each_entry(asd_y, ¬ifier->asd_list, asd_list) { + if (this_index >= 0 && j++ >= this_index) + break; + if (asd_equal(asd, asd_y)) + return true; } /* Check that an asd does not exist in other notifiers. */ @@ -397,7 +389,7 @@ v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier, static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier, struct v4l2_async_subdev *asd, - unsigned int this_index) + int this_index) { struct device *dev = notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL; @@ -438,36 +430,19 @@ EXPORT_SYMBOL(v4l2_async_notifier_init); static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) { struct v4l2_async_subdev *asd; - int ret; - int i; - - if (notifier->num_subdevs > V4L2_MAX_SUBDEVS) - return -EINVAL; + int ret, i = 0; INIT_LIST_HEAD(¬ifier->waiting); INIT_LIST_HEAD(¬ifier->done); mutex_lock(&list_lock); - if (notifier->subdevs) { - for (i = 0; i < notifier->num_subdevs; i++) { - asd = notifier->subdevs[i]; - - ret = v4l2_async_notifier_asd_valid(notifier, asd, i); - if (ret) - goto err_unlock; + list_for_each_entry(asd, ¬ifier->asd_list, asd_list) { + ret = v4l2_async_notifier_asd_valid(notifier, asd, i++); + if (ret) + goto err_unlock; - list_add_tail(&asd->list, ¬ifier->waiting); - } - } else { - i = 0; - list_for_each_entry(asd, ¬ifier->asd_list, asd_list) { - ret = v4l2_async_notifier_asd_valid(notifier, asd, i++); - if (ret) - goto err_unlock; - - list_add_tail(&asd->list, ¬ifier->waiting); - } + list_add_tail(&asd->list, ¬ifier->waiting); } ret = v4l2_async_notifier_try_all_subdevs(notifier); @@ -560,45 +535,22 @@ EXPORT_SYMBOL(v4l2_async_notifier_unregister); static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) { struct v4l2_async_subdev *asd, *tmp; - unsigned int i; if (!notifier) return; - if (notifier->subdevs) { - for (i = 0; i < notifier->num_subdevs; i++) { - asd = notifier->subdevs[i]; - - switch (asd->match_type) { - case V4L2_ASYNC_MATCH_FWNODE: - fwnode_handle_put(asd->match.fwnode); - break; - default: - break; - } - - kfree(asd); + list_for_each_entry_safe(asd, tmp, ¬ifier->asd_list, asd_list) { + switch (asd->match_type) { + case V4L2_ASYNC_MATCH_FWNODE: + fwnode_handle_put(asd->match.fwnode); + break; + default: + break; } - kvfree(notifier->subdevs); - notifier->subdevs = NULL; - } else { - list_for_each_entry_safe(asd, tmp, - ¬ifier->asd_list, asd_list) { - switch (asd->match_type) { - case V4L2_ASYNC_MATCH_FWNODE: - fwnode_handle_put(asd->match.fwnode); - break; - default: - break; - } - - list_del(&asd->asd_list); - kfree(asd); - } + list_del(&asd->asd_list); + kfree(asd); } - - notifier->num_subdevs = 0; } void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) @@ -618,27 +570,11 @@ int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, mutex_lock(&list_lock); - if (notifier->num_subdevs >= V4L2_MAX_SUBDEVS) { - ret = -EINVAL; - goto unlock; - } - - /* - * If caller uses this function, it cannot also allocate and - * place asd's in the notifier->subdevs array. - */ - if (WARN_ON(notifier->subdevs)) { - ret = -EINVAL; - goto unlock; - } - - ret = v4l2_async_notifier_asd_valid(notifier, asd, - notifier->num_subdevs); + ret = v4l2_async_notifier_asd_valid(notifier, asd, -1); if (ret) goto unlock; list_add_tail(&asd->asd_list, ¬ifier->asd_list); - notifier->num_subdevs++; unlock: mutex_unlock(&list_lock); diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 16b1e2b097c1..89b152f52ef9 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -20,9 +20,6 @@ struct v4l2_device; struct v4l2_subdev; struct v4l2_async_notifier; -/* A random max subdevice number, used to allocate an array on stack */ -#define V4L2_MAX_SUBDEVS 128U - /** * enum v4l2_async_match_type - type of asynchronous subdevice logic to be used * in order to identify a match @@ -124,20 +121,16 @@ struct v4l2_async_notifier_operations { * struct v4l2_async_notifier - v4l2_device notifier data * * @ops: notifier operations - * @num_subdevs: number of subdevices used in the subdevs array - * @subdevs: array of pointers to subdevice descriptors * @v4l2_dev: v4l2_device of the root notifier, NULL otherwise * @sd: sub-device that registered the notifier, NULL otherwise * @parent: parent notifier - * @asd_list: master list of struct v4l2_async_subdev, replaces @subdevs + * @asd_list: master list of struct v4l2_async_subdev * @waiting: list of struct v4l2_async_subdev, waiting for their drivers * @done: list of struct v4l2_subdev, already probed * @list: member in a global list of notifiers */ struct v4l2_async_notifier { const struct v4l2_async_notifier_operations *ops; - unsigned int num_subdevs; - struct v4l2_async_subdev **subdevs; struct v4l2_device *v4l2_dev; struct v4l2_subdev *sd; struct v4l2_async_notifier *parent; @@ -164,10 +157,8 @@ void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier); * @notifier: pointer to &struct v4l2_async_notifier * @asd: pointer to &struct v4l2_async_subdev * - * This can be used before registering a notifier to add an - * asd to the notifiers @asd_list. If the caller uses this - * method to compose an asd list, it must never allocate - * or place asd's in the @subdevs array. + * Call this function before registering a notifier to link the + * provided asd to the notifiers master @asd_list. */ int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, struct v4l2_async_subdev *asd); @@ -184,10 +175,8 @@ int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, * the driver's async sub-device struct, i.e. both * begin at the same memory address. * - * This can be used before registering a notifier to add a - * fwnode-matched asd to the notifiers master asd_list. If the caller - * uses this method to compose an asd list, it must never allocate - * or place asd's in the @subdevs array. + * Allocate a fwnode-matched asd of size asd_struct_size, and add it + * to the notifiers @asd_list. */ struct v4l2_async_subdev * v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 031ebb069dcb..8b4873c37098 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -259,12 +259,6 @@ typedef int (*parse_endpoint_func)(struct device *dev, * This function may not be called on a registered notifier and may be called on * a notifier only once. * - * Do not allocate the notifier's subdevs array, or change the notifier's - * num_subdevs field. This is because this function uses - * @v4l2_async_notifier_add_subdev to populate the notifier's asd_list, - * which is in-place-of the subdevs array which must remain unallocated - * and unused. - * * The &struct v4l2_fwnode_endpoint passed to the callback function * @parse_endpoint is released once the function is finished. If there is a need * to retain that configuration, the user needs to allocate memory for it. @@ -316,12 +310,6 @@ int v4l2_async_notifier_parse_fwnode_endpoints( * This function may not be called on a registered notifier and may be called on * a notifier only once per port. * - * Do not allocate the notifier's subdevs array, or change the notifier's - * num_subdevs field. This is because this function uses - * @v4l2_async_notifier_add_subdev to populate the notifier's asd_list, - * which is in-place-of the subdevs array which must remain unallocated - * and unused. - * * The &struct v4l2_fwnode_endpoint passed to the callback function * @parse_endpoint is released once the function is finished. If there is a need * to retain that configuration, the user needs to allocate memory for it. -- cgit v1.2.3 From 2d95e7ed07ed29715a801a3d33b2ad2a6fb26ee3 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 3 Jul 2018 17:19:27 -0400 Subject: media: v4l: mediabus: Recognise CSI-2 D-PHY and C-PHY The CSI-2 bus may use either D-PHY or C-PHY. Make this visible in media bus enum. Signed-off-by: Sakari Ailus Tested-by: Steve Longerbeam Tested-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- drivers/gpu/ipu-v3/ipu-csi.c | 6 +++--- drivers/media/i2c/adv7180.c | 2 +- drivers/media/i2c/ov5640.c | 6 +++--- drivers/media/i2c/ov5645.c | 2 +- drivers/media/i2c/ov7251.c | 4 ++-- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +- drivers/media/i2c/s5k5baf.c | 4 ++-- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 2 +- drivers/media/i2c/soc_camera/ov5642.c | 2 +- drivers/media/i2c/tc358743.c | 4 ++-- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 2 +- drivers/media/platform/cadence/cdns-csi2rx.c | 2 +- drivers/media/platform/cadence/cdns-csi2tx.c | 2 +- drivers/media/platform/marvell-ccic/mcam-core.c | 4 ++-- drivers/media/platform/marvell-ccic/mmp-driver.c | 2 +- drivers/media/platform/omap3isp/isp.c | 2 +- drivers/media/platform/pxa_camera.c | 2 +- drivers/media/platform/rcar-vin/rcar-csi2.c | 2 +- drivers/media/platform/soc_camera/soc_mediabus.c | 2 +- drivers/media/platform/stm32/stm32-dcmi.c | 2 +- drivers/media/platform/ti-vpe/cal.c | 2 +- drivers/media/v4l2-core/v4l2-fwnode.c | 2 +- drivers/staging/media/imx/imx-media-csi.c | 2 +- drivers/staging/media/imx/imx6-mipi-csi2.c | 2 +- drivers/staging/media/imx074/imx074.c | 2 +- include/media/v4l2-mediabus.h | 6 ++++-- 27 files changed, 38 insertions(+), 36 deletions(-) (limited to 'include/media') diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/ipu-v3/ipu-csi.c index 954eefe144e2..aa0e30a2ba18 100644 --- a/drivers/gpu/ipu-v3/ipu-csi.c +++ b/drivers/gpu/ipu-v3/ipu-csi.c @@ -232,7 +232,7 @@ static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code, case MEDIA_BUS_FMT_BGR565_2X8_LE: case MEDIA_BUS_FMT_RGB565_2X8_BE: case MEDIA_BUS_FMT_RGB565_2X8_LE: - if (mbus_type == V4L2_MBUS_CSI2) + if (mbus_type == V4L2_MBUS_CSI2_DPHY) cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565; else cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; @@ -359,7 +359,7 @@ static int fill_csi_bus_cfg(struct ipu_csi_bus_config *csicfg, else csicfg->clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE; break; - case V4L2_MBUS_CSI2: + case V4L2_MBUS_CSI2_DPHY: /* * MIPI CSI-2 requires non gated clock mode, all other * parameters are not applicable for MIPI CSI-2 bus. @@ -611,7 +611,7 @@ int ipu_csi_set_mipi_datatype(struct ipu_csi *csi, u32 vc, if (vc > 3) return -EINVAL; - ret = mbus_code_to_bus_cfg(&cfg, mbus_fmt->code, V4L2_MBUS_CSI2); + ret = mbus_code_to_bus_cfg(&cfg, mbus_fmt->code, V4L2_MBUS_CSI2_DPHY); if (ret < 0) return ret; diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 5a10ce31a1bd..99697baad2ea 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -752,7 +752,7 @@ static int adv7180_g_mbus_config(struct v4l2_subdev *sd, struct adv7180_state *state = to_state(sd); if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) { - cfg->type = V4L2_MBUS_CSI2; + cfg->type = V4L2_MBUS_CSI2_DPHY; cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 664ffacc8d66..73a4bd7c0291 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -1820,7 +1820,7 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on) goto power_off; /* We're done here for DVP bus, while CSI-2 needs setup. */ - if (sensor->ep.bus_type != V4L2_MBUS_CSI2) + if (sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY) return 0; /* @@ -1867,7 +1867,7 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on) usleep_range(500, 1000); } else { - if (sensor->ep.bus_type == V4L2_MBUS_CSI2) { + if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) { /* Reset MIPI bus settings to their default values. */ ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58); @@ -2625,7 +2625,7 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable) sensor->pending_fmt_change = false; } - if (sensor->ep.bus_type == V4L2_MBUS_CSI2) + if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) ret = ov5640_set_stream_mipi(sensor, enable); else ret = ov5640_set_stream_dvp(sensor, enable); diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index 1722cdab0daf..5eba8dd7222b 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -1127,7 +1127,7 @@ static int ov5645_probe(struct i2c_client *client, return ret; } - if (ov5645->ep.bus_type != V4L2_MBUS_CSI2) { + if (ov5645->ep.bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(dev, "invalid bus type, must be CSI2\n"); return -EINVAL; } diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c index d3ebb7529fca..0c10203f822b 100644 --- a/drivers/media/i2c/ov7251.c +++ b/drivers/media/i2c/ov7251.c @@ -1279,9 +1279,9 @@ static int ov7251_probe(struct i2c_client *client) return ret; } - if (ov7251->ep.bus_type != V4L2_MBUS_CSI2) { + if (ov7251->ep.bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(dev, "invalid bus type (%u), must be CSI2 (%u)\n", - ov7251->ep.bus_type, V4L2_MBUS_CSI2); + ov7251->ep.bus_type, V4L2_MBUS_CSI2_DPHY); return -EINVAL; } diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index c4145194251f..ed7348a8a01a 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1644,7 +1644,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state) if (ret) return ret; - if (ep.bus_type != V4L2_MBUS_CSI2) { + if (ep.bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(dev, "unsupported bus type\n"); return -EINVAL; } diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 5007c9659342..4c41a770b132 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -766,7 +766,7 @@ static int s5k5baf_hw_set_video_bus(struct s5k5baf *state) { u16 en_pkts; - if (state->bus_type == V4L2_MBUS_CSI2) + if (state->bus_type == V4L2_MBUS_CSI2_DPHY) en_pkts = EN_PACKETS_CSI2; else en_pkts = 0; @@ -1875,7 +1875,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev) state->bus_type = ep.bus_type; switch (state->bus_type) { - case V4L2_MBUS_CSI2: + case V4L2_MBUS_CSI2_DPHY: state->nlanes = ep.bus.mipi_csi2.num_data_lanes; break; case V4L2_MBUS_PARALLEL: diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 63cf8db82e7d..ab26f549d716 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -688,7 +688,7 @@ static int s5k6aa_configure_video_bus(struct s5k6aa *s5k6aa, * but there is nothing indicating how to switch between both * in the datasheet. For now default BT.601 interface is assumed. */ - if (bus_type == V4L2_MBUS_CSI2) + if (bus_type == V4L2_MBUS_CSI2_DPHY) cfg = nlanes; else if (bus_type != V4L2_MBUS_PARALLEL) return -EINVAL; diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index bccbf4c841d6..69495c6dc228 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2780,7 +2780,7 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) goto out_err; switch (bus_cfg->bus_type) { - case V4L2_MBUS_CSI2: + case V4L2_MBUS_CSI2_DPHY: hwcfg->csi_signalling_mode = SMIAPP_CSI_SIGNALLING_MODE_CSI2; hwcfg->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes; break; diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c index c6c41b03c0ef..0931898c79dd 100644 --- a/drivers/media/i2c/soc_camera/ov5642.c +++ b/drivers/media/i2c/soc_camera/ov5642.c @@ -912,7 +912,7 @@ static int ov5642_get_selection(struct v4l2_subdev *sd, static int ov5642_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { - cfg->type = V4L2_MBUS_CSI2; + cfg->type = V4L2_MBUS_CSI2_DPHY; cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 74159153dfad..0834f254f1c2 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1607,7 +1607,7 @@ static int tc358743_g_mbus_config(struct v4l2_subdev *sd, { struct tc358743_state *state = to_state(sd); - cfg->type = V4L2_MBUS_CSI2; + cfg->type = V4L2_MBUS_CSI2_DPHY; /* Support for non-continuous CSI-2 clock is missing in the driver */ cfg->flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; @@ -1922,7 +1922,7 @@ static int tc358743_probe_of(struct tc358743_state *state) goto put_node; } - if (endpoint->bus_type != V4L2_MBUS_CSI2 || + if (endpoint->bus_type != V4L2_MBUS_CSI2_DPHY || endpoint->bus.mipi_csi2.num_data_lanes == 0 || endpoint->nr_of_link_frequencies == 0) { dev_err(dev, "missing CSI-2 properties in endpoint\n"); diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index 06b422233215..452eb9b42140 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -1482,7 +1482,7 @@ static int cio2_fwnode_parse(struct device *dev, struct sensor_async_subdev *s_asd = container_of(asd, struct sensor_async_subdev, asd); - if (vep->bus_type != V4L2_MBUS_CSI2) { + if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(dev, "Only CSI2 bus type is currently supported\n"); return -EINVAL; } diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index da3eb349716f..0776a34f28ee 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -378,7 +378,7 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) return ret; } - if (v4l2_ep.bus_type != V4L2_MBUS_CSI2) { + if (v4l2_ep.bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(csi2rx->dev, "Unsupported media bus type: 0x%x\n", v4l2_ep.bus_type); of_node_put(ep); diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c b/drivers/media/platform/cadence/cdns-csi2tx.c index 40d0de690ff4..6224daf891d7 100644 --- a/drivers/media/platform/cadence/cdns-csi2tx.c +++ b/drivers/media/platform/cadence/cdns-csi2tx.c @@ -446,7 +446,7 @@ static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx) goto out; } - if (v4l2_ep.bus_type != V4L2_MBUS_CSI2) { + if (v4l2_ep.bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(csi2tx->dev, "Unsupported media bus type: 0x%x\n", v4l2_ep.bus_type); ret = -EINVAL; diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index f8e1af101817..f1b301810260 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -794,7 +794,7 @@ static void mcam_ctlr_image(struct mcam_camera *cam) /* * This field controls the generation of EOF(DVP only) */ - if (cam->bus_type != V4L2_MBUS_CSI2) + if (cam->bus_type != V4L2_MBUS_CSI2_DPHY) mcam_reg_set_bit(cam, REG_CTRL0, C0_EOF_VSYNC | C0_VEDGE_CTRL); } @@ -1023,7 +1023,7 @@ static int mcam_read_setup(struct mcam_camera *cam) cam->calc_dphy(cam); cam_dbg(cam, "camera: DPHY sets: dphy3=0x%x, dphy5=0x%x, dphy6=0x%x\n", cam->dphy[0], cam->dphy[1], cam->dphy[2]); - if (cam->bus_type == V4L2_MBUS_CSI2) + if (cam->bus_type == V4L2_MBUS_CSI2_DPHY) mcam_enable_mipi(cam); else mcam_disable_mipi(cam); diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c index 41968cd388ac..70a2833db0d1 100644 --- a/drivers/media/platform/marvell-ccic/mmp-driver.c +++ b/drivers/media/platform/marvell-ccic/mmp-driver.c @@ -362,7 +362,7 @@ static int mmpcam_probe(struct platform_device *pdev) mcam->mclk_div = pdata->mclk_div; mcam->bus_type = pdata->bus_type; mcam->dphy = pdata->dphy; - if (mcam->bus_type == V4L2_MBUS_CSI2) { + if (mcam->bus_type == V4L2_MBUS_CSI2_DPHY) { cam->mipi_clk = devm_clk_get(mcam->dev, "mipi"); if ((IS_ERR(cam->mipi_clk) && mcam->dphy[2] == 0)) return PTR_ERR(cam->mipi_clk); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index f5dde8774399..77fb7987b42f 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2054,7 +2054,7 @@ static int isp_fwnode_parse(struct device *dev, dev_dbg(dev, "CSI-1/CCP-2 configuration\n"); csi1 = true; break; - case V4L2_MBUS_CSI2: + case V4L2_MBUS_CSI2_DPHY: dev_dbg(dev, "CSI-2 configuration\n"); csi1 = false; break; diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index 2f083acdd269..6f01d0986b59 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -633,7 +633,7 @@ static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cf mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE); return (!hsync || !vsync || !pclk || !data || !mode) ? 0 : common_flags; - case V4L2_MBUS_CSI2: + case V4L2_MBUS_CSI2_DPHY: mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES; mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index 75ebd9c23813..25edc2edd197 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -714,7 +714,7 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv, if (vep->base.port || vep->base.id) return -ENOTCONN; - if (vep->bus_type != V4L2_MBUS_CSI2) { + if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) { dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type); return -EINVAL; } diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c index 0ad4b28266e4..be74008ec0ca 100644 --- a/drivers/media/platform/soc_camera/soc_mediabus.c +++ b/drivers/media/platform/soc_camera/soc_mediabus.c @@ -503,7 +503,7 @@ unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg, mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE); return (!hsync || !vsync || !pclk || !data || !mode) ? 0 : common_flags; - case V4L2_MBUS_CSI2: + case V4L2_MBUS_CSI2_DPHY: mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES; mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 48f514d7e34f..9719a2e8de07 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -1663,7 +1663,7 @@ static int dcmi_probe(struct platform_device *pdev) return -ENODEV; } - if (ep.bus_type == V4L2_MBUS_CSI2) { + if (ep.bus_type == V4L2_MBUS_CSI2_DPHY) { dev_err(&pdev->dev, "CSI bus not supported\n"); return -ENODEV; } diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index 51f604332eea..95a093f41905 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -1710,7 +1710,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) } v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), endpoint); - if (endpoint->bus_type != V4L2_MBUS_CSI2) { + if (endpoint->bus_type != V4L2_MBUS_CSI2_DPHY) { ctx_err(ctx, "Port:%d sub-device %pOFn is not a CSI2 device\n", inst, sensor_node); goto cleanup_exit; diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 104ef7f1754d..54162217bb36 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -115,7 +115,7 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, } bus->flags = flags; - vep->bus_type = V4L2_MBUS_CSI2; + vep->bus_type = V4L2_MBUS_CSI2_DPHY; return 0; } diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index bca13846ce6d..beb7c120bf35 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -124,7 +124,7 @@ static inline struct csi_priv *sd_to_dev(struct v4l2_subdev *sdev) static inline bool is_parallel_bus(struct v4l2_fwnode_endpoint *ep) { - return ep->bus_type != V4L2_MBUS_CSI2; + return ep->bus_type != V4L2_MBUS_CSI2_DPHY; } static inline bool is_parallel_16bit_bus(struct v4l2_fwnode_endpoint *ep) diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c index d60a52cfc69c..6a1cee55a49b 100644 --- a/drivers/staging/media/imx/imx6-mipi-csi2.c +++ b/drivers/staging/media/imx/imx6-mipi-csi2.c @@ -563,7 +563,7 @@ static int csi2_parse_endpoint(struct device *dev, return -EINVAL; } - if (vep->bus_type != V4L2_MBUS_CSI2) { + if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) { v4l2_err(&csi2->sd, "invalid bus type, must be MIPI CSI2\n"); return -EINVAL; } diff --git a/drivers/staging/media/imx074/imx074.c b/drivers/staging/media/imx074/imx074.c index c5256903e59f..1676c166dc83 100644 --- a/drivers/staging/media/imx074/imx074.c +++ b/drivers/staging/media/imx074/imx074.c @@ -262,7 +262,7 @@ static int imx074_s_power(struct v4l2_subdev *sd, int on) static int imx074_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { - cfg->type = V4L2_MBUS_CSI2; + cfg->type = V4L2_MBUS_CSI2_DPHY; cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index 4bbb5f3d2b02..26e1c644ded6 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -75,14 +75,16 @@ * also be used for BT.1120 * @V4L2_MBUS_CSI1: MIPI CSI-1 serial interface * @V4L2_MBUS_CCP2: CCP2 (Compact Camera Port 2) - * @V4L2_MBUS_CSI2: MIPI CSI-2 serial interface + * @V4L2_MBUS_CSI2_DPHY: MIPI CSI-2 serial interface, with D-PHY + * @V4L2_MBUS_CSI2_CPHY: MIPI CSI-2 serial interface, with C-PHY */ enum v4l2_mbus_type { V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, V4L2_MBUS_CSI1, V4L2_MBUS_CCP2, - V4L2_MBUS_CSI2, + V4L2_MBUS_CSI2_DPHY, + V4L2_MBUS_CSI2_CPHY, }; /** -- cgit v1.2.3 From 6970d37cc97d77189d775fd16d47b2ac87d0e757 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sat, 2 Jun 2018 12:19:35 -0400 Subject: media: v4l: fwnode: Let the caller provide V4L2 fwnode endpoint Instead of allocating the V4L2 fwnode endpoint in v4l2_fwnode_endpoint_alloc_parse, let the caller to do this. This allows setting default parameters for the endpoint which is a very common need for drivers. Signed-off-by: Sakari Ailus Tested-by: Steve Longerbeam Tested-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov2659.c | 14 +++++----- drivers/media/i2c/smiapp/smiapp-core.c | 26 +++++++++--------- drivers/media/i2c/tc358743.c | 26 +++++++++--------- drivers/media/v4l2-core/v4l2-fwnode.c | 49 +++++++++++++--------------------- include/media/v4l2-fwnode.h | 10 ++++--- 5 files changed, 60 insertions(+), 65 deletions(-) (limited to 'include/media') diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 4715edc8ca33..799acce803fe 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1347,8 +1347,9 @@ static struct ov2659_platform_data * ov2659_get_pdata(struct i2c_client *client) { struct ov2659_platform_data *pdata; - struct v4l2_fwnode_endpoint *bus_cfg; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *endpoint; + int ret; if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) return client->dev.platform_data; @@ -1357,8 +1358,9 @@ ov2659_get_pdata(struct i2c_client *client) if (!endpoint) return NULL; - bus_cfg = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint)); - if (IS_ERR(bus_cfg)) { + ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint), + &bus_cfg); + if (ret) { pdata = NULL; goto done; } @@ -1367,17 +1369,17 @@ ov2659_get_pdata(struct i2c_client *client) if (!pdata) goto done; - if (!bus_cfg->nr_of_link_frequencies) { + if (!bus_cfg.nr_of_link_frequencies) { dev_err(&client->dev, "link-frequencies property not found or too many\n"); pdata = NULL; goto done; } - pdata->link_frequency = bus_cfg->link_frequencies[0]; + pdata->link_frequency = bus_cfg.link_frequencies[0]; done: - v4l2_fwnode_endpoint_free(bus_cfg); + v4l2_fwnode_endpoint_free(&bus_cfg); of_node_put(endpoint); return pdata; } diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 69495c6dc228..2d6059e3a577 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2757,7 +2757,7 @@ static int __maybe_unused smiapp_resume(struct device *dev) static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) { struct smiapp_hwconfig *hwcfg; - struct v4l2_fwnode_endpoint *bus_cfg; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct fwnode_handle *ep; struct fwnode_handle *fwnode = dev_fwnode(dev); u32 rotation; @@ -2771,27 +2771,27 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) if (!ep) return NULL; - bus_cfg = v4l2_fwnode_endpoint_alloc_parse(ep); - if (IS_ERR(bus_cfg)) + rval = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); + if (rval) goto out_err; hwcfg = devm_kzalloc(dev, sizeof(*hwcfg), GFP_KERNEL); if (!hwcfg) goto out_err; - switch (bus_cfg->bus_type) { + switch (bus_cfg.bus_type) { case V4L2_MBUS_CSI2_DPHY: hwcfg->csi_signalling_mode = SMIAPP_CSI_SIGNALLING_MODE_CSI2; - hwcfg->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes; + hwcfg->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes; break; case V4L2_MBUS_CCP2: - hwcfg->csi_signalling_mode = (bus_cfg->bus.mipi_csi1.strobe) ? + hwcfg->csi_signalling_mode = (bus_cfg.bus.mipi_csi1.strobe) ? SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE : SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK; hwcfg->lanes = 1; break; default: - dev_err(dev, "unsupported bus %u\n", bus_cfg->bus_type); + dev_err(dev, "unsupported bus %u\n", bus_cfg.bus_type); goto out_err; } @@ -2823,28 +2823,28 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) dev_dbg(dev, "nvm %d, clk %d, mode %d\n", hwcfg->nvm_size, hwcfg->ext_clk, hwcfg->csi_signalling_mode); - if (!bus_cfg->nr_of_link_frequencies) { + if (!bus_cfg.nr_of_link_frequencies) { dev_warn(dev, "no link frequencies defined\n"); goto out_err; } hwcfg->op_sys_clock = devm_kcalloc( - dev, bus_cfg->nr_of_link_frequencies + 1 /* guardian */, + dev, bus_cfg.nr_of_link_frequencies + 1 /* guardian */, sizeof(*hwcfg->op_sys_clock), GFP_KERNEL); if (!hwcfg->op_sys_clock) goto out_err; - for (i = 0; i < bus_cfg->nr_of_link_frequencies; i++) { - hwcfg->op_sys_clock[i] = bus_cfg->link_frequencies[i]; + for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { + hwcfg->op_sys_clock[i] = bus_cfg.link_frequencies[i]; dev_dbg(dev, "freq %d: %lld\n", i, hwcfg->op_sys_clock[i]); } - v4l2_fwnode_endpoint_free(bus_cfg); + v4l2_fwnode_endpoint_free(&bus_cfg); fwnode_handle_put(ep); return hwcfg; out_err: - v4l2_fwnode_endpoint_free(bus_cfg); + v4l2_fwnode_endpoint_free(&bus_cfg); fwnode_handle_put(ep); return NULL; } diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 0834f254f1c2..ca5d92942820 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1895,11 +1895,11 @@ static void tc358743_gpio_reset(struct tc358743_state *state) static int tc358743_probe_of(struct tc358743_state *state) { struct device *dev = &state->i2c_client->dev; - struct v4l2_fwnode_endpoint *endpoint; + struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 }; struct device_node *ep; struct clk *refclk; u32 bps_pr_lane; - int ret = -EINVAL; + int ret; refclk = devm_clk_get(dev, "refclk"); if (IS_ERR(refclk)) { @@ -1915,26 +1915,28 @@ static int tc358743_probe_of(struct tc358743_state *state) return -EINVAL; } - endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep)); - if (IS_ERR(endpoint)) { + ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint); + if (ret) { dev_err(dev, "failed to parse endpoint\n"); - ret = PTR_ERR(endpoint); + ret = ret; goto put_node; } - if (endpoint->bus_type != V4L2_MBUS_CSI2_DPHY || - endpoint->bus.mipi_csi2.num_data_lanes == 0 || - endpoint->nr_of_link_frequencies == 0) { + if (endpoint.bus_type != V4L2_MBUS_CSI2_DPHY || + endpoint.bus.mipi_csi2.num_data_lanes == 0 || + endpoint.nr_of_link_frequencies == 0) { dev_err(dev, "missing CSI-2 properties in endpoint\n"); + ret = -EINVAL; goto free_endpoint; } - if (endpoint->bus.mipi_csi2.num_data_lanes > 4) { + if (endpoint.bus.mipi_csi2.num_data_lanes > 4) { dev_err(dev, "invalid number of lanes\n"); + ret = -EINVAL; goto free_endpoint; } - state->bus = endpoint->bus.mipi_csi2; + state->bus = endpoint.bus.mipi_csi2; ret = clk_prepare_enable(refclk); if (ret) { @@ -1967,7 +1969,7 @@ static int tc358743_probe_of(struct tc358743_state *state) * The CSI bps per lane must be between 62.5 Mbps and 1 Gbps. * The default is 594 Mbps for 4-lane 1080p60 or 2-lane 720p60. */ - bps_pr_lane = 2 * endpoint->link_frequencies[0]; + bps_pr_lane = 2 * endpoint.link_frequencies[0]; if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) { dev_err(dev, "unsupported bps per lane: %u bps\n", bps_pr_lane); goto disable_clk; @@ -2013,7 +2015,7 @@ static int tc358743_probe_of(struct tc358743_state *state) disable_clk: clk_disable_unprepare(refclk); free_endpoint: - v4l2_fwnode_endpoint_free(endpoint); + v4l2_fwnode_endpoint_free(&endpoint); put_node: of_node_put(ep); return ret; diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 54162217bb36..d6ba3e5d4356 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -290,23 +290,17 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep) return; kfree(vep->link_frequencies); - kfree(vep); } EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free); -struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse( - struct fwnode_handle *fwnode) +int v4l2_fwnode_endpoint_alloc_parse( + struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep) { - struct v4l2_fwnode_endpoint *vep; int rval; - vep = kzalloc(sizeof(*vep), GFP_KERNEL); - if (!vep) - return ERR_PTR(-ENOMEM); - rval = __v4l2_fwnode_endpoint_parse(fwnode, vep); if (rval < 0) - goto out_err; + return rval; rval = fwnode_property_read_u64_array(fwnode, "link-frequencies", NULL, 0); @@ -316,18 +310,18 @@ struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse( vep->link_frequencies = kmalloc_array(rval, sizeof(*vep->link_frequencies), GFP_KERNEL); - if (!vep->link_frequencies) { - rval = -ENOMEM; - goto out_err; - } + if (!vep->link_frequencies) + return -ENOMEM; vep->nr_of_link_frequencies = rval; rval = fwnode_property_read_u64_array( fwnode, "link-frequencies", vep->link_frequencies, vep->nr_of_link_frequencies); - if (rval < 0) - goto out_err; + if (rval < 0) { + v4l2_fwnode_endpoint_free(vep); + return rval; + } for (i = 0; i < vep->nr_of_link_frequencies; i++) pr_info("link-frequencies %u value %llu\n", i, @@ -336,11 +330,7 @@ struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse( pr_debug("===== end V4L2 endpoint properties\n"); - return vep; - -out_err: - v4l2_fwnode_endpoint_free(vep); - return ERR_PTR(rval); + return 0; } EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse); @@ -392,9 +382,9 @@ static int v4l2_async_notifier_fwnode_parse_endpoint( struct v4l2_fwnode_endpoint *vep, struct v4l2_async_subdev *asd)) { + struct v4l2_fwnode_endpoint vep = { .bus_type = 0 }; struct v4l2_async_subdev *asd; - struct v4l2_fwnode_endpoint *vep; - int ret = 0; + int ret; asd = kzalloc(asd_struct_size, GFP_KERNEL); if (!asd) @@ -409,23 +399,22 @@ static int v4l2_async_notifier_fwnode_parse_endpoint( goto out_err; } - vep = v4l2_fwnode_endpoint_alloc_parse(endpoint); - if (IS_ERR(vep)) { - ret = PTR_ERR(vep); + ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &vep); + if (ret) { dev_warn(dev, "unable to parse V4L2 fwnode endpoint (%d)\n", ret); goto out_err; } - ret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0; + ret = parse_endpoint ? parse_endpoint(dev, &vep, asd) : 0; if (ret == -ENOTCONN) - dev_dbg(dev, "ignoring port@%u/endpoint@%u\n", vep->base.port, - vep->base.id); + dev_dbg(dev, "ignoring port@%u/endpoint@%u\n", vep.base.port, + vep.base.id); else if (ret < 0) dev_warn(dev, "driver could not parse port@%u/endpoint@%u (%d)\n", - vep->base.port, vep->base.id, ret); - v4l2_fwnode_endpoint_free(vep); + vep.base.port, vep.base.id, ret); + v4l2_fwnode_endpoint_free(&vep); if (ret < 0) goto out_err; diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 8b4873c37098..4a371c3ad86c 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -161,6 +161,7 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); /** * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties * @fwnode: pointer to the endpoint's fwnode handle + * @vep: pointer to the V4L2 fwnode data structure * * All properties are optional. If none are found, we don't set any flags. This * means the port has a static configuration and no properties have to be @@ -170,6 +171,8 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a * reference to @fwnode. * + * The caller must set the bus_type field of @vep to zero. + * * v4l2_fwnode_endpoint_alloc_parse() has two important differences to * v4l2_fwnode_endpoint_parse(): * @@ -178,11 +181,10 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); * 2. The memory it has allocated to store the variable size data must be freed * using v4l2_fwnode_endpoint_free() when no longer needed. * - * Return: Pointer to v4l2_fwnode_endpoint if successful, on an error pointer - * on error. + * Return: 0 on success or a negative error code on failure. */ -struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse( - struct fwnode_handle *fwnode); +int v4l2_fwnode_endpoint_alloc_parse( + struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep); /** * v4l2_fwnode_parse_link() - parse a link between two endpoints -- cgit v1.2.3 From 2835b5b15370ff1ed7671fd42e15c6e1ac0d1ebc Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 31 Jul 2018 06:43:14 -0400 Subject: media: v4l: fwnode: Detect bus type correctly In case the device supports multiple video bus types on an endpoint, the V4L2 fwnode framework attempts to detect the type based on the available information. This wasn't working really well, and sometimes could lead to the V4L2 fwnode endpoint struct as being mishandled between the bus types. Default to Bt.656 if no properties suggesting a bus type are found. Signed-off-by: Sakari Ailus Tested-by: Steve Longerbeam Tested-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 31 +++++++++++++++++-------------- include/media/v4l2-mediabus.h | 2 ++ 2 files changed, 19 insertions(+), 14 deletions(-) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index d6ba3e5d4356..aa3d28c4a50b 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -114,8 +114,11 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; } - bus->flags = flags; - vep->bus_type = V4L2_MBUS_CSI2_DPHY; + if (lanes_used || have_clk_lane || + (flags & ~V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)) { + bus->flags = flags; + vep->bus_type = V4L2_MBUS_CSI2_DPHY; + } return 0; } @@ -145,11 +148,6 @@ static void v4l2_fwnode_endpoint_parse_parallel_bus( pr_debug("field-even-active %s\n", v ? "high" : "low"); } - if (flags) - vep->bus_type = V4L2_MBUS_PARALLEL; - else - vep->bus_type = V4L2_MBUS_BT656; - if (!fwnode_property_read_u32(fwnode, "pclk-sample", &v)) { flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING : V4L2_MBUS_PCLK_SAMPLE_FALLING; @@ -192,13 +190,21 @@ static void v4l2_fwnode_endpoint_parse_parallel_bus( } bus->flags = flags; - + if (flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH | + V4L2_MBUS_HSYNC_ACTIVE_LOW | + V4L2_MBUS_VSYNC_ACTIVE_HIGH | + V4L2_MBUS_VSYNC_ACTIVE_LOW | + V4L2_MBUS_FIELD_EVEN_HIGH | + V4L2_MBUS_FIELD_EVEN_LOW)) + vep->bus_type = V4L2_MBUS_PARALLEL; + else + vep->bus_type = V4L2_MBUS_BT656; } static void v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep, - u32 bus_type) + enum v4l2_fwnode_bus_type bus_type) { struct v4l2_fwnode_bus_mipi_csi1 *bus = &vep->bus.mipi_csi1; u32 v; @@ -250,11 +256,8 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep); if (rval) return rval; - /* - * Parse the parallel video bus properties only if none - * of the MIPI CSI-2 specific properties were found. - */ - if (vep->bus.mipi_csi2.flags == 0) + + if (vep->bus_type == V4L2_MBUS_UNKNOWN) v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep); break; diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index 26e1c644ded6..df1d552e9df6 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -70,6 +70,7 @@ /** * enum v4l2_mbus_type - media bus type + * @V4L2_MBUS_UNKNOWN: unknown bus type, no V4L2 mediabus configuration * @V4L2_MBUS_PARALLEL: parallel interface with hsync and vsync * @V4L2_MBUS_BT656: parallel interface with embedded synchronisation, can * also be used for BT.1120 @@ -79,6 +80,7 @@ * @V4L2_MBUS_CSI2_CPHY: MIPI CSI-2 serial interface, with C-PHY */ enum v4l2_mbus_type { + V4L2_MBUS_UNKNOWN, V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, V4L2_MBUS_CSI1, -- cgit v1.2.3 From 60359a28d59278e2a9e7558c15dc7be518d9beb8 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 31 Jul 2018 05:15:50 -0400 Subject: media: v4l: fwnode: Initialise the V4L2 fwnode endpoints to zero Initialise the V4L2 fwnode endpoints to zero in all drivers using v4l2_fwnode_endpoint_parse(). This prepares for setting default endpoint flags as well as the bus type. Setting bus type to zero will continue to guess the bus among the guessable set (parallel, Bt.656 and CSI-2 D-PHY). Signed-off-by: Sakari Ailus Tested-by: Steve Longerbeam Tested-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 2 +- drivers/media/i2c/mt9v032.c | 2 +- drivers/media/i2c/ov5647.c | 2 +- drivers/media/i2c/ov7670.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +- drivers/media/i2c/s5k5baf.c | 2 +- drivers/media/i2c/tda1997x.c | 2 +- drivers/media/i2c/tvp514x.c | 2 +- drivers/media/i2c/tvp5150.c | 2 +- drivers/media/i2c/tvp7002.c | 2 +- drivers/media/platform/am437x/am437x-vpfe.c | 2 +- drivers/media/platform/atmel/atmel-isc.c | 3 ++- drivers/media/platform/atmel/atmel-isi.c | 2 +- drivers/media/platform/cadence/cdns-csi2rx.c | 2 +- drivers/media/platform/cadence/cdns-csi2tx.c | 2 +- drivers/media/platform/davinci/vpif_capture.c | 2 +- drivers/media/platform/exynos4-is/media-dev.c | 2 +- drivers/media/platform/exynos4-is/mipi-csis.c | 2 +- drivers/media/platform/pxa_camera.c | 2 +- drivers/media/platform/rcar-vin/rcar-csi2.c | 2 +- drivers/media/platform/renesas-ceu.c | 3 ++- drivers/media/platform/stm32/stm32-dcmi.c | 2 +- drivers/staging/media/imx/imx-media-csi.c | 8 ++++---- include/media/v4l2-fwnode.h | 2 ++ 24 files changed, 30 insertions(+), 26 deletions(-) (limited to 'include/media') diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 070fdf65b714..1c89959b1509 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -3093,7 +3093,7 @@ MODULE_DEVICE_TABLE(of, adv76xx_of_id); static int adv76xx_parse_dt(struct adv76xx_state *state) { - struct v4l2_fwnode_endpoint bus_cfg; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *endpoint; struct device_node *np; unsigned int flags; diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index f74730d24d8f..67f69ad6ecf4 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c @@ -989,7 +989,7 @@ static struct mt9v032_platform_data * mt9v032_get_pdata(struct i2c_client *client) { struct mt9v032_platform_data *pdata = NULL; - struct v4l2_fwnode_endpoint endpoint; + struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 }; struct device_node *np; struct property *prop; diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index da39c49de503..4589631798c9 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -532,7 +532,7 @@ static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = { static int ov5647_parse_dt(struct device_node *np) { - struct v4l2_fwnode_endpoint bus_cfg; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *ep; int ret; diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 31bf577b0bd3..92f59ae1b624 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -1728,7 +1728,7 @@ static int ov7670_parse_dt(struct device *dev, struct ov7670_info *info) { struct fwnode_handle *fwnode = dev_fwnode(dev); - struct v4l2_fwnode_endpoint bus_cfg; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct fwnode_handle *ep; int ret; diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index ed7348a8a01a..c461847ddae8 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1603,7 +1603,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state) const struct s5c73m3_platform_data *pdata = dev->platform_data; struct device_node *node = dev->of_node; struct device_node *node_ep; - struct v4l2_fwnode_endpoint ep; + struct v4l2_fwnode_endpoint ep = { .bus_type = 0 }; int ret; if (!node) { diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 4c41a770b132..727db7c0670a 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1841,7 +1841,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev) { struct device_node *node = dev->of_node; struct device_node *node_ep; - struct v4l2_fwnode_endpoint ep; + struct v4l2_fwnode_endpoint ep = { .bus_type = 0 }; int ret; if (!node) { diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index d114ac5243ec..c4c2a6134e1e 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -2265,7 +2265,7 @@ MODULE_DEVICE_TABLE(of, tda1997x_of_id); static int tda1997x_parse_dt(struct tda1997x_state *state) { struct tda1997x_platform_data *pdata = &state->pdata; - struct v4l2_fwnode_endpoint bus_cfg; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *ep; struct device_node *np; unsigned int flags; diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 675b9ae212ab..1cc83cb934e2 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -989,7 +989,7 @@ static struct tvp514x_platform_data * tvp514x_get_pdata(struct i2c_client *client) { struct tvp514x_platform_data *pdata = NULL; - struct v4l2_fwnode_endpoint bus_cfg; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *endpoint; unsigned int flags; diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 4f746e02de22..0e91b9949c3a 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -1593,7 +1593,7 @@ static int tvp5150_init(struct i2c_client *c) static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np) { - struct v4l2_fwnode_endpoint bus_cfg; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *ep; #ifdef CONFIG_MEDIA_CONTROLLER struct device_node *connectors, *child; diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 4f5c627579c7..cab2f2bd0aa9 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -889,7 +889,7 @@ static const struct v4l2_subdev_ops tvp7002_ops = { static struct tvp7002_config * tvp7002_get_pdata(struct i2c_client *client) { - struct v4l2_fwnode_endpoint bus_cfg; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct tvp7002_config *pdata = NULL; struct device_node *endpoint; unsigned int flags; diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 0b1a03b64b19..e13d2b3a7168 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -2426,7 +2426,6 @@ static struct vpfe_config * vpfe_get_pdata(struct vpfe_device *vpfe) { struct device_node *endpoint = NULL; - struct v4l2_fwnode_endpoint bus_cfg; struct device *dev = vpfe->pdev; struct vpfe_subdev_info *sdinfo; struct vpfe_config *pdata; @@ -2446,6 +2445,7 @@ vpfe_get_pdata(struct vpfe_device *vpfe) return NULL; for (i = 0; ; i++) { + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *rem; endpoint = of_graph_get_next_endpoint(dev->of_node, endpoint); diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index 334de0f2e36a..50178968b8a6 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c @@ -2028,7 +2028,6 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) { struct device_node *np = dev->of_node; struct device_node *epn = NULL, *rem; - struct v4l2_fwnode_endpoint v4l2_epn; struct isc_subdev_entity *subdev_entity; unsigned int flags; int ret; @@ -2036,6 +2035,8 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) INIT_LIST_HEAD(&isc->subdev_entities); while (1) { + struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 }; + epn = of_graph_get_next_endpoint(np, epn); if (!epn) return 0; diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c index c4d5f05786e8..fdb255e4a956 100644 --- a/drivers/media/platform/atmel/atmel-isi.c +++ b/drivers/media/platform/atmel/atmel-isi.c @@ -790,7 +790,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi, struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - struct v4l2_fwnode_endpoint ep; + struct v4l2_fwnode_endpoint ep = { .bus_type = 0 }; int err; /* Default settings for ISI */ diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 0776a34f28ee..31ace114eda1 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -361,7 +361,7 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx, static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) { - struct v4l2_fwnode_endpoint v4l2_ep; + struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 }; struct fwnode_handle *fwh; struct device_node *ep; int ret; diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c b/drivers/media/platform/cadence/cdns-csi2tx.c index 6224daf891d7..5042d053b94e 100644 --- a/drivers/media/platform/cadence/cdns-csi2tx.c +++ b/drivers/media/platform/cadence/cdns-csi2tx.c @@ -432,7 +432,7 @@ static int csi2tx_get_resources(struct csi2tx_priv *csi2tx, static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx) { - struct v4l2_fwnode_endpoint v4l2_ep; + struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 }; struct device_node *ep; int ret; diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 187f965e341e..6216b7ac6875 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1511,7 +1511,6 @@ static struct vpif_capture_config * vpif_capture_get_pdata(struct platform_device *pdev) { struct device_node *endpoint = NULL; - struct v4l2_fwnode_endpoint bus_cfg; struct vpif_capture_config *pdata; struct vpif_subdev_info *sdinfo; struct vpif_capture_chan_config *chan; @@ -1541,6 +1540,7 @@ vpif_capture_get_pdata(struct platform_device *pdev) return NULL; for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) { + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct device_node *rem; unsigned int flags; int err; diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index fbad0635c6b5..870501b0f351 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -390,7 +390,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, { struct fimc_source_info *pd = &fmd->sensor[index].pdata; struct device_node *rem, *ep, *np; - struct v4l2_fwnode_endpoint endpoint; + struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 }; int ret; /* Assume here a port node can have only one endpoint node. */ diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index b4e28a299e26..35cb0162085b 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -718,7 +718,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, struct csis_state *state) { struct device_node *node = pdev->dev.of_node; - struct v4l2_fwnode_endpoint endpoint; + struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 }; int ret; if (of_property_read_u32(node, "clock-frequency", diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index 6f01d0986b59..5f930560eb30 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -2298,7 +2298,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev, { u32 mclk_rate; struct device_node *remote, *np = dev->of_node; - struct v4l2_fwnode_endpoint ep; + struct v4l2_fwnode_endpoint ep = { .bus_type = 0 }; int err = of_property_read_u32(np, "clock-frequency", &mclk_rate); if (!err) { diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index 25edc2edd197..b0044a08e71e 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -743,7 +743,7 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv, static int rcsi2_parse_dt(struct rcar_csi2 *priv) { struct device_node *ep; - struct v4l2_fwnode_endpoint v4l2_ep; + struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 }; int ret; ep = of_graph_get_endpoint_by_regs(priv->dev->of_node, 0, 0); diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c index eee4ae7234be..035f1d3f10e5 100644 --- a/drivers/media/platform/renesas-ceu.c +++ b/drivers/media/platform/renesas-ceu.c @@ -1536,7 +1536,6 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev, static int ceu_parse_dt(struct ceu_device *ceudev) { struct device_node *of = ceudev->dev->of_node; - struct v4l2_fwnode_endpoint fw_ep; struct device_node *ep, *remote; struct ceu_subdev *ceu_sd; unsigned int i; @@ -1552,6 +1551,8 @@ static int ceu_parse_dt(struct ceu_device *ceudev) return ret; for (i = 0; i < num_ep; i++) { + struct v4l2_fwnode_endpoint fw_ep = { .bus_type = 0 }; + ep = of_graph_get_endpoint_by_regs(of, 0, i); if (!ep) { dev_err(ceudev->dev, diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 9719a2e8de07..6732874114cf 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -1624,7 +1624,7 @@ static int dcmi_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; const struct of_device_id *match = NULL; - struct v4l2_fwnode_endpoint ep; + struct v4l2_fwnode_endpoint ep = { .bus_type = 0 }; struct stm32_dcmi *dcmi; struct vb2_queue *q; struct dma_chan *chan; diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index beb7c120bf35..4223f8d418ae 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -1053,7 +1053,7 @@ static int csi_link_validate(struct v4l2_subdev *sd, struct v4l2_subdev_format *sink_fmt) { struct csi_priv *priv = v4l2_get_subdevdata(sd); - struct v4l2_fwnode_endpoint upstream_ep; + struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 }; bool is_csi2; int ret; @@ -1167,7 +1167,7 @@ static int csi_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_mbus_code_enum *code) { struct csi_priv *priv = v4l2_get_subdevdata(sd); - struct v4l2_fwnode_endpoint upstream_ep; + struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 }; const struct imx_media_pixfmt *incc; struct v4l2_mbus_framefmt *infmt; int ret = 0; @@ -1406,7 +1406,7 @@ static int csi_set_fmt(struct v4l2_subdev *sd, { struct csi_priv *priv = v4l2_get_subdevdata(sd); struct imx_media_video_dev *vdev = priv->vdev; - struct v4l2_fwnode_endpoint upstream_ep; + struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 }; const struct imx_media_pixfmt *cc; struct v4l2_pix_format vdev_fmt; struct v4l2_mbus_framefmt *fmt; @@ -1545,7 +1545,7 @@ static int csi_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_selection *sel) { struct csi_priv *priv = v4l2_get_subdevdata(sd); - struct v4l2_fwnode_endpoint upstream_ep; + struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 }; struct v4l2_mbus_framefmt *infmt; struct v4l2_rect *crop, *compose; int pad, ret; diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 4a371c3ad86c..1ea1a3ecf6d5 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -139,6 +139,8 @@ struct v4l2_fwnode_link { * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a * reference to @fwnode. * + * The caller must set the bus_type field of @vep to zero. + * * NOTE: This function does not parse properties the size of which is variable * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in * new drivers instead. -- cgit v1.2.3 From 2e6e39324aecd10dbf66819b137a5ee73298b931 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 18 Jul 2018 06:09:57 -0400 Subject: media: v4l: fwnode: Update V4L2 fwnode endpoint parsing documentation The semantics of v4l2_fwnode_endpoint_parse() and v4l2_fwnode_endpoint_alloc_parse() have changed slightly: they now take the bus type from the user as well as a default configuration for the bus that shall reflect the DT binding defaults. Document this. Signed-off-by: Sakari Ailus Tested-by: Steve Longerbeam Tested-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-fwnode.h | 56 ++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 19 deletions(-) (limited to 'include/media') diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 1ea1a3ecf6d5..b4a49ca27579 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -131,21 +131,30 @@ struct v4l2_fwnode_link { * @fwnode: pointer to the endpoint's fwnode handle * @vep: pointer to the V4L2 fwnode data structure * - * All properties are optional. If none are found, we don't set any flags. This - * means the port has a static configuration and no properties have to be - * specified explicitly. If any properties that identify the bus as parallel - * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if - * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we - * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a - * reference to @fwnode. - * - * The caller must set the bus_type field of @vep to zero. + * This function parses the V4L2 fwnode endpoint specific parameters from the + * firmware. The caller is responsible for assigning @vep.bus_type to a valid + * media bus type. The caller may also set the default configuration for the + * endpoint --- a configuration that shall be in line with the DT binding + * documentation. Should a device support multiple bus types, the caller may + * call this function once the correct type is found --- with a default + * configuration valid for that type. + * + * As a compatibility means guessing the bus type is also supported by setting + * @vep.bus_type to V4L2_MBUS_UNKNOWN. The caller may not provide a default + * configuration in this case as the defaults are specific to a given bus type. + * This functionality is deprecated and should not be used in new drivers and it + * is only supported for CSI-2 D-PHY, parallel and Bt.656 busses. + * + * The function does not change the V4L2 fwnode endpoint state if it fails. * * NOTE: This function does not parse properties the size of which is variable * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in * new drivers instead. * - * Return: 0 on success or a negative error code on failure. + * Return: %0 on success or a negative error code on failure: + * %-ENOMEM on memory allocation failure + * %-EINVAL on parsing failure + * %-ENXIO on mismatching bus types */ int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep); @@ -165,15 +174,21 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); * @fwnode: pointer to the endpoint's fwnode handle * @vep: pointer to the V4L2 fwnode data structure * - * All properties are optional. If none are found, we don't set any flags. This - * means the port has a static configuration and no properties have to be - * specified explicitly. If any properties that identify the bus as parallel - * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if - * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we - * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a - * reference to @fwnode. + * This function parses the V4L2 fwnode endpoint specific parameters from the + * firmware. The caller is responsible for assigning @vep.bus_type to a valid + * media bus type. The caller may also set the default configuration for the + * endpoint --- a configuration that shall be in line with the DT binding + * documentation. Should a device support multiple bus types, the caller may + * call this function once the correct type is found --- with a default + * configuration valid for that type. + * + * As a compatibility means guessing the bus type is also supported by setting + * @vep.bus_type to V4L2_MBUS_UNKNOWN. The caller may not provide a default + * configuration in this case as the defaults are specific to a given bus type. + * This functionality is deprecated and should not be used in new drivers and it + * is only supported for CSI-2 D-PHY, parallel and Bt.656 busses. * - * The caller must set the bus_type field of @vep to zero. + * The function does not change the V4L2 fwnode endpoint state if it fails. * * v4l2_fwnode_endpoint_alloc_parse() has two important differences to * v4l2_fwnode_endpoint_parse(): @@ -183,7 +198,10 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); * 2. The memory it has allocated to store the variable size data must be freed * using v4l2_fwnode_endpoint_free() when no longer needed. * - * Return: 0 on success or a negative error code on failure. + * Return: %0 on success or a negative error code on failure: + * %-ENOMEM on memory allocation failure + * %-EINVAL on parsing failure + * %-ENXIO on mismatching bus types */ int v4l2_fwnode_endpoint_alloc_parse( struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep); -- cgit v1.2.3 From 6087b21533fed7b8eaade86097b279591bf42638 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 4 Oct 2018 17:10:46 -0400 Subject: media: v4l2-core: cleanup coding style at V4L2 async/fwnode There are several coding style issues at those definitions, and the previous patchset added even more. Address the trivial ones by first calling: ./scripts/checkpatch.pl --strict --fix-inline include/media/v4l2-async.h include/media/v4l2-fwnode.h include/media/v4l2-mediabus.h drivers/media/v4l2-core/v4l2-async.c drivers/media/v4l2-core/v4l2-fwnode.c and then manually adjusting the style where needed. Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-async.c | 45 +++++---- drivers/media/v4l2-core/v4l2-fwnode.c | 185 +++++++++++++++++++--------------- include/media/v4l2-async.h | 12 +-- include/media/v4l2-fwnode.h | 46 +++++---- include/media/v4l2-mediabus.h | 32 +++--- 5 files changed, 179 insertions(+), 141 deletions(-) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 70adbd9a01a2..a6d91370838d 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -57,6 +57,7 @@ static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) { #if IS_ENABLED(CONFIG_I2C) struct i2c_client *client = i2c_verify_client(sd->dev); + return client && asd->match.i2c.adapter_id == client->adapter->nr && asd->match.i2c.address == client->addr; @@ -89,10 +90,11 @@ static LIST_HEAD(subdev_list); static LIST_HEAD(notifier_list); static DEFINE_MUTEX(list_lock); -static struct v4l2_async_subdev *v4l2_async_find_match( - struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd) +static struct v4l2_async_subdev * +v4l2_async_find_match(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd) { - bool (*match)(struct v4l2_subdev *, struct v4l2_async_subdev *); + bool (*match)(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd); struct v4l2_async_subdev *asd; list_for_each_entry(asd, ¬ifier->waiting, list) { @@ -150,8 +152,8 @@ static bool asd_equal(struct v4l2_async_subdev *asd_x, } /* Find the sub-device notifier registered by a sub-device driver. */ -static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier( - struct v4l2_subdev *sd) +static struct v4l2_async_notifier * +v4l2_async_find_subdev_notifier(struct v4l2_subdev *sd) { struct v4l2_async_notifier *n; @@ -163,8 +165,8 @@ static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier( } /* Get v4l2_device related to the notifier if one can be found. */ -static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev( - struct v4l2_async_notifier *notifier) +static struct v4l2_device * +v4l2_async_notifier_find_v4l2_dev(struct v4l2_async_notifier *notifier) { while (notifier->parent) notifier = notifier->parent; @@ -175,8 +177,8 @@ static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev( /* * Return true if all child sub-device notifiers are complete, false otherwise. */ -static bool v4l2_async_notifier_can_complete( - struct v4l2_async_notifier *notifier) +static bool +v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier) { struct v4l2_subdev *sd; @@ -199,8 +201,8 @@ static bool v4l2_async_notifier_can_complete( * Complete the master notifier if possible. This is done when all async * sub-devices have been bound; v4l2_device is also available then. */ -static int v4l2_async_notifier_try_complete( - struct v4l2_async_notifier *notifier) +static int +v4l2_async_notifier_try_complete(struct v4l2_async_notifier *notifier) { /* Quick check whether there are still more sub-devices here. */ if (!list_empty(¬ifier->waiting)) @@ -221,8 +223,8 @@ static int v4l2_async_notifier_try_complete( return v4l2_async_notifier_call_complete(notifier); } -static int v4l2_async_notifier_try_all_subdevs( - struct v4l2_async_notifier *notifier); +static int +v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier); static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier, struct v4l2_device *v4l2_dev, @@ -268,8 +270,8 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier, } /* Test all async sub-devices in a notifier for a match. */ -static int v4l2_async_notifier_try_all_subdevs( - struct v4l2_async_notifier *notifier) +static int +v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier) { struct v4l2_device *v4l2_dev = v4l2_async_notifier_find_v4l2_dev(notifier); @@ -306,14 +308,17 @@ again: static void v4l2_async_cleanup(struct v4l2_subdev *sd) { v4l2_device_unregister_subdev(sd); - /* Subdevice driver will reprobe and put the subdev back onto the list */ + /* + * Subdevice driver will reprobe and put the subdev back + * onto the list + */ list_del_init(&sd->async_list); sd->asd = NULL; } /* Unbind all sub-devices in the notifier tree. */ -static void v4l2_async_notifier_unbind_all_subdevs( - struct v4l2_async_notifier *notifier) +static void +v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier) { struct v4l2_subdev *sd, *tmp; @@ -508,8 +513,8 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, } EXPORT_SYMBOL(v4l2_async_subdev_notifier_register); -static void __v4l2_async_notifier_unregister( - struct v4l2_async_notifier *notifier) +static void +__v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) { if (!notifier || (!notifier->v4l2_dev && !notifier->sd)) return; diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 6300b599c73d..4e518d5fddd8 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -211,7 +211,7 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, if (lanes_used & BIT(clock_lane)) { if (have_clk_lane || !use_default_lane_mapping) pr_warn("duplicated lane %u in clock-lanes, using defaults\n", - v); + v); use_default_lane_mapping = true; } @@ -265,9 +265,10 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, V4L2_MBUS_FIELD_EVEN_HIGH | \ V4L2_MBUS_FIELD_EVEN_LOW) -static void v4l2_fwnode_endpoint_parse_parallel_bus( - struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep, - enum v4l2_mbus_type bus_type) +static void +v4l2_fwnode_endpoint_parse_parallel_bus(struct fwnode_handle *fwnode, + struct v4l2_fwnode_endpoint *vep, + enum v4l2_mbus_type bus_type) { struct v4l2_fwnode_bus_parallel *bus = &vep->bus.parallel; unsigned int flags = 0; @@ -436,8 +437,7 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, if (mbus_type != V4L2_MBUS_UNKNOWN && vep->bus_type != mbus_type) { pr_debug("expecting bus type %s\n", - v4l2_fwnode_mbus_type_to_string( - vep->bus_type)); + v4l2_fwnode_mbus_type_to_string(vep->bus_type)); return -ENXIO; } } else { @@ -452,8 +452,8 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, return rval; if (vep->bus_type == V4L2_MBUS_UNKNOWN) - v4l2_fwnode_endpoint_parse_parallel_bus( - fwnode, vep, V4L2_MBUS_UNKNOWN); + v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep, + V4L2_MBUS_UNKNOWN); pr_debug("assuming media bus type %s (%u)\n", v4l2_fwnode_mbus_type_to_string(vep->bus_type), @@ -511,8 +511,8 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep) } EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free); -int v4l2_fwnode_endpoint_alloc_parse( - struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep) +int v4l2_fwnode_endpoint_alloc_parse(struct fwnode_handle *fwnode, + struct v4l2_fwnode_endpoint *vep) { int rval; @@ -533,9 +533,10 @@ int v4l2_fwnode_endpoint_alloc_parse( vep->nr_of_link_frequencies = rval; - rval = fwnode_property_read_u64_array( - fwnode, "link-frequencies", vep->link_frequencies, - vep->nr_of_link_frequencies); + rval = fwnode_property_read_u64_array(fwnode, + "link-frequencies", + vep->link_frequencies, + vep->nr_of_link_frequencies); if (rval < 0) { v4l2_fwnode_endpoint_free(vep); return rval; @@ -593,12 +594,14 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link) } EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link); -static int v4l2_async_notifier_fwnode_parse_endpoint( - struct device *dev, struct v4l2_async_notifier *notifier, - struct fwnode_handle *endpoint, unsigned int asd_struct_size, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) +static int +v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev, + struct v4l2_async_notifier *notifier, + struct fwnode_handle *endpoint, + unsigned int asd_struct_size, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) { struct v4l2_fwnode_endpoint vep = { .bus_type = 0 }; struct v4l2_async_subdev *asd; @@ -653,12 +656,14 @@ out_err: return ret == -ENOTCONN ? 0 : ret; } -static int __v4l2_async_notifier_parse_fwnode_endpoints( - struct device *dev, struct v4l2_async_notifier *notifier, - size_t asd_struct_size, unsigned int port, bool has_port, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) +static int +__v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, + struct v4l2_async_notifier *notifier, + size_t asd_struct_size, + unsigned int port, bool has_port, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) { struct fwnode_handle *fwnode; int ret = 0; @@ -687,8 +692,11 @@ static int __v4l2_async_notifier_parse_fwnode_endpoints( continue; } - ret = v4l2_async_notifier_fwnode_parse_endpoint( - dev, notifier, fwnode, asd_struct_size, parse_endpoint); + ret = v4l2_async_notifier_fwnode_parse_endpoint(dev, + notifier, + fwnode, + asd_struct_size, + parse_endpoint); if (ret < 0) break; } @@ -698,27 +706,33 @@ static int __v4l2_async_notifier_parse_fwnode_endpoints( return ret; } -int v4l2_async_notifier_parse_fwnode_endpoints( - struct device *dev, struct v4l2_async_notifier *notifier, - size_t asd_struct_size, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) +int +v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, + struct v4l2_async_notifier *notifier, + size_t asd_struct_size, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) { - return __v4l2_async_notifier_parse_fwnode_endpoints( - dev, notifier, asd_struct_size, 0, false, parse_endpoint); + return __v4l2_async_notifier_parse_fwnode_endpoints(dev, notifier, + asd_struct_size, 0, + false, + parse_endpoint); } EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints); -int v4l2_async_notifier_parse_fwnode_endpoints_by_port( - struct device *dev, struct v4l2_async_notifier *notifier, - size_t asd_struct_size, unsigned int port, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) +int +v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev, + struct v4l2_async_notifier *notifier, + size_t asd_struct_size, unsigned int port, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) { - return __v4l2_async_notifier_parse_fwnode_endpoints( - dev, notifier, asd_struct_size, port, true, parse_endpoint); + return __v4l2_async_notifier_parse_fwnode_endpoints(dev, notifier, + asd_struct_size, + port, true, + parse_endpoint); } EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port); @@ -733,17 +747,18 @@ EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port); * -ENOMEM if memory allocation failed * -EINVAL if property parsing failed */ -static int v4l2_fwnode_reference_parse( - struct device *dev, struct v4l2_async_notifier *notifier, - const char *prop) +static int v4l2_fwnode_reference_parse(struct device *dev, + struct v4l2_async_notifier *notifier, + const char *prop) { struct fwnode_reference_args args; unsigned int index; int ret; for (index = 0; - !(ret = fwnode_property_get_reference_args( - dev_fwnode(dev), prop, NULL, 0, index, &args)); + !(ret = fwnode_property_get_reference_args(dev_fwnode(dev), + prop, NULL, 0, + index, &args)); index++) fwnode_handle_put(args.fwnode); @@ -757,13 +772,15 @@ static int v4l2_fwnode_reference_parse( if (ret != -ENOENT && ret != -ENODATA) return ret; - for (index = 0; !fwnode_property_get_reference_args( - dev_fwnode(dev), prop, NULL, 0, index, &args); + for (index = 0; + !fwnode_property_get_reference_args(dev_fwnode(dev), prop, NULL, + 0, index, &args); index++) { struct v4l2_async_subdev *asd; - asd = v4l2_async_notifier_add_fwnode_subdev( - notifier, args.fwnode, sizeof(*asd)); + asd = v4l2_async_notifier_add_fwnode_subdev(notifier, + args.fwnode, + sizeof(*asd)); if (IS_ERR(asd)) { ret = PTR_ERR(asd); /* not an error if asd already exists */ @@ -939,9 +956,12 @@ error: * -EINVAL if property parsing otherwise failed * -ENOMEM if memory allocation failed */ -static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop( - struct fwnode_handle *fwnode, const char *prop, unsigned int index, - const char * const *props, unsigned int nprops) +static struct fwnode_handle * +v4l2_fwnode_reference_get_int_prop(struct fwnode_handle *fwnode, + const char *prop, + unsigned int index, + const char * const *props, + unsigned int nprops) { struct fwnode_reference_args fwnode_args; u64 *args = fwnode_args.args; @@ -1016,9 +1036,12 @@ static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop( * -EINVAL if property parsing otherwisefailed * -ENOMEM if memory allocation failed */ -static int v4l2_fwnode_reference_parse_int_props( - struct device *dev, struct v4l2_async_notifier *notifier, - const char *prop, const char * const *props, unsigned int nprops) +static int +v4l2_fwnode_reference_parse_int_props(struct device *dev, + struct v4l2_async_notifier *notifier, + const char *prop, + const char * const *props, + unsigned int nprops) { struct fwnode_handle *fwnode; unsigned int index; @@ -1044,9 +1067,12 @@ static int v4l2_fwnode_reference_parse_int_props( index++; } while (1); - for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop( - dev_fwnode(dev), prop, index, props, - nprops))); index++) { + for (index = 0; + !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(dev_fwnode(dev), + prop, index, + props, + nprops))); + index++) { struct v4l2_async_subdev *asd; asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, @@ -1070,8 +1096,8 @@ error: return ret; } -int v4l2_async_notifier_parse_fwnode_sensor_common( - struct device *dev, struct v4l2_async_notifier *notifier) +int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev, + struct v4l2_async_notifier *notifier) { static const char * const led_props[] = { "led" }; static const struct { @@ -1088,12 +1114,14 @@ int v4l2_async_notifier_parse_fwnode_sensor_common( int ret; if (props[i].props && is_acpi_node(dev_fwnode(dev))) - ret = v4l2_fwnode_reference_parse_int_props( - dev, notifier, props[i].name, - props[i].props, props[i].nprops); + ret = v4l2_fwnode_reference_parse_int_props(dev, + notifier, + props[i].name, + props[i].props, + props[i].nprops); else - ret = v4l2_fwnode_reference_parse( - dev, notifier, props[i].name); + ret = v4l2_fwnode_reference_parse(dev, notifier, + props[i].name); if (ret && ret != -ENOENT) { dev_warn(dev, "parsing property \"%s\" failed (%d)\n", props[i].name, ret); @@ -1147,12 +1175,12 @@ out_cleanup: } EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common); -int v4l2_async_register_fwnode_subdev( - struct v4l2_subdev *sd, size_t asd_struct_size, - unsigned int *ports, unsigned int num_ports, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) +int v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd, + size_t asd_struct_size, + unsigned int *ports, unsigned int num_ports, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) { struct v4l2_async_notifier *notifier; struct device *dev = sd->dev; @@ -1173,17 +1201,16 @@ int v4l2_async_register_fwnode_subdev( v4l2_async_notifier_init(notifier); if (!ports) { - ret = v4l2_async_notifier_parse_fwnode_endpoints( - dev, notifier, asd_struct_size, parse_endpoint); + ret = v4l2_async_notifier_parse_fwnode_endpoints(dev, notifier, + asd_struct_size, + parse_endpoint); if (ret < 0) goto out_cleanup; } else { unsigned int i; for (i = 0; i < num_ports; i++) { - ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port( - dev, notifier, asd_struct_size, - ports[i], parse_endpoint); + ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(dev, notifier, asd_struct_size, ports[i], parse_endpoint); if (ret < 0) goto out_cleanup; } diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 89b152f52ef9..1497bda66c3b 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -89,8 +89,8 @@ struct v4l2_async_subdev { unsigned short address; } i2c; struct { - bool (*match)(struct device *, - struct v4l2_async_subdev *); + bool (*match)(struct device *dev, + struct v4l2_async_subdev *sd); void *priv; } custom; } match; @@ -222,7 +222,6 @@ v4l2_async_notifier_add_devname_subdev(struct v4l2_async_notifier *notifier, const char *device_name, unsigned int asd_struct_size); - /** * v4l2_async_notifier_register - registers a subdevice asynchronous notifier * @@ -243,7 +242,8 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, struct v4l2_async_notifier *notifier); /** - * v4l2_async_notifier_unregister - unregisters a subdevice asynchronous notifier + * v4l2_async_notifier_unregister - unregisters a subdevice + * asynchronous notifier * * @notifier: pointer to &struct v4l2_async_notifier */ @@ -294,8 +294,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd); * An error is returned if the module is no longer loaded on any attempts * to register it. */ -int __must_check v4l2_async_register_subdev_sensor_common( - struct v4l2_subdev *sd); +int __must_check +v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd); /** * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index b4a49ca27579..21b3f9e5c269 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -71,8 +71,8 @@ struct v4l2_fwnode_bus_parallel { * @clock_lane: the number of the clock lane */ struct v4l2_fwnode_bus_mipi_csi1 { - bool clock_inv; - bool strobe; + unsigned char clock_inv:1; + unsigned char strobe:1; bool lane_polarity[2]; unsigned char data_lane; unsigned char clock_lane; @@ -203,8 +203,8 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); * %-EINVAL on parsing failure * %-ENXIO on mismatching bus types */ -int v4l2_fwnode_endpoint_alloc_parse( - struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep); +int v4l2_fwnode_endpoint_alloc_parse(struct fwnode_handle *fwnode, + struct v4l2_fwnode_endpoint *vep); /** * v4l2_fwnode_parse_link() - parse a link between two endpoints @@ -236,7 +236,6 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode, */ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link); - /** * typedef parse_endpoint_func - Driver's callback function to be called on * each V4L2 fwnode endpoint. @@ -255,7 +254,6 @@ typedef int (*parse_endpoint_func)(struct device *dev, struct v4l2_fwnode_endpoint *vep, struct v4l2_async_subdev *asd); - /** * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a * device node @@ -294,10 +292,11 @@ typedef int (*parse_endpoint_func)(struct device *dev, * %-EINVAL if graph or endpoint parsing failed * Other error codes as returned by @parse_endpoint */ -int v4l2_async_notifier_parse_fwnode_endpoints( - struct device *dev, struct v4l2_async_notifier *notifier, - size_t asd_struct_size, - parse_endpoint_func parse_endpoint); +int +v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, + struct v4l2_async_notifier *notifier, + size_t asd_struct_size, + parse_endpoint_func parse_endpoint); /** * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode @@ -345,10 +344,11 @@ int v4l2_async_notifier_parse_fwnode_endpoints( * %-EINVAL if graph or endpoint parsing failed * Other error codes as returned by @parse_endpoint */ -int v4l2_async_notifier_parse_fwnode_endpoints_by_port( - struct device *dev, struct v4l2_async_notifier *notifier, - size_t asd_struct_size, unsigned int port, - parse_endpoint_func parse_endpoint); +int +v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev, + struct v4l2_async_notifier *notifier, + size_t asd_struct_size, unsigned int port, + parse_endpoint_func parse_endpoint); /** * v4l2_fwnode_reference_parse_sensor_common - parse common references on @@ -368,8 +368,8 @@ int v4l2_async_notifier_parse_fwnode_endpoints_by_port( * -ENOMEM if memory allocation failed * -EINVAL if property parsing failed */ -int v4l2_async_notifier_parse_fwnode_sensor_common( - struct device *dev, struct v4l2_async_notifier *notifier); +int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev, + struct v4l2_async_notifier *notifier); /** * v4l2_async_register_fwnode_subdev - registers a sub-device to the @@ -401,11 +401,13 @@ int v4l2_async_notifier_parse_fwnode_sensor_common( * An error is returned if the module is no longer loaded on any attempts * to register it. */ -int v4l2_async_register_fwnode_subdev( - struct v4l2_subdev *sd, size_t asd_struct_size, - unsigned int *ports, unsigned int num_ports, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)); +int +v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd, + size_t asd_struct_size, + unsigned int *ports, + unsigned int num_ports, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)); #endif /* _V4L2_FWNODE_H */ diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index df1d552e9df6..66cb746ceeb5 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -14,7 +14,6 @@ #include #include - /* Parallel flags */ /* * Can the client run in master or in slave mode. By "Master mode" an operation @@ -63,10 +62,14 @@ #define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK BIT(8) #define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK BIT(9) -#define V4L2_MBUS_CSI2_LANES (V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_2_LANE | \ - V4L2_MBUS_CSI2_3_LANE | V4L2_MBUS_CSI2_4_LANE) -#define V4L2_MBUS_CSI2_CHANNELS (V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CHANNEL_1 | \ - V4L2_MBUS_CSI2_CHANNEL_2 | V4L2_MBUS_CSI2_CHANNEL_3) +#define V4L2_MBUS_CSI2_LANES (V4L2_MBUS_CSI2_1_LANE | \ + V4L2_MBUS_CSI2_2_LANE | \ + V4L2_MBUS_CSI2_3_LANE | \ + V4L2_MBUS_CSI2_4_LANE) +#define V4L2_MBUS_CSI2_CHANNELS (V4L2_MBUS_CSI2_CHANNEL_0 | \ + V4L2_MBUS_CSI2_CHANNEL_1 | \ + V4L2_MBUS_CSI2_CHANNEL_2 | \ + V4L2_MBUS_CSI2_CHANNEL_3) /** * enum v4l2_mbus_type - media bus type @@ -106,8 +109,9 @@ struct v4l2_mbus_config { * @pix_fmt: pointer to &struct v4l2_pix_format to be filled * @mbus_fmt: pointer to &struct v4l2_mbus_framefmt to be used as model */ -static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt, - const struct v4l2_mbus_framefmt *mbus_fmt) +static inline void +v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt, + const struct v4l2_mbus_framefmt *mbus_fmt) { pix_fmt->width = mbus_fmt->width; pix_fmt->height = mbus_fmt->height; @@ -128,7 +132,7 @@ static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt, * @code: data format code (from &enum v4l2_mbus_pixelcode) */ static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt, - const struct v4l2_pix_format *pix_fmt, + const struct v4l2_pix_format *pix_fmt, u32 code) { mbus_fmt->width = pix_fmt->width; @@ -148,9 +152,9 @@ static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt, * @pix_mp_fmt: pointer to &struct v4l2_pix_format_mplane to be filled * @mbus_fmt: pointer to &struct v4l2_mbus_framefmt to be used as model */ -static inline void v4l2_fill_pix_format_mplane( - struct v4l2_pix_format_mplane *pix_mp_fmt, - const struct v4l2_mbus_framefmt *mbus_fmt) +static inline void +v4l2_fill_pix_format_mplane(struct v4l2_pix_format_mplane *pix_mp_fmt, + const struct v4l2_mbus_framefmt *mbus_fmt) { pix_mp_fmt->width = mbus_fmt->width; pix_mp_fmt->height = mbus_fmt->height; @@ -168,9 +172,9 @@ static inline void v4l2_fill_pix_format_mplane( * @mbus_fmt: pointer to &struct v4l2_mbus_framefmt to be filled * @pix_mp_fmt: pointer to &struct v4l2_pix_format_mplane to be used as model */ -static inline void v4l2_fill_mbus_format_mplane( - struct v4l2_mbus_framefmt *mbus_fmt, - const struct v4l2_pix_format_mplane *pix_mp_fmt) +static inline void +v4l2_fill_mbus_format_mplane(struct v4l2_mbus_framefmt *mbus_fmt, + const struct v4l2_pix_format_mplane *pix_mp_fmt) { mbus_fmt->width = pix_mp_fmt->width; mbus_fmt->height = pix_mp_fmt->height; -- cgit v1.2.3 From c1e630559f2636607c4ef094c061c67f302c4883 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 4 Oct 2018 17:41:16 -0400 Subject: media: v4l2-fwnode: cleanup functions that parse endpoints There is already a typedef for the parse endpoint function. However, instead of using it, it is redefined at the C file (and on one of the function headers). Replace them by the function typedef, in order to cleanup several related coding style warnings. Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 64 +++++++++++++++-------------------- include/media/v4l2-fwnode.h | 19 +++++------ 2 files changed, 37 insertions(+), 46 deletions(-) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 4e518d5fddd8..a7c2487154a4 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -596,12 +596,10 @@ EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link); static int v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev, - struct v4l2_async_notifier *notifier, - struct fwnode_handle *endpoint, - unsigned int asd_struct_size, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) + struct v4l2_async_notifier *notifier, + struct fwnode_handle *endpoint, + unsigned int asd_struct_size, + parse_endpoint_func parse_endpoint) { struct v4l2_fwnode_endpoint vep = { .bus_type = 0 }; struct v4l2_async_subdev *asd; @@ -657,13 +655,12 @@ out_err: } static int -__v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, - struct v4l2_async_notifier *notifier, - size_t asd_struct_size, - unsigned int port, bool has_port, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) +__v4l2_async_notifier_parse_fwnode_ep(struct device *dev, + struct v4l2_async_notifier *notifier, + size_t asd_struct_size, + unsigned int port, + bool has_port, + parse_endpoint_func parse_endpoint) { struct fwnode_handle *fwnode; int ret = 0; @@ -708,31 +705,27 @@ __v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, int v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, - struct v4l2_async_notifier *notifier, - size_t asd_struct_size, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) + struct v4l2_async_notifier *notifier, + size_t asd_struct_size, + parse_endpoint_func parse_endpoint) { - return __v4l2_async_notifier_parse_fwnode_endpoints(dev, notifier, - asd_struct_size, 0, - false, - parse_endpoint); + return __v4l2_async_notifier_parse_fwnode_ep(dev, notifier, + asd_struct_size, 0, + false, parse_endpoint); } EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints); int v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev, - struct v4l2_async_notifier *notifier, - size_t asd_struct_size, unsigned int port, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) + struct v4l2_async_notifier *notifier, + size_t asd_struct_size, + unsigned int port, + parse_endpoint_func parse_endpoint) { - return __v4l2_async_notifier_parse_fwnode_endpoints(dev, notifier, - asd_struct_size, - port, true, - parse_endpoint); + return __v4l2_async_notifier_parse_fwnode_ep(dev, notifier, + asd_struct_size, + port, true, + parse_endpoint); } EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port); @@ -1176,11 +1169,10 @@ out_cleanup: EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common); int v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd, - size_t asd_struct_size, - unsigned int *ports, unsigned int num_ports, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)) + size_t asd_struct_size, + unsigned int *ports, + unsigned int num_ports, + parse_endpoint_func parse_endpoint) { struct v4l2_async_notifier *notifier; struct device *dev = sd->dev; diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 21b3f9e5c269..6d9d9f1839ac 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -346,9 +346,10 @@ v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, */ int v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev, - struct v4l2_async_notifier *notifier, - size_t asd_struct_size, unsigned int port, - parse_endpoint_func parse_endpoint); + struct v4l2_async_notifier *notifier, + size_t asd_struct_size, + unsigned int port, + parse_endpoint_func parse_endpoint); /** * v4l2_fwnode_reference_parse_sensor_common - parse common references on @@ -369,7 +370,7 @@ v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev, * -EINVAL if property parsing failed */ int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev, - struct v4l2_async_notifier *notifier); + struct v4l2_async_notifier *notifier); /** * v4l2_async_register_fwnode_subdev - registers a sub-device to the @@ -403,11 +404,9 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev, */ int v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd, - size_t asd_struct_size, - unsigned int *ports, - unsigned int num_ports, - int (*parse_endpoint)(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd)); + size_t asd_struct_size, + unsigned int *ports, + unsigned int num_ports, + parse_endpoint_func parse_endpoint); #endif /* _V4L2_FWNODE_H */ -- cgit v1.2.3 From 7a9b109d91cfc6089006378efd515cc287bdef67 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 19 Jul 2018 07:11:40 -0400 Subject: media: v4l: ctrl: Provide unlocked variant of v4l2_ctrl_grab Sometimes it may be necessary to grab a control while holding the control handler's lock. Provide an unlocked variant of v4l2_ctrl_grab for the purpose --- it's called __v4l2_ctrl_grab. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ctrls.c | 8 ++++---- include/media/v4l2-ctrls.h | 26 +++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 5 deletions(-) (limited to 'include/media') diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index ab393adf51eb..4c0ecf29d278 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -2511,14 +2511,15 @@ void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active) } EXPORT_SYMBOL(v4l2_ctrl_activate); -void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed) +void __v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed) { bool old; if (ctrl == NULL) return; - v4l2_ctrl_lock(ctrl); + lockdep_assert_held(ctrl->handler->lock); + if (grabbed) /* set V4L2_CTRL_FLAG_GRABBED */ old = test_and_set_bit(1, &ctrl->flags); @@ -2527,9 +2528,8 @@ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed) old = test_and_clear_bit(1, &ctrl->flags); if (old != grabbed) send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS); - v4l2_ctrl_unlock(ctrl); } -EXPORT_SYMBOL(v4l2_ctrl_grab); +EXPORT_SYMBOL(__v4l2_ctrl_grab); /* Log the control name and value */ static void log_ctrl(const struct v4l2_ctrl *ctrl, diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index f615ba1b29dd..ff89df428f79 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -728,6 +728,22 @@ struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id); */ void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active); +/** + * __v4l2_ctrl_grab() - Unlocked variant of v4l2_ctrl_grab. + * + * @ctrl: The control to (de)activate. + * @grabbed: True if the control should become grabbed. + * + * This sets or clears the V4L2_CTRL_FLAG_GRABBED flag atomically. + * Does nothing if @ctrl == NULL. + * The V4L2_EVENT_CTRL event will be generated afterwards. + * This will usually be called when starting or stopping streaming in the + * driver. + * + * This function assumes that the control handler is locked by the caller. + */ +void __v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed); + /** * v4l2_ctrl_grab() - Mark the control as grabbed or not grabbed. * @@ -743,7 +759,15 @@ void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active); * This function assumes that the control handler is not locked and will * take the lock itself. */ -void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed); +static inline void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed) +{ + if (!ctrl) + return; + + v4l2_ctrl_lock(ctrl); + __v4l2_ctrl_grab(ctrl, grabbed); + v4l2_ctrl_unlock(ctrl); +} /** *__v4l2_ctrl_modify_range() - Unlocked variant of v4l2_ctrl_modify_range() -- cgit v1.2.3 From 7d867a1b765e2b70815fec4964d7822a976ed349 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Oct 2018 08:00:21 -0400 Subject: media: cec: fix the Signal Free Time calculation The calculation of the Signal Free Time in the framework was not correct. If a message was received, then the next transmit should be considered a New Initiator and use a shorter SFT value. This was not done with the result that if both sides where continually sending messages, they both could use the same SFT value and one side could deny the other side access to the bus. Note that this fix does not take the corner case into account where a receive is in progress when you call adap_transmit. Signed-off-by: Hans Verkuil Cc: # for v4.18 and up Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 26 +++++++------------------- include/media/cec.h | 2 +- 2 files changed, 8 insertions(+), 20 deletions(-) (limited to 'include/media') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index e6e82b504e56..0c0d9107383e 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -526,9 +526,11 @@ int cec_thread_func(void *_adap) if (data->attempts) { /* should be >= 3 data bit periods for a retry */ signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY; - } else if (data->new_initiator) { + } else if (adap->last_initiator != + cec_msg_initiator(&data->msg)) { /* should be >= 5 data bit periods for new initiator */ signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR; + adap->last_initiator = cec_msg_initiator(&data->msg); } else { /* * should be >= 7 data bit periods for sending another @@ -713,7 +715,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, struct cec_fh *fh, bool block) { struct cec_data *data; - u8 last_initiator = 0xff; msg->rx_ts = 0; msg->tx_ts = 0; @@ -823,23 +824,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, data->adap = adap; data->blocking = block; - /* - * Determine if this message follows a message from the same - * initiator. Needed to determine the free signal time later on. - */ - if (msg->len > 1) { - if (!(list_empty(&adap->transmit_queue))) { - const struct cec_data *last; - - last = list_last_entry(&adap->transmit_queue, - const struct cec_data, list); - last_initiator = cec_msg_initiator(&last->msg); - } else if (adap->transmitting) { - last_initiator = - cec_msg_initiator(&adap->transmitting->msg); - } - } - data->new_initiator = last_initiator != cec_msg_initiator(msg); init_completion(&data->c); INIT_DELAYED_WORK(&data->work, cec_wait_timeout); @@ -1027,6 +1011,8 @@ void cec_received_msg_ts(struct cec_adapter *adap, mutex_lock(&adap->lock); dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg); + adap->last_initiator = 0xff; + /* Check if this message was for us (directed or broadcast). */ if (!cec_msg_is_broadcast(msg)) valid_la = cec_has_log_addr(adap, msg_dest); @@ -1489,6 +1475,8 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) } mutex_lock(&adap->devnode.lock); + adap->last_initiator = 0xff; + if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) && adap->ops->adap_enable(adap, true)) { mutex_unlock(&adap->devnode.lock); diff --git a/include/media/cec.h b/include/media/cec.h index 9f382f0c2970..254a610b9aa5 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -63,7 +63,6 @@ struct cec_data { struct delayed_work work; struct completion c; u8 attempts; - bool new_initiator; bool blocking; bool completed; }; @@ -174,6 +173,7 @@ struct cec_adapter { bool is_configuring; bool is_configured; bool cec_pin_is_high; + u8 last_initiator; u32 monitor_all_cnt; u32 monitor_pin_cnt; u32 follower_cnt; -- cgit v1.2.3 From 557c97b5133669297be561e6091da9ab6e488e65 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 4 Oct 2018 18:21:13 -0400 Subject: media: cec: name for RC passthrough device does not need 'RC for' An RC device is does not need to be called 'RC for'. Simply the name will suffice. Signed-off-by: Sean Young Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-core.c | 6 ++---- include/media/cec.h | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'include/media') diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index 74596f089ec9..e4edc930d4ed 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -307,12 +307,10 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, return ERR_PTR(-ENOMEM); } - snprintf(adap->device_name, sizeof(adap->device_name), - "RC for %s", name); snprintf(adap->input_phys, sizeof(adap->input_phys), - "%s/input0", name); + "%s/input0", adap->name); - adap->rc->device_name = adap->device_name; + adap->rc->device_name = adap->name; adap->rc->input_phys = adap->input_phys; adap->rc->input_id.bustype = BUS_CEC; adap->rc->input_id.vendor = 0; diff --git a/include/media/cec.h b/include/media/cec.h index 254a610b9aa5..3fe5e5d2bb7e 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -198,9 +198,7 @@ struct cec_adapter { u16 phys_addrs[15]; u32 sequence; - char device_name[32]; char input_phys[32]; - char input_drv[32]; }; static inline void *cec_get_drvdata(const struct cec_adapter *adap) -- cgit v1.2.3