Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp1281041ybi; Fri, 14 Jun 2019 11:44:53 -0700 (PDT) X-Google-Smtp-Source: APXvYqzgmSnI1bdl7P9kM5yfUQVjPKTiUT+N1AgAfUPgykv+woG3/6kuXKzx0ML1ZCwOrfHCkR3C X-Received: by 2002:a62:3103:: with SMTP id x3mr19341722pfx.107.1560537893704; Fri, 14 Jun 2019 11:44:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560537893; cv=none; d=google.com; s=arc-20160816; b=0y9aDvdadRUd9QjNaW/zhfytvw6b5ch80axbcVL/sZ4SC08eHCCTJAtB2ba43rwMIv BXEfP8Rz+Tf12nhFkusU/euXdKxOguNoluPLX6OW+uHhP9W0RigjDzrrbPdlltjpuStM tfKzNCSgbnVNlLal4XBQzcVoJbz+ALF/YQPYoSe1SlPJfc6nTur4Pupp98M2Dzx8d1Fq sCYqhQsHNBth+A504HED9uWaNSleUi2cwdEEIq72DYhRg88FSoNSdHe3A/MRju9Du+VE h/820TO68b1C3Mi0NLISjNhSa+FN4tA8vhaoH10xWjASXr6BpCr/xbimck9c1sTGTt0c eQ4A== 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=NcPWD2owkf1HweY/dIY4noKl+ZyW2mZPzhEBgvasKUc=; b=fyNDJ3GbG5DeP6IV5uZUMieWHMJpNEjYe/trjRf0Ukajd7o4Cm7dOU5geMSiWR81a0 s1/FCdOhpSKGyhJq0jzxaEl0Ttm2eNH99WyF9XCv7emZCS6fGZqy9Azr/rqx6oMfgNLb SKhxJUdv+eYesPZDOEq+w9FsuLj9pzRTkoTBUEmSe7rH9+Jet7ARIR6cbbTHbKpqs4Vf WA9tBjdvBv+7Tzpqu8WHiropqLaeUZoLWCXnf7AaZHqgBCCpoHZNlWBebBukG4TCIIxk 25u3qO24WcnOHwLQSS/oqrvEmbjkH8q/rqmmwxdsjTYK5T8zoPk4Y074HtJMymOJBTBA y+GQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=UGaMm1iU; 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 u1si3038365plb.234.2019.06.14.11.44.39; Fri, 14 Jun 2019 11:44:53 -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=UGaMm1iU; 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 S1726700AbfFNSnt (ORCPT + 99 others); Fri, 14 Jun 2019 14:43:49 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:37455 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726649AbfFNSnr (ORCPT ); Fri, 14 Jun 2019 14:43:47 -0400 Received: by mail-io1-f65.google.com with SMTP id e5so7997915iok.4 for ; Fri, 14 Jun 2019 11:43:47 -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=NcPWD2owkf1HweY/dIY4noKl+ZyW2mZPzhEBgvasKUc=; b=UGaMm1iUAB4mUuqs1e4dbPz6CJBwDUR4zGk0Trc7KQuRwM5qfZf+hbNVUaRLDcpAhD YU46h9lS/Cmp89w5WWliKp4LIbcMUkfPu8NPVQ1F5F3EYefUwpXXw7UNI6ZKwvx3R7qe +7nIBfSREak7YtyyZMhXZMY6VamTElAjZYUuo= 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=NcPWD2owkf1HweY/dIY4noKl+ZyW2mZPzhEBgvasKUc=; b=CqM9VZZzFV//ZsZK0rSNF8GlNbkeGdJCb0+YMRiIXY136PDsTNmpnfgzT49HkIXv4A p/ncIQjqMRYbJnDIktWcmCYVoyPr2s4zEw0NIvpua+QMe+noCLXJiMajZfWJyKDVUDNV pBLeIboLN4/FGD+z/IJ5CHN45CIPJ05Hjv3dorculZEY3poo3VPOy6qGROJGxDmUrdnr 4gRHx/bO9tLkrXjycYxSXC0cX85szYRO2rJMlC/J0RcnHAyKrbcQcTvXnHSQZ454Chwn qDZMmrHCdrxG/p7aCCTDUkwoESvgc+ATZ6yfkvC02KVTHc2kfyavM1lpV7w1AnfsLedA hqdA== X-Gm-Message-State: APjAAAUAA8P+ebqPEOjSlMP9f2d/Of1D+VXO47AXaQk6MVUlsyFSSsPv B5vgrcgisA+nFKKGXndS2lrdWx4Bds8LRQ== X-Received: by 2002:a02:bb05:: with SMTP id y5mr65333545jan.93.1560537826328; Fri, 14 Jun 2019 11:43:46 -0700 (PDT) Received: from localhost ([2620:15c:183:200:33ce:f5cf:f863:d3a6]) by smtp.gmail.com with ESMTPSA id c2sm2446577iok.53.2019.06.14.11.43.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Jun 2019 11:43:45 -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: Fri, 14 Jun 2019 12:43:15 -0600 Message-Id: <20190614184315.252945-5-fletcherw@chromium.org> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog In-Reply-To: <20190614184315.252945-1-fletcherw@chromium.org> References: <20190614184315.252945-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 a136ed0d82e36b..44d51b350b8860 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.410.gd8fdbe21b5-goog