From c10597366f60ff6bceba5386e9694634fb90c4ec Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sat, 30 Nov 2024 12:36:32 +0100 Subject: [PATCH 01/16] MAINTAINERS: Update own email address from Bootlin to sys-base Update my email address as I am no longer working at Bootlin and have started my own consulting company: sys-base. Signed-off-by: Paul Kocialkowski Signed-off-by: Hans Verkuil --- MAINTAINERS | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1e930c7a58b1..1ec1aa2684e5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -816,7 +816,7 @@ F: drivers/media/platform/sunxi/sun4i-csi/ ALLWINNER A31 CSI DRIVER M: Yong Deng -M: Paul Kocialkowski +M: Paul Kocialkowski L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media.git @@ -824,7 +824,7 @@ F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml F: drivers/media/platform/sunxi/sun6i-csi/ ALLWINNER A31 ISP DRIVER -M: Paul Kocialkowski +M: Paul Kocialkowski L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media.git @@ -833,7 +833,7 @@ F: drivers/staging/media/sunxi/sun6i-isp/ F: drivers/staging/media/sunxi/sun6i-isp/uapi/sun6i-isp-config.h ALLWINNER A31 MIPI CSI-2 BRIDGE DRIVER -M: Paul Kocialkowski +M: Paul Kocialkowski L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media.git @@ -876,7 +876,7 @@ F: drivers/thermal/sun8i_thermal.c ALLWINNER VPU DRIVER M: Maxime Ripard -M: Paul Kocialkowski +M: Paul Kocialkowski L: linux-media@vger.kernel.org S: Maintained F: drivers/staging/media/sunxi/cedrus/ @@ -7234,7 +7234,7 @@ F: Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml F: drivers/gpu/drm/panel/panel-lg-sw43408.c DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER -M: Paul Kocialkowski +M: Paul Kocialkowski S: Supported T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/gpu/drm/logicvc/ -- 2.49.0 From 53b01a5fdb41762db79a3f3192b209f6ccff805b Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Tue, 26 Nov 2024 15:31:25 +0530 Subject: [PATCH 02/16] media: qcom: camss: reducing the repitious error message string Introducing a new function camss_link_err to avoid repition of same error message, improving code maintainability. Signed-off-by: Vikram Sharma Reviewed-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil --- drivers/media/platform/qcom/camss/camss.c | 58 ++++++++++++++--------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 9fb31f4c18ad..6824ffbdf4a8 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -1993,6 +1993,24 @@ static int camss_init_subdevices(struct camss *camss) return 0; } +/* + * camss_link_entities - Register subdev nodes and create links + * camss_link_err - print error in case link creation fails + * @src_name: name for source of the link + * @sink_name: name for sink of the link + */ +inline void camss_link_err(struct camss *camss, + const char *src_name, + const char *sink_name, + int ret) +{ + dev_err(camss->dev, + "Failed to link %s->%s entities: %d\n", + src_name, + sink_name, + ret); +} + /* * camss_link_entities - Register subdev nodes and create links * @camss: CAMSS device @@ -2012,11 +2030,10 @@ static int camss_link_entities(struct camss *camss) MSM_CSID_PAD_SINK, 0); if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - camss->csiphy[i].subdev.entity.name, - camss->csid[j].subdev.entity.name, - ret); + camss_link_err(camss, + camss->csiphy[i].subdev.entity.name, + camss->csid[j].subdev.entity.name, + ret); return ret; } } @@ -2031,11 +2048,10 @@ static int camss_link_entities(struct camss *camss) MSM_ISPIF_PAD_SINK, 0); if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - camss->csid[i].subdev.entity.name, - camss->ispif->line[j].subdev.entity.name, - ret); + camss_link_err(camss, + camss->csid[i].subdev.entity.name, + camss->ispif->line[j].subdev.entity.name, + ret); return ret; } } @@ -2053,11 +2069,9 @@ static int camss_link_entities(struct camss *camss) MSM_VFE_PAD_SINK, 0); if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - ispif->entity.name, - vfe->entity.name, - ret); + camss_link_err(camss, ispif->entity.name, + vfe->entity.name, + ret); return ret; } } @@ -2074,11 +2088,9 @@ static int camss_link_entities(struct camss *camss) MSM_VFE_PAD_SINK, 0); if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - csid->entity.name, - vfe->entity.name, - ret); + camss_link_err(camss, csid->entity.name, + vfe->entity.name, + ret); return ret; } } @@ -2227,9 +2239,9 @@ static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async) input, MSM_CSIPHY_PAD_SINK, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - sensor->name, input->name, ret); + camss_link_err(camss, sensor->name, + input->name, + ret); return ret; } } -- 2.49.0 From cc1ecabe67d92a2da0b0402f715598e8dbdc3b9e Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Tue, 26 Nov 2024 15:31:26 +0530 Subject: [PATCH 03/16] media: qcom: camss: Restructure camss_link_entities Refactor the camss_link_entities function by breaking it down into three distinct functions. Each function will handle the linking of a specific entity separately. SC7280 and later targets mandates for 1:1 linking for csid -> vfe. i.e. csid0 can be mapped to vfe0 only. Signed-off-by: Suresh Vankadara Signed-off-by: Trishansh Bhardwaj Signed-off-by: Vikram Sharma Reviewed-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil --- drivers/media/platform/qcom/camss/camss.c | 155 ++++++++++++++-------- 1 file changed, 103 insertions(+), 52 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 6824ffbdf4a8..67fb11cbe865 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -1994,7 +1994,6 @@ static int camss_init_subdevices(struct camss *camss) } /* - * camss_link_entities - Register subdev nodes and create links * camss_link_err - print error in case link creation fails * @src_name: name for source of the link * @sink_name: name for sink of the link @@ -2012,14 +2011,64 @@ inline void camss_link_err(struct camss *camss, } /* - * camss_link_entities - Register subdev nodes and create links + * camss_link_entities_csid - Register subdev nodes and create links * @camss: CAMSS device * * Return 0 on success or a negative error code on failure */ -static int camss_link_entities(struct camss *camss) +static int camss_link_entities_csid(struct camss *camss) { - int i, j, k; + struct media_entity *src_entity; + struct media_entity *sink_entity; + int ret, line_num; + u16 sink_pad; + u16 src_pad; + int i, j; + + for (i = 0; i < camss->res->csid_num; i++) { + if (camss->ispif) + line_num = camss->ispif->line_num; + else + line_num = camss->vfe[i].res->line_num; + + src_entity = &camss->csid[i].subdev.entity; + for (j = 0; j < line_num; j++) { + if (camss->ispif) { + sink_entity = &camss->ispif->line[j].subdev.entity; + src_pad = MSM_CSID_PAD_SRC; + sink_pad = MSM_ISPIF_PAD_SINK; + } else { + sink_entity = &camss->vfe[i].line[j].subdev.entity; + src_pad = MSM_CSID_PAD_FIRST_SRC + j; + sink_pad = MSM_VFE_PAD_SINK; + } + + ret = media_create_pad_link(src_entity, + src_pad, + sink_entity, + sink_pad, + 0); + if (ret < 0) { + camss_link_err(camss, src_entity->name, + sink_entity->name, + ret); + return ret; + } + } + } + + return 0; +} + +/* + * camss_link_entities_csiphy - Register subdev nodes and create links + * @camss: CAMSS device + * + * Return 0 on success or a negative error code on failure + */ +static int camss_link_entities_csiphy(struct camss *camss) +{ + int i, j; int ret; for (i = 0; i < camss->res->csiphy_num; i++) { @@ -2039,66 +2088,68 @@ static int camss_link_entities(struct camss *camss) } } - if (camss->ispif) { - for (i = 0; i < camss->res->csid_num; i++) { - for (j = 0; j < camss->ispif->line_num; j++) { - ret = media_create_pad_link(&camss->csid[i].subdev.entity, - MSM_CSID_PAD_SRC, - &camss->ispif->line[j].subdev.entity, - MSM_ISPIF_PAD_SINK, + return 0; +} + +/* + * camss_link_entities_ispif - Register subdev nodes and create links + * @camss: CAMSS device + * + * Return 0 on success or a negative error code on failure + */ +static int camss_link_entities_ispif(struct camss *camss) +{ + int i, j, k; + int ret; + + for (i = 0; i < camss->ispif->line_num; i++) { + for (k = 0; k < camss->res->vfe_num; k++) { + for (j = 0; j < camss->vfe[k].res->line_num; j++) { + struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev; + struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; + + ret = media_create_pad_link(&ispif->entity, + MSM_ISPIF_PAD_SRC, + &vfe->entity, + MSM_VFE_PAD_SINK, 0); if (ret < 0) { - camss_link_err(camss, - camss->csid[i].subdev.entity.name, - camss->ispif->line[j].subdev.entity.name, + camss_link_err(camss, ispif->entity.name, + vfe->entity.name, ret); return ret; } } } - - for (i = 0; i < camss->ispif->line_num; i++) - for (k = 0; k < camss->res->vfe_num; k++) - for (j = 0; j < camss->vfe[k].res->line_num; j++) { - struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev; - struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; - - ret = media_create_pad_link(&ispif->entity, - MSM_ISPIF_PAD_SRC, - &vfe->entity, - MSM_VFE_PAD_SINK, - 0); - if (ret < 0) { - camss_link_err(camss, ispif->entity.name, - vfe->entity.name, - ret); - return ret; - } - } - } else { - for (i = 0; i < camss->res->csid_num; i++) - for (k = 0; k < camss->res->vfe_num; k++) - for (j = 0; j < camss->vfe[k].res->line_num; j++) { - struct v4l2_subdev *csid = &camss->csid[i].subdev; - struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; - - ret = media_create_pad_link(&csid->entity, - MSM_CSID_PAD_FIRST_SRC + j, - &vfe->entity, - MSM_VFE_PAD_SINK, - 0); - if (ret < 0) { - camss_link_err(camss, csid->entity.name, - vfe->entity.name, - ret); - return ret; - } - } } return 0; } +/* + * camss_link_entities - Register subdev nodes and create links + * @camss: CAMSS device + * + * Return 0 on success or a negative error code on failure + */ +static int camss_link_entities(struct camss *camss) +{ + int ret; + + ret = camss_link_entities_csiphy(camss); + if (ret < 0) + return ret; + + ret = camss_link_entities_csid(camss); + if (ret < 0) + return ret; + + if (camss->ispif) + ret = camss_link_entities_ispif(camss); + + return ret; +} + /* * camss_register_entities - Register subdev nodes and create links * @camss: CAMSS device -- 2.49.0 From b3347d7d618dbe94c73b4091781cb99023f295b6 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Thu, 28 Nov 2024 15:01:36 -0500 Subject: [PATCH 04/16] media: qcom: camss: document csiphy_lanes_cfg structure Add documentation for struct csiphy_lanes_cfg. Signed-off-by: Caleb Connolly Signed-off-by: David Heidelberg Acked-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil [hverkuil: added missing commit description] --- drivers/media/platform/qcom/camss/camss-csiphy.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index eebc1ff1cfab..e3b9e8f12806 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -26,6 +26,12 @@ struct csiphy_lane { u8 pol; }; +/** + * struct csiphy_lanes_cfg - CSIPHY lanes configuration + * @num_data: number of data lanes + * @data: data lanes configuration + * @clk: clock lane configuration (only for D-PHY) + */ struct csiphy_lanes_cfg { int num_data; struct csiphy_lane *data; -- 2.49.0 From c04e4bae9097a1ac62c6e8b1e0c485274f56a720 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 27 Nov 2024 14:29:45 +0200 Subject: [PATCH 05/16] dt-bindings: media: qcom,sc8280xp-camss: Fix interrupt types Qualcomm IP catalog says that all CAMSS interrupts are edge rising, fix it in the documented example from CAMSS device tree bindings for sc8280xp SoC. Fixes: bc5191e5799e ("media: dt-bindings: media: camss: Add qcom,sc8280xp-camss binding") Signed-off-by: Vladimir Zapolskiy Acked-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil --- .../bindings/media/qcom,sc8280xp-camss.yaml | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,sc8280xp-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sc8280xp-camss.yaml index c0bc31709873..9936f0132417 100644 --- a/Documentation/devicetree/bindings/media/qcom,sc8280xp-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,sc8280xp-camss.yaml @@ -328,26 +328,26 @@ examples: vdda-phy-supply = <&vreg_l6d>; vdda-pll-supply = <&vreg_l4d>; - interrupts = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; interrupt-names = "csid1_lite", "vfe_lite1", -- 2.49.0 From 349396bb55c4dfaa3b8cb0415c782af555e21c8a Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 27 Nov 2024 14:29:46 +0200 Subject: [PATCH 06/16] dt-bindings: media: qcom,sdm845-camss: Fix interrupt types Qualcomm IP catalog says that all CAMSS interrupts are edge rising, fix it in the documented example from CAMSS device tree bindings for sdm845 SoC. Fixes: d1d5ce260165 ("media: dt-bindings: media: camss: Add qcom,sdm845-camss binding") Signed-off-by: Vladimir Zapolskiy Acked-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil --- .../bindings/media/qcom,sdm845-camss.yaml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml index ec4380a0a03f..d32daaef1b50 100644 --- a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml @@ -296,16 +296,16 @@ examples: "vfe_lite_cphy_rx", "vfe_lite_src"; - interrupts = , - , - , - , - , - , - , - , - , - ; + interrupts = , + , + , + , + , + , + , + , + , + ; interrupt-names = "csid0", "csid1", -- 2.49.0 From d1028b5748164e3ddd6d2bb0bbceee846ed2fc71 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 27 Nov 2024 14:29:47 +0200 Subject: [PATCH 07/16] dt-bindings: media: qcom,sm8250-camss: Fix interrupt types Qualcomm IP catalog says that all CAMSS interrupts are edge rising, fix it in the documented example from CAMSS device tree bindings for SM8250 SoC. Fixes: 46f8ac8497c5 ("media: dt-bindings: media: camss: Add qcom,sm8250-camss binding") Signed-off-by: Vladimir Zapolskiy Acked-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil --- .../bindings/media/qcom,sm8250-camss.yaml | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml index fa5073c0fd1e..06db2c1e6079 100644 --- a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml @@ -329,20 +329,20 @@ examples: vdda-phy-supply = <&vreg_l5a_0p88>; vdda-pll-supply = <&vreg_l9a_1p2>; - interrupts = , - , - , - , - , - , - , - , - , - , - , - , - , - ; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + ; interrupt-names = "csiphy0", "csiphy1", "csiphy2", -- 2.49.0 From 86e5e8efb82cbee416e726e141decdc9e1a2d5f3 Mon Sep 17 00:00:00 2001 From: Dheeraj Reddy Jonnalagadda Date: Tue, 19 Nov 2024 12:56:53 +0530 Subject: [PATCH 08/16] media: rkisp1: Fix unused value issue This commit fixes an unused value issue detected by Coverity (CID 1519008). The error condition for the invalid MIPI CSI-2 is not properly handled as the break statement would only exit the switch block and not the entire loop. Fix this by breaking from the look immediately after the switch block when an error occurs. Signed-off-by: Dheeraj Reddy Jonnalagadda Fixes: 7d4f126fde89 ("media: rkisp1: Make the internal CSI-2 receiver optional") Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Link: https://lore.kernel.org/r/20241119072653.72260-1-dheeraj.linuxdev@gmail.com Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index 0100b9c3edbe..dc65a7924f8a 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -228,6 +228,9 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1) break; } + if (ret) + break; + /* Parse the endpoint and validate the bus type. */ ret = v4l2_fwnode_endpoint_parse(ep, &vep); if (ret) { -- 2.49.0 From 6c10d1adae82e1c8da16e7ebd2320e69f20b9d6f Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Mon, 7 Oct 2024 14:42:24 +0200 Subject: [PATCH 09/16] media: rkisp1: Reduce min_queued_buffers to 1 There apparently is no reason to require 3 queued buffers to call streamon() for the RkISP1 as the driver operates with a scratch buffer where frames can be directed to if there's no available buffer provided by userspace. Reduce the number of required buffers to 1 to allow applications to operate with a single queued buffer. Tested with libcamera, by operating with a single capture request. The same request (and associated capture buffer) gets recycled once completed. This of course causes a frame rate drop but doesn't hinder operations. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20241007124225.63463-1-jacopo.mondi@ideasonboard.com Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c index 02339cd94486..6dcefd144d5a 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c @@ -35,8 +35,6 @@ #define RKISP1_SP_DEV_NAME RKISP1_DRIVER_NAME "_selfpath" #define RKISP1_MP_DEV_NAME RKISP1_DRIVER_NAME "_mainpath" -#define RKISP1_MIN_BUFFERS_NEEDED 3 - enum rkisp1_plane { RKISP1_PLANE_Y = 0, RKISP1_PLANE_CB = 1, @@ -1561,7 +1559,7 @@ static int rkisp1_register_capture(struct rkisp1_capture *cap) q->ops = &rkisp1_vb2_ops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct rkisp1_buffer); - q->min_queued_buffers = RKISP1_MIN_BUFFERS_NEEDED; + q->min_queued_buffers = 1; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->lock = &node->vlock; q->dev = cap->rkisp1->dev; -- 2.49.0 From 11c7fd6e0f62b24b3e6b0558bcbd0c3bbf541718 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sun, 13 Oct 2024 00:39:32 +0100 Subject: [PATCH 10/16] media: cx18: Remove unused cx18_reset_ir_gpio cx18_reset_ir_gpio() has been unused in tree since 2009 commit eefe1010a465 ("V4L/DVB (10759): cx18: Convert GPIO connected functions to act as v4l2_subdevices") It has a comment saying it's exported for use by 'lirc_pvr150' but I don't see any sign of it in the lirc git, and I see it removed support for lirc_i2c.c 'Flavors of the Hauppage PVR-150...' in 2014. Remove it. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-gpio.c | 15 --------------- drivers/media/pci/cx18/cx18-gpio.h | 1 - 2 files changed, 16 deletions(-) diff --git a/drivers/media/pci/cx18/cx18-gpio.c b/drivers/media/pci/cx18/cx18-gpio.c index c85eb8d25837..485a6cbeb15a 100644 --- a/drivers/media/pci/cx18/cx18-gpio.c +++ b/drivers/media/pci/cx18/cx18-gpio.c @@ -305,21 +305,6 @@ int cx18_gpio_register(struct cx18 *cx, u32 hw) return v4l2_device_register_subdev(&cx->v4l2_dev, sd); } -void cx18_reset_ir_gpio(void *data) -{ - struct cx18 *cx = to_cx18(data); - - if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0) - return; - - CX18_DEBUG_INFO("Resetting IR microcontroller\n"); - - v4l2_subdev_call(&cx->sd_resetctrl, - core, reset, CX18_GPIO_RESET_Z8F0811); -} -EXPORT_SYMBOL(cx18_reset_ir_gpio); -/* This symbol is exported for use by lirc_pvr150 for the IR-blaster */ - /* Xceive tuner reset function */ int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value) { diff --git a/drivers/media/pci/cx18/cx18-gpio.h b/drivers/media/pci/cx18/cx18-gpio.h index 0fa4c7ad2286..8d5797dea7f5 100644 --- a/drivers/media/pci/cx18/cx18-gpio.h +++ b/drivers/media/pci/cx18/cx18-gpio.h @@ -17,5 +17,4 @@ enum cx18_gpio_reset_type { CX18_GPIO_RESET_XC2028 = 2, }; -void cx18_reset_ir_gpio(void *data); int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value); -- 2.49.0 From b5e7850cc87e749edd6bbb2bc2d071900ed4afd3 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 28 Oct 2024 15:59:26 +0000 Subject: [PATCH 11/16] media: mceusb: don't push static constants on stack for %*ph There is no need to pass constants via stack. The width may be explicitly specified in the format. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mceusb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index cd7af4d88b7f..d5ea3868d5a3 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -658,8 +658,8 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, u8 *buf, int buf_len, if (len == 2) dev_dbg(dev, "Get hw/sw rev?"); else - dev_dbg(dev, "hw/sw rev %*ph", - 4, &buf[offset + 2]); + dev_dbg(dev, "hw/sw rev %4ph", + &buf[offset + 2]); break; case MCE_CMD_RESUME: dev_dbg(dev, "Device resume requested"); -- 2.49.0 From ef2cc59cb623444a5b57ce55b336e0185f78e762 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 28 Oct 2024 15:59:27 +0000 Subject: [PATCH 12/16] media: imon: don't push static constants on stack for %*ph There is no need to pass constants via stack. The width may be explicitly specified in the format. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/imon_raw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c index b02ded52f19e..3a526dea6532 100644 --- a/drivers/media/rc/imon_raw.c +++ b/drivers/media/rc/imon_raw.c @@ -37,7 +37,7 @@ static void imon_ir_data(struct imon *imon) if (packet_no == 0xff) return; - dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf); + dev_dbg(imon->dev, "data: %8ph", imon->ir_buf); /* * Only the first 5 bytes contain IR data. Right shift so we move -- 2.49.0 From ff8f969da0532fd4220eaa1ddfbd9cabdf20476c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 18 Nov 2024 08:29:06 +0100 Subject: [PATCH 13/16] media: mceusb: don't include 'pm_wakeup.h' directly The header clearly states that it does not want to be included directly, only via 'device.h'. 'platform_device.h' works equally well. Remove the direct inclusion. Signed-off-by: Wolfram Sang Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mceusb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index d5ea3868d5a3..044767eb3a38 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #define DRIVER_VERSION "1.95" -- 2.49.0 From b98d5000c50544f14bacb248c34e5219fbe81287 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 26 Nov 2024 14:17:22 +0100 Subject: [PATCH 14/16] media: rc: iguanair: handle timeouts In case of a timeout the IO must be cancelled or the next IO using the URB will fail and/or overwrite an operational URB. The automatic bisection fails because it arrives at a commit that correctly lets the test case run without an error. Signed-off-by: Oliver Neukum Fixes: e99a7cfe93fd ("[media] iguanair: reuse existing urb callback for command responses") Reported-by: syzbot+ffba8e636870dac0e0c0@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/66f5cc9a.050a0220.46d20.0004.GAE@google.com/ Tested-by: syzbot+ffba8e636870dac0e0c0@syzkaller.appspotmail.com Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/iguanair.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index 276bf3c8a8cb..8af94246e591 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -194,8 +194,10 @@ static int iguanair_send(struct iguanair *ir, unsigned size) if (rc) return rc; - if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) + if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) { + usb_kill_urb(ir->urb_out); return -ETIMEDOUT; + } return rc; } -- 2.49.0 From 5593555343f3ec299ca28d46a478e718c1119f74 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Sat, 7 Dec 2024 00:48:56 +0530 Subject: [PATCH 15/16] media: dt-bindings: Add qcom,sc7280-camss Add bindings for qcom,sc7280-camss to support the camera subsystem on the SC7280 platform. Signed-off-by: Suresh Vankadara Signed-off-by: Trishansh Bhardwaj Signed-off-by: Vikram Sharma Reviewed-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil --- .../bindings/media/qcom,sc7280-camss.yaml | 425 ++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml diff --git a/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml new file mode 100644 index 000000000000..e11141b812a0 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml @@ -0,0 +1,425 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/qcom,sc7280-camss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SC7280 CAMSS ISP + +maintainers: + - Azam Sadiq Pasha Kapatrala Syed + - Hariram Purushothaman + +description: + The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms. + +properties: + compatible: + const: qcom,sc7280-camss + + reg: + maxItems: 15 + + reg-names: + items: + - const: csid0 + - const: csid1 + - const: csid2 + - const: csid_lite0 + - const: csid_lite1 + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: csiphy3 + - const: csiphy4 + - const: vfe0 + - const: vfe1 + - const: vfe2 + - const: vfe_lite0 + - const: vfe_lite1 + + clocks: + maxItems: 33 + + clock-names: + items: + - const: camnoc_axi + - const: cpas_ahb + - const: csiphy0 + - const: csiphy0_timer + - const: csiphy1 + - const: csiphy1_timer + - const: csiphy2 + - const: csiphy2_timer + - const: csiphy3 + - const: csiphy3_timer + - const: csiphy4 + - const: csiphy4_timer + - const: gcc_camera_ahb + - const: gcc_cam_hf_axi + - const: icp_ahb + - const: vfe0 + - const: vfe0_axi + - const: vfe0_cphy_rx + - const: vfe0_csid + - const: vfe1 + - const: vfe1_axi + - const: vfe1_cphy_rx + - const: vfe1_csid + - const: vfe2 + - const: vfe2_axi + - const: vfe2_cphy_rx + - const: vfe2_csid + - const: vfe_lite0 + - const: vfe_lite0_cphy_rx + - const: vfe_lite0_csid + - const: vfe_lite1 + - const: vfe_lite1_cphy_rx + - const: vfe_lite1_csid + + interrupts: + maxItems: 15 + + interrupt-names: + items: + - const: csid0 + - const: csid1 + - const: csid2 + - const: csid_lite0 + - const: csid_lite1 + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: csiphy3 + - const: csiphy4 + - const: vfe0 + - const: vfe1 + - const: vfe2 + - const: vfe_lite0 + - const: vfe_lite1 + + interconnects: + maxItems: 2 + + interconnect-names: + items: + - const: ahb + - const: hf_0 + + iommus: + maxItems: 1 + + power-domains: + items: + - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller. + - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller. + - description: IFE2 GDSC - Image Front End, Global Distributed Switch Controller. + - description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller. + + power-domain-names: + items: + - const: ife0 + - const: ife1 + - const: ife2 + - const: top + + vdda-phy-supply: + description: + Phandle to a regulator supply to PHY core block. + + vdda-pll-supply: + description: + Phandle to 1.8V regulator supply to PHY refclk pll block. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + description: + CSI input ports. + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data on CSIPHY 0. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - data-lanes + + port@1: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data on CSIPHY 1. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - data-lanes + + port@2: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data on CSIPHY 2. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - data-lanes + + port@3: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data on CSIPHY 3. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - data-lanes + + port@4: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data on CSIPHY 4. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - data-lanes + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - interrupts + - interrupt-names + - interconnects + - interconnect-names + - iommus + - power-domains + - power-domain-names + - vdda-phy-supply + - vdda-pll-supply + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + isp@acb3000 { + compatible = "qcom,sc7280-camss"; + + reg = <0x0 0x0acb3000 0x0 0x1000>, + <0x0 0x0acba000 0x0 0x1000>, + <0x0 0x0acc1000 0x0 0x1000>, + <0x0 0x0acc8000 0x0 0x1000>, + <0x0 0x0accf000 0x0 0x1000>, + <0x0 0x0ace0000 0x0 0x2000>, + <0x0 0x0ace2000 0x0 0x2000>, + <0x0 0x0ace4000 0x0 0x2000>, + <0x0 0x0ace6000 0x0 0x2000>, + <0x0 0x0ace8000 0x0 0x2000>, + <0x0 0x0acaf000 0x0 0x4000>, + <0x0 0x0acb6000 0x0 0x4000>, + <0x0 0x0acbd000 0x0 0x4000>, + <0x0 0x0acc4000 0x0 0x4000>, + <0x0 0x0accb000 0x0 0x4000>; + reg-names = "csid0", + "csid1", + "csid2", + "csid_lite0", + "csid_lite1", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "csiphy4", + "vfe0", + "vfe1", + "vfe2", + "vfe_lite0", + "vfe_lite1"; + + clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>, + <&camcc CAM_CC_CPAS_AHB_CLK>, + <&camcc CAM_CC_CSIPHY0_CLK>, + <&camcc CAM_CC_CSI0PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY1_CLK>, + <&camcc CAM_CC_CSI1PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY2_CLK>, + <&camcc CAM_CC_CSI2PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY3_CLK>, + <&camcc CAM_CC_CSI3PHYTIMER_CLK>, + <&camcc CAM_CC_CSIPHY4_CLK>, + <&camcc CAM_CC_CSI4PHYTIMER_CLK>, + <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_HF_AXI_CLK>, + <&camcc CAM_CC_ICP_AHB_CLK>, + <&camcc CAM_CC_IFE_0_CLK>, + <&camcc CAM_CC_IFE_0_AXI_CLK>, + <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_0_CSID_CLK>, + <&camcc CAM_CC_IFE_1_CLK>, + <&camcc CAM_CC_IFE_1_AXI_CLK>, + <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_1_CSID_CLK>, + <&camcc CAM_CC_IFE_2_CLK>, + <&camcc CAM_CC_IFE_2_AXI_CLK>, + <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_2_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_0_CLK>, + <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>, + <&camcc CAM_CC_IFE_LITE_1_CLK>, + <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>, + <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>; + clock-names = "camnoc_axi", + "cpas_ahb", + "csiphy0", + "csiphy0_timer", + "csiphy1", + "csiphy1_timer", + "csiphy2", + "csiphy2_timer", + "csiphy3", + "csiphy3_timer", + "csiphy4", + "csiphy4_timer", + "gcc_camera_ahb", + "gcc_cam_hf_axi", + "icp_ahb", + "vfe0", + "vfe0_axi", + "vfe0_cphy_rx", + "vfe0_csid", + "vfe1", + "vfe1_axi", + "vfe1_cphy_rx", + "vfe1_csid", + "vfe2", + "vfe2_axi", + "vfe2_cphy_rx", + "vfe2_csid", + "vfe_lite0", + "vfe_lite0_cphy_rx", + "vfe_lite0_csid", + "vfe_lite1", + "vfe_lite1_cphy_rx", + "vfe_lite1_csid"; + + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "csid0", + "csid1", + "csid2", + "csid_lite0", + "csid_lite1", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "csiphy4", + "vfe0", + "vfe1", + "vfe2", + "vfe_lite0", + "vfe_lite1"; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &cnoc2 SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>, + <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "ahb", + "hf_0"; + + iommus = <&apps_smmu 0x800 0x4e0>; + + power-domains = <&camcc CAM_CC_IFE_0_GDSC>, + <&camcc CAM_CC_IFE_1_GDSC>, + <&camcc CAM_CC_IFE_2_GDSC>, + <&camcc CAM_CC_TITAN_TOP_GDSC>; + power-domain-names = "ife0", + "ife1", + "ife2", + "top"; + + vdda-phy-supply = <&vreg_l10c_0p88>; + vdda-pll-supply = <&vreg_l6b_1p2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; -- 2.49.0 From 3522673b8f291cd8ae40c03c8fe4ac07e68b3398 Mon Sep 17 00:00:00 2001 From: Vikram Sharma Date: Sat, 7 Dec 2024 00:48:57 +0530 Subject: [PATCH 16/16] media: qcom: camss: Sort camss version enums and compatible strings Sort CAMSS version enums and compatible strings alphanumerically. Signed-off-by: Suresh Vankadara Signed-off-by: Trishansh Bhardwaj Signed-off-by: Vikram Sharma Reviewed-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil --- .../media/platform/qcom/camss/camss-csiphy-3ph-1-0.c | 10 +++++----- drivers/media/platform/qcom/camss/camss-vfe.c | 6 +++--- drivers/media/platform/qcom/camss/camss.c | 2 +- drivers/media/platform/qcom/camss/camss.h | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index df7e93a5a4f6..7d2490c9de01 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -505,10 +505,6 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy, u32 val; switch (csiphy->camss->res->version) { - case CAMSS_845: - r = &lane_regs_sdm845[0][0]; - array_size = ARRAY_SIZE(lane_regs_sdm845[0]); - break; case CAMSS_8250: r = &lane_regs_sm8250[0][0]; array_size = ARRAY_SIZE(lane_regs_sm8250[0]); @@ -517,6 +513,10 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy, r = &lane_regs_sc8280xp[0][0]; array_size = ARRAY_SIZE(lane_regs_sc8280xp[0]); break; + case CAMSS_845: + r = &lane_regs_sdm845[0][0]; + array_size = ARRAY_SIZE(lane_regs_sdm845[0]); + break; default: WARN(1, "unknown cspi version\n"); return; @@ -557,9 +557,9 @@ static bool csiphy_is_gen2(u32 version) bool ret = false; switch (version) { - case CAMSS_845: case CAMSS_8250: case CAMSS_8280XP: + case CAMSS_845: ret = true; break; } diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 80a62ba11295..fb3234c65403 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -334,11 +334,11 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, return sink_code; } break; - case CAMSS_8x96: case CAMSS_660: - case CAMSS_845: + case CAMSS_8x96: case CAMSS_8250: case CAMSS_8280XP: + case CAMSS_845: switch (sink_code) { case MEDIA_BUS_FMT_YUYV8_1X16: { @@ -1693,9 +1693,9 @@ static int vfe_bpl_align(struct vfe_device *vfe) int ret = 8; switch (vfe->camss->res->version) { - case CAMSS_845: case CAMSS_8250: case CAMSS_8280XP: + case CAMSS_845: ret = 16; break; default: diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 67fb11cbe865..789e1b80f25e 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -2689,10 +2689,10 @@ static const struct of_device_id camss_dt_match[] = { { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources }, { .compatible = "qcom,msm8953-camss", .data = &msm8953_resources }, { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources }, + { .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources }, { .compatible = "qcom,sdm660-camss", .data = &sdm660_resources }, { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources }, { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources }, - { .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources }, { } }; diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 9da7f48f5dd7..ffce0a0edbc5 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -77,13 +77,13 @@ enum pm_domain { }; enum camss_version { + CAMSS_660, CAMSS_8x16, CAMSS_8x53, CAMSS_8x96, - CAMSS_660, - CAMSS_845, CAMSS_8250, CAMSS_8280XP, + CAMSS_845, }; enum icc_count { -- 2.49.0