Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp7320164ybi; Wed, 5 Jun 2019 15:27:07 -0700 (PDT) X-Google-Smtp-Source: APXvYqylRNZzKpMOmUy1dCxmfwPu6PamVzXdm0XAbv940MoSsT/6ZFl8YQMvk1grCu6k+JT7pu8J X-Received: by 2002:aa7:8e46:: with SMTP id d6mr49280261pfr.91.1559773627564; Wed, 05 Jun 2019 15:27:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559773627; cv=none; d=google.com; s=arc-20160816; b=UW9Ui0xuf0PSH+EXaMgnjI60bJsJdN2m+QYsinFBNWA7X7weEQhJqrcz06OLhawtb2 A8f9tDb/yE0xXe8H4JJqfNAHoPajPH/AgXW53aAXnz2LfE4RqytJA/gkYTFrIZ+waVoF 0vHpgxYFuQFgPaqOleR2kGar7GxY2bA4MYwnaFwC+q+K5uhcBDBUnONkkEF2lfd1Ya0V V1uCj1J99QgmcyrucZqnjcm2q1Eas1oaSxLGA1OTcvu9wTDHYZrelwLkl0LmHEOE7mQa wHnCtELJbaYTBUJDr1u4SY+z2msn5UeegFQAkFK3txiYhk7omRin59k/NCssf2Fmfk52 b5QQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ENEfQXnBKgsiB2d36L6+P4CJJ9i3migBmA1QXIq3dJc=; b=olSftTJknuxSZm/7wenWpgfbfjTXZ3LwqPc6Od5lOZRBvVdbplQ/RNhJJ/3M+cm9Tt Zicj/B9T7J5+OYY+FxYF6Lv1TLbuEstojVhlJ0rtucxMHh56AEFO5T5KwyPoqYY85Dr/ HSSyN4uf0UyrgqnJEVgw5MZOITz4vycIHSuqVrCPUZkAa7kqGKSZpxxh1dTM757zorDl QZPcu4MD+QSyxTfgNPc2Pa237PCZDVU9sxSIgzAjjvF/Lm8U44WsCReEU6VLPhwdaA3v 5ICW6R1jEmPRUwl0+/uNktzV7JRlZ6bicX7ZG1GS6SyDmQxTvS1kO0+YdtmAGBCG3LZI 5/Jg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b="PH7N9pU/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m26si168974pgv.388.2019.06.05.15.26.50; Wed, 05 Jun 2019 15:27:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b="PH7N9pU/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726808AbfFEWZA (ORCPT + 99 others); Wed, 5 Jun 2019 18:25:00 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:46871 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726535AbfFEWY5 (ORCPT ); Wed, 5 Jun 2019 18:24:57 -0400 Received: by mail-io1-f68.google.com with SMTP id i10so229818iol.13 for ; Wed, 05 Jun 2019 15:24:56 -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=ENEfQXnBKgsiB2d36L6+P4CJJ9i3migBmA1QXIq3dJc=; b=PH7N9pU/PcBPixEKjGT9dOemu7GSJnSM5tyYxvbdDhRJejXacgwteNTBAACtytrbZP weVzwsXbz/aCam4SwCAzGMilMDQnThHw0SaOYdk8yU11bL11E1rJPMz91S58rggIkF5j oaoYF+qjcdjYhWtebt8cZhNeV4F7XrOYpnaNE= 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=ENEfQXnBKgsiB2d36L6+P4CJJ9i3migBmA1QXIq3dJc=; b=ABhqnJDucpVPNpUJVEEAvi616Mt2hRaxF/OD9/U1paKbEMwgcNCXK7Ra3MytSDphky o4pT7/O9Qm25JbDcaFUw5W6azTMCbPTOmg6lDUoxF45GMDPWVsjNlLp54tqsrcr+O1YX i74CmDRzY14OeDJuEfM0a3aoC4mojxA41QuymLu67lRi0LTdS5WlAmVspQ9LIhbGAwWe OWreH0yAZlhuz6xifc5zCCMUP0wKU3wT0gzVBCI5M81tKiuWIyoj10AscvY1PNMaLZdl FiSOAgICOYbh4HA4RoTLLWmZO/kOV1TdenMDFRXXj8rN27iC5l2ovc1qQGIH+U/WcDaT jsMg== X-Gm-Message-State: APjAAAWlFmTz+uLcAitPtYx0M9vzHlJo3TJHuPNGmdjalQKJ53rVU8NI wlh8IYOXN2isJAlH+ZmkqWhKxe8iM0k/ig== X-Received: by 2002:a6b:b602:: with SMTP id g2mr12815416iof.54.1559773496152; Wed, 05 Jun 2019 15:24:56 -0700 (PDT) Received: from localhost ([2620:15c:183:200:33ce:f5cf:f863:d3a6]) by smtp.gmail.com with ESMTPSA id e3sm81783ith.18.2019.06.05.15.24.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 05 Jun 2019 15:24:55 -0700 (PDT) From: Fletcher Woodruff To: linux-kernel@vger.kernel.org Cc: Ben Zhang , Jaroslav Kysela , Liam Girdwood , Mark Brown , Oder Chiou , Takashi Iwai , Curtis Malainey , Ross Zwisler , alsa-devel@alsa-project.org, Fletcher Woodruff Subject: [PATCH v6 4/4] ASoC: rt5677: handle concurrent interrupts Date: Wed, 5 Jun 2019 16:24:19 -0600 Message-Id: <20190605222419.54479-5-fletcherw@chromium.org> X-Mailer: git-send-email 2.22.0.rc1.311.g5d7573a151-goog In-Reply-To: <20190605222419.54479-1-fletcherw@chromium.org> References: <20190507220115.90395-1-fletcherw@chromium.org> <20190605222419.54479-1-fletcherw@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 86555d7ec9ea8d..7f7e60aceb49d3 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -5071,38 +5071,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); -- 2.22.0.rc1.311.g5d7573a151-goog