Received: by 2002:a05:6358:bb9e:b0:b9:5105:a5b4 with SMTP id df30csp5407124rwb; Wed, 7 Sep 2022 02:15:10 -0700 (PDT) X-Google-Smtp-Source: AA6agR63RPqpeZwrdlxWHrIzHPht8F4qmQbuiQgSJckK83pMilTviLKNgrtt9Z9GcvulDKWb9hlO X-Received: by 2002:a63:e22:0:b0:41d:3a50:bc55 with SMTP id d34-20020a630e22000000b0041d3a50bc55mr2639904pgl.255.1662542110557; Wed, 07 Sep 2022 02:15:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1662542110; cv=none; d=google.com; s=arc-20160816; b=GtSbHQNbWPxOQ18wxWpdQjRAn4L2IayJj0eYuCZc+IdF5YfFhr/m6W+K0dOu9aNyir oDOt6214AFwwD6W733UozQ/u0FMv/cujNCL6P3TIlja8MAiBcEwxZ/Yk7sJUF7/fBaDU 1+9EW22VBdjtZsdS+DGxGL4NKF4NeZKJ4hxdtjptoUpsWQY9WO+CrpgL2HGdRppxLF4L yrEz4LGViTCHpJ1mJASBu7fHjZ1eJjc5KGzibWJinmWqpyNNlFnxqpAstf7E0y/XZeCb HyfUGOcwAASeM6guel8KfqUEythZDw0FD+6Zh3F+r/16qDDMqeJ6Q0cagxKKIyLY8D7n e+nw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=NEWIwwUk2NSaBA+z9rQHvgwX/oZVvP/K2rLEZAPGJC4=; b=w8aYP6Fj1UUM3ecJL/w8rGqMNZ14cT+P+vJya69ATuQMVvm3c0IheroDWkoqcPu7EP u2PH4xT4r1YvuxDFxUnozXoobreUB4vmarGLHhaOU95C954c+tMl9jJEE/Oew05t21Db +P4iB1ghtgNpN+jks/E75OjuL4KfoPMhdw45f4703hb4j6NpLQ2LO2AB6BTMQmP2Q2bX bcnmEbt2YOauUn+fk4yHGK4OpqRK5ukedydrGIruX8sVPbU5JQmbUbuevmnLAwFW64G4 lA12LyijWLi2DVIJiFMrhQ2mi7LnEPgUpFtSmuHosCJN8QG8XyxQTrRjwz0RnFwI9EBb iPqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=kHSqQQif; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 92-20020a17090a09e500b001f2df544a5dsi20431082pjo.68.2022.09.07.02.14.58; Wed, 07 Sep 2022 02:15:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=kHSqQQif; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229600AbiIGIiN (ORCPT + 99 others); Wed, 7 Sep 2022 04:38:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33772 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229673AbiIGIiK (ORCPT ); Wed, 7 Sep 2022 04:38:10 -0400 Received: from mail-qt1-x82d.google.com (mail-qt1-x82d.google.com [IPv6:2607:f8b0:4864:20::82d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ACD63AE87D; Wed, 7 Sep 2022 01:37:35 -0700 (PDT) Received: by mail-qt1-x82d.google.com with SMTP id l5so9870860qtv.4; Wed, 07 Sep 2022 01:37:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date; bh=NEWIwwUk2NSaBA+z9rQHvgwX/oZVvP/K2rLEZAPGJC4=; b=kHSqQQifER8vqeU6eF7kWC4cLxZ9oF8kZrtRAZvp/7pQ5JiGlUBMgTtV9LykTLyR4W eCGZbRJzHpRkdABCMrtP9IhcD/cK8jMg2SFD3Wwo7FJiFQ+WKkmTEux7T2Qu2B5x88Kd x+baYiiN3gEHqt62NJlxYlTLsqAhDKTKSJIhUPhPkJnkjcxUAfdakxJFc6JbS/DbVst4 J+04MKU9W3XuUtCa3tWoxHnlOLTArqs9Avjw4bhY9mOkHxQXPYnC5RZPbIN29uRIYvFh VhJJ8yYLyt4jDESNwgzxrHiJuluILwjeuKAw9QFvehieqVVakqszRpkbBzYRQku5ZFoL 1Jvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date; bh=NEWIwwUk2NSaBA+z9rQHvgwX/oZVvP/K2rLEZAPGJC4=; b=kkC7XncocM1gKtQ4B/n/lz010JNe1NRvdxtPwGNEjqctEHK8QanXVF+Oofx7Y/xWkM Jqh0PxDXZHNfTur/UUEVCaGl5EP9CLhpzqYSGeeOMDL0GIubH3/vEuBQqYezHqJDtxYw YVkye6CE4XzKhrJRtkrroIFjD07GKByfwSNwKeFYOcJRqpGTCFQYkp6XVwZQbffpKUOI 383sYftBz49QIY65Owxd0mZ0CcE1feYoV562Qe2FWTrbSgV3EXglETsBRv/NToYL8ViN WccS4woJANW2Eg0nSitCzJi5sY3uaZ4IswrqO6NrY87nFTnK6IG2OPH+/qq6rfdgJEFN 9p9Q== X-Gm-Message-State: ACgBeo0DiwC+XnfDs/WicqlYVBGJbVTXyOOgcZPG7ZD6YpjwCy4whpaQ LdLO5E5ItUKj0ygR7R3/wi1Qi8lbDx2ZDSGV7pcLFfUOD4Q= X-Received: by 2002:ac8:5786:0:b0:343:3051:170d with SMTP id v6-20020ac85786000000b003433051170dmr2193079qta.429.1662539853505; Wed, 07 Sep 2022 01:37:33 -0700 (PDT) MIME-Version: 1.0 References: <20220907080251.3391659-1-horatiu.vultur@microchip.com> In-Reply-To: <20220907080251.3391659-1-horatiu.vultur@microchip.com> From: Andy Shevchenko Date: Wed, 7 Sep 2022 11:36:57 +0300 Message-ID: Subject: Re: [PATCH v2] pinctrl: ocelot: Fix interrupt controller To: Horatiu Vultur Cc: "open list:GPIO SUBSYSTEM" , Linux Kernel Mailing List , Linus Walleij , Microchip Linux Driver Support Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Sep 7, 2022 at 10:59 AM Horatiu Vultur wrote: > > When an external device generated a level based interrupt then the > interrupt controller could miss the interrupt. The reason is that the > interrupt controller can detect only link changes. > > In the following example, if there is a PHY that generates an interrupt > then the following would happen. The GPIO detected that the interrupt > line changed, and then the 'ocelot_irq_handler' will be called. Here it was called > detects which GPIO line seen the change and for that will call the saw > following: > 1. irq_mask > 2. phy interrupt routine > 3. irq_eoi > 4. irq_unmask > > And this works fine for simple cases, but if the PHY generates many > interrupts, for example when doing PTP timestamping, then the following > could happen. Again the function 'ocelot_irq_handler' will be called > and then from here the following could happen: > 1. irq_mask > 2. phy interrupt routine > 3. irq_eoi > 4. irq_unmask > > Right before step 3(irq_eoi), the PHY will generate another interrupt. > Now the interrupt controller will acknowledge the change in the > interrupt line. So we miss the interrupt. > > A solution will be to use 'handle_level_irq' instead of > 'handle_fasteoi_irq', because for this will change routine order of > handling the interrupt. > 1. irq_mask > 2. irq_ack > 3. phy interrupt routine > 4. irq_unmask > > And now if the PHY will generate a new interrupt before irq_unmask, the > interrupt controller will detect this because it already acknowledge the > change in interrupt line at step 2(irq_ack). > > But this is not the full solution because there is another issue. In > case there are 2 PHYs that share the interrupt line. For example phy1 > generates an interrupt, then the following can happen: > 1.irq_mask > 2.irq_ack > 3.phy0 interrupt routine > 4.phy1 interrupt routine > 5.irq_unmask > > In case phy0 will generate an interrupt while clearing the interrupt > source in phy1, then the interrupt line will be kept down by phy0. So > the interrupt controller will not see any changes in the interrupt line. > The solution here is to update 'irq_unmask' such that it can detect if > the interrupt line is still active or not. And if it is active then call > again the procedure to clear the interrupts. But we don't want to do it > every time, only if we know that the interrupt controller have not seen has not seen > already that the interrupt line has changed. > > While at this, add support also for IRQ_TYPE_LEVEL_LOW. ... > + regmap_read(info->map, REG(OCELOT_GPIO_IN, info, gpio), &val); > + if ((!(val & BIT(gpio % 32)) && trigger_level == IRQ_TYPE_LEVEL_LOW) || > + (val & BIT(gpio % 32) && trigger_level == IRQ_TYPE_LEVEL_HIGH)) > + active = true; You can use temporary variable for the bit, like unsigned int bit = BIT(gpio % 32); ... > + /* > + * In case the interrupt line is still active and the interrupt > + * controller has not seen any changes in the interrupt line, then it > + * means that there happen another interrupt while the line was active. > + * So we missed that one, so we need to kick again the interrupt the interrupt again > + * handler. > + */ > + if (active && !ack) { > + struct ocelot_irq_work *work; > + > + work = kmalloc(sizeof(*work), GFP_ATOMIC); > + if (!work) > + return; > + > + work->irq_desc = desc; > + INIT_WORK(&work->irq_work, ocelot_irq_work); > + queue_work(system_wq, &work->irq_work); > + } Here I see potential issues with the object lifetime. 1) The memory is allocated here and what does guarantee its freeing? 2) What does guarantee that work will be not scheduled if the driver or its parts are gone? -- With Best Regards, Andy Shevchenko