From patchwork Fri Apr 5 20:42:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fletcher Woodruff X-Patchwork-Id: 10887825 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 759581575 for ; Fri, 5 Apr 2019 20:46:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 56EC126E73 for ; Fri, 5 Apr 2019 20:46:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 47E0628A41; Fri, 5 Apr 2019 20:46:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7779426E73 for ; Fri, 5 Apr 2019 20:46:47 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id AA7DD1661; Fri, 5 Apr 2019 22:45:55 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AA7DD1661 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1554497205; bh=a9VJdLqSD0jFSvGB9KP4jz+eee6xbPZy5saISco7DRk=; h=From:To:Date:In-Reply-To:References:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=SWr8VjyvZQBfm/DCmpOkIWlXu24JsKqNRJLuOkf1TZrwPXpbk2ONr3fJb7RAmXLIw tipgeY5IcBw/edFfc7bCisPP66ScljboSBGQUz+IAalOJ7lPMpMhp8R8ofSaSPAU7k CxjAKJ/L5OM6zwuvr7J+SXWJEH3ohP+/HxhdP/kE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 9A371F89720; Fri, 5 Apr 2019 22:44:31 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 89513F89721; Fri, 5 Apr 2019 22:44:30 +0200 (CEST) Received: from mail-it1-x144.google.com (mail-it1-x144.google.com [IPv6:2607:f8b0:4864:20::144]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id BE5F6F8971D for ; Fri, 5 Apr 2019 22:44:27 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BE5F6F8971D Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="QawFVsyf" Received: by mail-it1-x144.google.com with SMTP id y134so5064772itc.5 for ; Fri, 05 Apr 2019 13:44:27 -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=QawFVsyfgU9Gkppe5q5iwa/Qeczf6OJ5+jzBypifbopEYUtGhkt/OJhhjG7p1dHIgH xbDZjQ4d/yVyy+J4rsL7/AFp6lt7XoXbWseLF7cGAoxz+KDXEdHPGEZ53KqY1aPEkR4D Odo9lWFQS3+eL5nrHIBLhENtjuLIv0rA5gI1E= 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=JOhwIQQl8/GsPhBVr9ocjvhK1Bt9MKxYT2NdE6jtBXlZbOnneam3r/pt8R1uUKjgVR jeiQ/s/29AoilfYGWshDvpse65wFIEeegrHc8slrtdeAWEG595GfPOLCOfR4s6PkuB16 rdJbmYKCV/xRwj8Qyru0G3d/Re62H1mMJGvmDVwt+q63XD4q+HNXxrzedBN4o2dAdGGr L6CbVmmjAXUV93v+a/2L738bihNk7XXZcvK9STz1De8AhIuH9sL+zqc9rFzyWP714abp eROrYgHwJaODtp/PoDlLWswP6I4zuFLDGoE7mxRa97rLOyqOuCv/QOFhUhEDfuIlpyQ8 qu6w== X-Gm-Message-State: APjAAAXA87s6uXX2tab6RW+q4k8RsepZa86/5Nylh09hWut1d+kJsFiE 2blCcsZtyS2rrnvlpVXXVN7/ZQ== X-Google-Smtp-Source: APXvYqwoTgOaLFfML6+EvH5EyrBBoinunPVnK6f5EW5rF+72qHLiEkEXtGSD3Qllkts4ZCLpH0/71Q== X-Received: by 2002:a24:791:: with SMTP id f139mr10801627itf.73.1554497066677; Fri, 05 Apr 2019 13:44:26 -0700 (PDT) Received: from localhost ([2620:15c:183:200:70a8:812a:cdeb:6e0]) by smtp.gmail.com with ESMTPSA id t2sm1604109itb.37.2019.04.05.13.44.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Apr 2019 13:44:25 -0700 (PDT) From: Fletcher Woodruff To: linux-kernel@vger.kernel.org Date: Fri, 5 Apr 2019 14:42:56 -0600 Message-Id: <20190405204257.87095-3-fletcherw@chromium.org> X-Mailer: git-send-email 2.21.0.392.gf8f6787159e-goog In-Reply-To: <20190405204257.87095-1-fletcherw@chromium.org> References: <20190401205519.34023-2-fletcherw@chromium.org> <20190405204257.87095-1-fletcherw@chromium.org> MIME-Version: 1.0 Cc: Oder Chiou , alsa-devel@alsa-project.org, Ross Zwisler , Takashi Iwai , Liam Girdwood , Ben Zhang , Mark Brown , Curtis Malainey , Fletcher Woodruff Subject: [alsa-devel] [PATCH v2 2/3] ASoC: rt5677: handle concurrent interrupts X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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: