Received: by 10.192.165.148 with SMTP id m20csp5099490imm; Tue, 8 May 2018 22:18:51 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrENrSB0Amo2tMkKorRjRTe7FH/5+8spX+5z3Pi3tWFJAL+xwIZHkF2nuZ+KO7yJtjyceBZ X-Received: by 2002:a63:91c4:: with SMTP id l187-v6mr34664835pge.261.1525843131210; Tue, 08 May 2018 22:18:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525843131; cv=none; d=google.com; s=arc-20160816; b=HJKXYCVpZhTu6hiZt5smZTV/H4Wbbq46mth3zWX1Oa9cdN2+gI4jAzAz1hJaFr4vjx HqqYAyE75GpG8VwFaiWgnmu74jksgVqk0tSpwwc9reT39xmV59tnz0saIZLAKbvvvAwQ 8Htp3YzRV5L1bo76MicxW51B2f05mPC1vHgKOtc+vh8cvVLLGHH5mVcsJz6H1Eq1DB5b fTetjqNZ7wW8xY9uicVVVvvYRqAGPZmBQtU2JEDGezQoMXLFTsYr5BGhGsAj1ELKuPfC 6VmQCDdK4IX5KnyO/L63rBHQ8S2A9MBRCEMPqcVFUcOHkX5xy9/2DF4AsNTyEWRK6b9y MIhA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature:dkim-signature :arc-authentication-results; bh=1cQsJ2F0Nez6fURhDAyCsJg0hWyJWaILjCyd3er5CVo=; b=UcjtnHgY9+OOhpbow8dbV9gOIqjtYGq3CQlfVpudGyB4Dlk3hAG2fz3X8yP220ce/X RwpnLlLt3QujeUCM2pl+cNKq0ywlV/bw1MbJYFxaKQtRwQ/0cWZ3VreTiLd954kD/fhH rfn0WWYGyZZatmZW0OCLxF7r1eZg1aUT9AiAWu3Rwy7MN5YJNxtvLYECR6Rja68txZpu chSDgSmZvnzbCSPBNMmnmNykCxwydM8zumMZfMnDePd/5XqCL9aTFtCaAMn4USC8I2qk CMeAfXmpfnVi8690+RfQ5gcS9/hOMZXrRukNHKrZYemdB4V+kFrpjHT27Lvm4LLz97Bg 6J9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@google.com header.s=20161025 header.b=ohmZPyH7; dkim=fail header.i=@chromium.org header.s=google header.b=OGTe9lwd; 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=fail (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 24si20654131pfp.161.2018.05.08.22.18.36; Tue, 08 May 2018 22:18:51 -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=fail header.i=@google.com header.s=20161025 header.b=ohmZPyH7; dkim=fail header.i=@chromium.org header.s=google header.b=OGTe9lwd; 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=fail (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756116AbeEIFSX (ORCPT + 99 others); Wed, 9 May 2018 01:18:23 -0400 Received: from mail-vk0-f44.google.com ([209.85.213.44]:37315 "EHLO mail-vk0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752931AbeEIFSV (ORCPT ); Wed, 9 May 2018 01:18:21 -0400 Received: by mail-vk0-f44.google.com with SMTP id m144-v6so21092918vke.4 for ; Tue, 08 May 2018 22:18:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=1cQsJ2F0Nez6fURhDAyCsJg0hWyJWaILjCyd3er5CVo=; b=ohmZPyH7QwsLLty9z1pWUbLlu1aCsYwURgT7IW3PLKoaIkbOataIuRqS9KKGgu/DEp 39ObG1/yh9H4jab+BDZ7xTz/kS3/nguplDKDp6z1+VgzWU2lSVE4vIDYfoGu9/LM9QOu 3ARmPOFM1mvtBCsr8ip2sUD3U+rqczlmfHm0S+OexwYBUrv6hs0RnHH040ust1PICNSJ Rtt3ysV0a+6pGs4IzLEek2uilOlvY9+3POC9IiFGNO5ZLCR/BmFr2Tx65c47wIxQHcAj Ty/mBKPN++nfIE95TgggfqPFj2QEQY9aoWZ0+CxTa1GwVFdtKvoWbvpyAwFwUdPsgYqX SwYA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=1cQsJ2F0Nez6fURhDAyCsJg0hWyJWaILjCyd3er5CVo=; b=OGTe9lwdrLw4GK5j3JoatPRbplrBZv2GVDhjkYpa5ZekyF9WRyHbPIsjyNcosYEu3h JEzy2zLcsUb1CeYMXP47sTA3wk6lgIXWBQINOC1oVDtmZSmUp/Weji3UsDQ6F6mmiQWW ieF5xHkVasUrn7kaPoe27zI2TYCdrM75oZMKo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc; bh=1cQsJ2F0Nez6fURhDAyCsJg0hWyJWaILjCyd3er5CVo=; b=F+epiEoD5DaGWqH3hpswQCsTlmmmIvruJdnTh1fQS4vJ0wTYYm5nMM2Ge9JW5Xe1N6 qCe41dy+VQOKvT10Uyrksm7x1i4LlhAWVr4J9R6Ki1BzNPEh4oowHmDleiVtpgkKbvtF KXwC6MPi7snG1IxbClRDTxKV7FaAJlRg+rpddT/uAr5vG7iyVESIlRE5XRTrUVG0A/6Q vIv191P7vsSNBgjdjVNwpNprYjpO/cXvEYTvOlcCnm5JrGDtdW6+6yCXEWemZsrUpv2P 2MLNyOLzmDsGEtLjbj/Zr1MJ/QEFDfCXa7Be+ttHdqYZ3Rmog32dr3Odu60ptka19+rF A6TA== X-Gm-Message-State: ALQs6tC+OiUd+PjL/7TlZVg+2iMWazkQq29xz4W9cCLJMbsT+x28jr1M E1pymY6wHMEXRlfxDTLoXOqf5c8jzdmOkJAd2/fLnQ== X-Received: by 2002:a1f:1e04:: with SMTP id e4-v6mr34729156vke.117.1525843100258; Tue, 08 May 2018 22:18:20 -0700 (PDT) MIME-Version: 1.0 Received: by 10.31.48.82 with HTTP; Tue, 8 May 2018 22:18:18 -0700 (PDT) In-Reply-To: <5AF25B2E.8080901@rock-chips.com> References: <20180503065553.7762-1-jeffy.chen@rock-chips.com> <20180507221511.GA6448@rodete-desktop-imager.corp.google.com> <5AF0FF18.1050905@rock-chips.com> <20180508015623.GA61455@rodete-desktop-imager.corp.google.com> <5AF25B2E.8080901@rock-chips.com> From: Doug Anderson Date: Tue, 8 May 2018 22:18:18 -0700 X-Google-Sender-Auth: rmNS31WeKWbvKc7fbvP9geqd86k Message-ID: Subject: Re: [RESEND PATCH] pinctrl: rockchip: Disable interrupt when changing it's capability To: JeffyChen Cc: Brian Norris , LKML , =?UTF-8?Q?Heiko_St=C3=BCbner?= , "open list:ARM/Rockchip SoC..." , Linus Walleij , linux-gpio@vger.kernel.org, Linux ARM Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On Tue, May 8, 2018 at 7:21 PM, JeffyChen wrote: > Hi Doug, > > On 05/09/2018 03:46 AM, Doug Anderson wrote: >> >> One note is that in the case Brian points at (where we need to >> simulate EDGE_BOTH by swapping edges) we purposely ignored the TRM and >> we needed to do that to avoid losing interrupts. For details, see >> commit 53b1bfc76df2 ("pinctrl: rockchip: Avoid losing interrupts when >> supporting both edges"). We did this because: >> >> 1. We believed that the IP block in Rockchip SoCs has nearly the same >> logic as "gpio-dwapb.c" and that's what "gpio-dwapb.c" did. >> > > hmm, but i saw the gpio-dwapb.c actually toggle trigger after handle irq, > which might avoid the race Brian mentioned: > + generic_handle_irq(gpio_irq); > + irq_status &= ~BIT(hwirq); > + > + if ((irq_get_trigger_type(gpio_irq) & IRQ_TYPE_SENSE_MASK) > + == IRQ_TYPE_EDGE_BOTH) > + dwapb_toggle_trigger(gpio, hwirq); The code you point at in dwapb_toggle_trigger() specifically is an example of toggling the polarity _without_ disabling the interrupt in between. We took this as "working" code and as proof that it was OK to change polarity without disabling the interrupt in-between. > and i also saw ./qcom/pinctrl-msm.c do the > toggle(msm_gpio_update_dual_edge_pos) at the end of msm_gpio_irq_set_type > and msm_gpio_irq_ack, that seems can avoid the polarity races too. > >> 2. We were actually losing real interrupts and this was the only way >> we could figure out how to fix it. >> >> When I tested that back in the day I was fairly convinced that we >> weren't losing any interrupts in the EDGE_BOTH case after my fix, but >> I certainly could have messed up. >> >> >> For the EDGE_BOTH case it was important not to lose an interrupt >> because, as you guys are talking about, we could end up configured the >> wrong way. I think in your case where you're just picking one >> polarity losing an interrupt shouldn't matter since it's undefined >> exactly if an edge happens while you're in the middle of executing >> rockchip_irq_set_type(). Is that right? > > > right, so we now have 2 cases: rockchip_irq_demux/ rockchip_irq_set_type > > if i'm right about the spurious irq(only happen when set rising for a high > gpio, or set falling for a low gpio), then: > > 1/ rockchip_irq_demux > it's important to not losing irqs in this case, maybe we can > > a) ack irq > b) update polarity for edge both irq > > we don't need to disable irq in b), since we would not hit the spurious irq > cases here(always check gpio level to toggle it) Unless you have some sort of proof that rockchip_irq_demux(), I would take it as an example of something that works. I remember stress testing the heck out of it. Do you have some evidence that it's not working? I think Brian was simply speculating that there might be a race here, but I don't think anyone has shown it have they? Looking back at my notes, the thing I really made sure to stress was that we never got into a situation where we were losing an edge (AKA we were never configured to look for a falling edge when the line was already low). I'm not sure I confirmed that we never got an extra interrupt. I'm at home right now and I can't add prints and poke at things, but as I understand it for edge interrupts the usual flow to make sure interrupts aren't ever lost is: 1. See that the interrupt went off 2. Ack it (clear it) 3. Call the interrupt handler ...presumably in this case rockchip_irq_demux() is called after step #2 (but I don't know if it's called before or after step #3). If the line is toggling like crazy while the 3 steps are going on, it's OK if the interrupt handler is called more than once. In general this could be considered expected. That's why you Ack before handling--any extra edges that come in any time after the interrupt handler starts (even after the very first instruction) need to cause the interrupt handler to get called again. This is different than Brian's understanding since he seemed to think the Ack was happening later. If you're in front of something where you can add printouts, maybe you can tell us. I tried to look through the code and it was too twisted for me to be sure. > 2/ rockchip_irq_set_type > it's important to not having spurious irqs > > so we can disable irq during changing polarity only in these case: > ((rising && gpio is heigh) || (falling && gpio is low)) > > i'm still confirming the spurious irq with IC guys. Hmmm, thinking about all this more, I'm curious how callers expect this to work. Certainly things are undefined if you have the following situation: Start: rising edge trigger, line is actually high Request: change to falling edge trigger Line falls during the request In that case it's OK to throw the interrupt away because it can be argued that the line could have fallen before the request actually took place. ...but it seems like there could be situations where the user wouldn't expect interrupts to be thrown away by a call to irq_set_type(). In other words: Start: rising edge trigger, line is actually high Request: change to falling edge trigger Line falls, rises, and falls during the request ...in that case you'd expect that some sort of interrupt would have gone off and not be thrown away. No matter what instant in time the request actually took place it should have caught an edge, right? Said another way: As a client of irq_set_type() I'd expect it to not throw away interrupts, but I'd expect that the change in type would be atomic. That is: if the interrupt came in before the type change in type applied then it should trigger with the old rules. If the interrupt came in after the type change then it should trigger with the new rules. I would be tempted to confirm your testing and just clear the spurious interrupts that you're aware of. AKA: if there's no interrupt pending and you change the type to "IRQ_TYPE_EDGE_RISING" or "IRQ_TYPE_EDGE_FALLING" then you should clear the interrupt. It's still racy, but I guess it's the best you can do unless IC guys come up with something better. Anyway, it's past my bedtime. Hopefully some of the above made sense. I'm sure you'll tell me if it didn't or if I said something stupid/wrong. :-P -Doug