From patchwork Fri Jun 14 19:48:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fletcher Woodruff X-Patchwork-Id: 10996409 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 20F0F13AF for ; Fri, 14 Jun 2019 19:53:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 115CA28734 for ; Fri, 14 Jun 2019 19:53:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 05B992873B; Fri, 14 Jun 2019 19:53:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 34FC428734 for ; Fri, 14 Jun 2019 19:52:59 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 89A8C18A0; Fri, 14 Jun 2019 21:52:07 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 89A8C18A0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1560541977; bh=H6LwavlMRV6x+ZeGA1GigjRGAiXDiJEe0frWhBx+C50=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=R42wbMIWzqio3s2iEfXpME0olPpQ+c3XygSQUwGdpOUnmeP51X9coJavzRFKWxztv EnWoxXiYAHhbypQizihQSon26ASGGT5606pIYjhNtwmd8N124fl3QkSCxF8Km+10mM i6AeUaRzUPC6LUQ4kXYcNzh/PnuUbNbQ/4NXwhqQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 64A9AF8973A; Fri, 14 Jun 2019 21:49:17 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8CA3DF89717; Fri, 14 Jun 2019 21:49:12 +0200 (CEST) Received: from mail-io1-xd42.google.com (mail-io1-xd42.google.com [IPv6:2607:f8b0:4864:20::d42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id EF685F896EA for ; Fri, 14 Jun 2019 21:49:09 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz EF685F896EA Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="IcGT9d46" Received: by mail-io1-xd42.google.com with SMTP id m24so8412748ioo.2 for ; Fri, 14 Jun 2019 12:49:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XggeDQFBfdb+3YPzkLYpmWXYVa5T1jw4aJqqW4WiNOA=; b=IcGT9d468pa+P0C/mZsnm+76M4esye5WR1AG3Fs9hpOA1WazPNvMyCaPZ3GV5rPiya 2KtHsM/4gjym/ah4xhtbpliypu1e+PnUiCZaokJrszASKUXSrgbr/PvxzanFGEsmifBY s5ANW07qb8ca6ORspZf9tviVpZiVXhdNV5GMs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XggeDQFBfdb+3YPzkLYpmWXYVa5T1jw4aJqqW4WiNOA=; b=YjFrU15fduJFiDgShHlP6x4WeXi1Zbjv1PPGf0uuKA1KLHOz6Oh/aHpvcNFLowATrB BaJ8rP8ygcPw+vsK+xhEZwUoqj4doA4CY7micPSPhCNDMhlT5XMkET09tTUKjg4ib3im FMbS0W9n2Cw+A2bDrzGqNynbhIBju3jR65/3l3DLChMd0vfRS/CjdyKboqHHVD9QnU6x XyGRPGTG8DD1Gdy4HjACacEvH/RpfTyihcZ4RABM8uB/bWUMmACxPZYO/njLZfdMvraE nrbXY+8SCrfMyz+hCSU2DGDTT9x5lXW572vRN8gPwNDpWZ0rY1EHm8nGJZebN7Y67F2E md1A== X-Gm-Message-State: APjAAAW9Xx1F8qeGmiXqNWzq/DpEA/917xv/+MXm1GE0lOEbMHAkCun6 CGo6skKBLSHjyuquKX6S1DxLXQ== X-Google-Smtp-Source: APXvYqyE7eru/RE1iSZF7KO0qV8mLZ2lVU1qwdUdCbJMgemExUEXY/hklfZPRXfgsLUdwHut7+rSFw== X-Received: by 2002:a02:a90a:: with SMTP id n10mr54237065jam.61.1560541748599; Fri, 14 Jun 2019 12:49:08 -0700 (PDT) Received: from localhost ([2620:15c:183:200:33ce:f5cf:f863:d3a6]) by smtp.gmail.com with ESMTPSA id n17sm3128185iog.63.2019.06.14.12.49.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Jun 2019 12:49:08 -0700 (PDT) From: Fletcher Woodruff To: linux-kernel@vger.kernel.org Date: Fri, 14 Jun 2019 13:48:54 -0600 Message-Id: <20190614194854.208436-5-fletcherw@chromium.org> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog In-Reply-To: <20190614194854.208436-1-fletcherw@chromium.org> References: <20190614194854.208436-1-fletcherw@chromium.org> MIME-Version: 1.0 Cc: Oder Chiou , alsa-devel@alsa-project.org, Takashi Iwai , Liam Girdwood , Ben Zhang , Mark Brown , Ross Zwisler , Curtis Malainey , Fletcher Woodruff Subject: [alsa-devel] [PATCH v7 4/4] ASoC: rt5677: handle concurrent interrupts X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Ben Zhang The rt5677 driver writes to the IRQ control register within the IRQ handler in order to flip the polarity of the interrupts that have been signalled. If an interrupt fires in the interval between the regmap_read and the regmap_write, it will not trigger a new call to rt5677_irq. Add a bounded loop to rt5677_irq that keeps checking interrupts until none are seen, so that any interrupts that are signalled in that interval are correctly handled. Signed-off-by: Ben Zhang Signed-off-by: Fletcher Woodruff --- sound/soc/codecs/rt5677.c | 67 ++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 87466ee222ee59..e88766e34ddb1d 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -5072,38 +5072,55 @@ static const struct rt5677_irq_desc rt5677_irq_descs[] = { static irqreturn_t rt5677_irq(int unused, void *data) { struct rt5677_priv *rt5677 = data; - int ret = 0, i, reg_irq, virq; + int ret = 0, loop, i, reg_irq, virq; bool irq_fired = false; mutex_lock(&rt5677->irq_lock); - /* Read interrupt status */ - ret = regmap_read(rt5677->regmap, RT5677_IRQ_CTRL1, ®_irq); - if (ret) { - pr_err("rt5677: failed reading IRQ status: %d\n", ret); - goto exit; - } - for (i = 0; i < RT5677_IRQ_NUM; i++) { - if (reg_irq & rt5677_irq_descs[i].status_mask) { - irq_fired = true; - virq = irq_find_mapping(rt5677->domain, i); - if (virq) - handle_nested_irq(virq); - - /* Clear the interrupt by flipping the polarity of the - * interrupt source line that fired - */ - reg_irq ^= rt5677_irq_descs[i].polarity_mask; + /* + * Loop to handle interrupts until the last i2c read shows no pending + * irqs. The interrupt line is shared by multiple interrupt sources. + * After the regmap_read() below, a new interrupt source line may + * become high before the regmap_write() finishes, so there isn't a + * rising edge on the shared interrupt line for the new interrupt. Thus, + * the loop is needed to avoid missing irqs. + * + * A safeguard of 20 loops is used to avoid hanging in the irq handler + * if there is something wrong with the interrupt status update. The + * interrupt sources here are audio jack plug/unplug events which + * shouldn't happen at a high frequency for a long period of time. + * Empirically, more than 3 loops have never been seen. + */ + for (loop = 0; loop < 20; loop++) { + /* Read interrupt status */ + ret = regmap_read(rt5677->regmap, RT5677_IRQ_CTRL1, ®_irq); + if (ret) { + pr_err("rt5677: failed reading IRQ status: %d\n", ret); + goto exit; } - } - if (!irq_fired) - goto exit; + irq_fired = false; + for (i = 0; i < RT5677_IRQ_NUM; i++) { + if (reg_irq & rt5677_irq_descs[i].status_mask) { + irq_fired = true; + virq = irq_find_mapping(rt5677->domain, i); + if (virq) + handle_nested_irq(virq); + + /* Clear the interrupt by flipping the polarity + * of the interrupt source line that fired + */ + reg_irq ^= rt5677_irq_descs[i].polarity_mask; + } + } + if (!irq_fired) + goto exit; - ret = regmap_write(rt5677->regmap, RT5677_IRQ_CTRL1, reg_irq); - if (ret) { - pr_err("rt5677: failed updating IRQ status: %d\n", ret); - goto exit; + ret = regmap_write(rt5677->regmap, RT5677_IRQ_CTRL1, reg_irq); + if (ret) { + pr_err("rt5677: failed updating IRQ status: %d\n", ret); + goto exit; + } } exit: mutex_unlock(&rt5677->irq_lock);