Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp2125012yba; Thu, 25 Apr 2019 11:01:45 -0700 (PDT) X-Google-Smtp-Source: APXvYqy/sP7X7wsw7A2K+nwy7OhnhhC6fpzC9mJFBq5ZFsNUgudvlbEevWkYA5UDzir6Io7Nui9Q X-Received: by 2002:a63:5012:: with SMTP id e18mr38069987pgb.383.1556215305078; Thu, 25 Apr 2019 11:01:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556215305; cv=none; d=google.com; s=arc-20160816; b=V0YbmDWWtxa2HITJTHhrubppd35wLhq7TZ/RU+oq0zpLdSHKlmTHFTXix7DIGciSOJ 88IuUsEdn7irw3peeQlI0gSvHSeYDoUjrsq2F7f6vrRZ/Hh5jRNgTyPWP3ntwDUn5FHV 9PcNxSJmFk2DuIOx97mgpQCaf/oB4KWUz+yWnOyPoDvifiXhE7ol2dkRsg4hmkEvHlUX vlfWSaRfDzYUwmnER/bRfzTP8nTqt1j6CCI4nU2QY4Ob353ZqOu3tBPBu4i3NHAgZcLx /AyrciW3y4s3ezx9H3r69lMHhT7cvksVgFqXxrzF71FDCL+FiB35fX5NImBp9Lno7eTH 72fA== 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=6dFa/9ivc6HEwS7NtOOcCuyDA7RF6EsHuQ/nOlCBBV4=; b=JV+ZDudCQvk+FHILLMEZoXG3Pk/YkQM9dDxWafQiawRq0mlwQFHsQPvHoD7W8Ucf6V s8vaQGVZA0MJm632e1yFGWG8ZUn/5UF1vuq2NgxCf1T26ZV76p5ee14dDq6s4QpKFR47 GM4Tr52U91kyRT5yS/YTpvT1LYOqr1W+yyajZLvJk8Tqk/7Q4I8oaEm+iw242fcomOJD AY3R0t3QBJowW14FjZFo4jdYXRcY6QJfpGvErfEGS9BhckIfzuB3IDL22S2ct/4z2+KE b+oBxxkxHofqszBCXCanPfmanh1RZEiyn/QtmuNqkQHi2Lcxim5p4xFVVWx2tqgUs5cJ O8uQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=mgsvA0RG; 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 m12si21093535pgv.586.2019.04.25.11.01.30; Thu, 25 Apr 2019 11:01:45 -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=mgsvA0RG; 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 S1729114AbfDYPbN (ORCPT + 99 others); Thu, 25 Apr 2019 11:31:13 -0400 Received: from mail-it1-f194.google.com ([209.85.166.194]:52770 "EHLO mail-it1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726026AbfDYPbN (ORCPT ); Thu, 25 Apr 2019 11:31:13 -0400 Received: by mail-it1-f194.google.com with SMTP id x132so792186itf.2 for ; Thu, 25 Apr 2019 08:31:12 -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=6dFa/9ivc6HEwS7NtOOcCuyDA7RF6EsHuQ/nOlCBBV4=; b=mgsvA0RGxTCrDsOn06cR9B+czZWX5MsTiLB0a9nWLhXFf6HYTj1uxNpSYSufDUoDUl fx/5qBICjPTdg9Ql7ApeyQ5K2sPZLT1cPeV/53D97m7lH+iVb2sr5pgZiMJHQSc3eqwX OpBc/d4xy0xtFUJ1h0x2p4mMwkvJbN/JVAuEM= 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=6dFa/9ivc6HEwS7NtOOcCuyDA7RF6EsHuQ/nOlCBBV4=; b=t9q0z8dUOPd6wcbnhwvDx3C/hC/fIp024m0KJlyed66ue6tlSlzZUjGbIDYx+z6ff5 dAw27CQAKrF7GTXImESm7HZlGukQm2Di5NuQ3amv6mv23PkVIwDuY5YJo0Zi9uXD5waw 0qpDaDFl/FSfK+pIG7JeFewslRc7ZJtf585sHOYy+NqUoBxwOk5VW+dN+YtKF36ZXU6X 1s9LMZemQP1tP2wNPCk57D8+b/7550Y/fG19NUaLrFl1qLZwAxyYbZlOIlskJYuBJzwb qRNmtz2VoaFH+RghMTafRu4JgcdDnWbKWS2sbAO7SR1h4wBT9LNV7KklpV1RQnvgBWJw RkYA== X-Gm-Message-State: APjAAAVhUFwW8R12cC9MQPcuilljJCYQn9A7meYVsqytl97tmQaKyCgO WBQkFzYSWCiT0RAo7eHMs6PPcE7+I0M= X-Received: by 2002:a24:4e12:: with SMTP id r18mr4642745ita.128.1556206271744; Thu, 25 Apr 2019 08:31:11 -0700 (PDT) Received: from localhost ([2620:15c:183:200:33ce:f5cf:f863:d3a6]) by smtp.gmail.com with ESMTPSA id k18sm7694331iob.60.2019.04.25.08.31.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 25 Apr 2019 08:31:10 -0700 (PDT) From: Fletcher Woodruff To: linux-kernel@vger.kernel.org Cc: Ben Zhang , Bard Liao , Jaroslav Kysela , Liam Girdwood , Mark Brown , Oder Chiou , Takashi Iwai , alsa-devel@alsa-project.org, Fletcher Woodruff Subject: [PATCH v3 2/3] ASoC: rt5677: handle concurrent interrupts Date: Thu, 25 Apr 2019 09:31:04 -0600 Message-Id: <20190425153105.118799-1-fletcherw@chromium.org> X-Mailer: git-send-email 2.21.0.593.g511ec345e18-goog In-Reply-To: <20190415194557.9182-2-fletcherw@chromium.org> References: <20190415194557.9182-2-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 ef50314ac61eb5..6bff0df53c6c6b 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -5070,47 +5070,63 @@ static irqreturn_t rt5677_irq(int unused, void *data) { struct i2c_client *i2c = data; struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); - 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(&i2c->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(&i2c->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(&i2c->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(&i2c->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.392.gf8f6787159e-goog