lkml.org 
[lkml]   [2022]   [Aug]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 415/545] ASoC: mchp-spdifrx: disable end of block interrupt on failures
    Date
    From: Claudiu Beznea <claudiu.beznea@microchip.com>

    [ Upstream commit 768ac4f12ca0fda935f58eb8c5120e9d795bc6e3 ]

    Disable end of block interrupt in case of wait for completion timeout
    or errors to undo previously enable operation (done in
    mchp_spdifrx_isr_blockend_en()). Otherwise we can end up with an
    unbalanced reference counter for this interrupt.

    Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX")
    Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
    Link: https://lore.kernel.org/r/20220727090814.2446111-2-claudiu.beznea@microchip.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    sound/soc/atmel/mchp-spdifrx.c | 9 ++++++---
    1 file changed, 6 insertions(+), 3 deletions(-)

    diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
    index e6ded6f8453f..46f3407ed0e8 100644
    --- a/sound/soc/atmel/mchp-spdifrx.c
    +++ b/sound/soc/atmel/mchp-spdifrx.c
    @@ -288,15 +288,17 @@ static void mchp_spdifrx_isr_blockend_en(struct mchp_spdifrx_dev *dev)
    spin_unlock_irqrestore(&dev->blockend_lock, flags);
    }

    -/* called from atomic context only */
    +/* called from atomic/non-atomic context */
    static void mchp_spdifrx_isr_blockend_dis(struct mchp_spdifrx_dev *dev)
    {
    - spin_lock(&dev->blockend_lock);
    + unsigned long flags;
    +
    + spin_lock_irqsave(&dev->blockend_lock, flags);
    dev->blockend_refcount--;
    /* don't enable BLOCKEND interrupt if it's already enabled */
    if (dev->blockend_refcount == 0)
    regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
    - spin_unlock(&dev->blockend_lock);
    + spin_unlock_irqrestore(&dev->blockend_lock, flags);
    }

    static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
    @@ -575,6 +577,7 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev,
    if (ret <= 0) {
    dev_dbg(dev->dev, "user data for channel %d timeout\n",
    channel);
    + mchp_spdifrx_isr_blockend_dis(dev);
    return ret;
    }

    --
    2.35.1


    \
     
     \ /
      Last update: 2022-08-19 18:43    [W:2.383 / U:0.304 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site