From patchwork Fri Oct 2 21:31:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 54458 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f199.google.com (mail-lb0-f199.google.com [209.85.217.199]) by patches.linaro.org (Postfix) with ESMTPS id 2C8BA218EF for ; Fri, 2 Oct 2015 21:31:49 +0000 (UTC) Received: by lbcao8 with SMTP id ao8sf20451876lbc.1 for ; Fri, 02 Oct 2015 14:31:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=LSUHPfDBwPbJY+6nbtierIz1t9AazXdQWXxSpNz0Ppo=; b=cVGRAaEyGGAOVVWewJdt29vkcWXMQKekaADbSdY0vQZlTe4IaaXcNQV9vBdv45pz8I OktCwn4s/pDhSoQFGXQ1YfXiBEGHH/GuV0S4vk3kD4VqVjcrFvJrGQXIq8Qof6JeeGU4 aTY+m/LCZ6Q/nCsjKz2s0Ep4gZeCSUz7dU2yo6eEc2Kb9WblUBpA+nJjbJTIfRmkwYHE fGjcDysyxxPUENKfe4Lf0mLKW+BnQT1ubNhHVtVufQyyeCCcutlketiGPULlWmd2Z1Ts gy7KrG/K8Te/QFlqv4gsar1IeMNU9yYrSSlfL2VD4Pqq6tBYDJhZn0hRdxjghpRdwDhv 2Rvg== X-Gm-Message-State: ALoCoQkLBijADH1K/gLt3oEX0f9LN4rtqsfK92AFvvo0zkp94Wr2J8ITRrlW0CjU6WNzLYsQKMaT X-Received: by 10.112.209.73 with SMTP id mk9mr3023600lbc.14.1443821507994; Fri, 02 Oct 2015 14:31:47 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.25.149.7 with SMTP id x7ls267096lfd.51.gmail; Fri, 02 Oct 2015 14:31:47 -0700 (PDT) X-Received: by 10.25.85.202 with SMTP id j193mr4243499lfb.2.1443821507854; Fri, 02 Oct 2015 14:31:47 -0700 (PDT) Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com. [209.85.217.181]) by mx.google.com with ESMTPS id r134si7502002lfd.0.2015.10.02.14.31.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Oct 2015 14:31:47 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) client-ip=209.85.217.181; Received: by lbcao8 with SMTP id ao8so33108595lbc.3 for ; Fri, 02 Oct 2015 14:31:47 -0700 (PDT) X-Received: by 10.25.38.9 with SMTP id m9mr4137753lfm.112.1443821507522; Fri, 02 Oct 2015 14:31:47 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp1465336lbq; Fri, 2 Oct 2015 14:31:46 -0700 (PDT) X-Received: by 10.66.230.137 with SMTP id sy9mr23184648pac.154.1443821506189; Fri, 02 Oct 2015 14:31:46 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id kv12si19423669pab.226.2015.10.02.14.31.45; Fri, 02 Oct 2015 14:31:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751305AbbJBVbp (ORCPT + 3 others); Fri, 2 Oct 2015 17:31:45 -0400 Received: from mail-lb0-f179.google.com ([209.85.217.179]:36805 "EHLO mail-lb0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751262AbbJBVbo (ORCPT ); Fri, 2 Oct 2015 17:31:44 -0400 Received: by lbcao8 with SMTP id ao8so33107805lbc.3 for ; Fri, 02 Oct 2015 14:31:42 -0700 (PDT) X-Received: by 10.25.15.71 with SMTP id e68mr4269786lfi.49.1443821502510; Fri, 02 Oct 2015 14:31:42 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-297471d5.01-192-6c756e10.cust.bredbandsbolaget.se. [213.113.116.41]) by smtp.gmail.com with ESMTPSA id oz1sm1825909lbb.26.2015.10.02.14.31.41 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Oct 2015 14:31:41 -0700 (PDT) From: Linus Walleij To: linux-gpio@vger.kernel.org Cc: Alexandre Courbot , Linus Walleij , Grygorii Strashko Subject: [PATCH] gpio: add a real time compliance checklist Date: Fri, 2 Oct 2015 14:31:36 -0700 Message-Id: <1443821496-19818-1-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 2.4.3 Sender: linux-gpio-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-gpio@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: linus.walleij@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add some information about real time compliance to the driver document. Inspired by Grygorii Strashko's real time compliance patches. Cc: Grygorii Strashko Signed-off-by: Linus Walleij --- Grygorii: can you help out with some heavy comments on all I do wrong in this document? Thx. For example I have no real clue of the difference between generic_handle_irq() and handle_nested_irq() in this context. We also need to think about new helper functions that can aid driver writers in getting drivers real time compliant and properly preemptible. Should we have the goal to make *all* drivers using the helpers use nested/threaded IRQs, or do you think there are (old) systems around that would suffer too much from this? --- Documentation/gpio/driver.txt | 72 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/Documentation/gpio/driver.txt b/Documentation/gpio/driver.txt index 90d0f6aba7a6..9d7985171f07 100644 --- a/Documentation/gpio/driver.txt +++ b/Documentation/gpio/driver.txt @@ -93,22 +93,37 @@ GPIO irqchips usually fall in one of two categories: Chained GPIO irqchips typically can NOT set the .can_sleep flag on struct gpio_chip, as everything happens directly in the callbacks. -* NESTED THREADED GPIO irqchips: these are off-chip GPIO expanders and any - other GPIO irqchip residing on the other side of a sleeping bus. Of course - such drivers that need slow bus traffic to read out IRQ status and similar, - traffic which may in turn incur other IRQs to happen, cannot be handled - in a quick IRQ handler with IRQs disabled. Instead they need to spawn a - thread and then mask the parent IRQ line until the interrupt is handled - by the driver. The hallmark of this driver is to call something like - this in its interrupt handler: + NOTE: chained IRQ handlers are usually not good for real time. If you + are submitting a new driver or refactoring a driver for real time compliance, + consider using creating a nested/threaded irqchip instead, see below. + +* NESTED THREADED GPIO irqchips: these are traditionally off-chip GPIO + expanders and any other GPIO irqchip residing on the other side of a + sleeping bus. Of course such drivers that need slow bus traffic to read + out IRQ status and similar, traffic which may in turn incur other IRQs to + happen, cannot be handled in a quick IRQ handler with IRQs disabled. + + With the introduction of real time support in the Linux kernel, also other + GPIO irqchips are encouraged to use a nested and threaded IRQ handler. + Doing so makes the interrupts naturally preemptible on a real time + setup, which means the system can easily be configured for real time with + a (usually negligable) performance loss. + + These drivers spawn a thread and then mask the parent IRQ line until the + interrupt is handled by the driver. The hallmark of this driver is to call + something like this in its interrupt handler: static irqreturn_t tc3589x_gpio_irq(int irq, void *data) ... handle_nested_irq(irq); + OR + generic_handle_irq(irq); - The hallmark of threaded GPIO irqchips is that they set the .can_sleep - flag on struct gpio_chip to true, indicating that this chip may sleep - when accessing the GPIOs. + Threaded GPIO irqchips should set the .can_sleep flag on struct gpio_chip + to true if they are e.g. accessing the chip over I2C or SPI, indicating that + this chip may sleep when accessing the GPIOs. irqchips that are just made + threaded to be preemptible and thus real time compliant need not do this: + preemption is not sleeping. To help out in handling the set-up and management of GPIO irqchips and the associated irqdomain and resource allocation callbacks, the gpiolib has @@ -125,7 +140,7 @@ symbol: gpio_chip from a parent IRQ and passes the struct gpio_chip* as handler data. (Notice handler data, since the irqchip data is likely used by the parent irqchip!) This is for the chained type of chip. This is also used - to set up a nested irqchip if NULL is passed as handler. + to set up a threaded/nested irqchip if NULL is passed as handler. To use the helpers please keep the following in mind: @@ -170,6 +185,39 @@ typically be called in the .startup() and .shutdown() callbacks from the irqchip. +Real-Time compliance for GPIO IRQ chips +--------------------------------------- + +Any provider of irqchips needs to be carefully tailored to support Real Time +preemption. It is desireable that all irqchips in the GPIO subsystem keep this +in mind and does the proper testing to assure they are real time-enabled. The +following is a checklist to follow when preparing a driver for real +time-compliance: + +- Nominally use raw_spinlock_t in the IRQ context path of the IRQ handler as + we do not want these sections to be preempted. + +- Do NOT use chained_irq_enter() or chained_irq_exit() in the IRQ handler, + as we want the hotpath to be preemptible. + +- Instead use nested IRQs and generic handlers such as handle_bad_irq(), + handle_level_irq() and handle_edge_irq(). Consequentally the handler + argument of gpiochip_set_chained_irqchip() should be NULL when using the + gpiolib irqchip helpers. + +- Nominally set all handlers to handle_bad_irq() in the setup call, then + set the handler to handle_level_irq() and/or handle_edge_irq() in the irqchip + .set_type() callback depending on what your controller supports. + +- If you need to use the pm_runtime_get*()/pm_runtime_put*() callbacks in some + of the irqchip callbacks, these should be moved to the .irq_bus_lock() + and .irq_bus_unlock() callbacks respectively, as these are the only + slowpath callbacks on an irqchip. Create the callbacks if need be. + +- Test your driver with the apropriate in-kernel real time test cases for both + level and edge IRQs. + + Requesting self-owned GPIO pins -------------------------------