Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp4255057yba; Tue, 7 May 2019 15:04:15 -0700 (PDT) X-Google-Smtp-Source: APXvYqxEs2Sh6A0OnQnXw6Ee0IIftskNFRuX9BiwdtAyx8assWFdZ8qBMoTOw2xFlvIC7rHSr434 X-Received: by 2002:a63:10c:: with SMTP id 12mr43650816pgb.276.1557266655578; Tue, 07 May 2019 15:04:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1557266655; cv=none; d=google.com; s=arc-20160816; b=EL73AZsQOihlvK6WUkEA7fCaxXe+jvGcIVlmOlG0oxBeY2zi3QujiL7qlZ5n4XZBZ+ X+zFdeKVVmfmuxo07kBUFihV28gM83DNt942vhkJDyPuJcptuHUUbtR14zpYCqXJBTzM wtrjkIfx+Ip9oJAeZ1cmrpXrazDCysze1Rg0fwwJNrPVEGodkDL1voslv7/fWcqTqcbA HtG+XIaA3/z7YCrPOVnfdHhyLfnYeJRQKSauqLUVvnosCjBY2ysxIsGVLjkZUzVEMWLR Z+R2jV8buDRuM5TqfE+JwMb4eOOsiCh8Fs2f8M0W/etoWbN+dXw6YwRT/aSRWMZXvYfd 7t9Q== 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=0y6QmCNGHLhzoejt/pdxavffrkeNyFEyZD1nqAARdlY=; b=yDA1Oio3SD6uiobs0A7YyR6tlduLhwCaLYz+RfSAgVzbbq2k8gJvhpIjsAuGW1rzv9 vQP8naqZXrvYVDu4K+3ar/NgQqHn6Osy6Bu3Brzfo06+sURD2pyHmm2Ipb7obzEcnovy 7YKN0gRNeLEukUHtWHi8YNdo2q3XYlkVAxGcr51c3iE0GlPWzp46A3tsIuJmQNvEsPmi aN+KY41F3F1Ark2rdH/X9lKnLSwL4lPjPOMKtvDNnGmIBh8nXNQ4HHIJsRQEuJ/ftI9b aEzel8II1+ZsdArIb9oc0BLc4cqEr6hLuHQCB0y/MvuUS2nBXsKKxuLQqL0UB6eBG1TU zVVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=Ur0+n8U1; 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 l12si19339567pgq.329.2019.05.07.15.03.59; Tue, 07 May 2019 15:04:15 -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=Ur0+n8U1; 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 S1726486AbfEGWBk (ORCPT + 99 others); Tue, 7 May 2019 18:01:40 -0400 Received: from mail-it1-f194.google.com ([209.85.166.194]:34058 "EHLO mail-it1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726225AbfEGWBk (ORCPT ); Tue, 7 May 2019 18:01:40 -0400 Received: by mail-it1-f194.google.com with SMTP id p18so638161itm.1 for ; Tue, 07 May 2019 15:01:39 -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=0y6QmCNGHLhzoejt/pdxavffrkeNyFEyZD1nqAARdlY=; b=Ur0+n8U1zxyYcca0cp4iDatcc90uGmWj59N95mD1hHvZ5jqmdm/qfp4xIoe1UoopXk 4cWDRkSBJaIL9LjeknZH+MhNhyJZMFXn4224ptWmtxOuArRmVXh6G/UcuS0N16G392rN 44aSS3bHuVQk+VB5Yh2qgQenoJg//hOd3Ce3Q= 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=0y6QmCNGHLhzoejt/pdxavffrkeNyFEyZD1nqAARdlY=; b=cZZYSbqH+XJ4SMOUwyMoICUgmwrl0XBZdyT20Kj5N9wPpKiW5+I/UT59eAN7BiJ8U2 vtDDGB7YN4AExA+mj5xnnr/ad7vWYv7EInDhoro0b5owMG/i/+xEUbZU7Si99FA1BvmM M+i9zfAABeyYcNvjARpgXRXb1TtwFXM4PCbv7npUvfckUOv8n6dWrwtoiqCX4wIZ4Q86 TWFfF8XqYPdzN0LTAn/fQT4l6YrA13o/eWL2DXbG3nSSEm9VUMLVat9yd+1M0OnGsL8P RaQSNXL0kZnreGo9rVyw2YNY5M24Z8YzjovNj7yqatoLEFopNh5AcUjXyvJrIwyfZGiE NfHg== X-Gm-Message-State: APjAAAWNkrZQXd8Mt5/clorbtBpfkvjv21nar8GgnNgUZhHZMKucfHQJ nJT0OoQYxK2xRgQYE+mChuRPAOJMbaI= X-Received: by 2002:a24:a946:: with SMTP id x6mr623969iti.136.1557266498735; Tue, 07 May 2019 15:01:38 -0700 (PDT) Received: from localhost ([2620:15c:183:200:33ce:f5cf:f863:d3a6]) by smtp.gmail.com with ESMTPSA id f129sm170255itf.4.2019.05.07.15.01.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 May 2019 15:01:38 -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 , alsa-devel@alsa-project.org, Fletcher Woodruff Subject: [PATCH v5 2/3] ASoC: rt5677: handle concurrent interrupts Date: Tue, 7 May 2019 16:01:14 -0600 Message-Id: <20190507220115.90395-3-fletcherw@chromium.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190507220115.90395-1-fletcherw@chromium.org> References: <20190507220115.90395-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 | 84 +++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 7d2039f3f67e75..091ef3e78fe3d2 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -5069,47 +5069,63 @@ 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; mutex_lock(&rt5677->irq_lock); - /* Read interrupt status */ - ret = regmap_read(rt5677->regmap, RT5677_IRQ_CTRL1, ®_irq); - if (ret) { - dev_err(rt5677->component->dev, - "Failed to read IRQ status: %d\n", - ret); - goto exit; - } /* - * Clear the interrupt by flipping the polarity of the - * interrupt source lines that just fired + * 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. */ - irq_fired = false; - for (i = 0; i < RT5677_IRQ_NUM; i++) { - if (reg_irq & rt5677_irq_descs[i].status_mask) { - reg_irq ^= rt5677_irq_descs[i].polarity_mask; - irq_fired = true; + for (loop = 0; loop < 20; loop++) { + /* Read interrupt status */ + ret = regmap_read(rt5677->regmap, RT5677_IRQ_CTRL1, ®_irq); + if (ret) { + dev_err(rt5677->component->dev, + "Failed to read IRQ status: %d\n", + ret); + goto exit; + } + /* + * Clear the interrupt by flipping the polarity of the + * interrupt source lines that just fired + */ + irq_fired = false; + for (i = 0; i < RT5677_IRQ_NUM; i++) { + if (reg_irq & rt5677_irq_descs[i].status_mask) { + reg_irq ^= rt5677_irq_descs[i].polarity_mask; + irq_fired = true; + } + } + if (!irq_fired) + goto exit; + + ret = regmap_write(rt5677->regmap, RT5677_IRQ_CTRL1, reg_irq); + if (ret) { + dev_err(rt5677->component->dev, + "Failed to update IRQ status: %d\n", + ret); + goto exit; } - } - if (!irq_fired) - goto exit; - - ret = regmap_write(rt5677->regmap, RT5677_IRQ_CTRL1, reg_irq); - if (ret) { - dev_err(rt5677->component->dev, - "Failed to update IRQ status: %d\n", - ret); - goto exit; - } - /* Process interrupts */ - for (i = 0; i < RT5677_IRQ_NUM; i++) { - if ((reg_irq & rt5677_irq_descs[i].enable_mask) && - (reg_irq & rt5677_irq_descs[i].status_mask)) { - virq = irq_find_mapping(rt5677->domain, i); - if (virq) - handle_nested_irq(virq); + /* Process interrupts */ + for (i = 0; i < RT5677_IRQ_NUM; i++) { + if ((reg_irq & rt5677_irq_descs[i].enable_mask) && + (reg_irq & rt5677_irq_descs[i].status_mask)) { + virq = irq_find_mapping(rt5677->domain, i); + if (virq) + handle_nested_irq(virq); + } } } exit: -- 2.21.0.1020.gf2820cf01a-goog