Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp1336528ybi; Fri, 14 Jun 2019 12:51:33 -0700 (PDT) X-Google-Smtp-Source: APXvYqz0muSWL0LQVW2YF9teV0H3LWDzB6kKRX7JdvVocNYV2z4HxTjIYyA8GQ8ATd6ghEmBXDRQ X-Received: by 2002:a62:e119:: with SMTP id q25mr64543856pfh.148.1560541893477; Fri, 14 Jun 2019 12:51:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560541893; cv=none; d=google.com; s=arc-20160816; b=T/c47Y6vBCAG6K0W7yCT+gQVuNPJVCXD6oU78FB8P4DK6s8ASUjahQrW5LbVcEiGXN CR7wy8oKlvOnya0Y6fOxWrOUe9xwrJPPdnAFPSGwd8K2Mn3D9W8b3tlDDb3mi8UV1Jai ogevHjVZQOscYbCzcJhZh73XDUq3KtG1yxyUY7pxwLC7pVdoXxyiMFsD9pfKOOd2nlCA jfx79PdQDa1EMfPYILLA9ps9naAm8YdBcUX04pEdD9f5EWXt82K2PokOTUcbu7Cxnkp5 TPFS1BKCPnJ5+pifS6+6rJzuDcNjrLmZ3CNFXdHEa6WdOHrYNNE4oq0EYOo64aElhl4p C2fQ== 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=XggeDQFBfdb+3YPzkLYpmWXYVa5T1jw4aJqqW4WiNOA=; b=hrUTOCkkXLYWpyt0KY7V0d5F6Ed2NbYSO1vfrHywjz2oct9dfVl2QRXpijweQt/cpB iV7h9cv7CrhJTO65MmF9LiLNxPm2WjCQwD/BThlfEUMEGvMQcPwl8g74tbxoCqiZT0MN cpw1o2f4E1qAdiPjOZgDllnOj47XZ8DABGniyfRISZZ9EGlu2CQMLwQ3nD6kM5rS9Xue clFkMgICWBXLb/uSQRivGPSxRoRj74r1yfY+drB+8ZsEi/+qP4NV4UdN35sNWpG2GMP+ gpv6RGIaTUHH2bpDpuhXIKM1wvt16RI522SCUxYyQot6aYzEqSgD9RE5kHdfz62tX/cw hb/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=IcGT9d46; 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 t7si3308169pgu.3.2019.06.14.12.51.18; Fri, 14 Jun 2019 12:51:33 -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=IcGT9d46; 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 S1726318AbfFNTtM (ORCPT + 99 others); Fri, 14 Jun 2019 15:49:12 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:34472 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726213AbfFNTtK (ORCPT ); Fri, 14 Jun 2019 15:49:10 -0400 Received: by mail-io1-f65.google.com with SMTP id k8so8438949iot.1 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=M6Xb864SNm5zaq5rX9EvUqru9rlYUbyAvOP4HmnhBmVBDVxSG0I+rDjNMDOhXP/9SI qQUhQPnAXhAMb/T96qzkDM7dFDReYsxGx76KZfG92UPHO5EgdHnT14Ai4fPIS1mJT7gw 4CMHPDUyIWcfSEIvtEvstZIFvIbqjImIXCSAylNS+kh6CaC4utSVa5dZ6XPUpd5448Wn LEJCk/vO3YrAZ5tQOtq6uYAVlEEmpn4NjqDNb9ItVwwrNdUJrYcHvm2i/U+dIQXnnmKp Cp0Dm1fzBoqhQa7z9Bqr5XBNZNNkTmRREYXh/aRouigCe76ayJrZ4VjcOCciL74iK48n ClyQ== X-Gm-Message-State: APjAAAUqUSuIUCdYD3kyq4IKc9C5+dHD5g+WPqS9kyPchQhCFyxtdBnB RYEd0S5hohzevROOE+p8UgITNMl6t0Y0+A== 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 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 v7 4/4] ASoC: rt5677: handle concurrent interrupts 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 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 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); -- 2.22.0.410.gd8fdbe21b5-goog