1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- From ba0375640d2d82158600a398181bb9f9c3835d0a Mon Sep 17 00:00:00 2001
- From: Maxime Ripard <[email protected]>
- Date: Fri, 24 Sep 2021 14:27:38 +0200
- Subject: [PATCH] drm/vc4: hdmi: Check the device state in prepare()
- Even though we already check that the encoder->crtc pointer is there
- during in startup(), which is part of the open() path in ASoC, nothing
- guarantees that our encoder state won't change between the time when we
- open the device and the time we prepare it.
- Move the sanity checks we do in startup() to a helper and call it from
- prepare().
- Fixes: 91e99e113929 ("drm/vc4: hdmi: Register HDMI codec")
- Signed-off-by: Maxime Ripard <[email protected]>
- ---
- drivers/gpu/drm/vc4/vc4_hdmi.c | 35 +++++++++++++++++++++++++++-------
- 1 file changed, 28 insertions(+), 7 deletions(-)
- --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
- +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
- @@ -1407,20 +1407,36 @@ static inline struct vc4_hdmi *dai_to_hd
- return snd_soc_card_get_drvdata(card);
- }
-
- +static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi)
- +{
- + struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
- +
- + lockdep_assert_held(&vc4_hdmi->mutex);
- +
- + /*
- + * The encoder doesn't have a CRTC until the first modeset.
- + */
- + if (!encoder->crtc)
- + return false;
- +
- + /*
- + * If the encoder is currently in DVI mode, treat the codec DAI
- + * as missing.
- + */
- + if (!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & VC4_HDMI_RAM_PACKET_ENABLE))
- + return false;
- +
- + return true;
- +}
- +
- static int vc4_hdmi_audio_startup(struct device *dev, void *data)
- {
- struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
- - struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
- unsigned long flags;
-
- mutex_lock(&vc4_hdmi->mutex);
-
- - /*
- - * If the HDMI encoder hasn't probed, or the encoder is
- - * currently in DVI mode, treat the codec dai as missing.
- - */
- - if (!encoder->crtc || !(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
- - VC4_HDMI_RAM_PACKET_ENABLE)) {
- + if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) {
- mutex_unlock(&vc4_hdmi->mutex);
- return -ENODEV;
- }
- @@ -1550,6 +1566,11 @@ static int vc4_hdmi_audio_prepare(struct
-
- mutex_lock(&vc4_hdmi->mutex);
-
- + if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) {
- + mutex_unlock(&vc4_hdmi->mutex);
- + return -EINVAL;
- + }
- +
- vc4_hdmi_audio_set_mai_clock(vc4_hdmi, sample_rate);
-
- spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
|