* [PATCH v11 19/22] drm/tests: hdmi: Add tests for HDMI helper's mode_valid
From: Nicolas Frattaroli @ 2026-03-24 16:01 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring,
Jonathan Corbet, Shuah Khan
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, linux-doc,
Nicolas Frattaroli
In-Reply-To: <20260324-color-format-v11-0-605559af4fb4@collabora.com>
Add some KUnit tests to verify that the HDMI state helper's mode_valid
implementation does not improperly reject chroma subsampled modes on the
basis of their clock rate not being satisfiable in RGB.
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 109 +++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
index 3444c93c615f..74c9933eabfc 100644
--- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
@@ -77,6 +77,23 @@ static struct drm_display_mode *find_420_only_mode(struct drm_connector *connect
return NULL;
}
+static struct drm_display_mode *find_420_also_mode(struct drm_connector *connector)
+{
+ struct drm_device *drm = connector->dev;
+ struct drm_display_mode *mode;
+
+ mutex_lock(&drm->mode_config.mutex);
+ list_for_each_entry(mode, &connector->modes, head) {
+ if (drm_mode_is_420_also(&connector->display_info, mode)) {
+ mutex_unlock(&drm->mode_config.mutex);
+ return mode;
+ }
+ }
+ mutex_unlock(&drm->mode_config.mutex);
+
+ return NULL;
+}
+
static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
const void *edid, size_t edid_len)
{
@@ -2745,11 +2762,103 @@ static void drm_test_check_mode_valid_reject_max_clock(struct kunit *test)
KUNIT_EXPECT_EQ(test, preferred->clock, 25200);
}
+/*
+ * Test that drm_hdmi_connector_mode_valid() will accept modes that require a
+ * 4:2:0 chroma subsampling, even if said mode would violate maximum clock
+ * constraints if it used RGB 4:4:4.
+ */
+static void drm_test_check_mode_valid_yuv420_only_max_clock(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_display_mode *dank;
+ struct drm_connector *conn;
+
+ priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV420),
+ 8,
+ &dummy_connector_hdmi_funcs,
+ test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 200 * 1000);
+
+ dank = find_420_only_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, dank);
+ KUNIT_EXPECT_EQ(test, dank->hdisplay, 3840);
+ KUNIT_EXPECT_EQ(test, dank->vdisplay, 2160);
+
+ /*
+ * Note: The mode's "clock" here is not accurate to the actual TMDS
+ * clock that HDMI will use for a subsampled mode. Hence, why the mode's
+ * clock is above the .max_tmds_clock of 200MHz.
+ */
+ KUNIT_EXPECT_EQ(test, dank->clock, 297000);
+}
+
+/*
+ * Test that drm_hdmi_connector_mode_valid() will reject modes that require
+ * 4:2:0 chroma subsampling, if the connector does not support 4:2:0.
+ */
+static void
+drm_test_check_mode_valid_reject_yuv420_only_connector(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_display_mode *dank;
+ struct drm_connector *conn;
+
+ priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8,
+ &dummy_connector_hdmi_funcs,
+ test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 200 * 1000);
+
+ dank = find_420_only_mode(conn);
+ KUNIT_EXPECT_NULL(test, dank);
+}
+
+/*
+ * Test that drm_hdmi_connector_mode_valid() will accept modes that allow (among
+ * other color formats) 4:2:0 chroma subsampling, even if the connector does not
+ * support 4:2:0, but the mode's clock works for RGB 4:4:4.
+ */
+static void
+drm_test_check_mode_valid_accept_yuv420_also_connector_rgb(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_display_mode *mode;
+ struct drm_connector *conn;
+
+ priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8,
+ &dummy_connector_hdmi_funcs,
+ test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 340 * 1000);
+
+ mode = find_420_also_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+ KUNIT_EXPECT_EQ(test, mode->hdisplay, 3840);
+ KUNIT_EXPECT_EQ(test, mode->vdisplay, 2160);
+ KUNIT_EXPECT_EQ(test, mode->clock, 297000);
+}
+
static struct kunit_case drm_atomic_helper_connector_hdmi_mode_valid_tests[] = {
KUNIT_CASE(drm_test_check_mode_valid),
KUNIT_CASE(drm_test_check_mode_valid_reject),
KUNIT_CASE(drm_test_check_mode_valid_reject_rate),
KUNIT_CASE(drm_test_check_mode_valid_reject_max_clock),
+ KUNIT_CASE(drm_test_check_mode_valid_yuv420_only_max_clock),
+ KUNIT_CASE(drm_test_check_mode_valid_reject_yuv420_only_connector),
+ KUNIT_CASE(drm_test_check_mode_valid_accept_yuv420_also_connector_rgb),
{ }
};
--
2.53.0
^ permalink raw reply related
* [PATCH v11 20/22] drm/tests: bridge: Add KUnit tests for bridge chain format selection
From: Nicolas Frattaroli @ 2026-03-24 16:01 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring,
Jonathan Corbet, Shuah Khan
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, linux-doc,
Nicolas Frattaroli
In-Reply-To: <20260324-color-format-v11-0-605559af4fb4@collabora.com>
With the "color format" property, the bridge chain format selection has
gained increased complexity. Instead of simply finding any sequence of
bus formats that works, the bridge chain format selection needs to pick
a sequence that results in the requested color format.
Add KUnit tests for this new logic. These take the form of some pleasant
preprocessor macros to make it less cumbersome to define test bridges
with a set of possible input and output formats.
The input and output formats are defined for bridges in the form of
tuples, where the first member defines the input format, and the second
member defines the output format that can be produced from this input
format. This means the tests can construct scenarios in which not all
inputs can be converted to all outputs.
Some tests are added to test interesting scenarios to exercise the bus
format selection in the presence of a specific color format request.
Furthermore, tests are added to verify that bridge chains that end in an
HDMI connector will always prefer RGB when the color format is
DRM_CONNECTOR_COLOR_FORMAT_AUTO, as is the behaviour in the HDMI state
helpers.
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/tests/drm_bridge_test.c | 787 ++++++++++++++++++++++++++++++++
1 file changed, 787 insertions(+)
diff --git a/drivers/gpu/drm/tests/drm_bridge_test.c b/drivers/gpu/drm/tests/drm_bridge_test.c
index 887020141c7f..cb821c606070 100644
--- a/drivers/gpu/drm/tests/drm_bridge_test.c
+++ b/drivers/gpu/drm/tests/drm_bridge_test.c
@@ -2,15 +2,23 @@
/*
* Kunit test for drm_bridge functions
*/
+#include <linux/cleanup.h>
+#include <linux/media-bus-format.h>
+
#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_atomic_uapi.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_bridge_helper.h>
+#include <drm/drm_edid.h>
#include <drm/drm_kunit_helpers.h>
+#include <drm/drm_managed.h>
#include <kunit/device.h>
#include <kunit/test.h>
+#include "drm_kunit_edid.h"
+
/*
* Mimick the typical "private" struct defined by a bridge driver, which
* embeds a bridge plus other fields.
@@ -37,6 +45,21 @@ struct drm_bridge_init_priv {
bool destroyed;
};
+struct drm_bridge_chain_priv {
+ struct drm_device drm;
+ struct drm_encoder encoder;
+ struct drm_plane *plane;
+ struct drm_crtc *crtc;
+ struct drm_connector *connector;
+ unsigned int num_bridges;
+
+ /**
+ * @test_bridges: array of pointers to &struct drm_bridge_priv entries
+ * of which the first @num_bridges entries are valid.
+ */
+ struct drm_bridge_priv **test_bridges;
+};
+
static struct drm_bridge_priv *bridge_to_priv(struct drm_bridge *bridge)
{
return container_of(bridge, struct drm_bridge_priv, bridge);
@@ -95,6 +118,229 @@ static const struct drm_bridge_funcs drm_test_bridge_atomic_funcs = {
.atomic_reset = drm_atomic_helper_bridge_reset,
};
+/**
+ * struct fmt_tuple - a tuple of input/output MEDIA_BUS_FMT_*
+ */
+struct fmt_tuple {
+ u32 in_fmt;
+ u32 out_fmt;
+};
+
+/*
+ * Format mapping that only accepts RGB888, and outputs only RGB888
+ */
+static const struct fmt_tuple rgb8_passthrough[] = {
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 },
+};
+
+/*
+ * Format mapping that only accepts YUV444, and outputs only YUV444
+ */
+static const struct fmt_tuple yuv8_passthrough[] = {
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+};
+
+/*
+ * Format mapping where 8bpc RGB -> 8bpc YUV444, or ID(RGB) or ID(YUV444)
+ */
+static const struct fmt_tuple rgb8_to_yuv8_or_id[] = {
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 },
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+};
+
+static const struct fmt_tuple rgb8_to_id_yuv8_or_yuv8_to_yuv422_yuv420[] = {
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 },
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_UYVY8_1X16 },
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_UYYVYY8_0_5X24 },
+};
+
+/*
+ * Format mapping where 8bpc YUV444 -> 8bpc RGB, or ID(YUV444)
+ */
+static const struct fmt_tuple yuv8_to_rgb8_or_id[] = {
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_RGB888_1X24 },
+};
+
+/*
+ * A format mapping that acts like a video processor that generates an RGB signal
+ */
+static const struct fmt_tuple rgb_producer[] = {
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 },
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB101010_1X30 },
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB121212_1X36 },
+};
+
+/*
+ * A format mapping that acts like a video processor that generates an 8-bit RGB,
+ * YUV444 or YUV420 signal
+ */
+static const struct fmt_tuple rgb_yuv444_yuv420_producer[] = {
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 },
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_YUV8_1X24 },
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_UYYVYY8_0_5X24 },
+};
+
+static const struct fmt_tuple rgb8_yuv444_yuv422_passthrough[] = {
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 },
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16 },
+};
+
+static const struct fmt_tuple yuv444_yuv422_rgb8_passthrough[] = {
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16 },
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 },
+};
+
+static bool fmt_in_list(const u32 fmt, const u32 *out_fmts, const size_t num_fmts)
+{
+ size_t i;
+
+ for (i = 0; i < num_fmts; i++)
+ if (out_fmts[i] == fmt)
+ return true;
+
+ return false;
+}
+
+/**
+ * get_tuples_out_fmts - Get unique output formats of a &struct fmt_tuple list
+ * @fmt_tuples: array of &struct fmt_tuple
+ * @num_fmt_tuples: number of entries in @fmt_tuples
+ * @out_fmts: target array to store the unique output bus formats
+ *
+ * Returns the number of unique output formats, i.e. the number of entries in
+ * @out_fmts that were populated with sensible values.
+ */
+static size_t get_tuples_out_fmts(const struct fmt_tuple *fmt_tuples,
+ const size_t num_fmt_tuples, u32 *out_fmts)
+{
+ size_t num_unique = 0;
+ size_t i;
+
+ for (i = 0; i < num_fmt_tuples; i++)
+ if (!fmt_in_list(fmt_tuples[i].out_fmt, out_fmts, num_unique))
+ out_fmts[num_unique++] = fmt_tuples[i].out_fmt;
+
+ return num_unique;
+}
+
+#define DEFINE_FMT_FUNCS_FROM_TUPLES(name) \
+static u32 *drm_test_bridge_ ## name ## _out_fmts(struct drm_bridge *bridge, \
+ struct drm_bridge_state *bridge_state, \
+ struct drm_crtc_state *crtc_state, \
+ struct drm_connector_state *conn_state, \
+ unsigned int *num_output_fmts) \
+{ \
+ u32 *out_fmts = kcalloc(ARRAY_SIZE((name)), sizeof(u32), GFP_KERNEL); \
+ \
+ if (out_fmts) \
+ *num_output_fmts = get_tuples_out_fmts((name), ARRAY_SIZE((name)), out_fmts); \
+ else \
+ *num_output_fmts = 0; \
+ \
+ return out_fmts; \
+} \
+ \
+static u32 *drm_test_bridge_ ## name ## _in_fmts(struct drm_bridge *bridge, \
+ struct drm_bridge_state *bridge_state, \
+ struct drm_crtc_state *crtc_state, \
+ struct drm_connector_state *conn_state, \
+ u32 output_fmt, \
+ unsigned int *num_input_fmts) \
+{ \
+ u32 *in_fmts = kcalloc(ARRAY_SIZE((name)), sizeof(u32), GFP_KERNEL); \
+ unsigned int num_fmts = 0; \
+ size_t i; \
+ \
+ if (!in_fmts) { \
+ *num_input_fmts = 0; \
+ return NULL; \
+ } \
+ \
+ for (i = 0; i < ARRAY_SIZE((name)); i++) \
+ if ((name)[i].out_fmt == output_fmt) \
+ in_fmts[num_fmts++] = (name)[i].in_fmt; \
+ \
+ *num_input_fmts = num_fmts; \
+ \
+ return in_fmts; \
+}
+
+#define DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI_FUNC(ident, input_fmts_func, output_fmts_func, \
+ hdmi_write_infoframe_func, \
+ hdmi_clear_infoframe_func) \
+static const struct drm_bridge_funcs (ident) = { \
+ .atomic_enable = drm_test_bridge_atomic_enable, \
+ .atomic_disable = drm_test_bridge_atomic_disable, \
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, \
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, \
+ .atomic_reset = drm_atomic_helper_bridge_reset, \
+ .atomic_get_input_bus_fmts = (input_fmts_func), \
+ .atomic_get_output_bus_fmts = (output_fmts_func), \
+ .hdmi_write_avi_infoframe = (hdmi_write_infoframe_func), \
+ .hdmi_clear_avi_infoframe = (hdmi_clear_infoframe_func), \
+ .hdmi_write_hdmi_infoframe = (hdmi_write_infoframe_func), \
+ .hdmi_clear_hdmi_infoframe = (hdmi_clear_infoframe_func), \
+}
+
+#define DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_FUNC(ident, input_fmts_func, output_fmts_func) \
+ DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI_FUNC(ident, input_fmts_func, output_fmts_func, \
+ NULL, NULL)
+
+#define DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(_name) \
+ DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_FUNC(_name ## _funcs, \
+ drm_test_bridge_ ## _name ## _in_fmts, \
+ drm_test_bridge_ ## _name ## _out_fmts)
+
+static int drm_test_bridge_write_infoframe_stub(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len)
+{
+ return 0;
+}
+
+static int drm_test_bridge_clear_infoframe_stub(struct drm_bridge *bridge)
+{
+ return 0;
+}
+
+#define DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI(_name) \
+ DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI_FUNC(_name ## _hdmi ## _funcs, \
+ drm_test_bridge_ ## _name ## _in_fmts, \
+ drm_test_bridge_ ## _name ## _out_fmts, \
+ drm_test_bridge_write_infoframe_stub, \
+ drm_test_bridge_clear_infoframe_stub)
+DEFINE_FMT_FUNCS_FROM_TUPLES(rgb8_passthrough)
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb8_passthrough);
+
+DEFINE_FMT_FUNCS_FROM_TUPLES(yuv8_passthrough)
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(yuv8_passthrough);
+
+DEFINE_FMT_FUNCS_FROM_TUPLES(rgb8_to_yuv8_or_id)
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb8_to_yuv8_or_id);
+
+DEFINE_FMT_FUNCS_FROM_TUPLES(yuv8_to_rgb8_or_id)
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(yuv8_to_rgb8_or_id);
+
+DEFINE_FMT_FUNCS_FROM_TUPLES(rgb_producer)
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb_producer);
+
+DEFINE_FMT_FUNCS_FROM_TUPLES(rgb_yuv444_yuv420_producer)
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb_yuv444_yuv420_producer);
+
+DEFINE_FMT_FUNCS_FROM_TUPLES(rgb8_to_id_yuv8_or_yuv8_to_yuv422_yuv420)
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb8_to_id_yuv8_or_yuv8_to_yuv422_yuv420);
+
+DEFINE_FMT_FUNCS_FROM_TUPLES(rgb8_yuv444_yuv422_passthrough)
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(rgb8_yuv444_yuv422_passthrough);
+
+DEFINE_FMT_FUNCS_FROM_TUPLES(yuv444_yuv422_rgb8_passthrough)
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT(yuv444_yuv422_rgb8_passthrough);
+DRM_BRIDGE_ATOMIC_WITH_BUS_FMT_HDMI(yuv444_yuv422_rgb8_passthrough);
+
KUNIT_DEFINE_ACTION_WRAPPER(drm_bridge_remove_wrapper,
drm_bridge_remove,
struct drm_bridge *);
@@ -180,6 +426,119 @@ drm_test_bridge_init(struct kunit *test, const struct drm_bridge_funcs *funcs)
return priv;
}
+static struct drm_bridge_chain_priv *
+drm_test_bridge_chain_init(struct kunit *test, unsigned int num_bridges,
+ const struct drm_bridge_funcs **funcs)
+{
+ struct drm_bridge_chain_priv *priv;
+ const struct drm_edid *edid;
+ struct drm_bridge *prev;
+ struct drm_encoder *enc;
+ struct drm_bridge *bridge;
+ struct drm_device *drm;
+ bool has_hdmi = false;
+ struct device *dev;
+ unsigned int i;
+ int ret;
+
+ dev = drm_kunit_helper_alloc_device(test);
+ if (IS_ERR(dev))
+ return ERR_CAST(dev);
+
+ priv = drm_kunit_helper_alloc_drm_device(test, dev, struct drm_bridge_chain_priv,
+ drm, DRIVER_MODESET | DRIVER_ATOMIC);
+ if (IS_ERR(priv))
+ return ERR_CAST(priv);
+
+ drm = &priv->drm;
+
+ priv->test_bridges = drmm_kmalloc_array(drm, num_bridges, sizeof(*priv->test_bridges),
+ GFP_KERNEL);
+ if (!priv->test_bridges)
+ return ERR_PTR(-ENOMEM);
+
+ priv->num_bridges = num_bridges;
+
+ for (i = 0; i < num_bridges; i++) {
+ priv->test_bridges[i] = devm_drm_bridge_alloc(dev, struct drm_bridge_priv,
+ bridge, funcs[i]);
+ if (IS_ERR(priv->test_bridges[i]))
+ return ERR_CAST(priv->test_bridges[i]);
+
+ priv->test_bridges[i]->data = priv;
+ }
+
+ priv->plane = drm_kunit_helper_create_primary_plane(test, drm, NULL, NULL,
+ NULL, 0, NULL);
+ if (IS_ERR(priv->plane))
+ return ERR_CAST(priv->plane);
+
+ priv->crtc = drm_kunit_helper_create_crtc(test, drm, priv->plane, NULL,
+ NULL, NULL);
+ if (IS_ERR(priv->crtc))
+ return ERR_CAST(priv->crtc);
+
+ enc = &priv->encoder;
+ ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
+ if (ret)
+ return ERR_PTR(ret);
+
+ enc->possible_crtcs = drm_crtc_mask(priv->crtc);
+
+ prev = NULL;
+ for (i = 0; i < num_bridges; i++) {
+ bridge = &priv->test_bridges[i]->bridge;
+ bridge->type = DRM_MODE_CONNECTOR_VIRTUAL;
+
+ if (bridge->funcs->hdmi_write_hdmi_infoframe) {
+ has_hdmi = true;
+ bridge->ops |= DRM_BRIDGE_OP_HDMI;
+ bridge->type = DRM_MODE_CONNECTOR_HDMIA;
+ bridge->vendor = "LNX";
+ bridge->product = "KUnit";
+ bridge->supported_formats = (BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444) |
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420));
+ }
+
+ ret = drm_kunit_bridge_add(test, bridge);
+ if (ret)
+ return ERR_PTR(ret);
+
+ ret = drm_bridge_attach(enc, bridge, prev, 0);
+ if (ret)
+ return ERR_PTR(ret);
+
+ prev = bridge;
+ }
+
+ priv->connector = drm_bridge_connector_init(drm, enc);
+ if (IS_ERR(priv->connector))
+ return ERR_CAST(priv->connector);
+
+ drm_connector_attach_encoder(priv->connector, enc);
+
+ drm_mode_config_reset(drm);
+
+ if (!has_hdmi)
+ return priv;
+
+ scoped_guard(mutex, &drm->mode_config.mutex) {
+ edid = drm_edid_alloc(test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz));
+ if (!edid)
+ return ERR_PTR(-EINVAL);
+
+ drm_edid_connector_update(priv->connector, edid);
+ KUNIT_ASSERT_GT(test, drm_edid_connector_add_modes(priv->connector), 0);
+
+ ret = priv->connector->funcs->fill_modes(priv->connector, 4096, 4096);
+ }
+
+ return priv;
+}
+
/*
* Test that drm_bridge_get_current_state() returns the last committed
* state for an atomic bridge.
@@ -508,14 +867,442 @@ static struct kunit_suite drm_bridge_alloc_test_suite = {
.test_cases = drm_bridge_alloc_tests,
};
+/**
+ * drm_test_bridge_chain_verify_fmt - Verify bridge chain format selection
+ * @test: pointer to KUnit test object
+ * @priv: pointer to a &struct drm_bridge_chain_priv for this chain
+ * @expected: constant array of &struct fmt_tuple describing the expected
+ * input and output bus formats
+ * @num_expected: number of entries in @expected
+ *
+ * Runs the KUNIT_EXPECT clauses to verify the bridge chain format selection
+ * resulted in the expected formats. If %0 is given as a format in a
+ * &struct fmt_tuple, then it is understood to mean "any".
+ *
+ * Must be called with the modeset lock held.
+ */
+static void drm_test_bridge_chain_verify_fmt(struct kunit *test,
+ struct drm_bridge_chain_priv *priv,
+ const struct fmt_tuple *const expected,
+ const unsigned int num_expected)
+{
+ struct drm_bridge_state *bstate;
+ unsigned int i = 0;
+
+ drm_for_each_bridge_in_chain_scoped(&priv->encoder, bridge) {
+ KUNIT_ASSERT_LT(test, i, num_expected);
+
+ bstate = drm_bridge_get_current_state(bridge);
+ if (expected[i].in_fmt)
+ KUNIT_EXPECT_EQ(test, bstate->input_bus_cfg.format,
+ expected[i].in_fmt);
+ if (expected[i].out_fmt)
+ KUNIT_EXPECT_EQ(test, bstate->output_bus_cfg.format,
+ expected[i].out_fmt);
+
+ i++;
+ }
+
+ KUNIT_ASSERT_EQ_MSG(test, i, num_expected,
+ "Fewer bridges (%u) than expected (%u)\n", i, num_expected);
+}
+
+/*
+ * Test that constructs a bridge chain in which an RGB888 producer is chained to
+ * two bridges that will convert from RGB to YUV and from YUV to RGB respectively.
+ *
+ * The test requests an output color_format of RGB using the color_format property,
+ * so to satisfy this request, the bridge chain must take a detour over YUV.
+ */
+static void drm_test_bridge_rgb_yuv_rgb(struct kunit *test)
+{
+ static const struct drm_bridge_funcs *funcs[] = {
+ &rgb_producer_funcs,
+ &rgb8_to_yuv8_or_id_funcs,
+ &yuv8_to_rgb8_or_id_funcs,
+ };
+ static const struct fmt_tuple expected[] = {
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 },
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_RGB888_1X24 },
+ };
+ struct drm_connector_state *conn_state;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_bridge_chain_priv *priv;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *mode;
+ int ret;
+
+ priv = drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+retry_commit:
+ conn_state = drm_atomic_get_connector_state(state, priv->connector);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
+
+ conn_state->color_format = DRM_CONNECTOR_COLOR_FORMAT_RGB444;
+
+ ret = drm_atomic_set_crtc_for_connector(conn_state, priv->crtc);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state = drm_atomic_get_crtc_state(state, priv->crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+ ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state->enable = true;
+ crtc_state->active = true;
+
+ ret = drm_atomic_commit(state);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ drm_test_bridge_chain_verify_fmt(test, priv, expected, ARRAY_SIZE(expected));
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+}
+
+/*
+ * Test in which a bridge capable of producing RGB, YUV444 and YUV420 has to
+ * produce RGB and convert with a downstream bridge in the chain to reach the
+ * requested YUV444 color format, as no direct path exists between its YUV444
+ * and the last bridge.
+ *
+ * The rationale behind this test is to devise a scenario in which naively
+ * assuming any format the video processor can output, and the connector
+ * requests, is the right format to pick, does not work.
+ */
+static void drm_test_bridge_must_convert_to_yuv444(struct kunit *test)
+{
+ static const struct drm_bridge_funcs *funcs[] = {
+ &rgb_yuv444_yuv420_producer_funcs,
+ &rgb8_passthrough_funcs,
+ &rgb8_to_id_yuv8_or_yuv8_to_yuv422_yuv420_funcs,
+ &rgb8_yuv444_yuv422_passthrough_funcs,
+ };
+ static const struct fmt_tuple expected[] = {
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 },
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 },
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+ };
+ struct drm_connector_state *conn_state;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_bridge_chain_priv *priv;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *mode;
+ int ret;
+
+ priv = drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+retry_commit:
+ conn_state = drm_atomic_get_connector_state(state, priv->connector);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
+
+ conn_state->color_format = DRM_CONNECTOR_COLOR_FORMAT_YCBCR444;
+
+ ret = drm_atomic_set_crtc_for_connector(conn_state, priv->crtc);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state = drm_atomic_get_crtc_state(state, priv->crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+ ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state->enable = true;
+ crtc_state->active = true;
+
+ ret = drm_atomic_commit(state);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ drm_test_bridge_chain_verify_fmt(test, priv, expected, ARRAY_SIZE(expected));
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+}
+
+/*
+ * Test which checks that no matter the order of bus formats returned by an
+ * HDMI bridge, RGB is preferred on DRM_CONNECTOR_COLOR_FORMAT_AUTO if it's
+ * available.
+ */
+static void drm_test_bridge_hdmi_auto_rgb(struct kunit *test)
+{
+ static const struct drm_bridge_funcs *funcs[] = {
+ &rgb_yuv444_yuv420_producer_funcs,
+ &yuv444_yuv422_rgb8_passthrough_hdmi_funcs,
+ };
+ static const struct fmt_tuple expected[] = {
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_RGB888_1X24 },
+ { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_RGB888_1X24 },
+ };
+ struct drm_connector_state *conn_state;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_bridge_chain_priv *priv;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *mode;
+ int ret;
+
+ priv = drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+retry_commit:
+ conn_state = drm_atomic_get_connector_state(state, priv->connector);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
+
+ KUNIT_ASSERT_EQ(test, conn_state->color_format, DRM_CONNECTOR_COLOR_FORMAT_AUTO);
+
+ ret = drm_atomic_set_crtc_for_connector(conn_state, priv->crtc);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state = drm_atomic_get_crtc_state(state, priv->crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+ ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state->enable = true;
+ crtc_state->active = true;
+
+ ret = drm_atomic_commit(state);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
+
+ drm_test_bridge_chain_verify_fmt(test, priv, expected, ARRAY_SIZE(expected));
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+}
+
+/*
+ * Test which checks that DRM_CONNECTOR_COLOR_FORMAT_AUTO on non-HDMI connectors
+ * will result in the first bus format on the output to be picked.
+ */
+static void drm_test_bridge_auto_first(struct kunit *test)
+{
+ static const struct drm_bridge_funcs *funcs[] = {
+ &rgb_yuv444_yuv420_producer_funcs,
+ &yuv444_yuv422_rgb8_passthrough_funcs,
+ };
+ static const struct fmt_tuple expected[] = {
+ { MEDIA_BUS_FMT_FIXED, MEDIA_BUS_FMT_YUV8_1X24 },
+ { MEDIA_BUS_FMT_YUV8_1X24, MEDIA_BUS_FMT_YUV8_1X24 },
+ };
+ struct drm_connector_state *conn_state;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_bridge_chain_priv *priv;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *mode;
+ int ret;
+
+ priv = drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+retry_commit:
+ conn_state = drm_atomic_get_connector_state(state, priv->connector);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
+
+ KUNIT_ASSERT_EQ(test, conn_state->color_format, DRM_CONNECTOR_COLOR_FORMAT_AUTO);
+
+ ret = drm_atomic_set_crtc_for_connector(conn_state, priv->crtc);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state = drm_atomic_get_crtc_state(state, priv->crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+ ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state->enable = true;
+ crtc_state->active = true;
+
+ ret = drm_atomic_commit(state);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ drm_test_bridge_chain_verify_fmt(test, priv, expected, ARRAY_SIZE(expected));
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+}
+
+/*
+ * Test which checks that in a configuration of bridge chains where an RGB
+ * producer is hooked to a YUV444-only pass-through, the atomic commit fails as
+ * the bridge format selection cannot find a valid sequence of bus formats.
+ */
+static void drm_test_bridge_rgb_yuv_no_path(struct kunit *test)
+{
+ static const struct drm_bridge_funcs *funcs[] = {
+ &rgb_producer_funcs,
+ &yuv8_passthrough_funcs,
+ &rgb8_yuv444_yuv422_passthrough_funcs,
+ };
+ struct drm_connector_state *conn_state;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_bridge_chain_priv *priv;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *mode;
+ int ret;
+
+ priv = drm_test_bridge_chain_init(test, ARRAY_SIZE(funcs), funcs);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+retry_commit:
+ conn_state = drm_atomic_get_connector_state(state, priv->connector);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
+
+ ret = drm_atomic_set_crtc_for_connector(conn_state, priv->crtc);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state = drm_atomic_get_crtc_state(state, priv->crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+ ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state->enable = true;
+ crtc_state->active = true;
+
+ ret = drm_atomic_commit(state);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_EXPECT_EQ(test, ret, -ENOTSUPP);
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+}
+
+static struct kunit_case drm_bridge_bus_fmt_tests[] = {
+ KUNIT_CASE(drm_test_bridge_rgb_yuv_rgb),
+ KUNIT_CASE(drm_test_bridge_must_convert_to_yuv444),
+ KUNIT_CASE(drm_test_bridge_hdmi_auto_rgb),
+ KUNIT_CASE(drm_test_bridge_auto_first),
+ KUNIT_CASE(drm_test_bridge_rgb_yuv_no_path),
+ { }
+};
+
+static struct kunit_suite drm_bridge_bus_fmt_test_suite = {
+ .name = "drm_bridge_bus_fmt",
+ .test_cases = drm_bridge_bus_fmt_tests,
+};
+
kunit_test_suites(
&drm_bridge_get_current_state_test_suite,
&drm_bridge_helper_reset_crtc_test_suite,
&drm_bridge_alloc_test_suite,
+ &drm_bridge_bus_fmt_test_suite,
);
MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
MODULE_AUTHOR("Luca Ceresoli <luca.ceresoli@bootlin.com>");
+MODULE_AUTHOR("Nicolas Frattaroli <nicolas.frattaroli@collabora.com>");
MODULE_DESCRIPTION("Kunit test for drm_bridge functions");
MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related
* [PATCH v11 21/22] drm/tests: bridge: Add test for HDMI output bus formats helper
From: Nicolas Frattaroli @ 2026-03-24 16:01 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring,
Jonathan Corbet, Shuah Khan
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, linux-doc,
Nicolas Frattaroli
In-Reply-To: <20260324-color-format-v11-0-605559af4fb4@collabora.com>
The common atomic_get_output_bus_fmts helper for HDMI bridge connectors,
called drm_atomic_helper_bridge_get_hdmi_output_bus_fmts, should return
an array of output bus formats depending on the supported formats of the
connector, and the current output BPC.
Add a test to exercise some of this helper.
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/gpu/drm/tests/drm_bridge_test.c | 184 ++++++++++++++++++++++++++++++++
1 file changed, 184 insertions(+)
diff --git a/drivers/gpu/drm/tests/drm_bridge_test.c b/drivers/gpu/drm/tests/drm_bridge_test.c
index cb821c606070..d9bd930b1197 100644
--- a/drivers/gpu/drm/tests/drm_bridge_test.c
+++ b/drivers/gpu/drm/tests/drm_bridge_test.c
@@ -5,6 +5,7 @@
#include <linux/cleanup.h>
#include <linux/media-bus-format.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_bridge.h>
@@ -118,6 +119,28 @@ static const struct drm_bridge_funcs drm_test_bridge_atomic_funcs = {
.atomic_reset = drm_atomic_helper_bridge_reset,
};
+static int dummy_clear_infoframe(struct drm_bridge *bridge)
+{
+ return 0;
+}
+
+static int dummy_write_infoframe(struct drm_bridge *bridge, const u8 *buffer,
+ size_t len)
+{
+ return 0;
+}
+
+static const struct drm_bridge_funcs drm_test_bridge_bus_fmts_funcs = {
+ .atomic_get_output_bus_fmts = drm_atomic_helper_bridge_get_hdmi_output_bus_fmts,
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+ .atomic_reset = drm_atomic_helper_bridge_reset,
+ .hdmi_write_avi_infoframe = dummy_write_infoframe,
+ .hdmi_write_hdmi_infoframe = dummy_write_infoframe,
+ .hdmi_clear_avi_infoframe = dummy_clear_infoframe,
+ .hdmi_clear_hdmi_infoframe = dummy_clear_infoframe,
+};
+
/**
* struct fmt_tuple - a tuple of input/output MEDIA_BUS_FMT_*
*/
@@ -539,6 +562,83 @@ drm_test_bridge_chain_init(struct kunit *test, unsigned int num_bridges,
return priv;
}
+static struct drm_bridge_init_priv *
+drm_test_bridge_hdmi_init(struct kunit *test, const struct drm_bridge_funcs *funcs,
+ unsigned int supported_formats, int max_bpc)
+{
+ struct drm_bridge_init_priv *priv;
+ struct drm_encoder *enc;
+ struct drm_bridge *bridge;
+ struct drm_device *drm;
+ struct device *dev;
+ int ret;
+
+ dev = drm_kunit_helper_alloc_device(test);
+ if (IS_ERR(dev))
+ return ERR_CAST(dev);
+
+ priv = drm_kunit_helper_alloc_drm_device(test, dev,
+ struct drm_bridge_init_priv, drm,
+ DRIVER_MODESET | DRIVER_ATOMIC);
+ if (IS_ERR(priv))
+ return ERR_CAST(priv);
+
+ priv->test_bridge = devm_drm_bridge_alloc(dev, struct drm_bridge_priv, bridge, funcs);
+ if (IS_ERR(priv->test_bridge))
+ return ERR_CAST(priv->test_bridge);
+
+ priv->test_bridge->data = priv;
+
+ drm = &priv->drm;
+ priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
+ NULL,
+ NULL,
+ NULL, 0,
+ NULL);
+ if (IS_ERR(priv->plane))
+ return ERR_CAST(priv->plane);
+
+ priv->crtc = drm_kunit_helper_create_crtc(test, drm,
+ priv->plane, NULL,
+ NULL,
+ NULL);
+ if (IS_ERR(priv->crtc))
+ return ERR_CAST(priv->crtc);
+
+ enc = &priv->encoder;
+ ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
+ if (ret)
+ return ERR_PTR(ret);
+
+ enc->possible_crtcs = drm_crtc_mask(priv->crtc);
+
+ bridge = &priv->test_bridge->bridge;
+ bridge->type = DRM_MODE_CONNECTOR_HDMIA;
+ bridge->supported_formats = supported_formats;
+ bridge->max_bpc = max_bpc;
+ bridge->ops |= DRM_BRIDGE_OP_HDMI;
+ bridge->vendor = "LNX";
+ bridge->product = "KUnit";
+
+ ret = drm_kunit_bridge_add(test, bridge);
+ if (ret)
+ return ERR_PTR(ret);
+
+ ret = drm_bridge_attach(enc, bridge, NULL, 0);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv->connector = drm_bridge_connector_init(drm, enc);
+ if (IS_ERR(priv->connector))
+ return ERR_CAST(priv->connector);
+
+ drm_connector_attach_encoder(priv->connector, enc);
+
+ drm_mode_config_reset(drm);
+
+ return priv;
+}
+
/*
* Test that drm_bridge_get_current_state() returns the last committed
* state for an atomic bridge.
@@ -786,10 +886,94 @@ static void drm_test_drm_bridge_helper_reset_crtc_legacy(struct kunit *test)
KUNIT_EXPECT_EQ(test, bridge_priv->disable_count, 1);
}
+/*
+ * Test that a bridge using the drm_atomic_helper_bridge_get_hdmi_output_bus_fmts()
+ * function for &drm_bridge_funcs.atomic_get_output_bus_fmts behaves as expected
+ * for an HDMI connector bridge. Does so by creating an HDMI bridge connector
+ * with RGB444, YCBCR444, and YCBCR420 (but not YCBCR422) as supported formats,
+ * sets the output depth to 8 bits per component, and then validates the returned
+ * list of bus formats.
+ */
+static void drm_test_drm_bridge_helper_hdmi_output_bus_fmts(struct kunit *test)
+{
+ struct drm_connector_state *conn_state;
+ struct drm_bridge_state *bridge_state;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_bridge_init_priv *priv;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *mode;
+ unsigned int num_output_fmts;
+ struct drm_bridge *bridge;
+ u32 *out_bus_fmts;
+ int ret;
+
+ priv = drm_test_bridge_hdmi_init(test, &drm_test_bridge_bus_fmts_funcs,
+ BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444) |
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420),
+ 12);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+
+ bridge = &priv->test_bridge->bridge;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+retry_commit:
+ conn_state = drm_atomic_get_connector_state(state, priv->connector);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ conn_state->hdmi.output_bpc = 8;
+
+ mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
+
+ ret = drm_atomic_set_crtc_for_connector(conn_state, priv->crtc);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state = drm_atomic_get_crtc_state(state, priv->crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+ ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ goto retry_commit;
+ }
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ crtc_state->enable = true;
+ crtc_state->active = true;
+
+ bridge_state = drm_atomic_get_bridge_state(state, bridge);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bridge_state);
+
+ out_bus_fmts = bridge->funcs->atomic_get_output_bus_fmts(
+ bridge, bridge_state, crtc_state, conn_state, &num_output_fmts);
+ KUNIT_EXPECT_NOT_NULL(test, out_bus_fmts);
+ KUNIT_EXPECT_EQ(test, num_output_fmts, 3);
+
+ KUNIT_EXPECT_EQ(test, out_bus_fmts[0], MEDIA_BUS_FMT_RGB888_1X24);
+ KUNIT_EXPECT_EQ(test, out_bus_fmts[1], MEDIA_BUS_FMT_YUV8_1X24);
+ KUNIT_EXPECT_EQ(test, out_bus_fmts[2], MEDIA_BUS_FMT_UYYVYY8_0_5X24);
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
+ kfree(out_bus_fmts);
+}
+
static struct kunit_case drm_bridge_helper_reset_crtc_tests[] = {
KUNIT_CASE(drm_test_drm_bridge_helper_reset_crtc_atomic),
KUNIT_CASE(drm_test_drm_bridge_helper_reset_crtc_atomic_disabled),
KUNIT_CASE(drm_test_drm_bridge_helper_reset_crtc_legacy),
+ KUNIT_CASE(drm_test_drm_bridge_helper_hdmi_output_bus_fmts),
{ }
};
--
2.53.0
^ permalink raw reply related
* [PATCH v11 22/22] drm/bridge: Document bridge chain format selection
From: Nicolas Frattaroli @ 2026-03-24 16:01 UTC (permalink / raw)
To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring,
Jonathan Corbet, Shuah Khan
Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
linux-rockchip, intel-gfx, intel-xe, linux-doc,
Nicolas Frattaroli
In-Reply-To: <20260324-color-format-v11-0-605559af4fb4@collabora.com>
The bridge chain format selection behaviour was, until now,
undocumented. With the addition of the "color format" DRM property, it's
not sufficiently complex enough that documentation is warranted,
especially for driver authors trying to do the right thing.
Add a high-level overview of how the process is supposed to work, and
mention what the display driver is supposed to do if it wants to make
use of this functionality.
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
Documentation/gpu/drm-kms-helpers.rst | 6 ++++++
drivers/gpu/drm/drm_bridge.c | 40 +++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 781129f78b06..47c4f593cf9d 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -181,6 +181,12 @@ Bridge Operations
.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
:doc: bridge operations
+Bridge Chain Format Selection
+-----------------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
+ :doc: bridge chain format selection
+
Bridge Connector Helper
-----------------------
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 9ee3a8c25510..188606a34313 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -198,6 +198,46 @@
* driver.
*/
+/**
+ * DOC: bridge chain format selection
+ *
+ * A bridge chain, from display output processor to connector, may contain
+ * bridges capable of converting between bus formats on their inputs, and
+ * output formats on their outputs. For example, a bridge may be able to convert
+ * from RGB to YCbCr 4:4:4, and pass through YCbCr 4:2:0 as-is, but not convert
+ * from RGB to YCbCr 4:2:0. This means not all input formats map to all output
+ * formats.
+ *
+ * Further adding to this, a desired output color format, as specified with the
+ * "color format" DRM property, might not correspond 1:1 to what the display
+ * driver should set at its output. The bridge chain it feeds into may only be
+ * able to reach the desired output format, if a conversion from a different
+ * starting format is performed.
+ *
+ * To deal with this complexity, the recursive bridge chain bus format selection
+ * logic starts with the last bridge in the chain, usually the connector, and
+ * then recursively walks the chain of bridges backwards to the first bridge,
+ * trying to find a path.
+ *
+ * For a display driver to work in such a scenario, it should read the first
+ * bridge's bridge state to figure out which bus format the chain resolved to.
+ * If the first bridge's input format resolved to %MEDIA_BUS_FMT_FIXED, then its
+ * output format should be used.
+ *
+ * Special handling is done for HDMI as it relates to format selection. Instead
+ * of directly using the "color format" DRM property for bridge chains that end
+ * in HDMI bridges, the bridge chain format selection logic will trust the logic
+ * that set the HDMI output format. For the common HDMI state helper
+ * functionality, this means that %DRM_CONNECTOR_COLOR_FORMAT_AUTO will allow
+ * fallbacks to YCBCr 4:2:0 if the bandwidth requirements would otherwise be too
+ * high but the mode and connector allow it.
+ *
+ * For bridge chains that do not end in an HDMI bridge,
+ * %DRM_CONNECTOR_COLOR_FORMAT_AUTO will be satisfied with the first output
+ * format on the last bridge for which it can find a path back to the first
+ * bridge.
+ */
+
/* Protect bridge_list and bridge_lingering_list */
static DEFINE_MUTEX(bridge_lock);
static LIST_HEAD(bridge_list);
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] docs: driver-api: fix 6 spelling typos in Documentation/driver-api
From: Jonathan Corbet @ 2026-03-24 16:09 UTC (permalink / raw)
To: tovicito; +Cc: skhan, linux-doc, linux-kernel, tovicito
In-Reply-To: <20260324160048.4899-1-tovictakamine@gmail.com>
tovicito <tovictakamine@gmail.com> writes:
> Signed-off-by: tovicito <tovictakamine@gmail.com>
> ---
> Documentation/driver-api/acpi/acpi-drivers.rst | 2 +-
> Documentation/driver-api/cxl/platform/acpi/cedt.rst | 2 +-
> Documentation/driver-api/cxl/platform/bios-and-efi.rst | 2 +-
> Documentation/driver-api/dmaengine/pxa_dma.rst | 2 +-
> Documentation/driver-api/libata.rst | 2 +-
> Documentation/driver-api/pci/p2pdma.rst | 2 +-
> 6 files changed, 6 insertions(+), 6 deletions(-)
The changes don't look terrible, but please resubmit with a proper
changelog and a full-name Signed-off-by line.
Thanks,
jon
^ permalink raw reply
* Re: [PATCH v2 2/6] gpio: move hogs into GPIO core
From: Geert Uytterhoeven @ 2026-03-24 16:16 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Linus Walleij, Bartosz Golaszewski, Frank Rowand, Mika Westerberg,
Andy Shevchenko, Aaro Koskinen, Janusz Krzysztofik, Tony Lindgren,
Russell King, Jonathan Corbet, Shuah Khan, linux-gpio,
linux-kernel, linux-acpi, linux-arm-kernel, linux-omap, linux-doc,
Mika Westerberg
In-Reply-To: <20260309-gpio-hog-fwnode-v2-2-4e61f3dbf06a@oss.qualcomm.com>
Hi Bartosz,
On Mon, 9 Mar 2026 at 13:43, Bartosz Golaszewski
<bartosz.golaszewski@oss.qualcomm.com> wrote:
> Refactor line hogging code by moving the parts duplicated in
> gpiolib-acpi-core.c and gpiolib-of.c into gpiolib.c, leaving just the
> OF-specific bits in the latter.
>
> This makes fwnode the primary API for setting up hogs and allows to use
> software nodes in addition to ACPI and OF nodes.
>
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Reviewed-by: Linus Walleij <linusw@kernel.org>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Thanks for your patch, which is now commit d1d564ec4992945d ("gpio:
move hogs into GPIO core") in gpio/gpio/for-next.
This breaks GPIO on the Renesas Marzen (R-Car H1) board:
-gpio_rcar ffc40000.gpio: driving 32 GPIOs
+gpiochip_add_data_with_key: GPIOs 512..543 (ffc40000.gpio) failed
to register, -22
+gpio_rcar ffc40000.gpio: failed to add GPIO controller
+gpio_rcar ffc40000.gpio: probe with driver gpio_rcar failed with error -22
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -960,6 +960,98 @@ static void machine_gpiochip_add(struct gpio_chip *gc)
> }
> }
>
> +int gpiochip_add_hog(struct gpio_chip *gc, struct fwnode_handle *fwnode)
> +{
> + struct fwnode_handle *gc_node = dev_fwnode(&gc->gpiodev->dev);
> + struct fwnode_reference_args gpiospec;
> + enum gpiod_flags dflags;
> + struct gpio_desc *desc;
> + unsigned long lflags;
> + const char *name;
> + int ret, argc;
> + u32 gpios[3]; /* We support up to three-cell bindings. */
> + u32 cells;
> +
> + lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
> + dflags = GPIOD_ASIS;
> + name = NULL;
> +
> + argc = fwnode_property_count_u32(fwnode, "gpios");
> + if (argc < 0)
> + return argc;
> + if (argc > 3)
> + return -EINVAL;
The GPIO hog at [1] has a gpios property with two entries:
gpios = <17 GPIO_ACTIVE_LOW>, <18 GPIO_ACTIVE_LOW>;
hence argc = 4, which is considered invalid.
The check should take into account the actual value of #gpio-cells,
and handle the presence of multiple GPIOs.
"git grep -Ww gpio-hog -- arch/*/boot/dts/ | grep 'gpios\s*=.*>,'" finds
several other places where multiple GPIOs are specified.
> +
> + ret = fwnode_property_read_u32_array(fwnode, "gpios", gpios, argc);
> + if (ret < 0)
> + return ret;
> +
> + if (is_of_node(fwnode)) {
> + /*
> + * OF-nodes need some additional special handling for
> + * translating of devicetree flags.
> + */
> + ret = fwnode_property_read_u32(gc_node, "#gpio-cells", &cells);
> + if (ret)
> + return ret;
> + if (!ret && argc != cells)
> + return -EINVAL;
> +
> + memset(&gpiospec, 0, sizeof(gpiospec));
> + gpiospec.fwnode = fwnode;
> + gpiospec.nargs = argc;
> +
> + for (int i = 0; i < argc; i++)
> + gpiospec.args[i] = gpios[i];
> +
> + ret = of_gpiochip_get_lflags(gc, &gpiospec, &lflags);
> + if (ret)
> + return ret;
> + } else {
> + /*
> + * GPIO_ACTIVE_LOW is currently the only lookup flag
> + * supported for non-OF firmware nodes.
> + */
> + if (gpios[1])
> + lflags |= GPIO_ACTIVE_LOW;
> + }
> +
> + if (fwnode_property_present(fwnode, "input"))
> + dflags |= GPIOD_IN;
> + else if (fwnode_property_present(fwnode, "output-low"))
> + dflags |= GPIOD_OUT_LOW;
> + else if (fwnode_property_present(fwnode, "output-high"))
> + dflags |= GPIOD_OUT_HIGH;
> + else
> + return -EINVAL;
> +
> + fwnode_property_read_string(fwnode, "line-name", &name);
> +
> + desc = gpiochip_get_desc(gc, gpios[0]);
> + if (IS_ERR(desc))
> + return PTR_ERR(desc);
> +
> + return gpiod_hog(desc, name, lflags, dflags);
> +}
[1] https://elixir.bootlin.com/linux/v6.19.9/source/arch/arm/boot/dts/renesas/r8a7779-marzen.dts#L196
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH v2] docs: driver-api: fix 6 spelling typos in Documentation/driver-api
From: Tomás Pando @ 2026-03-24 16:19 UTC (permalink / raw)
To: corbet; +Cc: skhan, linux-doc, linux-kernel, tovicito
From: tovicito <tovictakamine@gmail.com>
Fix minor spelling mistakes in the driver-api documentation. These
changes improve readability in ACPI, CXL, DMA and PCI docs.
Signed-off-by: tovicito <tovictakamine@gmail.com>
Signed-off-by: Tomás Pando <tovictakamine@gmail.com>
---
Documentation/driver-api/acpi/acpi-drivers.rst | 2 +-
Documentation/driver-api/cxl/platform/acpi/cedt.rst | 2 +-
Documentation/driver-api/cxl/platform/bios-and-efi.rst | 2 +-
Documentation/driver-api/dmaengine/pxa_dma.rst | 2 +-
Documentation/driver-api/libata.rst | 2 +-
Documentation/driver-api/pci/p2pdma.rst | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Documentation/driver-api/acpi/acpi-drivers.rst b/Documentation/driver-api/acpi/acpi-drivers.rst
index b1fbbddb8..376b6d8a6 100644
--- a/Documentation/driver-api/acpi/acpi-drivers.rst
+++ b/Documentation/driver-api/acpi/acpi-drivers.rst
@@ -47,7 +47,7 @@ generally be avoided and so struct acpi_driver objects should not be used.
Moreover, a device ID is necessary to bind a driver directly to an ACPI device
node, but device IDs are not generally associated with all of them. Some of
them contain alternative information allowing the corresponding pieces of
-hardware to be identified, for example represeted by an _ADR object return
+hardware to be identified, for example represented by an _ADR object return
value, and device IDs are not used in those cases. In consequence, confusingly
enough, binding an ACPI driver to an ACPI device node may even be impossible.
diff --git a/Documentation/driver-api/cxl/platform/acpi/cedt.rst b/Documentation/driver-api/cxl/platform/acpi/cedt.rst
index 1d9c9d359..217a75fb4 100644
--- a/Documentation/driver-api/cxl/platform/acpi/cedt.rst
+++ b/Documentation/driver-api/cxl/platform/acpi/cedt.rst
@@ -55,7 +55,7 @@ voltile vs persistent, etc). One or more bits may be set. ::
Bit[1]: CXL Type 3 Memory
Bit[2]: Volatile Memory
Bit[3]: Persistent Memory
- Bit[4]: Fixed Config (HPA cannot be re-used)
+ Bit[4]: Fixed Config (HPA cannot be reused)
INTRA-host-bridge interleave (multiple devices on one host bridge) is NOT
reported in this structure, and is solely defined via CXL device decoder
diff --git a/Documentation/driver-api/cxl/platform/bios-and-efi.rst b/Documentation/driver-api/cxl/platform/bios-and-efi.rst
index a4b44c018..5d918b06f 100644
--- a/Documentation/driver-api/cxl/platform/bios-and-efi.rst
+++ b/Documentation/driver-api/cxl/platform/bios-and-efi.rst
@@ -277,7 +277,7 @@ The CFMWS field of the CEDT has special restriction bits which describe whether
the described memory region allows volatile or persistent memory (or both). If
the platform intends to support either:
-1) A device with multiple medias, or
+1) A device with multiple media, or
2) Using a persistent memory device as normal memory
A platform may wish to create multiple CEDT CFMWS entries to describe the same
diff --git a/Documentation/driver-api/dmaengine/pxa_dma.rst b/Documentation/driver-api/dmaengine/pxa_dma.rst
index 442ee691a..8f9da66b0 100644
--- a/Documentation/driver-api/dmaengine/pxa_dma.rst
+++ b/Documentation/driver-api/dmaengine/pxa_dma.rst
@@ -40,7 +40,7 @@ Design
======
a) Virtual channels
Same concept as in sa11x0 driver, ie. a driver was assigned a "virtual
-channel" linked to the requestor line, and the physical DMA channel is
+channel" linked to the requester line, and the physical DMA channel is
assigned on the fly when the transfer is issued.
b) Transfer anatomy for a scatter-gather transfer
diff --git a/Documentation/driver-api/libata.rst b/Documentation/driver-api/libata.rst
index 93d97fe78..28b8437f6 100644
--- a/Documentation/driver-api/libata.rst
+++ b/Documentation/driver-api/libata.rst
@@ -286,7 +286,7 @@ and other exceptional conditions. The primary responsibility of an
implementation is to call :c:func:`ata_std_error_handler`.
:c:func:`ata_std_error_handler` will perform a standard error handling sequence
-to resurect failed devices, detach lost devices and add new devices (if any).
+to resurrect failed devices, detach lost devices and add new devices (if any).
This function will call the various reset operations for a port, as needed.
These operations are as follows.
diff --git a/Documentation/driver-api/pci/p2pdma.rst b/Documentation/driver-api/pci/p2pdma.rst
index 280673b50..d3f406cca 100644
--- a/Documentation/driver-api/pci/p2pdma.rst
+++ b/Documentation/driver-api/pci/p2pdma.rst
@@ -38,7 +38,7 @@ for all usage refcounts to reach zero.
At the lowest level the P2P subsystem offers a naked struct p2p_provider that
delegates lifecycle management to the providing driver. It is expected that
drivers using this option will wrap their MMIO memory in DMABUF and use DMABUF
-to provide an invalidation shutdown. These MMIO addresess have no struct page, and
+to provide an invalidation shutdown. These MMIO addresses have no struct page, and
if used with mmap() must create special PTEs. As such there are very few
kernel uAPIs that can accept pointers to them; in particular they cannot be used
with read()/write(), including O_DIRECT.
--
2.53.0
^ permalink raw reply related
* Re: [PATCH net-next v2] docs/mlx5: Fix typo subfuction
From: Randy Dunlap @ 2026-03-24 16:21 UTC (permalink / raw)
To: Ryohei Kinugawa, rrameshbabu, saeedm, leon, tariqt, mbloch, davem,
edumazet, kuba, pabeni, horms, corbet, skhan
Cc: netdev, linux-rdma, linux-doc, joe
In-Reply-To: <20260324053416.70166-1-ryohei.kinugawa@gmail.com>
On 3/23/26 10:34 PM, Ryohei Kinugawa wrote:
> Fix two typos:
> - 'Subfunctons' -> 'Subfunctions'
> - 'subfuction' -> 'subfunction'
>
> Reviewed-by: Joe Damato <joe@dama.to>
> Signed-off-by: Ryohei Kinugawa <ryohei.kinugawa@gmail.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org>
thanks.
> ---
> .../device_drivers/ethernet/mellanox/mlx5/kconfig.rst | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/kconfig.rst b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/kconfig.rst
> index 34e911480108..b45d6871492c 100644
> --- a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/kconfig.rst
> +++ b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/kconfig.rst
> @@ -114,13 +114,13 @@ Enabling the driver and kconfig options
> **CONFIG_MLX5_SF=(y/n)**
>
> | Build support for subfunction.
> -| Subfunctons are more light weight than PCI SRIOV VFs. Choosing this option
> +| Subfunctions are more light weight than PCI SRIOV VFs. Choosing this option
> | will enable support for creating subfunction devices.
>
>
> **CONFIG_MLX5_SF_MANAGER=(y/n)**
>
> -| Build support for subfuction port in the NIC. A Mellanox subfunction
> +| Build support for subfunction port in the NIC. A Mellanox subfunction
> | port is managed through devlink. A subfunction supports RDMA, netdevice
> | and vdpa device. It is similar to a SRIOV VF but it doesn't require
> | SRIOV support.
--
~Randy
^ permalink raw reply
* Re: [PATCH] docs: driver-api: fix 6 spelling typos in Documentation/driver-api
From: Randy Dunlap @ 2026-03-24 16:24 UTC (permalink / raw)
To: Jonathan Corbet, tovicito; +Cc: skhan, linux-doc, linux-kernel
In-Reply-To: <87tsu56wg2.fsf@trenco.lwn.net>
On 3/24/26 9:09 AM, Jonathan Corbet wrote:
> tovicito <tovictakamine@gmail.com> writes:
>
>> Signed-off-by: tovicito <tovictakamine@gmail.com>
>> ---
>> Documentation/driver-api/acpi/acpi-drivers.rst | 2 +-
>> Documentation/driver-api/cxl/platform/acpi/cedt.rst | 2 +-
>> Documentation/driver-api/cxl/platform/bios-and-efi.rst | 2 +-
>> Documentation/driver-api/dmaengine/pxa_dma.rst | 2 +-
>> Documentation/driver-api/libata.rst | 2 +-
>> Documentation/driver-api/pci/p2pdma.rst | 2 +-
>> 6 files changed, 6 insertions(+), 6 deletions(-)
>
> The changes don't look terrible, but please resubmit with a proper
> changelog and a full-name Signed-off-by line.
and you can add to the v2 patch:
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
thanks.
--
~Randy
^ permalink raw reply
* [PATCH v2] docs: driver-api: fix 6 spelling typos in Documentation/driver-api
From: Tomás Pando @ 2026-03-24 16:24 UTC (permalink / raw)
To: corbet; +Cc: skhan, linux-doc, linux-kernel, Tomás Pando
Fix minor spelling mistakes in the driver-api documentation. These
changes improve readability in ACPI, CXL, DMA and PCI docs.
Signed-off-by: Tomás Pando <tovictakamine@gmail.com>
---
Documentation/driver-api/acpi/acpi-drivers.rst | 2 +-
Documentation/driver-api/cxl/platform/acpi/cedt.rst | 2 +-
Documentation/driver-api/cxl/platform/bios-and-efi.rst | 2 +-
Documentation/driver-api/dmaengine/pxa_dma.rst | 2 +-
Documentation/driver-api/libata.rst | 2 +-
Documentation/driver-api/pci/p2pdma.rst | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Documentation/driver-api/acpi/acpi-drivers.rst b/Documentation/driver-api/acpi/acpi-drivers.rst
index b1fbbddb8..376b6d8a6 100644
--- a/Documentation/driver-api/acpi/acpi-drivers.rst
+++ b/Documentation/driver-api/acpi/acpi-drivers.rst
@@ -47,7 +47,7 @@ generally be avoided and so struct acpi_driver objects should not be used.
Moreover, a device ID is necessary to bind a driver directly to an ACPI device
node, but device IDs are not generally associated with all of them. Some of
them contain alternative information allowing the corresponding pieces of
-hardware to be identified, for example represeted by an _ADR object return
+hardware to be identified, for example represented by an _ADR object return
value, and device IDs are not used in those cases. In consequence, confusingly
enough, binding an ACPI driver to an ACPI device node may even be impossible.
diff --git a/Documentation/driver-api/cxl/platform/acpi/cedt.rst b/Documentation/driver-api/cxl/platform/acpi/cedt.rst
index 1d9c9d359..217a75fb4 100644
--- a/Documentation/driver-api/cxl/platform/acpi/cedt.rst
+++ b/Documentation/driver-api/cxl/platform/acpi/cedt.rst
@@ -55,7 +55,7 @@ voltile vs persistent, etc). One or more bits may be set. ::
Bit[1]: CXL Type 3 Memory
Bit[2]: Volatile Memory
Bit[3]: Persistent Memory
- Bit[4]: Fixed Config (HPA cannot be re-used)
+ Bit[4]: Fixed Config (HPA cannot be reused)
INTRA-host-bridge interleave (multiple devices on one host bridge) is NOT
reported in this structure, and is solely defined via CXL device decoder
diff --git a/Documentation/driver-api/cxl/platform/bios-and-efi.rst b/Documentation/driver-api/cxl/platform/bios-and-efi.rst
index a4b44c018..5d918b06f 100644
--- a/Documentation/driver-api/cxl/platform/bios-and-efi.rst
+++ b/Documentation/driver-api/cxl/platform/bios-and-efi.rst
@@ -277,7 +277,7 @@ The CFMWS field of the CEDT has special restriction bits which describe whether
the described memory region allows volatile or persistent memory (or both). If
the platform intends to support either:
-1) A device with multiple medias, or
+1) A device with multiple media, or
2) Using a persistent memory device as normal memory
A platform may wish to create multiple CEDT CFMWS entries to describe the same
diff --git a/Documentation/driver-api/dmaengine/pxa_dma.rst b/Documentation/driver-api/dmaengine/pxa_dma.rst
index 442ee691a..8f9da66b0 100644
--- a/Documentation/driver-api/dmaengine/pxa_dma.rst
+++ b/Documentation/driver-api/dmaengine/pxa_dma.rst
@@ -40,7 +40,7 @@ Design
======
a) Virtual channels
Same concept as in sa11x0 driver, ie. a driver was assigned a "virtual
-channel" linked to the requestor line, and the physical DMA channel is
+channel" linked to the requester line, and the physical DMA channel is
assigned on the fly when the transfer is issued.
b) Transfer anatomy for a scatter-gather transfer
diff --git a/Documentation/driver-api/libata.rst b/Documentation/driver-api/libata.rst
index 93d97fe78..28b8437f6 100644
--- a/Documentation/driver-api/libata.rst
+++ b/Documentation/driver-api/libata.rst
@@ -286,7 +286,7 @@ and other exceptional conditions. The primary responsibility of an
implementation is to call :c:func:`ata_std_error_handler`.
:c:func:`ata_std_error_handler` will perform a standard error handling sequence
-to resurect failed devices, detach lost devices and add new devices (if any).
+to resurrect failed devices, detach lost devices and add new devices (if any).
This function will call the various reset operations for a port, as needed.
These operations are as follows.
diff --git a/Documentation/driver-api/pci/p2pdma.rst b/Documentation/driver-api/pci/p2pdma.rst
index 280673b50..d3f406cca 100644
--- a/Documentation/driver-api/pci/p2pdma.rst
+++ b/Documentation/driver-api/pci/p2pdma.rst
@@ -38,7 +38,7 @@ for all usage refcounts to reach zero.
At the lowest level the P2P subsystem offers a naked struct p2p_provider that
delegates lifecycle management to the providing driver. It is expected that
drivers using this option will wrap their MMIO memory in DMABUF and use DMABUF
-to provide an invalidation shutdown. These MMIO addresess have no struct page, and
+to provide an invalidation shutdown. These MMIO addresses have no struct page, and
if used with mmap() must create special PTEs. As such there are very few
kernel uAPIs that can accept pointers to them; in particular they cannot be used
with read()/write(), including O_DIRECT.
--
2.53.0
^ permalink raw reply related
* Re: [PATCH 2/2] Documentation: document panic_on_unrecoverable_memory_failure sysctl
From: Randy Dunlap @ 2026-03-24 16:27 UTC (permalink / raw)
To: Akira Yokosawa, leitao
Cc: akpm, corbet, kernel-team, linmiaohe, linux-doc, linux-kernel,
linux-mm, nao.horiguchi, skhan
In-Reply-To: <2ceb291b-3b18-43a7-9d51-5c752f1eebf4@gmail.com>
On 3/24/26 4:48 AM, Akira Yokosawa wrote:
> Hi,
>
> On Tue, 24 Mar 2026 03:09:25 -0700, Breno Leitao wrote:
>> Hello Randy,
>>
>> On Mon, Mar 23, 2026 at 09:51:55AM -0700, Randy Dunlap wrote:
>>> On 3/23/26 8:29 AM, Breno Leitao wrote:
>>>> Document the new vm.panic_on_unrecoverable_memory_failure sysctl in the
>>>> admin guide, following the same format as panic_on_unrecovered_nmi.
>>>>
>>>> Signed-off-by: Breno Leitao <leitao@debian.org>
>>>> ---
>>>> Documentation/admin-guide/sysctl/vm.rst | 27 +++++++++++++++++++++++++++
>>>> 1 file changed, 27 insertions(+)
>>>>
>>>> diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst
>>>> index 97e12359775c9..3310fb8272fb9 100644
>>>> --- a/Documentation/admin-guide/sysctl/vm.rst
>>>> +++ b/Documentation/admin-guide/sysctl/vm.rst
>>>
>>>
>>>> +
>>>> += ===================================================================
>>>> +0 Try to continue operation (default).
>>>> +1 Panic immediately. If the ``panic`` sysctl is also non-zero then the
>>>> + machine will be rebooted.
>>>> += ===================================================================
>>>
>>> The table begin and end lines must be at least as long as the text (may be
>>> longer). Please extend the =========== lines by a few characters.
>>
>> The HTML renders correctly in Sphinx (likely due to automatic column
>> expansion), but I agree the raw table format should be properly
>> structured.
>
> Just to be clear, Sphinx is behaving as expected here.
>
> The table is in the form of so-called "simple tables" in the reST
> (or docutils) parlance. The rightmost column can exceed the width
> indicated by "==========".
>
> Quote from [1]:
>
> The rightmost column is unbounded; text may continue past the
> edge of the table (as indicated by the table borders). However,
> it is recommended that borders be made long enough to contain
> the entire text.
>
> [1]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#simple-tables
>
> So, it's just a recommendation, rather than a requirement.
>
> "Grid tables" have a stricter rule.
>
> Hope this helps.
>
> Regards,
> Akira
>
>>
>> I'll send v2 with this corrected.
>>
>> Thanks for the review,
>> --breno
Thanks to both of you for the edumcation.
--
~Randy
^ permalink raw reply
* Re: [PATCH] Documentation/rtla: Document SIGINT behavior
From: Tomas Glozar @ 2026-03-24 16:30 UTC (permalink / raw)
To: Steven Rostedt
Cc: Jonathan Corbet, Shuah Khan, John Kacur, Luis Goncalves,
Crystal Wood, Costa Shulyupin, Wander Lairson Costa, LKML,
linux-trace-kernel, linux-doc, Attila Fazekas
In-Reply-To: <20260324112249.5fe25641@gandalf.local.home>
út 24. 3. 2026 v 16:22 odesílatel Steven Rostedt <rostedt@goodmis.org> napsal:
> >
> > Note: There was a bug in SIGINT behavior, fixed in upcoming commit [1].
> >
> > [1] https://lore.kernel.org/linux-trace-kernel/20260310160725.144443-1-tglozar@redhat.com/
>
> Hmm, this may be interesting enough to add to the change log itself.
>
I thought about that, but it felt a bit redundant, since the other
patch will also be a part of the commit history. I see that some
documentation patches do mention the commit that introduced the
change. Here, it is only the SIGINT during cleanup part that got
changed (segfault/undefined behavior -> default handler) so it might
make sense.
> > +Also note that when using the timerlat tool in BPF mode, samples are processed
> > +in-kernel; RTLA only copies them out to display them to the user. A second
> > +SIGINT does not affect in-kernel sample aggregation.
>
> But does it affect the user space side of reading that information?
>
No, it shouldn't, the pattern for both timerlat-top and timerlat-hist is:
while(stop_tracing) {
timerlat_bpf_wait(...);
timerlat_{top,hist}_pull_bpf_data(...);
...
}
The BPF program is detached after this, so all data gathered up to the
point of the SIGINT will be displayed. A second SIGINT does not affect
it, since it calls tracefs_iterate_stop() which stops
tracefs_iterate_raw_events(). It does not stop
timelat_{top,hist}_pull_bpf_data() - which is aggregated anyway, so
stopping it would just leave a part of the histogram/top empty.
> > +
> > EXIT STATUS
> > ===========
> >
>
> Other than that ... LGTM,
>
> Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
>
> -- Steve
>
Thanks for looking at this.
Tomas
^ permalink raw reply
* Re: [PATCH v3 06/24] vfio/pci: Register a file handler with Live Update Orchestrator
From: David Matlack @ 2026-03-24 16:33 UTC (permalink / raw)
To: Yi Liu
Cc: Alex Williamson, Bjorn Helgaas, Adithya Jayachandran,
Alexander Graf, Alex Mastro, Andrew Morton, Ankit Agrawal,
Arnd Bergmann, Askar Safin, Borislav Petkov (AMD), Chris Li,
Dapeng Mi, David Rientjes, Feng Tang, Jacob Pan, Jason Gunthorpe,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Kees Cook,
Kevin Tian, kexec, kvm, Leon Romanovsky, Leon Romanovsky,
linux-doc, linux-kernel, linux-kselftest, linux-mm, linux-pci,
Li RongQing, Lukas Wunner, Marco Elver, Michał Winiarski,
Mike Rapoport, Parav Pandit, Pasha Tatashin, Paul E. McKenney,
Pawan Gupta, Peter Zijlstra (Intel), Pranjal Shrivastava,
Pratyush Yadav, Raghavendra Rao Ananta, Randy Dunlap,
Rodrigo Vivi, Saeed Mahameed, Samiullah Khawaja, Shuah Khan,
Vipin Sharma, Vivek Kasireddy, William Tu, Zhu Yanjun
In-Reply-To: <0d2eedec-01c1-41c9-bc74-0133ae6ebb04@intel.com>
On Tue, Mar 24, 2026 at 6:00 AM Yi Liu <yi.l.liu@intel.com> wrote:
> On 3/24/26 07:57, David Matlack wrote:
> > --- a/drivers/vfio/pci/vfio_pci.c
> > +++ b/drivers/vfio/pci/vfio_pci.c
> > @@ -170,6 +170,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> > ret = vfio_pci_core_register_device(vdev);
> > if (ret)
> > goto out_put_vdev;
> > +
>
> a meaningless line here.
Will fix in v4, thanks.
> > --- /dev/null
> > +++ b/include/linux/kho/abi/vfio_pci.h
> > @@ -0,0 +1,28 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +
> > +/*
> > + * Copyright (c) 2025, Google LLC.
>
> would be nice to update 2025 to 2026 now. :)
Oops, missed this one, thanks. Will fix in v4.
^ permalink raw reply
* Re: [PATCH v4 05/21] mm: switch the rmap lock held option off in compat layer
From: Lorenzo Stoakes (Oracle) @ 2026-03-24 16:35 UTC (permalink / raw)
To: Vlastimil Babka (SUSE)
Cc: Andrew Morton, Jonathan Corbet, Clemens Ladisch, Arnd Bergmann,
Greg Kroah-Hartman, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Long Li, Alexander Shishkin, Maxime Coquelin,
Alexandre Torgue, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra, Bodo Stroesser, Martin K . Petersen,
David Howells, Marc Dionne, Alexander Viro, Christian Brauner,
Jan Kara, David Hildenbrand, Liam R . Howlett, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Jann Horn, Pedro Falcato,
linux-kernel, linux-doc, linux-hyperv, linux-stm32,
linux-arm-kernel, linux-mtd, linux-staging, linux-scsi,
target-devel, linux-afs, linux-fsdevel, linux-mm, Ryan Roberts
In-Reply-To: <d5b66671-697f-4a4d-8039-d9c9ac5ad4d7@kernel.org>
On Tue, Mar 24, 2026 at 03:26:28PM +0100, Vlastimil Babka (SUSE) wrote:
> On 3/20/26 23:39, Lorenzo Stoakes (Oracle) wrote:
> > In the mmap_prepare compatibility layer, we don't need to hold the rmap
> > lock, as we are being called from an .mmap handler.
> >
> > The .mmap_prepare hook, when invoked in the VMA logic, is called prior to
> > the VMA being instantiated, but the completion hook is called after the VMA
> > is linked into the maple tree, meaning rmap walkers can reach it.
> >
> > The mmap hook does not link the VMA into the tree, so this cannot happen.
> >
> > Therefore it's safe to simply disable this in the mmap_prepare
> > compatibility layer.
> >
> > Also update VMA tests code to reflect current compatibility layer state.
> >
> > Signed-off-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
>
> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
>
> a typo fix below, Andrew can fix locally?
>
> > ---
> > mm/util.c | 6 ++++-
> > tools/testing/vma/include/dup.h | 42 +++++++++++++++++----------------
> > 2 files changed, 27 insertions(+), 21 deletions(-)
> >
> > diff --git a/mm/util.c b/mm/util.c
> > index a2cfa0d77c35..182f0f5cc400 100644
> > --- a/mm/util.c
> > +++ b/mm/util.c
> > @@ -1204,6 +1204,7 @@ int compat_vma_mmap(struct file *file, struct vm_area_struct *vma)
> >
> > .action.type = MMAP_NOTHING, /* Default */
> > };
> > + struct mmap_action *action = &desc.action;
> > int err;
> >
> > err = vfs_mmap_prepare(file, &desc);
> > @@ -1214,8 +1215,11 @@ int compat_vma_mmap(struct file *file, struct vm_area_struct *vma)
> > if (err)
> > return err;
> >
> > + /* being invoked from .mmmap means we don't have to enforce this. */
>
> .mmap
mmmmm map! ;)
Andrew - could you fixup in place? Thanks.
>
> > + action->hide_from_rmap_until_complete = false;
> > +
> > set_vma_from_desc(vma, &desc);
> > - err = mmap_action_complete(vma, &desc.action);
> > + err = mmap_action_complete(vma, action);
> > if (err) {
> > const size_t len = vma_pages(vma) << PAGE_SHIFT;
> >
^ permalink raw reply
* [PATCH v3] docs: driver-api: fix 6 spelling typos in Documentation/driver-api
From: Tomás Pando @ 2026-03-24 16:36 UTC (permalink / raw)
To: corbet; +Cc: skhan, linux-doc, linux-kernel, Tomás Pando, Randy Dunlap
Fix minor spelling mistakes in the driver-api documentation. These
changes improve readability in ACPI, CXL, DMA and PCI docs.
v3: Added reviewed-by from Randy Dunlap.
v2: Added full name as requested by Jon Corbet.
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Tomás Pando <tovictakamine@gmail.com>
---
Documentation/driver-api/acpi/acpi-drivers.rst | 2 +-
Documentation/driver-api/cxl/platform/acpi/cedt.rst | 2 +-
Documentation/driver-api/cxl/platform/bios-and-efi.rst | 2 +-
Documentation/driver-api/dmaengine/pxa_dma.rst | 2 +-
Documentation/driver-api/libata.rst | 2 +-
Documentation/driver-api/pci/p2pdma.rst | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Documentation/driver-api/acpi/acpi-drivers.rst b/Documentation/driver-api/acpi/acpi-drivers.rst
index b1fbbddb8..376b6d8a6 100644
--- a/Documentation/driver-api/acpi/acpi-drivers.rst
+++ b/Documentation/driver-api/acpi/acpi-drivers.rst
@@ -47,7 +47,7 @@ generally be avoided and so struct acpi_driver objects should not be used.
Moreover, a device ID is necessary to bind a driver directly to an ACPI device
node, but device IDs are not generally associated with all of them. Some of
them contain alternative information allowing the corresponding pieces of
-hardware to be identified, for example represeted by an _ADR object return
+hardware to be identified, for example represented by an _ADR object return
value, and device IDs are not used in those cases. In consequence, confusingly
enough, binding an ACPI driver to an ACPI device node may even be impossible.
diff --git a/Documentation/driver-api/cxl/platform/acpi/cedt.rst b/Documentation/driver-api/cxl/platform/acpi/cedt.rst
index 1d9c9d359..217a75fb4 100644
--- a/Documentation/driver-api/cxl/platform/acpi/cedt.rst
+++ b/Documentation/driver-api/cxl/platform/acpi/cedt.rst
@@ -55,7 +55,7 @@ voltile vs persistent, etc). One or more bits may be set. ::
Bit[1]: CXL Type 3 Memory
Bit[2]: Volatile Memory
Bit[3]: Persistent Memory
- Bit[4]: Fixed Config (HPA cannot be re-used)
+ Bit[4]: Fixed Config (HPA cannot be reused)
INTRA-host-bridge interleave (multiple devices on one host bridge) is NOT
reported in this structure, and is solely defined via CXL device decoder
diff --git a/Documentation/driver-api/cxl/platform/bios-and-efi.rst b/Documentation/driver-api/cxl/platform/bios-and-efi.rst
index a4b44c018..5d918b06f 100644
--- a/Documentation/driver-api/cxl/platform/bios-and-efi.rst
+++ b/Documentation/driver-api/cxl/platform/bios-and-efi.rst
@@ -277,7 +277,7 @@ The CFMWS field of the CEDT has special restriction bits which describe whether
the described memory region allows volatile or persistent memory (or both). If
the platform intends to support either:
-1) A device with multiple medias, or
+1) A device with multiple media, or
2) Using a persistent memory device as normal memory
A platform may wish to create multiple CEDT CFMWS entries to describe the same
diff --git a/Documentation/driver-api/dmaengine/pxa_dma.rst b/Documentation/driver-api/dmaengine/pxa_dma.rst
index 442ee691a..8f9da66b0 100644
--- a/Documentation/driver-api/dmaengine/pxa_dma.rst
+++ b/Documentation/driver-api/dmaengine/pxa_dma.rst
@@ -40,7 +40,7 @@ Design
======
a) Virtual channels
Same concept as in sa11x0 driver, ie. a driver was assigned a "virtual
-channel" linked to the requestor line, and the physical DMA channel is
+channel" linked to the requester line, and the physical DMA channel is
assigned on the fly when the transfer is issued.
b) Transfer anatomy for a scatter-gather transfer
diff --git a/Documentation/driver-api/libata.rst b/Documentation/driver-api/libata.rst
index 93d97fe78..28b8437f6 100644
--- a/Documentation/driver-api/libata.rst
+++ b/Documentation/driver-api/libata.rst
@@ -286,7 +286,7 @@ and other exceptional conditions. The primary responsibility of an
implementation is to call :c:func:`ata_std_error_handler`.
:c:func:`ata_std_error_handler` will perform a standard error handling sequence
-to resurect failed devices, detach lost devices and add new devices (if any).
+to resurrect failed devices, detach lost devices and add new devices (if any).
This function will call the various reset operations for a port, as needed.
These operations are as follows.
diff --git a/Documentation/driver-api/pci/p2pdma.rst b/Documentation/driver-api/pci/p2pdma.rst
index 280673b50..d3f406cca 100644
--- a/Documentation/driver-api/pci/p2pdma.rst
+++ b/Documentation/driver-api/pci/p2pdma.rst
@@ -38,7 +38,7 @@ for all usage refcounts to reach zero.
At the lowest level the P2P subsystem offers a naked struct p2p_provider that
delegates lifecycle management to the providing driver. It is expected that
drivers using this option will wrap their MMIO memory in DMABUF and use DMABUF
-to provide an invalidation shutdown. These MMIO addresess have no struct page, and
+to provide an invalidation shutdown. These MMIO addresses have no struct page, and
if used with mmap() must create special PTEs. As such there are very few
kernel uAPIs that can accept pointers to them; in particular they cannot be used
with read()/write(), including O_DIRECT.
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] doc: Add CPU Isolation documentation
From: Sebastian Andrzej Siewior @ 2026-03-24 16:40 UTC (permalink / raw)
To: Waiman Long
Cc: Frederic Weisbecker, LKML, Anna-Maria Behnsen, Gabriele Monaco,
Ingo Molnar, Jonathan Corbet, Marcelo Tosatti, Marco Crivellari,
Michal Hocko, Paul E . McKenney, Peter Zijlstra, Phil Auld,
Steven Rostedt, Thomas Gleixner, Valentin Schneider,
Vlastimil Babka, linux-doc
In-Reply-To: <579827ac-a933-45ec-b396-01656c30c9e4@redhat.com>
On 2026-03-24 12:00:17 [-0400], Waiman Long wrote:
> > while looking at this again, shouldn't you also do
> > echo 7 > cpuset.cpus.exclusive
> >
> > to ensure the CPU isn't used somewhere else?
>
> For backport compatibility, the use of cpuset.cpus.exclusive is optional for
> creating a local partition underneath the cgroup root. The example should
> still work without setting cpuset.cpus.exclusive.
I would have to double check but I think only after the
cpuset.cpus.exclusive the CPU vanished from the cpumask of my current
task.
> Cheers,
> Longman
Sebastian
^ permalink raw reply
* Re: [PATCH v3] docs: driver-api: fix 6 spelling typos in Documentation/driver-api
From: Jonathan Corbet @ 2026-03-24 16:44 UTC (permalink / raw)
To: Tomás Pando
Cc: skhan, linux-doc, linux-kernel, Tomás Pando, Randy Dunlap
In-Reply-To: <20260324163604.5710-1-tovictakamine@gmail.com>
Tomás Pando <tovictakamine@gmail.com> writes:
> Fix minor spelling mistakes in the driver-api documentation. These
> changes improve readability in ACPI, CXL, DMA and PCI docs.
> v3: Added reviewed-by from Randy Dunlap.
> v2: Added full name as requested by Jon Corbet.
For future reference, the version-change lines should go below the "---"
line so that the maintainer doesn't have to strip them out.
(No need to resubmit for that this time).
> Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
> Signed-off-by: Tomás Pando <tovictakamine@gmail.com>
> ---
> Documentation/driver-api/acpi/acpi-drivers.rst | 2 +-
> Documentation/driver-api/cxl/platform/acpi/cedt.rst | 2 +-
> Documentation/driver-api/cxl/platform/bios-and-efi.rst | 2 +-
> Documentation/driver-api/dmaengine/pxa_dma.rst | 2 +-
> Documentation/driver-api/libata.rst | 2 +-
> Documentation/driver-api/pci/p2pdma.rst | 2 +-
> 6 files changed, 6 insertions(+), 6 deletions(-)
Thanks,
jon
^ permalink raw reply
* Re: [PATCH v3 07/24] vfio/pci: Preserve vfio-pci device files across Live Update
From: David Matlack @ 2026-03-24 16:46 UTC (permalink / raw)
To: Yi Liu
Cc: Alex Williamson, Bjorn Helgaas, Adithya Jayachandran,
Alexander Graf, Alex Mastro, Andrew Morton, Ankit Agrawal,
Arnd Bergmann, Askar Safin, Borislav Petkov (AMD), Chris Li,
Dapeng Mi, David Rientjes, Feng Tang, Jacob Pan, Jason Gunthorpe,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Kees Cook,
Kevin Tian, kexec, kvm, Leon Romanovsky, Leon Romanovsky,
linux-doc, linux-kernel, linux-kselftest, linux-mm, linux-pci,
Li RongQing, Lukas Wunner, Marco Elver, Michał Winiarski,
Mike Rapoport, Parav Pandit, Pasha Tatashin, Paul E. McKenney,
Pawan Gupta, Peter Zijlstra (Intel), Pranjal Shrivastava,
Pratyush Yadav, Raghavendra Rao Ananta, Randy Dunlap,
Rodrigo Vivi, Saeed Mahameed, Samiullah Khawaja, Shuah Khan,
Vipin Sharma, Vivek Kasireddy, William Tu, Zhu Yanjun
In-Reply-To: <df5dac48-8a54-49e2-acb8-9370b7078033@intel.com>
On Tue, Mar 24, 2026 at 6:01 AM Yi Liu <yi.l.liu@intel.com> wrote:
> On 3/24/26 07:57, David Matlack wrote:
> > + * Usage Example
> > + * =============
> > + *
> > + * VFIO PCI devices can be preserved across a kexec by preserving the file
> > + * associated with the device in a LUO session::
> > + *
> > + * device_fd = open("/dev/vfio/devices/X");
>
> /dev/vfio/devices/vfioX
Will fix in v4.
> > + * * The device file must have been acquired from the VFIO character device,
> > + * not ``VFIO_GROUP_GET_DEVICE_FD``.
>
> how about "The device file descriptor must be obtained by opening the
> VFIO device
> character device (``/dev/vfio/devices/vfioX``), not via
> ``VFIO_GROUP_GET_DEVICE_FD``."?
>
> just be aligned with the below words in vfio.rst.
>
> "Traditionally user acquires a device fd via VFIO_GROUP_GET_DEVICE_FD
> user can now acquire a device fd by directly opening a character device
> /dev/vfio/devices/vfioX"
Thanks for the suggestion. Here is the wording I have for v4:
* * The device file being preserved must have been obtained by
opening the
* VFIO character device (``/dev/vfio/devices/vfioX``), not via
* ``VFIO_GROUP_GET_DEVICE_FD``.
> > +#include <linux/kexec_handover.h>
> > #include <linux/kho/abi/vfio_pci.h>
> > #include <linux/liveupdate.h>
> > #include <linux/errno.h>
> > +#include <linux/vfio.h>
>
> maybe follow alphabet order. errno.h would be moved to the top first.
I will reorder errno.h to be at the top in the previous patch (where
the alphabetical ordering issue is introduced).
^ permalink raw reply
* Re: [PATCH v3] docs: driver-api: fix 6 spelling typos in Documentation/driver-api
From: Josh Law @ 2026-03-24 16:54 UTC (permalink / raw)
To: Tomás Pando, corbet; +Cc: skhan, linux-doc, linux-kernel, Randy Dunlap
In-Reply-To: <20260324163604.5710-1-tovictakamine@gmail.com>
On 24 March 2026 16:36:04 GMT, "Tomás Pando" <tovictakamine@gmail.com> wrote:
>Fix minor spelling mistakes in the driver-api documentation. These
>changes improve readability in ACPI, CXL, DMA and PCI docs.
>v3: Added reviewed-by from Randy Dunlap.
>v2: Added full name as requested by Jon Corbet.
>
>Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
>Signed-off-by: Tomás Pando <tovictakamine@gmail.com>
>---
> Documentation/driver-api/acpi/acpi-drivers.rst | 2 +-
> Documentation/driver-api/cxl/platform/acpi/cedt.rst | 2 +-
> Documentation/driver-api/cxl/platform/bios-and-efi.rst | 2 +-
> Documentation/driver-api/dmaengine/pxa_dma.rst | 2 +-
> Documentation/driver-api/libata.rst | 2 +-
> Documentation/driver-api/pci/p2pdma.rst | 2 +-
> 6 files changed, 6 insertions(+), 6 deletions(-)
>
>diff --git a/Documentation/driver-api/acpi/acpi-drivers.rst b/Documentation/driver-api/acpi/acpi-drivers.rst
>index b1fbbddb8..376b6d8a6 100644
>--- a/Documentation/driver-api/acpi/acpi-drivers.rst
>+++ b/Documentation/driver-api/acpi/acpi-drivers.rst
>@@ -47,7 +47,7 @@ generally be avoided and so struct acpi_driver objects should not be used.
> Moreover, a device ID is necessary to bind a driver directly to an ACPI device
> node, but device IDs are not generally associated with all of them. Some of
> them contain alternative information allowing the corresponding pieces of
>-hardware to be identified, for example represeted by an _ADR object return
>+hardware to be identified, for example represented by an _ADR object return
> value, and device IDs are not used in those cases. In consequence, confusingly
> enough, binding an ACPI driver to an ACPI device node may even be impossible.
>
>diff --git a/Documentation/driver-api/cxl/platform/acpi/cedt.rst b/Documentation/driver-api/cxl/platform/acpi/cedt.rst
>index 1d9c9d359..217a75fb4 100644
>--- a/Documentation/driver-api/cxl/platform/acpi/cedt.rst
>+++ b/Documentation/driver-api/cxl/platform/acpi/cedt.rst
>@@ -55,7 +55,7 @@ voltile vs persistent, etc). One or more bits may be set. ::
> Bit[1]: CXL Type 3 Memory
> Bit[2]: Volatile Memory
> Bit[3]: Persistent Memory
>- Bit[4]: Fixed Config (HPA cannot be re-used)
>+ Bit[4]: Fixed Config (HPA cannot be reused)
>
> INTRA-host-bridge interleave (multiple devices on one host bridge) is NOT
> reported in this structure, and is solely defined via CXL device decoder
>diff --git a/Documentation/driver-api/cxl/platform/bios-and-efi.rst b/Documentation/driver-api/cxl/platform/bios-and-efi.rst
>index a4b44c018..5d918b06f 100644
>--- a/Documentation/driver-api/cxl/platform/bios-and-efi.rst
>+++ b/Documentation/driver-api/cxl/platform/bios-and-efi.rst
>@@ -277,7 +277,7 @@ The CFMWS field of the CEDT has special restriction bits which describe whether
> the described memory region allows volatile or persistent memory (or both). If
> the platform intends to support either:
>
>-1) A device with multiple medias, or
>+1) A device with multiple media, or
> 2) Using a persistent memory device as normal memory
>
> A platform may wish to create multiple CEDT CFMWS entries to describe the same
>diff --git a/Documentation/driver-api/dmaengine/pxa_dma.rst b/Documentation/driver-api/dmaengine/pxa_dma.rst
>index 442ee691a..8f9da66b0 100644
>--- a/Documentation/driver-api/dmaengine/pxa_dma.rst
>+++ b/Documentation/driver-api/dmaengine/pxa_dma.rst
>@@ -40,7 +40,7 @@ Design
> ======
> a) Virtual channels
> Same concept as in sa11x0 driver, ie. a driver was assigned a "virtual
>-channel" linked to the requestor line, and the physical DMA channel is
>+channel" linked to the requester line, and the physical DMA channel is
> assigned on the fly when the transfer is issued.
>
> b) Transfer anatomy for a scatter-gather transfer
>diff --git a/Documentation/driver-api/libata.rst b/Documentation/driver-api/libata.rst
>index 93d97fe78..28b8437f6 100644
>--- a/Documentation/driver-api/libata.rst
>+++ b/Documentation/driver-api/libata.rst
>@@ -286,7 +286,7 @@ and other exceptional conditions. The primary responsibility of an
> implementation is to call :c:func:`ata_std_error_handler`.
>
> :c:func:`ata_std_error_handler` will perform a standard error handling sequence
>-to resurect failed devices, detach lost devices and add new devices (if any).
>+to resurrect failed devices, detach lost devices and add new devices (if any).
> This function will call the various reset operations for a port, as needed.
> These operations are as follows.
>
>diff --git a/Documentation/driver-api/pci/p2pdma.rst b/Documentation/driver-api/pci/p2pdma.rst
>index 280673b50..d3f406cca 100644
>--- a/Documentation/driver-api/pci/p2pdma.rst
>+++ b/Documentation/driver-api/pci/p2pdma.rst
>@@ -38,7 +38,7 @@ for all usage refcounts to reach zero.
> At the lowest level the P2P subsystem offers a naked struct p2p_provider that
> delegates lifecycle management to the providing driver. It is expected that
> drivers using this option will wrap their MMIO memory in DMABUF and use DMABUF
>-to provide an invalidation shutdown. These MMIO addresess have no struct page, and
>+to provide an invalidation shutdown. These MMIO addresses have no struct page, and
> if used with mmap() must create special PTEs. As such there are very few
> kernel uAPIs that can accept pointers to them; in particular they cannot be used
> with read()/write(), including O_DIRECT.
Acked-By: Josh Law <objecting@objecting.org>
Patches like these are good clarification
Keep it up!
V/R
Josh Law
^ permalink raw reply
* Re: [PATCH v11 03/22] drm: Add new general DRM property "color format"
From: Ville Syrjälä @ 2026-03-24 17:00 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring,
Jonathan Corbet, Shuah Khan, kernel, amd-gfx, dri-devel,
linux-kernel, linux-arm-kernel, linux-rockchip, intel-gfx,
intel-xe, linux-doc, Werner Sembach, Andri Yngvason, Marius Vlad
In-Reply-To: <20260324-color-format-v11-3-605559af4fb4@collabora.com>
On Tue, Mar 24, 2026 at 05:01:07PM +0100, Nicolas Frattaroli wrote:
> +enum drm_connector_color_format {
> + /**
> + * @DRM_CONNECTOR_COLOR_FORMAT_AUTO: The driver or display protocol
> + * helpers should pick a suitable color format. All implementations of a
> + * specific display protocol must behave the same way with "AUTO", but
> + * different display protocols do not necessarily have the same "AUTO"
> + * semantics.
> + *
> + * For HDMI, "AUTO" picks RGB, but falls back to YCbCr 4:2:0 if the
> + * bandwidth required for full-scale RGB is not available, or the mode
> + * is YCbCr 4:2:0-only, as long as the mode and output both support
> + * YCbCr 4:2:0.
> + *
> + * For display protocols other than HDMI, the recursive bridge chain
> + * format selection picks the first chain of bridge formats that works,
> + * as has already been the case before the introduction of the "color
> + * format" property. Non-HDMI bridges should therefore either sort their
> + * bus output formats by preference, or agree on a unified auto format
> + * selection logic that's implemented in a common state helper (like
> + * how HDMI does it).
> + */
> + DRM_CONNECTOR_COLOR_FORMAT_AUTO = 0,
> +
> + /**
> + * @DRM_CONNECTOR_COLOR_FORMAT_RGB444: RGB output format
> + */
> + DRM_CONNECTOR_COLOR_FORMAT_RGB444,
> +
> + /**
> + * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR444: YCbCr 4:4:4 output format (ie.
> + * not subsampled)
> + */
> + DRM_CONNECTOR_COLOR_FORMAT_YCBCR444,
> +
> + /**
> + * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR422: YCbCr 4:2:2 output format (ie.
> + * with horizontal subsampling)
> + */
> + DRM_CONNECTOR_COLOR_FORMAT_YCBCR422,
> +
> + /**
> + * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR420: YCbCr 4:2:0 output format (ie.
> + * with horizontal and vertical subsampling)
> + */
> + DRM_CONNECTOR_COLOR_FORMAT_YCBCR420,
Seems like this should document what the quantization range
should be for each format.
> +
> + /**
> + * @DRM_CONNECTOR_COLOR_FORMAT_COUNT: Number of valid connector color
> + * format values in this enum
> + */
> + DRM_CONNECTOR_COLOR_FORMAT_COUNT,
> +};
> +
> +/**
> + * drm_connector_color_format_valid - Validate drm_connector_color_format value
> + * @fmt: value to check against all values of &enum drm_connector_color_format
> + *
> + * Checks whether the passed in value of @fmt is one of the allowable values in
> + * &enum drm_connector_color_format.
> + *
> + * Returns: %true if it's a valid value for the enum, %false otherwise.
> + */
> +static inline bool __pure
> +drm_connector_color_format_valid(enum drm_connector_color_format fmt)
> +{
> + switch (fmt) {
> + case DRM_CONNECTOR_COLOR_FORMAT_AUTO:
> + case DRM_CONNECTOR_COLOR_FORMAT_RGB444:
> + case DRM_CONNECTOR_COLOR_FORMAT_YCBCR444:
> + case DRM_CONNECTOR_COLOR_FORMAT_YCBCR422:
> + case DRM_CONNECTOR_COLOR_FORMAT_YCBCR420:
> + return true;
> + default:
> + return false;
> + }
> +}
> +
> const char *
> drm_hdmi_connector_get_output_format_name(enum drm_output_color_format fmt);
>
> @@ -1129,6 +1217,13 @@ struct drm_connector_state {
> */
> enum drm_colorspace colorspace;
>
> + /**
> + * @color_format: State variable for Connector property to request
> + * color format change on Sink. This is most commonly used to switch
> + * between RGB to YUV and vice-versa.
> + */
> + enum drm_connector_color_format color_format;
> +
> /**
> * @writeback_job: Writeback job for writeback connectors
> *
> @@ -2127,6 +2222,12 @@ struct drm_connector {
> */
> struct drm_property *colorspace_property;
>
> + /**
> + * @color_format_property: Connector property to set the suitable
> + * color format supported by the sink.
> + */
> + struct drm_property *color_format_property;
> +
> /**
> * @path_blob_ptr:
> *
> @@ -2610,6 +2711,9 @@ bool drm_connector_has_possible_encoder(struct drm_connector *connector,
> struct drm_encoder *encoder);
> const char *drm_get_colorspace_name(enum drm_colorspace colorspace);
>
> +int drm_connector_attach_color_format_property(struct drm_connector *connector,
> + unsigned long supported_color_formats);
> +
> /**
> * drm_for_each_connector_iter - connector_list iterator macro
> * @connector: &struct drm_connector pointer used as cursor
>
> --
> 2.53.0
--
Ville Syrjälä
Intel
^ permalink raw reply
* Re: [PATCH v3 08/24] vfio/pci: Retrieve preserved device files after Live Update
From: David Matlack @ 2026-03-24 17:05 UTC (permalink / raw)
To: Yi Liu
Cc: Alex Williamson, Bjorn Helgaas, Adithya Jayachandran,
Alexander Graf, Alex Mastro, Andrew Morton, Ankit Agrawal,
Arnd Bergmann, Askar Safin, Borislav Petkov (AMD), Chris Li,
Dapeng Mi, David Rientjes, Feng Tang, Jacob Pan, Jason Gunthorpe,
Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Kees Cook,
Kevin Tian, kexec, kvm, Leon Romanovsky, Leon Romanovsky,
linux-doc, linux-kernel, linux-kselftest, linux-mm, linux-pci,
Li RongQing, Lukas Wunner, Marco Elver, Michał Winiarski,
Mike Rapoport, Parav Pandit, Pasha Tatashin, Paul E. McKenney,
Pawan Gupta, Peter Zijlstra (Intel), Pranjal Shrivastava,
Pratyush Yadav, Raghavendra Rao Ananta, Randy Dunlap,
Rodrigo Vivi, Saeed Mahameed, Samiullah Khawaja, Shuah Khan,
Vipin Sharma, Vivek Kasireddy, William Tu, Zhu Yanjun
In-Reply-To: <815947ee-2603-47f0-9b03-f523601eae86@intel.com>
On 2026-03-24 09:08 PM, Yi Liu wrote:
> On 3/24/26 07:58, David Matlack wrote:
> > From: Vipin Sharma <vipinsh@google.com>
> >
> > Enable userspace to retrieve preserved VFIO device files from VFIO after
> > a Live Update by implementing the retrieve() and finish() file handler
> > callbacks.
> >
> > Use an anonymous inode when creating the file, since the retrieved
> > device file is not opened through any particular cdev inode, and the
> > cdev inode does not matter in practice.
>
> do we have a list of struct file fields that do not matter?
My understanding is that VFIO only cares about these fields in struct
file:
- private_data: Pointer to struct vfio_device_file
- f_op: Pointer to vfio_device_fops
- f_mapping: Pointer to vfio_device->inode->i_mapping
This is based on cross-referencing VFIO_GROUP_GET_DEVICE_FD (which uses
an anonymous inode) and the cdev code.
> > +err_free_device_file:
> > + kvfree(df);
>
> any reason to use kvfree()?
No this can be kfree(). Will fix in v4.
^ permalink raw reply
* Re: [PATCH v3] docs: driver-api: fix 6 spelling typos in Documentation/driver-api
From: Jonathan Corbet @ 2026-03-24 17:10 UTC (permalink / raw)
To: Josh Law, Tomás Pando; +Cc: skhan, linux-doc, linux-kernel, Randy Dunlap
In-Reply-To: <2F84DD09-2880-45E0-AA98-204F10848F85@objecting.org>
Josh Law <objecting@objecting.org> writes:
> Acked-By: Josh Law <objecting@objecting.org>
>
> Patches like these are good clarification
>
> Keep it up!
I'm all for encouraging contributors, but an Acked-by from a random
contributor to a typo-fix patch, without having even bothered to trim
100 lines of stuff, is not particularly helpful for maintainers. What
is your purpose here?
Thanks,
jon
^ permalink raw reply
* Re: [PATCH v3] docs: driver-api: fix 6 spelling typos in Documentation/driver-api
From: Josh Law @ 2026-03-24 17:19 UTC (permalink / raw)
To: Jonathan Corbet, Tomás Pando
Cc: skhan, linux-doc, linux-kernel, Randy Dunlap
In-Reply-To: <87a4vxtaqa.fsf@trenco.lwn.net>
On 24 March 2026 17:10:05 GMT, Jonathan Corbet <corbet@lwn.net> wrote:
>Josh Law <objecting@objecting.org> writes:
>
>> Acked-By: Josh Law <objecting@objecting.org>
>>
>> Patches like these are good clarification
>>
>> Keep it up!
>
>I'm all for encouraging contributors, but an Acked-by from a random
>contributor to a typo-fix patch, without having even bothered to trim
>100 lines of stuff, is not particularly helpful for maintainers. What
>is your purpose here?
>
>Thanks,
>
>jon
>
Apologies Jon, I just like patches that fix typos, because when maintainers (or others..) have to read the code in let's say, 10 years, they will be able to understand the code easier.
V/R
Josh Law
^ permalink raw reply
* Re: [PATCH v5 00/21] Virtual Swap Space
From: Nhat Pham @ 2026-03-24 17:23 UTC (permalink / raw)
To: Askar Safin
Cc: Liam.Howlett, akpm, apopple, axelrasmussen, baohua, baolin.wang,
bhe, byungchul, cgroups, chengming.zhou, chrisl, corbet, david,
dev.jain, gourry, hannes, hughd, jannh, joshua.hahnjy, kasong,
kernel-team, lance.yang, lenb, linux-doc, linux-kernel, linux-mm,
linux-pm, lorenzo.stoakes, matthew.brost, mhocko, muchun.song,
npache, pavel, peterx, peterz, pfalcato, rafael, rakie.kim, riel,
roman.gushchin, rppt, ryan.roberts, shakeel.butt, shikemeng,
surenb, tglx, vbabka, weixugc, ying.huang, yosry.ahmed, yuanchu,
zhengqi.arch, ziy, Kairui Song, Matthew Wilcox
In-Reply-To: <20260324131931.4004123-1-safinaskar@gmail.com>
On Tue, Mar 24, 2026 at 9:19 AM Askar Safin <safinaskar@gmail.com> wrote:
>
> Nhat Pham <nphamcs@gmail.com>:
> > We can even perform compressed writeback
> > (i.e writing these pages without decompressing them) (see [12]).
>
> > [12]: https://lore.kernel.org/linux-mm/ZeZSDLWwDed0CgT3@casper.infradead.org/
>
> This is supported in zram. The support was added here:
> https://lore.kernel.org/all/20251201094754.4149975-1-senozhatsky@chromium.org/ .
> It is already in mainline.
I'm aware of that work. It's an improvement, but my understanding is:
1. It only works for zram.
2. We still occupy the full PAGE_SIZE slot.
3. The writeback IO request is still of size PAGE_SIZE.
So we're saving the CPU work for decompression, but not the rest of
the potential benefits of compressed writeback.
For zswap, decoupling zswap and disk swap is a pre-requisite
(otherwise every zswap slot occupy a PAGE_SIZE slot in the swapfile
anyway).
Then, we have two alternatives. Either we implement a small-slot
allocator for swapfile-infra, or we writeback a full backing page for
compressed memory. The second option is a bit more straightforward,
but then we lose relative age of these objects - a backing page might
combine very recent compressed pages and very old compressed pages.
These approaches have different performance tradeoffs and need to be
evaluated. But anyway this is future work.
^ permalink raw reply
* Re: [PATCH v3 01/10] ACPI: APEI: GHES: share macros via a private header
From: Jonathan Cameron @ 2026-03-24 17:28 UTC (permalink / raw)
To: Ahmed Tiba
Cc: linux-acpi, devicetree, linux-cxl, Michael.Zhao2, robh,
linux-arm-kernel, Dmitry.Lamerov, rafael, conor, will, bp,
catalin.marinas, krzk+dt, linux-doc, mchehab+huawei, tony.luck
In-Reply-To: <20260318-topics-ahmtib01-ras_ffh_arm_internal_review-v3-1-48e6a1c249ef@arm.com>
On Wed, 18 Mar 2026 20:47:58 +0000
Ahmed Tiba <ahmed.tiba@arm.com> wrote:
> Carve the CPER helper macros out of ghes.c and place them in a private
> header so they can be shared with upcoming helper files. This is a
> mechanical include change with no functional differences.
>
> Signed-off-by: Ahmed Tiba <ahmed.tiba@arm.com>
> diff --git a/include/acpi/ghes_cper.h b/include/acpi/ghes_cper.h
> new file mode 100644
> index 000000000000..a38e3440b927
> --- /dev/null
> +++ b/include/acpi/ghes_cper.h
> @@ -0,0 +1,103 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Shared GHES declarations for firmware-first CPER error handling.
> + *
> + * This header groups the GHES declarations that are needed by the shared
> + * CPER handling path.
shared CPER is unclear. Start with something broad like:
GHES declarations are used both for ACPI APEI handling and xyz.
I'm not sure I'd put any additional justification here beyond such a
simple sentence.
> + *
> + * The split lets GHES and other firmware-first error sources use the same
I would consider rewriting this. What split? Not obvious from what you have
in this header.
> + * code for reading status blocks, caching records, handling vendor data,
> + * and reporting errors, so the non-ACPI path follows the same behavior as
> + * GHES instead of carrying a separate copy.
> + *
> + * Derived from the ACPI APEI GHES driver.
> + *
> + * Copyright 2010,2011 Intel Corp.
> + * Author: Huang Ying <ying.huang@intel.com>
> + */
> +
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox