Skip to content

Commit

Permalink
drm/vc4: hdmi: Check the device state in prepare()
Browse files Browse the repository at this point in the history
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().

Link: https://lore.kernel.org/r/20211025141113.702757-8-maxime@cerno.tech
Fixes: 91e99e1 ("drm/vc4: hdmi: Register HDMI codec")
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
  • Loading branch information
Maxime Ripard committed Nov 5, 2021
1 parent 633be8c commit a64ff88
Showing 1 changed file with 28 additions and 7 deletions.
35 changes: 28 additions & 7 deletions drivers/gpu/drm/vc4/vc4_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1395,20 +1395,36 @@ static inline struct vc4_hdmi *dai_to_hdmi(struct snd_soc_dai *dai)
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;
}
Expand Down Expand Up @@ -1538,6 +1554,11 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,

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);
Expand Down

0 comments on commit a64ff88

Please sign in to comment.