cf78bb0b13f6144fbae52ec27f3d436bdd278568
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.15 / 950-0010-drm-vc4-hdmi-Check-the-device-state-in-prepare.patch
1 From ba0375640d2d82158600a398181bb9f9c3835d0a Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Fri, 24 Sep 2021 14:27:38 +0200
4 Subject: [PATCH] drm/vc4: hdmi: Check the device state in prepare()
5
6 Even though we already check that the encoder->crtc pointer is there
7 during in startup(), which is part of the open() path in ASoC, nothing
8 guarantees that our encoder state won't change between the time when we
9 open the device and the time we prepare it.
10
11 Move the sanity checks we do in startup() to a helper and call it from
12 prepare().
13
14 Fixes: 91e99e113929 ("drm/vc4: hdmi: Register HDMI codec")
15 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
16 ---
17 drivers/gpu/drm/vc4/vc4_hdmi.c | 35 +++++++++++++++++++++++++++-------
18 1 file changed, 28 insertions(+), 7 deletions(-)
19
20 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
21 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
22 @@ -1406,20 +1406,36 @@ static inline struct vc4_hdmi *dai_to_hd
23 return snd_soc_card_get_drvdata(card);
24 }
25
26 +static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi)
27 +{
28 + struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
29 +
30 + lockdep_assert_held(&vc4_hdmi->mutex);
31 +
32 + /*
33 + * The encoder doesn't have a CRTC until the first modeset.
34 + */
35 + if (!encoder->crtc)
36 + return false;
37 +
38 + /*
39 + * If the encoder is currently in DVI mode, treat the codec DAI
40 + * as missing.
41 + */
42 + if (!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & VC4_HDMI_RAM_PACKET_ENABLE))
43 + return false;
44 +
45 + return true;
46 +}
47 +
48 static int vc4_hdmi_audio_startup(struct device *dev, void *data)
49 {
50 struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
51 - struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
52 unsigned long flags;
53
54 mutex_lock(&vc4_hdmi->mutex);
55
56 - /*
57 - * If the HDMI encoder hasn't probed, or the encoder is
58 - * currently in DVI mode, treat the codec dai as missing.
59 - */
60 - if (!encoder->crtc || !(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
61 - VC4_HDMI_RAM_PACKET_ENABLE)) {
62 + if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) {
63 mutex_unlock(&vc4_hdmi->mutex);
64 return -ENODEV;
65 }
66 @@ -1549,6 +1565,11 @@ static int vc4_hdmi_audio_prepare(struct
67
68 mutex_lock(&vc4_hdmi->mutex);
69
70 + if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) {
71 + mutex_unlock(&vc4_hdmi->mutex);
72 + return -EINVAL;
73 + }
74 +
75 vc4_hdmi_audio_set_mai_clock(vc4_hdmi, sample_rate);
76
77 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);