devm_drm_bridge_alloc() returns ERR_PTR on failure instead of a
NULL pointer, so use IS_ERR() to check the returned pointer.
While at it, on failure, return ERR_CAST(dp) instead of
ERR_PTR(-ENOMEM) in order not to depend on devm_drm_bridge_alloc()
error code implementation.
Fixes: 48f05c3b4b ("drm/bridge: analogix_dp: Use devm_drm_bridge_alloc() API")
Signed-off-by: Liu Ying <victor.liu@nxp.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://lore.kernel.org/r/20250806095224.527938-1-victor.liu@nxp.com
In some application scenarios, we hope to get the corresponding
connector when the bridge's detect hook is invoked.
In most cases, we can get the connector by drm_atomic_get_connector_for_encoder
if the encoder attached to the bridge is enabled, however there will
still be some scenarios where the detect hook of the bridge is called
but the corresponding encoder has not been enabled yet. For instance,
this occurs when the device is hot plug in for the first time.
Since the call to bridge's detect is initiated by the connector, passing
down the corresponding connector directly will make things simpler.
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250703125027.311109-3-andyshrk@163.com
[DB: added the chunk to the cdn-dp driver]
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
devm_drm_bridge_alloc() is the new API to be used for allocating
(and partially initializing) a private driver struct embedding
a struct drm_bridge.
Analogix DP driver somehow missed the automated conversion in commit
9c399719cf ("drm: convert many bridge drivers from devm_kzalloc() to
devm_drm_bridge_alloc() API"), what causes the following warning:
------------[ cut here ]------------
WARNING: lib/refcount.c:25 at drm_bridge_attach+0x2c/0x248, CPU#1: kworker/u8:1/34
refcount_t: addition on 0; use-after-free.
Modules linked in:
CPU: 1 UID: 0 PID: 34 Comm: kworker/u8:1 Not tainted 6.16.0-rc3-next-20250627-dirty #15839 PREEMPT
Hardware name: Samsung Exynos (Flattened Device Tree)
Workqueue: events_unbound deferred_probe_work_func
Call trace:
unwind_backtrace from show_stack+0x10/0x14
show_stack from dump_stack_lvl+0x68/0x88
dump_stack_lvl from __warn+0x94/0x1f0
__warn from warn_slowpath_fmt+0x124/0x1bc
warn_slowpath_fmt from drm_bridge_attach+0x2c/0x248
drm_bridge_attach from analogix_dp_bind+0x70/0xc8
analogix_dp_bind from exynos_dp_bind+0x58/0xc4
exynos_dp_bind from component_bind_all+0x11c/0x27c
component_bind_all from exynos_drm_bind+0xe8/0x198
exynos_drm_bind from try_to_bring_up_aggregate_device+0x200/0x2d8
try_to_bring_up_aggregate_device from __component_add+0xb0/0x170
__component_add from exynos_dp_probe+0xc0/0x164
exynos_dp_probe from platform_probe+0x5c/0xb8
platform_probe from really_probe+0xe0/0x3d8
really_probe from __driver_probe_device+0x9c/0x1e0
__driver_probe_device from driver_probe_device+0x30/0xc0
driver_probe_device from __device_attach_driver+0xa8/0x120
__device_attach_driver from bus_for_each_drv+0x84/0xdc
bus_for_each_drv from __device_attach+0xb0/0x20c
__device_attach from bus_probe_device+0x8c/0x90
bus_probe_device from deferred_probe_work_func+0x98/0xe0
deferred_probe_work_func from process_one_work+0x24c/0x70c
process_one_work from worker_thread+0x1b8/0x3bc
worker_thread from kthread+0x13c/0x264
kthread from ret_from_fork+0x14/0x28
...
---[ end trace 0000000000000000 ]---
Fix this by switching the driver to the new API.
Note the above warning only appears starting with commit a7748dd127
("drm/bridge: get/put the bridge reference in drm_bridge_add/remove()")
which is the first commmit having added a drm_bridge_get/put() pair and
thus exposing the incorrect initial refcount issue.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Fixes: a7748dd127 ("drm/bridge: get/put the bridge reference in drm_bridge_add/remove()")
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://lore.kernel.org/r/20250627165652.580798-1-m.szyprowski@samsung.com
[Luca: add Fixes tag and mention the reason in commit message]
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Fix compile-time warnings
drivers/gpu/drm/bridge/analogix/analogix-i2c-dptx.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/aux-bridge.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/aux-hpd-bridge.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/panel.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/samsung-dsim.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/drm_bridge.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
drivers/gpu/drm/drm_bridge_helper.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: a934a57a42 ("scripts/misc-check: check missing #include <linux/export.h> when W=1")
Reviewed-by: André Almeida <andrealmeid@igalia.com>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Link: https://lore.kernel.org/r/20250612121633.229222-4-tzimmermann@suse.de
Commit 6579a03e68 ("drm/bridge: analogix_dp: Remove the unnecessary
calls to clk_disable_unprepare() during probing") removed the mismatched
clock_disable calls from analogix_dp_probe.
But that patch was created and sent before
commit e5e9fa9f7a ("drm/bridge: analogix_dp: Add support to get panel
from the DP AUX bus") was merged, so couldn't know about this change.
So in the original patch the last change is
if (ret) {
dev_err(&pdev->dev, "failed to request irq\n");
- goto err_disable_clk;
+ return ERR_PTR(ret);
}
disable_irq(dp->irq);
return dp;
-
-err_disable_clk:
- clk_disable_unprepare(dp->clock);
- return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(analogix_dp_probe);
the analogix_dp_core.c actually now has the runtime-pm handling between
disable_irq() and return do introducing another goto err_clk_disable there.
So remove that one too and return an error pointer, to not create build
breakage.
Fixes: 6579a03e68 ("drm/bridge: analogix_dp: Remove the unnecessary calls to clk_disable_unprepare() during probing")
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250527225120.3361663-1-heiko@sntech.de
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
devm_drm_bridge_alloc() is the new API to be used for allocating (and
partially initializing) a private driver struct embedding a struct
drm_bridge.
For many drivers having a simple code flow in the probe function, this
commit does a mass conversion automatically with the following semantic
patch. The changes have been reviewed manually for correctness as well as
to find any false positives.
The patch has been applied with the explicit exclusion of bridge/panel.c,
handled by a separate patch.
After applying the semantic patch, manually fixed these issues:
- 4 drivers need ERR_CAST() instead of PTR_ERR() as the function calling
devm_drm_bridge_alloc() returns a pointer
- re-added empty lines and comments that the script had removed but that
should stay
@@
type T;
identifier C;
identifier BR;
expression DEV;
expression FUNCS;
@@
-T *C;
+T *C;
...
(
-C = devm_kzalloc(DEV, ...);
-if (!C)
- return -ENOMEM;
+C = devm_drm_bridge_alloc(DEV, T, BR, FUNCS);
+if (IS_ERR(C))
+ return PTR_ERR(C);
|
-C = devm_kzalloc(DEV, ...);
-if (!C)
- return ERR_PTR(-ENOMEM);
+C = devm_drm_bridge_alloc(DEV, T, BR, FUNCS);
+if (IS_ERR(C))
+ return PTR_ERR(C);
)
...
-C->BR.funcs = FUNCS;
Reviewed-by: Manikandan Muralidharan <manikandan.m@microchip.com> # microchip-lvds.c
Reviewed-by: Douglas Anderson <dianders@chromium.org> # parade-ps8640
Tested-by: Douglas Anderson <dianders@chromium.org> # parade-ps8640
Acked-by: Maxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/20250509-drm-bridge-convert-to-alloc-api-v3-2-b8bc1f16d7aa@bootlin.com
[Luca: fixed trivial patch conflict in adv7511_drv.c while applying]
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Use gpiod_set_value_cansleep() instead of gpiod_set_value()
to fix the below call trace in the boot log:
[ 5.690534] Call trace:
[ 5.690536] gpiod_set_value+0x40/0xa4
[ 5.690540] anx7625_runtime_pm_resume+0xa0/0x324 [anx7625]
[ 5.690545] __rpm_callback+0x48/0x1d8
[ 5.690549] rpm_callback+0x6c/0x78
Certain GPIO controllers require access via message-based buses
such as I2C or SPI, which may cause the GPIOs to enter a sleep
state. Therefore, use the gpiod_set_value_cansleep().
Signed-off-by: Ayushi Makhija <quic_amakhija@quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20250505094245.2660750-7-quic_amakhija@quicinc.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
In the anx7625_sink_detect(), the device is checked to see
if it is a panel bridge, and it always sends a "connected"
status to the connector. When adding the DP port on port 1 of the
anx7625, it incorrectly treats it as a panel bridge and sends an
always "connected" status. Instead of checking the status on the
panel bridge, it's better to check the hpd_status for connectors
that supports hot-plugging. This way, it verifies the hpd_status
variable before sending the status to the connector.
In case of eDP, anx7625_bridge_detect() will not get called because
the bridge->ops condition in anx7625_link_bridge() will not be
satisfied. Since anx7625_sink_detect() is called from
anx7625_bridge_detect(), this results in the sink_detect logic not
being executed for eDP.
Signed-off-by: Ayushi Makhija <quic_amakhija@quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250505094245.2660750-6-quic_amakhija@quicinc.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
The anx7625_link_bridge() checks if a device is not a panel
bridge and add DRM_BRIDGE_OP_HPD and DRM_BRIDGE_OP_DETECT
flags to the drm_bridge->ops. However, on port 1 of the anx7625
bridge, any device added is always treated as a panel bridge,
preventing connector_detect() from being called. To resolve
this, instead of just checking if it is a panel bridge, verify
the type of device based on aux whether it is a DisplayPort or
eDP panel. If the device is not of the eDP type, add
DRM_BRIDGE_OP_HPD and DRM_BRIDGE_OP_DETECT flags to the to
the drm_bridge->ops.
Signed-off-by: Ayushi Makhija <quic_amakhija@quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250505094245.2660750-5-quic_amakhija@quicinc.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
The drm_bridge structure contains an encoder pointer that is widely used
by bridge drivers. This pattern is largely documented as deprecated in
other KMS entities for atomic drivers.
However, one of the main use of that pointer is done in attach to just
call drm_bridge_attach on the next bridge to add it to the bridge list.
While this dereferences the bridge->encoder pointer, it's effectively
the same encoder the bridge was being attached to.
We can make it more explicit by adding the encoder the bridge is
attached to to the list of attach parameters. This also removes the need
to dereference bridge->encoder in most drivers.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250313-bridge-connector-v6-1-511c54a604fb@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
When user enabled HDCP feature, userspace will set HDCP content
to DRM_MODE_CONTENT_PROTECTION_DESIRED. Next, anx7625 will update
HDCP content to DRM_MODE_CONTENT_PROTECTION_ENABLED if down stream
support HDCP feature.
As anx7625 bridge IC will be power down after call .atomic_disable(),
then all HDCP status will be lost on chip. So we should reestablish
HDCP again in .atomic_enable(), and update hdcp content to DESIRE if
current HDCP content is ENABLE in .atomic_disable().
v4:
- Change HDCP content value to DESIRED if HDCP status is ENABLE in bridge
interface .atomic_enable().
v3:
- Move hdcp content value checking from bridge interface
.atomic_check() to .atomic_enable()
v2:
- Add more details in commit message
Signed-off-by: Xin Ji <xji@analogixsemi.com>
Tested-by: Pin-yen Lin <treapking@chromium.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20241219070330.224996-1-xji@analogixsemi.com
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20241219070330.224996-1-xji@analogixsemi.com
The bridge might miss the display change events when it's powered off.
This happens when a user changes the external monitor when the system
is suspended and the embedded controller doesn't not wake AP up.
It's also observed that one DP-to-HDMI bridge doesn't work correctly
when there is no EDID read after it is powered on.
Drop the cache to force an EDID read after system resume to fix this.
Fixes: 8bdfc5dae4 ("drm/bridge: anx7625: Add anx7625 MIPI DSI/DPI to DP")
Signed-off-by: Pin-yen Lin <treapking@chromium.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240926092931.3870342-2-treapking@chromium.org
There's no need to get the length of an DT array property before
parsing the array. of_property_read_variable_u8_array() takes a minimum
and maximum length and returns the actual length (or error code).
This is part of a larger effort to remove callers of of_get_property()
and similar functions. of_get_property() leaks the DT property data
pointer which is a problem for dynamically allocated nodes which may
be freed.
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Robert Foss <rfoss@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240731201407.1838385-4-robh@kernel.org