From patchwork Thu Jul 2 14:17:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grzegorz Jaszczyk X-Patchwork-Id: 192238 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1488688ilg; Thu, 2 Jul 2020 07:19:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwvEd+MVKafjWg14BLfDrygLcQMJXOgjLpQDSkJ/Opi9xhsyzcIrnyFGAZBHoVkmyQsWV0n X-Received: by 2002:aa7:d3ca:: with SMTP id o10mr36239347edr.138.1593699586074; Thu, 02 Jul 2020 07:19:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593699586; cv=none; d=google.com; s=arc-20160816; b=HMtcpEvvdioHa94cxXRCPBplzHJCyNEFfsnW7uCjNdO8JAMGV6OYw8R+joa/o7aVUm CW3ixDpak62+YcKaTd4nkoXz2Si/lS4kEFSsuW31MUop+88ZOdm5fBvE2YKhc70FRgY1 xvOmjIHLa9od6VMQ1/AzEwnv05l+hEO0oO/BIai+uIEFNgv4hsYHFZLmp1+AZbHm/x/U EnVAe2J5slq5D61IIm+G5nDTJvDrlmgHvC+yKqBY/LIP95diJ4j4MLyjKbBisri5dlDk nETnEgLEwnq1LGwERCs2+BMeqf/rLNIW36uVJhOWXBLjP/KkJGO6yn7+QhdtkYJGjAvk 85qQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=iH/5SdRt0ZmEKr6tLnBuXOQ6nM/oBq9dcRUdUYhDi1c=; b=gxdeZvPlWCwDngEuBhvGP+QYC/fzGORAEQlsKMJHiuW3dCF4NFPySmbEWdWtUNilTr y/iosXNXG/aFWJFkorGiCc4DulmmUGLJRyVTaxt2B9y93KmDcC1wsTxoUQIzKN8AaB0q 4EctwlSlwsPFbss6ual/ABThnsfvY7IfmP4WALLqHjK0tAoQWBmWorvD/YyAlslrg2QM WPf9TAAs2V7pvCZPIFdDQ/LJT0Ymi35ciwfrTJevvJt6W7lIq6AUwRC8qb9RUkIjt5tC u4soKhB1P1gPl/UTIogzYdFQ90Dvi5px3zG28UBzNlf7Gxsj9Bpo8nr1P7F7nWOb75TW Ex0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ElVKkYIz; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k20si5725716ejq.621.2020.07.02.07.19.45; Thu, 02 Jul 2020 07:19:46 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ElVKkYIz; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729591AbgGBOTp (ORCPT + 6 others); Thu, 2 Jul 2020 10:19:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729571AbgGBOTo (ORCPT ); Thu, 2 Jul 2020 10:19:44 -0400 Received: from mail-lj1-x22b.google.com (mail-lj1-x22b.google.com [IPv6:2a00:1450:4864:20::22b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C50CAC08C5DC for ; Thu, 2 Jul 2020 07:19:43 -0700 (PDT) Received: by mail-lj1-x22b.google.com with SMTP id f8so20107677ljc.2 for ; Thu, 02 Jul 2020 07:19:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=iH/5SdRt0ZmEKr6tLnBuXOQ6nM/oBq9dcRUdUYhDi1c=; b=ElVKkYIzUTrbjnA/8+ynwLd3swQXBuKGGHqCcOuVLyUAaR0T0MVVr3+AjndeZJX4Z8 oR318bwOn7Qq2XsFRt95NksT4coWT1iX7oLGgi5Wt+/w+iZhqb3uDOQOO/Qq+L3La8rl SNzJRGlKgTl5IdNZM2csvyjabp4nTNxGEOM5MKRxhQyIZOYiHHkt3j8SfegHnGTKd/pb VaJpaAYnZ5o2caZqTi4YfIvNZObt6KhNlrExAHKQmb9rEmsy6v6hI64XXSlwXxdY2Oao xms16sCrBxfh/jYEbL++O/dpi8ylJByaZGqcSpiBSFPMMAw1jxiPIBNo+0c3ifnHzafR rvfQ== 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; bh=iH/5SdRt0ZmEKr6tLnBuXOQ6nM/oBq9dcRUdUYhDi1c=; b=Qhj6MI2jm3tSeu8PtQd6xGzc2Bxehn86y0Z46ijf4ZjrwM1R/Bcy2fbGCYTFRuEwFo oC5kBmlwpSg/jj6yCKk+lC888FPOAVhesGPdxE2ljJXZx4g53Sk3dS0uNzm8Qvvq4eGc jjAiqytbqumXWD6zC/Z9Mmv2GBhiHO4pdceDcPlGPZq+QODPLTQ34rSVJLQF7SAu96ss WR9Hp111TD948zPVj13BHi9AQ/EP7zZ8Zu7Ihpb23BEKu2SyiJllyGoUk2QcOsIHcdZL eXFnFFKoXVBFOdShfFno1/KzH6cp5tJSL26MEdkg2cFcsSe8Omj4qLUMyNEv0dPAQvGy nqYQ== X-Gm-Message-State: AOAM533kXj7PWCR5AoyZokNNvWXsG489a1ApN6auiWD8MzaupxzxcdRC hpqCCJ0eBaujsPD6OwV9khUY4g== X-Received: by 2002:a05:651c:512:: with SMTP id o18mr17586734ljp.226.1593699582099; Thu, 02 Jul 2020 07:19:42 -0700 (PDT) Received: from gilgamesh.semihalf.com (193-106-246-138.noc.fibertech.net.pl. [193.106.246.138]) by smtp.gmail.com with ESMTPSA id v10sm692581ljg.113.2020.07.02.07.19.40 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Jul 2020 07:19:41 -0700 (PDT) From: Grzegorz Jaszczyk To: tglx@linutronix.de, jason@lakedaemon.net, maz@kernel.org, s-anna@ti.com Cc: grzegorz.jaszczyk@linaro.org, robh+dt@kernel.org, lee.jones@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, david@lechnology.com, wmills@ti.com, "Andrew F . Davis" , Roger Quadros Subject: [PATCHv3 1/6] dt-bindings: irqchip: Add PRU-ICSS interrupt controller bindings Date: Thu, 2 Jul 2020 16:17:54 +0200 Message-Id: <1593699479-1445-2-git-send-email-grzegorz.jaszczyk@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> References: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Suman Anna The Programmable Real-Time Unit and Industrial Communication Subsystem (PRU-ICSS or simply PRUSS) contains an interrupt controller (INTC) that can handle various system input events and post interrupts back to the device-level initiators. The INTC can support upto 64 input events on most SoCs with individual control configuration and h/w prioritization. These events are mapped onto 10 output interrupt lines through two levels of many-to-one mapping support. Different interrupt lines are routed to the individual PRU cores or to the host CPU or to other PRUSS instances. The K3 AM65x and J721E SoCs have the next generation of the PRU-ICSS IP, commonly called ICSSG. The ICSSG interrupt controller on K3 SoCs provide a higher number of host interrupts (20 vs 10) and can handle an increased number of input events (160 vs 64) from various SoC interrupt sources. Add the bindings document for these interrupt controllers on all the applicable SoCs. It covers the OMAP architecture SoCs - AM33xx, AM437x and AM57xx; the Keystone 2 architecture based 66AK2G SoC; the Davinci architecture based OMAPL138 SoCs, and the K3 architecture based AM65x and J721E SoCs. Signed-off-by: Suman Anna Signed-off-by: Andrew F. Davis Signed-off-by: Roger Quadros Signed-off-by: Grzegorz Jaszczyk Reviewed-by: Lee Jones --- v2->v3: - Convert dt-binding to YAML v1->v2: - https://patchwork.kernel.org/patch/11069767/ --- .../interrupt-controller/ti,pruss-intc.yaml | 135 +++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml -- 2.7.4 diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml new file mode 100644 index 0000000..7fe4b95 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml @@ -0,0 +1,135 @@ +# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/ti,pruss-intc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI PRU-ICSS Local Interrupt Controller + +maintainers: + - Suman Anna + +description: | + Each PRU-ICSS has a single interrupt controller instance that is common + to all the PRU cores. Most interrupt controllers can route 64 input events + which are then mapped to 10 possible output interrupts through two levels + of mapping. The input events can be triggered by either the PRUs and/or + various other PRUSS internal and external peripherals. The first 2 output + interrupts (0, 1) are fed exclusively to the internal PRU cores, with the + remaining 8 (2 through 9) connected to external interrupt controllers + including the MPU and/or other PRUSS instances, DSPs or devices. + + The properties "ti,irqs-reserved" and "ti,irqs-shared" are used for denoting + the connection differences on the output interrupts 2 through 9. If neither + of these properties are defined, it implies that all the PRUSS INTC output + interrupts 2 through 9 (host_intr0 through host_intr7) are connected + exclusively to the Arm interrupt controller. + + The K3 family of SoCs can handle 160 input events that can be mapped to 20 + different possible output interrupts. The additional output interrupts (10 + through 19) are connected to new sub-modules within the ICSSG instances. + + This interrupt-controller node should be defined as a child node of the + corresponding PRUSS node. The node should be named "interrupt-controller". + +allOf: + - $ref: /schemas/interrupt-controller.yaml# + - $ref: /schemas/interrupts.yaml# + +properties: + compatible: + enum: + - ti,pruss-intc + - ti,icssg-intc + description: | + Use "ti,pruss-intc" for OMAP-L13x/AM18x/DA850 SoCs, + AM335x family of SoCs, + AM437x family of SoCs, + AM57xx family of SoCs + 66AK2G family of SoCs + Use "ti,icssg-intc" for K3 AM65x & J721E family of SoCs + + reg: + items: + - description: base address and size for the PRUSS INTC sub-module + + interrupts: + minItems: 1 + maxItems: 8 + description: | + all the interrupts generated towards the main host processor in the SoC. + The format depends on the interrupt specifier for the particular SoC's + Arm parent interrupt controller. A shared interrupt can be skipped if + the desired destination and usage is by a different processor/device. + + interrupt-names: + minItems: 1 + maxItems: 8 + items: + pattern: host_intr[0-7] + description: | + should use one of the above names for each valid host event interrupt + connected to Arm interrupt controller, the name should match the + corresponding host event interrupt number + + interrupt-controller: true + + "#interrupt-cells": + const: 1 + description: | + Client users shall use the PRU System event number (the interrupt source + that the client is interested in) as the value of the interrupts property + in their node + + ti,irqs-reserved: + $ref: /schemas/types.yaml#definitions/uint8-array + description: | + an array of 8-bit elements of host interrupts between 0 and 7 + (corresponding to PRUSS INTC output interrupts 2 through 9) that are + not connected to the Arm interrupt controller. + Eg: AM437x and 66AK2G SoCs do not have "host_intr5" interrupt connected + to MPU + + ti,irqs-shared: + $ref: /schemas/types.yaml#definitions/uint8-array + description: | + an array of 8-bit elements of host interrupts between 0 and 7 + (corresponding to PRUSS INTC output interrupts 2 through 9) that are + also connected to other devices or processors in the SoC. + Eg: AM65x and J721E SoCs have "host_intr5", "host_intr6" and + "host_intr7" interrupts connected to MPU, and other ICSSG + instances + +required: + - compatible + - reg + - interrupts + - interrupt-names + - interrupt-controller + - "#interrupt-cells" + +additionalProperties: false + +examples: + - | + /* AM33xx PRU-ICSS */ + pruss: pruss@0 { + compatible = "ti,am3356-pruss"; + reg = <0x0 0x80000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pruss_intc: interrupt-controller@20000 { + compatible = "ti,pruss-intc"; + reg = <0x20000 0x2000>; + interrupts = <20 21 22 23 24 25 26 27>; + interrupt-names = "host_intr0", "host_intr1", + "host_intr2", "host_intr3", + "host_intr4", "host_intr5", + "host_intr6", "host_intr7"; + interrupt-controller; + #interrupt-cells = <1>; + ti,irqs-shared = /bits/ 8 <0 6 7>; + }; + }; From patchwork Thu Jul 2 14:17:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grzegorz Jaszczyk X-Patchwork-Id: 192239 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1488900ilg; Thu, 2 Jul 2020 07:20:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwbN/GD4nrE5r1HCk2pZifJlsnkb6hBJwsJdcf7lVK12/mw8PK12BWFRuM5Gd5VRp/eSSmV X-Received: by 2002:a17:906:7cc4:: with SMTP id h4mr11447430ejp.339.1593699602240; Thu, 02 Jul 2020 07:20:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593699602; cv=none; d=google.com; s=arc-20160816; b=rBvYXTcXfx6zI/q7ZYpZmekkX8NI+2+XJkOLMH5tByvaQfTk+Zlmrf3WTqprowPIgo E09pI8NFJQjycJYLa/8+pDZI73Et+RI3XLd5LrkS7attgBQdhdYUEL3LRchAHvsrDlbi PyVo/5GwFYj9QefEPHF7rFz36M1su3YUFzTAkqsE9wr7+FXW7Y6pW5P458z8TT25iPRS Ao+dQoiJdqvDyEs4JQovNm8maOuDgwcmFQ4BDfS7wrd9jUjnSQt0zC07FQUyvXKM7ZOY fWNZ2WE3pusCRUNeBTbOVI7dD7bkv9HRi1DN2ARxwQCOHzsif+8kGCLwCEXp1TxdEa7z XGtg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=e2p7Qgo0iovqEwvWwPOoN8STIZ8vtZ2v+ghlQhOSJCg=; b=SEemyBnyMvDfreoCIYkq4CjEz58MsZOitEDPgdwCBnDxEToziybCrXyVKl37/523/2 gL0agdZd2IoOy8MoNd7ZMiB2LAIgADAY76XEckTcSCQQhOTpXduW5BqO1Y9FGyJE26dh Z0VBDj64OHmYqiwXgRauEbOMnJzMQx6ieqjHerI1mnQZfsPFyZT42o0BrauNuowhNSX8 rHoYLX+dORVjfh59+wVy4qpA+OabNsHtzi4JV9sZJI7PLIo8ATfG1Q6AJ69Xi11K+Zn4 hTKg1zypSmOB9vpqKzDlKZIGBJyDAnqZ6zWcOQQ51gfOOVm6c77uxTLKmvUwbChw/5MD mNpQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Nl6KDI+L; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m1si6229220edr.207.2020.07.02.07.20.01; Thu, 02 Jul 2020 07:20:02 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Nl6KDI+L; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729671AbgGBOT6 (ORCPT + 6 others); Thu, 2 Jul 2020 10:19:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729645AbgGBOT5 (ORCPT ); Thu, 2 Jul 2020 10:19:57 -0400 Received: from mail-lj1-x241.google.com (mail-lj1-x241.google.com [IPv6:2a00:1450:4864:20::241]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 68298C08C5DD for ; Thu, 2 Jul 2020 07:19:57 -0700 (PDT) Received: by mail-lj1-x241.google.com with SMTP id q7so19145719ljm.1 for ; Thu, 02 Jul 2020 07:19:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=e2p7Qgo0iovqEwvWwPOoN8STIZ8vtZ2v+ghlQhOSJCg=; b=Nl6KDI+LgqLnFpFPYAzowFno0hi/vDCI21qHMyn7odZ2qli1bBWHO05yQlC0/dYaIF FUnbACAdnpUCO7jctCGmLvoT/dk+gpUJut3Io5TKHeRMjNMdJ7nxGvsiSDCO8/p/D09R RNpI/u/t4Axup0n4XkhYMwx+Tb3XqTm9Gk1GqZG1ECMeSiupYhRq7GZX3Mv56LYwH1Sz OajzlhlzCIQiRnWfdsDpljYWlWljLZzrfGEBEz+ggvu8BlpxEVuCASv4OLovLxKJlUzX aAIKTzKh5jvOwY0rdU75B4qM3kSG28iMixHARiUuhKl1RwLI/lRHwyjSUmfO/H0bFl3K htyQ== 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; bh=e2p7Qgo0iovqEwvWwPOoN8STIZ8vtZ2v+ghlQhOSJCg=; b=huBSRWwKd9GpAG5x+xzFKcHm0k7Qz2CpASAZseH6lhRPPKCpJdwHjU0ZNMhcZ9GKby u2WJ1qgB6KBfyTXAEtzuJqsNvtCKd5t7IaY9GYRafIxDAxsYuWNU3dypGOE4Hha9ejig qh0fFHR1a5UgWTv5BP+g/JMPJVj5ZuTEck78q7umCoQ5mvc/8ffY1oXWcjnWpo80YX+w qBKhZGru9+SJQEpU4Gn697ou9Q4aX0zcOnlIKwcNYHn51BzQ0b0FWWTPf6qlVKs2GIXc +2CCpzEZHIveUffyco8dDCOaMHEkwR6skak+ifknRwUw4PUNByTZ5RWwdR9tWrE28VqU eDXQ== X-Gm-Message-State: AOAM532YJ88DpfSBMK80fRusHSzxuo+PagqxWNCTD9NJ9ZmLqo92kdhI 2yzUH4mJbLilxxSbOvZSdZSWcQ== X-Received: by 2002:a2e:7116:: with SMTP id m22mr13912368ljc.271.1593699595616; Thu, 02 Jul 2020 07:19:55 -0700 (PDT) Received: from gilgamesh.semihalf.com (193-106-246-138.noc.fibertech.net.pl. [193.106.246.138]) by smtp.gmail.com with ESMTPSA id v10sm692581ljg.113.2020.07.02.07.19.54 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Jul 2020 07:19:55 -0700 (PDT) From: Grzegorz Jaszczyk To: tglx@linutronix.de, jason@lakedaemon.net, maz@kernel.org, s-anna@ti.com Cc: grzegorz.jaszczyk@linaro.org, robh+dt@kernel.org, lee.jones@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, david@lechnology.com, wmills@ti.com, "Andrew F . Davis" , Roger Quadros Subject: [PATCHv3 2/6] irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS interrupts Date: Thu, 2 Jul 2020 16:17:55 +0200 Message-Id: <1593699479-1445-3-git-send-email-grzegorz.jaszczyk@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> References: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Suman Anna The Programmable Real-Time Unit Subsystem (PRUSS) contains a local interrupt controller (INTC) that can handle various system input events and post interrupts back to the device-level initiators. The INTC can support upto 64 input events with individual control configuration and hardware prioritization. These events are mapped onto 10 output interrupt lines through two levels of many-to-one mapping support. Different interrupt lines are routed to the individual PRU cores or to the host CPU, or to other devices on the SoC. Some of these events are sourced from peripherals or other sub-modules within that PRUSS, while a few others are sourced from SoC-level peripherals/devices. The PRUSS INTC platform driver manages this PRUSS interrupt controller and implements an irqchip driver to provide a Linux standard way for the PRU client users to enable/disable/ack/re-trigger a PRUSS system event. The system events to interrupt channels and output interrupts relies on the mapping configuration provided either through the PRU firmware blob or via the PRU application's device tree node. The mappings will be programmed during the boot/shutdown of a PRU core. The PRUSS INTC module is reference counted during the interrupt setup phase through the irqchip's irq_request_resources() and irq_release_resources() ops. This restricts the module from being removed as long as there are active interrupt users. The driver currently supports and can be built for OMAP architecture based AM335x, AM437x and AM57xx SoCs; Keystone2 architecture based 66AK2G SoCs and Davinci architecture based OMAP-L13x/AM18x/DA850 SoCs. All of these SoCs support 64 system events, 10 interrupt channels and 10 output interrupt lines per PRUSS INTC with a few SoC integration differences. NOTE: Each PRU-ICSS's INTC on AM57xx SoCs is preceded by a Crossbar that enables multiple external events to be routed to a specific number of input interrupt events. Any non-default external interrupt event directed towards PRUSS needs this crossbar to be setup properly. Signed-off-by: Suman Anna Signed-off-by: Andrew F. Davis Signed-off-by: Roger Quadros Signed-off-by: Grzegorz Jaszczyk Reviewed-by: Lee Jones --- v2->v3: - use single irqchip description instead of separately allocating it for each pruss_intc - get rid of unused mutex - improve error handling v1->v2: - https://patchwork.kernel.org/patch/11069771/ --- drivers/irqchip/Kconfig | 10 ++ drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-pruss-intc.c | 307 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 318 insertions(+) create mode 100644 drivers/irqchip/irq-pruss-intc.c -- 2.7.4 diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 29fead2..733d7ec 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -493,6 +493,16 @@ config TI_SCI_INTA_IRQCHIP If you wish to use interrupt aggregator irq resources managed by the TI System Controller, say Y here. Otherwise, say N. +config TI_PRUSS_INTC + tristate "TI PRU-ICSS Interrupt Controller" + depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX || ARCH_KEYSTONE + select IRQ_DOMAIN + help + This enables support for the PRU-ICSS Local Interrupt Controller + present within a PRU-ICSS subsystem present on various TI SoCs. + The PRUSS INTC enables various interrupts to be routed to multiple + different processors within the SoC. + config RISCV_INTC bool "RISC-V Local Interrupt Controller" depends on RISCV diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 133f9c4..990a106 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -106,6 +106,7 @@ obj-$(CONFIG_MADERA_IRQ) += irq-madera.o obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o +obj-$(CONFIG_TI_PRUSS_INTC) += irq-pruss-intc.o obj-$(CONFIG_LOONGSON_LIOINTC) += irq-loongson-liointc.o obj-$(CONFIG_LOONGSON_HTPIC) += irq-loongson-htpic.o obj-$(CONFIG_LOONGSON_HTVEC) += irq-loongson-htvec.o diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c new file mode 100644 index 0000000..fb3dda3 --- /dev/null +++ b/drivers/irqchip/irq-pruss-intc.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * PRU-ICSS INTC IRQChip driver for various TI SoCs + * + * Copyright (C) 2016-2020 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis + * Suman Anna + */ + +#include +#include +#include +#include +#include +#include + +/* + * Number of host interrupts reaching the main MPU sub-system. Note that this + * is not the same as the total number of host interrupts supported by the PRUSS + * INTC instance + */ +#define MAX_NUM_HOST_IRQS 8 + +/* minimum starting host interrupt number for MPU */ +#define MIN_PRU_HOST_INT 2 + +/* maximum number of system events */ +#define MAX_PRU_SYS_EVENTS 64 + +/* PRU_ICSS_INTC registers */ +#define PRU_INTC_REVID 0x0000 +#define PRU_INTC_CR 0x0004 +#define PRU_INTC_GER 0x0010 +#define PRU_INTC_GNLR 0x001c +#define PRU_INTC_SISR 0x0020 +#define PRU_INTC_SICR 0x0024 +#define PRU_INTC_EISR 0x0028 +#define PRU_INTC_EICR 0x002c +#define PRU_INTC_HIEISR 0x0034 +#define PRU_INTC_HIDISR 0x0038 +#define PRU_INTC_GPIR 0x0080 +#define PRU_INTC_SRSR0 0x0200 +#define PRU_INTC_SRSR1 0x0204 +#define PRU_INTC_SECR0 0x0280 +#define PRU_INTC_SECR1 0x0284 +#define PRU_INTC_ESR0 0x0300 +#define PRU_INTC_ESR1 0x0304 +#define PRU_INTC_ECR0 0x0380 +#define PRU_INTC_ECR1 0x0384 +#define PRU_INTC_CMR(x) (0x0400 + (x) * 4) +#define PRU_INTC_HMR(x) (0x0800 + (x) * 4) +#define PRU_INTC_HIPIR(x) (0x0900 + (x) * 4) +#define PRU_INTC_SIPR0 0x0d00 +#define PRU_INTC_SIPR1 0x0d04 +#define PRU_INTC_SITR0 0x0d80 +#define PRU_INTC_SITR1 0x0d84 +#define PRU_INTC_HINLR(x) (0x1100 + (x) * 4) +#define PRU_INTC_HIER 0x1500 + +/* HIPIR register bit-fields */ +#define INTC_HIPIR_NONE_HINT 0x80000000 + +/** + * struct pruss_intc - PRUSS interrupt controller structure + * @irqs: kernel irq numbers corresponding to PRUSS host interrupts + * @base: base virtual address of INTC register space + * @domain: irq domain for this interrupt controller + */ +struct pruss_intc { + unsigned int irqs[MAX_NUM_HOST_IRQS]; + void __iomem *base; + struct irq_domain *domain; +}; + +static inline u32 pruss_intc_read_reg(struct pruss_intc *intc, unsigned int reg) +{ + return readl_relaxed(intc->base + reg); +} + +static inline void pruss_intc_write_reg(struct pruss_intc *intc, + unsigned int reg, u32 val) +{ + writel_relaxed(val, intc->base + reg); +} + +static void pruss_intc_init(struct pruss_intc *intc) +{ + int i; + + /* configure polarity to active high for all system interrupts */ + pruss_intc_write_reg(intc, PRU_INTC_SIPR0, 0xffffffff); + pruss_intc_write_reg(intc, PRU_INTC_SIPR1, 0xffffffff); + + /* configure type to pulse interrupt for all system interrupts */ + pruss_intc_write_reg(intc, PRU_INTC_SITR0, 0); + pruss_intc_write_reg(intc, PRU_INTC_SITR1, 0); + + /* clear all 16 interrupt channel map registers */ + for (i = 0; i < 16; i++) + pruss_intc_write_reg(intc, PRU_INTC_CMR(i), 0); + + /* clear all 3 host interrupt map registers */ + for (i = 0; i < 3; i++) + pruss_intc_write_reg(intc, PRU_INTC_HMR(i), 0); +} + +static void pruss_intc_irq_ack(struct irq_data *data) +{ + struct pruss_intc *intc = irq_data_get_irq_chip_data(data); + unsigned int hwirq = data->hwirq; + + pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq); +} + +static void pruss_intc_irq_mask(struct irq_data *data) +{ + struct pruss_intc *intc = irq_data_get_irq_chip_data(data); + unsigned int hwirq = data->hwirq; + + pruss_intc_write_reg(intc, PRU_INTC_EICR, hwirq); +} + +static void pruss_intc_irq_unmask(struct irq_data *data) +{ + struct pruss_intc *intc = irq_data_get_irq_chip_data(data); + unsigned int hwirq = data->hwirq; + + pruss_intc_write_reg(intc, PRU_INTC_EISR, hwirq); +} + +static int pruss_intc_irq_reqres(struct irq_data *data) +{ + if (!try_module_get(THIS_MODULE)) + return -ENODEV; + + return 0; +} + +static void pruss_intc_irq_relres(struct irq_data *data) +{ + module_put(THIS_MODULE); +} + +static struct irq_chip pruss_irqchip = { + .name = "pruss-intc", + .irq_ack = pruss_intc_irq_ack, + .irq_mask = pruss_intc_irq_mask, + .irq_unmask = pruss_intc_irq_unmask, + .irq_request_resources = pruss_intc_irq_reqres, + .irq_release_resources = pruss_intc_irq_relres, +}; + +static int pruss_intc_irq_domain_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + struct pruss_intc *intc = d->host_data; + + irq_set_chip_data(virq, intc); + irq_set_chip_and_handler(virq, &pruss_irqchip, handle_level_irq); + + return 0; +} + +static void pruss_intc_irq_domain_unmap(struct irq_domain *d, unsigned int virq) +{ + irq_set_chip_and_handler(virq, NULL, NULL); + irq_set_chip_data(virq, NULL); +} + +static const struct irq_domain_ops pruss_intc_irq_domain_ops = { + .xlate = irq_domain_xlate_onecell, + .map = pruss_intc_irq_domain_map, + .unmap = pruss_intc_irq_domain_unmap, +}; + +static void pruss_intc_irq_handler(struct irq_desc *desc) +{ + unsigned int irq = irq_desc_get_irq(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + struct pruss_intc *intc = irq_get_handler_data(irq); + u32 hipir; + unsigned int virq; + int i, hwirq; + + chained_irq_enter(chip, desc); + + /* find our host irq number */ + for (i = 0; i < MAX_NUM_HOST_IRQS; i++) + if (intc->irqs[i] == irq) + break; + if (i == MAX_NUM_HOST_IRQS) + goto err; + + i += MIN_PRU_HOST_INT; + + /* get highest priority pending PRUSS system event */ + hipir = pruss_intc_read_reg(intc, PRU_INTC_HIPIR(i)); + while (!(hipir & INTC_HIPIR_NONE_HINT)) { + hwirq = hipir & GENMASK(9, 0); + virq = irq_linear_revmap(intc->domain, hwirq); + + /* + * NOTE: manually ACK any system events that do not have a + * handler mapped yet + */ + if (WARN_ON(!virq)) + pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq); + else + generic_handle_irq(virq); + + /* get next system event */ + hipir = pruss_intc_read_reg(intc, PRU_INTC_HIPIR(i)); + } +err: + chained_irq_exit(chip, desc); +} + +static int pruss_intc_probe(struct platform_device *pdev) +{ + static const char * const irq_names[MAX_NUM_HOST_IRQS] = { + "host_intr0", "host_intr1", "host_intr2", "host_intr3", + "host_intr4", "host_intr5", "host_intr6", "host_intr7", }; + struct device *dev = &pdev->dev; + struct pruss_intc *intc; + int i, irq; + + intc = devm_kzalloc(dev, sizeof(*intc), GFP_KERNEL); + if (!intc) + return -ENOMEM; + platform_set_drvdata(pdev, intc); + + intc->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(intc->base)) { + dev_err(dev, "failed to parse and map intc memory resource\n"); + return PTR_ERR(intc->base); + } + + pruss_intc_init(intc); + + /* always 64 events */ + intc->domain = irq_domain_add_linear(dev->of_node, MAX_PRU_SYS_EVENTS, + &pruss_intc_irq_domain_ops, intc); + if (!intc->domain) + return -ENOMEM; + + for (i = 0; i < MAX_NUM_HOST_IRQS; i++) { + irq = platform_get_irq_byname(pdev, irq_names[i]); + if (irq <= 0) { + dev_err(dev, "platform_get_irq_byname failed for %s : %d\n", + irq_names[i], irq); + goto fail_irq; + } + + intc->irqs[i] = irq; + irq_set_handler_data(irq, intc); + irq_set_chained_handler(irq, pruss_intc_irq_handler); + } + + return 0; + +fail_irq: + while (--i >= 0) + irq_set_chained_handler_and_data(intc->irqs[i], NULL, NULL); + + irq_domain_remove(intc->domain); + + return irq; +} + +static int pruss_intc_remove(struct platform_device *pdev) +{ + struct pruss_intc *intc = platform_get_drvdata(pdev); + unsigned int hwirq; + int i; + + for (i = 0; i < MAX_NUM_HOST_IRQS; i++) + irq_set_chained_handler_and_data(intc->irqs[i], NULL, NULL); + + for (hwirq = 0; hwirq < MAX_PRU_SYS_EVENTS; hwirq++) + irq_dispose_mapping(irq_find_mapping(intc->domain, hwirq)); + + irq_domain_remove(intc->domain); + + return 0; +} + +static const struct of_device_id pruss_intc_of_match[] = { + { .compatible = "ti,pruss-intc", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, pruss_intc_of_match); + +static struct platform_driver pruss_intc_driver = { + .driver = { + .name = "pruss-intc", + .of_match_table = pruss_intc_of_match, + .suppress_bind_attrs = true, + }, + .probe = pruss_intc_probe, + .remove = pruss_intc_remove, +}; +module_platform_driver(pruss_intc_driver); + +MODULE_AUTHOR("Andrew F. Davis "); +MODULE_AUTHOR("Suman Anna "); +MODULE_DESCRIPTION("TI PRU-ICSS INTC Driver"); +MODULE_LICENSE("GPL v2"); From patchwork Thu Jul 2 14:17:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grzegorz Jaszczyk X-Patchwork-Id: 192240 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1488978ilg; Thu, 2 Jul 2020 07:20:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyz/QDXUVLQXnfkO+umdJvjOak/jqEzRjLazf9j/BKYbGRKD6Q2XPsH4BbMNAVq+Fo+8ZBl X-Received: by 2002:a05:6402:1655:: with SMTP id s21mr33560124edx.289.1593699606791; Thu, 02 Jul 2020 07:20:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593699606; cv=none; d=google.com; s=arc-20160816; b=ZrBYGz1XfV3HWbgrQfmNFFPVkfpkxCH0d9aJPDZP9iEBn3AvItz0GQ091SDzYi5mB8 Cq4DKRxlIxSbIFopxDHLqt9/bUgtSbMTc3If9G2HzlOGylqEt9jvRNk+GMFjMMBi0Yci KNXZV8FUb7wz1BdSsbBNFsjeawyTAs5fT454qoVxPlvL2eMKUuvsMJJLYNL2nB0OkOED Ml6feIQcqLbo5AEMKjgfxpiDwoFD961I2q7ZlNoRNcP+xQzk2iCH3BsBPHL0995xspkw x8uNJljdDvvRZsUaqVKLbP1Pi6U7sH8sPhTag71tDmW3GdAasuf1B1aBCf8v3zGPfV3w CR5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=RoJjFQSX48jhwhl8Ul5YCo93h9fATpR+8tZryrxKU3c=; b=EAtihCm/p1M0Uhj4Z9umQa2ONk2YdRqVtmQblNYWkLl1HyUBZeUiyuky5VskGsuUG+ sec2jdY/3AjCiV7cHkH0+dfltXhtXenqghcHNxmg41jocO1/EdGru7Kh4t7/7kRtYqHm QSRtLR7Sn+g1xZL+liP3iGqV2RkWd3LV3mDzzMZFvDOLxfbynbtsl5X03yM5bqNbD40A PxWS9zLRWZyDCJIn5lehmFRKEFVvMZxnvniuQSQRR/22YzFLbbriKasFcyn4SAO/ygXc igCJjzWm7tp9NLTfAOE+A6IBbPQYisThH1ydUisGsz+/amkYPHSa2KfS4IzI1i6XqxQ0 sfoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=K5JQX5Cn; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m1si6229220edr.207.2020.07.02.07.20.06; Thu, 02 Jul 2020 07:20:06 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=K5JQX5Cn; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729718AbgGBOUG (ORCPT + 6 others); Thu, 2 Jul 2020 10:20:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46040 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729712AbgGBOUF (ORCPT ); Thu, 2 Jul 2020 10:20:05 -0400 Received: from mail-lj1-x241.google.com (mail-lj1-x241.google.com [IPv6:2a00:1450:4864:20::241]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29CC0C08C5DD for ; Thu, 2 Jul 2020 07:20:05 -0700 (PDT) Received: by mail-lj1-x241.google.com with SMTP id b25so28799125ljp.6 for ; Thu, 02 Jul 2020 07:20:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RoJjFQSX48jhwhl8Ul5YCo93h9fATpR+8tZryrxKU3c=; b=K5JQX5CnCB6yZjVindc2bgU/7edLnaiW8yXFIh/IIEyv1kN375fz1yNU0nCk4pC5lv sipMjiRouaBgQcsud6+xI/bdGQeyWgQHO1RxeRbDx5IkUPdSeyd+ij8a4P1flRlIP7TD Z9wlO7HZr2D6Fvfv439KMkwaM/KFmJjAhgVOsqCteuNoBNg0VhRFc8cwc4TJiUVCZjyG MSd+AXD0Mr81XWhKXWJkCjrXTE6hsVjYYZ4ufuQJIhDLphNxewZjhGOL+RmyC7E/tJuC Y430FOWIbYT10yqdSM/Ja1/dMrc5wFVGs5L4gTqk8HIeyHviVudizaCPafWKyxxJYJVs OO8w== 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; bh=RoJjFQSX48jhwhl8Ul5YCo93h9fATpR+8tZryrxKU3c=; b=Fq9ND2SBkHMGcocwoYt7ghmZs/xdNslP3+FREM7Uy4wVq3cGm8PxGSsdeA07DcDFw5 YRsiqSuF18XQPGS971MeHfz+1owYTtZAvdU1ajmCdm54L7sQ0xdMPiTXU7bvCogrUQIH LzgQ/CWBLiyML0Wx8WJyhrl0MUy/6odOOCqIS/x8Xmz3E0R3JgNv6fECQJLByylr3KZ9 Paalf1a3YUzJan2r5QR6NViTdfY6tgXIgTpuuTy6DLX1QElQ6mq6+0Ova6Mcf29a5KrS 7b1Joehj1xBEWOz2iEnsuVaz5ieazha3292rBtqX/K3OMiU/N0YvvA7rhD1xaLvSYlt3 Nueg== X-Gm-Message-State: AOAM533KYCzLPganEpqoRxAiFmoFWieJgARDGz7PHv66vAhiO/U9hki3 yW0TmCHbDmdcQiIak+1th9H2og== X-Received: by 2002:a2e:6e05:: with SMTP id j5mr16118253ljc.135.1593699603585; Thu, 02 Jul 2020 07:20:03 -0700 (PDT) Received: from gilgamesh.semihalf.com (193-106-246-138.noc.fibertech.net.pl. [193.106.246.138]) by smtp.gmail.com with ESMTPSA id v10sm692581ljg.113.2020.07.02.07.20.02 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Jul 2020 07:20:02 -0700 (PDT) From: Grzegorz Jaszczyk To: tglx@linutronix.de, jason@lakedaemon.net, maz@kernel.org, s-anna@ti.com Cc: grzegorz.jaszczyk@linaro.org, robh+dt@kernel.org, lee.jones@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, david@lechnology.com, wmills@ti.com Subject: [PATCHv3 3/6] irqchip/irq-pruss-intc: Add support for shared and invalid interrupts Date: Thu, 2 Jul 2020 16:17:56 +0200 Message-Id: <1593699479-1445-4-git-send-email-grzegorz.jaszczyk@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> References: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Suman Anna The PRUSS INTC has a fixed number of output interrupt lines that are connected to a number of processors or other PRUSS instances or other devices (like DMA) on the SoC. The output interrupt lines 2 through 9 are usually connected to the main Arm host processor and are referred to as host interrupts 0 through 7 from ARM/MPU perspective. All of these 8 host interrupts are not always exclusively connected to the Arm interrupt controller. Some SoCs have some interrupt lines not connected to the Arm interrupt controller at all, while a few others have the interrupt lines connected to multiple processors in which they need to be partitioned as per SoC integration needs. For example, AM437x and 66AK2G SoCs have 2 PRUSS instances each and have the host interrupt 5 connected to the other PRUSS, while AM335x has host interrupt 0 shared between MPU and TSC_ADC and host interrupts 6 & 7 shared between MPU and a DMA controller. Add support to the PRUSS INTC driver to allow both these shared and invalid interrupts by not returning a failure if any of these interrupts are skipped from the corresponding INTC DT node. Signed-off-by: Suman Anna Signed-off-by: Grzegorz Jaszczyk --- v2->v3: - Extra checks for (intc->irqs[i]) in error/remove path was moved from "irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS interrupts" to this patch v1->v2: - https://patchwork.kernel.org/patch/11069757/ --- drivers/irqchip/irq-pruss-intc.c | 73 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 5 deletions(-) -- 2.7.4 diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index fb3dda3..49c936f 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -65,11 +65,15 @@ * @irqs: kernel irq numbers corresponding to PRUSS host interrupts * @base: base virtual address of INTC register space * @domain: irq domain for this interrupt controller + * @shared_intr: bit-map denoting if the MPU host interrupt is shared + * @invalid_intr: bit-map denoting if host interrupt is not connected to MPU */ struct pruss_intc { unsigned int irqs[MAX_NUM_HOST_IRQS]; void __iomem *base; struct irq_domain *domain; + u16 shared_intr; + u16 invalid_intr; }; static inline u32 pruss_intc_read_reg(struct pruss_intc *intc, unsigned int reg) @@ -222,7 +226,8 @@ static int pruss_intc_probe(struct platform_device *pdev) "host_intr4", "host_intr5", "host_intr6", "host_intr7", }; struct device *dev = &pdev->dev; struct pruss_intc *intc; - int i, irq; + int i, irq, count; + u8 temp_intr[MAX_NUM_HOST_IRQS] = { 0 }; intc = devm_kzalloc(dev, sizeof(*intc), GFP_KERNEL); if (!intc) @@ -235,6 +240,52 @@ static int pruss_intc_probe(struct platform_device *pdev) return PTR_ERR(intc->base); } + count = of_property_read_variable_u8_array(dev->of_node, + "ti,irqs-reserved", + temp_intr, 0, + MAX_NUM_HOST_IRQS); + /* + * The irqs-reserved is used only for some SoC's therefore not having + * this property is still valid + */ + if (count == -EINVAL) + count = 0; + if (count < 0) + return count; + + for (i = 0; i < count; i++) { + if (temp_intr[i] >= MAX_NUM_HOST_IRQS) { + dev_warn(dev, "ignoring invalid reserved irq %d\n", + temp_intr[i]); + continue; + } + + intc->invalid_intr |= BIT(temp_intr[i]); + } + + count = of_property_read_variable_u8_array(dev->of_node, + "ti,irqs-shared", + temp_intr, 0, + MAX_NUM_HOST_IRQS); + /* + * The irqs-shared is used only for some SoC's therefore not having + * this property is still valid + */ + if (count == -EINVAL) + count = 0; + if (count < 0) + return count; + + for (i = 0; i < count; i++) { + if (temp_intr[i] >= MAX_NUM_HOST_IRQS) { + dev_warn(dev, "ignoring invalid shared irq %d\n", + temp_intr[i]); + continue; + } + + intc->shared_intr |= BIT(temp_intr[i]); + } + pruss_intc_init(intc); /* always 64 events */ @@ -244,8 +295,14 @@ static int pruss_intc_probe(struct platform_device *pdev) return -ENOMEM; for (i = 0; i < MAX_NUM_HOST_IRQS; i++) { + if (intc->invalid_intr & BIT(i)) + continue; + irq = platform_get_irq_byname(pdev, irq_names[i]); if (irq <= 0) { + if (intc->shared_intr & BIT(i)) + continue; + dev_err(dev, "platform_get_irq_byname failed for %s : %d\n", irq_names[i], irq); goto fail_irq; @@ -259,8 +316,11 @@ static int pruss_intc_probe(struct platform_device *pdev) return 0; fail_irq: - while (--i >= 0) - irq_set_chained_handler_and_data(intc->irqs[i], NULL, NULL); + while (--i >= 0) { + if (intc->irqs[i]) + irq_set_chained_handler_and_data(intc->irqs[i], NULL, + NULL); + } irq_domain_remove(intc->domain); @@ -273,8 +333,11 @@ static int pruss_intc_remove(struct platform_device *pdev) unsigned int hwirq; int i; - for (i = 0; i < MAX_NUM_HOST_IRQS; i++) - irq_set_chained_handler_and_data(intc->irqs[i], NULL, NULL); + for (i = 0; i < MAX_NUM_HOST_IRQS; i++) { + if (intc->irqs[i]) + irq_set_chained_handler_and_data(intc->irqs[i], NULL, + NULL); + } for (hwirq = 0; hwirq < MAX_PRU_SYS_EVENTS; hwirq++) irq_dispose_mapping(irq_find_mapping(intc->domain, hwirq)); From patchwork Thu Jul 2 14:17:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grzegorz Jaszczyk X-Patchwork-Id: 192241 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1489057ilg; Thu, 2 Jul 2020 07:20:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxh3iCrLCTIzboJEnFacxUFRYJK+mBx0HZTKP8a9nQwaMY7fCTO0ayPa1W0LwiEhOkY/Dny X-Received: by 2002:a50:b0a1:: with SMTP id j30mr35173718edd.387.1593699611320; Thu, 02 Jul 2020 07:20:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593699611; cv=none; d=google.com; s=arc-20160816; b=Y0nDjZF/s+DQ7rHdL/pngjOt7iQB2VXOR8S4A8xZNtxj55nrUY2z1195J0SSxDeCm4 We8w7M5O6yMvQzNP+Oo72wCaJuJRBvV81NC0+N3RKqT4PQ/pS3pEAs1PGIx+8IdxZrLQ Kp+hd9vCOSjAy5iE4qocL8NWXpwHjmk55musSsbw+CCRDLwqmaR6YC3fugwgz+22ZXEY kw6eBMZl8JRKBj5P6DkdNwV3fAuBhI3ZFftXk/1Ho7octp/KNlhYIZli7XY7Hiqv2SG0 asGZDO3IidcRiJrotVusdx9yYZ/ou8ECsKTzAOadSBFTF977C59pSeQ/5AYiHcmmHa6O FayA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=4HO8KIlLqlwP/f8Ruj28glCZZ5K9Sse59aSvMxbiXe4=; b=f+svV2K3qwdPMsNtSqE2/BWneb0xMHH+2KIf2hxF6cJYVUwgZGDLeC8rpOc5A4Qzq/ sCeX8gykrGcS6GaNB5T91corRuOs7gdX77sy1b2D8fMVq4xCrEB1RB12C+ckunsmO1oe BevWXlXg6SD+UC1KOX2TyCVY9/KDEM4xOk9CzRXtjlrMa34wJJYRzafL5rKtyqKE9zFT 2baBWE9oa2cJFi8r4uL5fr6LMTA0vxojg1lErl7TlAK/hMHHQHdLTFvH4FNnno7UeD68 zJRSljxTsTDPkOsAEHHWG+zc13tUbh6MO93sedz3/yf0KJLhbpDkhnJERQAXF0IaiIyn ma5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NVq8KjQj; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m1si6229220edr.207.2020.07.02.07.20.11; Thu, 02 Jul 2020 07:20:11 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NVq8KjQj; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729754AbgGBOUK (ORCPT + 6 others); Thu, 2 Jul 2020 10:20:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46050 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729753AbgGBOUI (ORCPT ); Thu, 2 Jul 2020 10:20:08 -0400 Received: from mail-lj1-x242.google.com (mail-lj1-x242.google.com [IPv6:2a00:1450:4864:20::242]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7B197C08C5C1 for ; Thu, 2 Jul 2020 07:20:08 -0700 (PDT) Received: by mail-lj1-x242.google.com with SMTP id h19so32372609ljg.13 for ; Thu, 02 Jul 2020 07:20:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4HO8KIlLqlwP/f8Ruj28glCZZ5K9Sse59aSvMxbiXe4=; b=NVq8KjQj97pZ12DfuDX6ObhQONPpx/XLwguVE7MeHvMriwV3ZpTcy5F3yNAwmciTo3 piNKbV7bXjATmWytRK9un5tZckGbMaIkUPi1Ty6/ovHoLgHd+TrSwF82jtVj0d7b+amR GQcYfyGAS6qpR3QiIhsE1NR0PD11MCyHhkJnn/nwWCiMbYwM6foJ6gFV9E3sIsUeOMmm i3OmQyS7TnPi/O3+1sGIy6kRdIBGXm79RoZhFmXV2b2Y5uuj0P5nfo9aX5Fkq6B6RD0M Z6zKn3L5yTSgEaLl85/tpdp3pqryd3JTPo/l/DqMik2PATKjrwduG4jEYdjxwfzvTZhy nKow== 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; bh=4HO8KIlLqlwP/f8Ruj28glCZZ5K9Sse59aSvMxbiXe4=; b=GPjWqHkXnx/g6Dr8dd6rlEzrqqIVNCJVl7Ui1jL6c2Hb7y7gHK2wjuAmGyG3fHroMv /4bwKXfPqXgdbbtdKlFpJBOwLbpEiJ2oeJSWxkD6l4xqKPd/Mi9rwi9T+DOJi/xpJeF9 iUdABlCMmxOBeN2A+l9NHeSVuy88ba9NkD5Ct0/xkPaY3Y61H3pRX3e0b6mf2byX8eeN t+t38Zd4VO27GBek47SGahJY0LRgaB3IvvWlmBaXoD0VXViOd/0/8vhUPjnDuqJJnZSQ IFRHITca8hyiagcoD2Ee9MZToJUK4G8QhPL2opANFUVKElfe1w4YNJoanAK3AYexx672 dNsA== X-Gm-Message-State: AOAM533QNlc8cGg5vzu9CMhgWacp9WGIAtmEMIhzZXAPMmyFQ8Lc52zB RaVMkK8H5q4DJwGA6Z6BZvUOIQ== X-Received: by 2002:a2e:91da:: with SMTP id u26mr10525805ljg.311.1593699606933; Thu, 02 Jul 2020 07:20:06 -0700 (PDT) Received: from gilgamesh.semihalf.com (193-106-246-138.noc.fibertech.net.pl. [193.106.246.138]) by smtp.gmail.com with ESMTPSA id v10sm692581ljg.113.2020.07.02.07.20.05 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Jul 2020 07:20:06 -0700 (PDT) From: Grzegorz Jaszczyk To: tglx@linutronix.de, jason@lakedaemon.net, maz@kernel.org, s-anna@ti.com Cc: grzegorz.jaszczyk@linaro.org, robh+dt@kernel.org, lee.jones@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, david@lechnology.com, wmills@ti.com Subject: [PATCHv3 4/6] irqchip/irq-pruss-intc: Implement irq_{get, set}_irqchip_state ops Date: Thu, 2 Jul 2020 16:17:57 +0200 Message-Id: <1593699479-1445-5-git-send-email-grzegorz.jaszczyk@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> References: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: David Lechner This implements the irq_get_irqchip_state and irq_set_irqchip_state callbacks for the TI PRUSS INTC driver. The set callback can be used by drivers to "kick" a PRU by enabling a PRU system event. Example: irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING, true); Signed-off-by: David Lechner Signed-off-by: Suman Anna Signed-off-by: Grzegorz Jaszczyk Reviewed-by: Lee Jones --- v2->v3: - Get rid of unnecessary pruss_intc_check_write() and use pruss_intc_write_reg directly. v1->v2: - https://patchwork.kernel.org/patch/11069769/ --- drivers/irqchip/irq-pruss-intc.c | 43 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) -- 2.7.4 diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index 49c936f..19b3d38 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -7,6 +7,7 @@ * Suman Anna */ +#include #include #include #include @@ -39,8 +40,7 @@ #define PRU_INTC_HIEISR 0x0034 #define PRU_INTC_HIDISR 0x0038 #define PRU_INTC_GPIR 0x0080 -#define PRU_INTC_SRSR0 0x0200 -#define PRU_INTC_SRSR1 0x0204 +#define PRU_INTC_SRSR(x) (0x0200 + (x) * 4) #define PRU_INTC_SECR0 0x0280 #define PRU_INTC_SECR1 0x0284 #define PRU_INTC_ESR0 0x0300 @@ -145,6 +145,43 @@ static void pruss_intc_irq_relres(struct irq_data *data) module_put(THIS_MODULE); } +static int pruss_intc_irq_get_irqchip_state(struct irq_data *data, + enum irqchip_irq_state which, + bool *state) +{ + struct pruss_intc *intc = irq_data_get_irq_chip_data(data); + u32 reg, mask, srsr; + + if (which != IRQCHIP_STATE_PENDING) + return -EINVAL; + + reg = PRU_INTC_SRSR(data->hwirq / 32); + mask = BIT(data->hwirq % 32); + + srsr = pruss_intc_read_reg(intc, reg); + + *state = !!(srsr & mask); + + return 0; +} + +static int pruss_intc_irq_set_irqchip_state(struct irq_data *data, + enum irqchip_irq_state which, + bool state) +{ + struct pruss_intc *intc = irq_data_get_irq_chip_data(data); + + if (which != IRQCHIP_STATE_PENDING) + return -EINVAL; + + if (state) + pruss_intc_write_reg(intc, PRU_INTC_SISR, data->hwirq); + else + pruss_intc_write_reg(intc, PRU_INTC_SICR, data->hwirq); + + return 0; +} + static struct irq_chip pruss_irqchip = { .name = "pruss-intc", .irq_ack = pruss_intc_irq_ack, @@ -152,6 +189,8 @@ static struct irq_chip pruss_irqchip = { .irq_unmask = pruss_intc_irq_unmask, .irq_request_resources = pruss_intc_irq_reqres, .irq_release_resources = pruss_intc_irq_relres, + .irq_get_irqchip_state = pruss_intc_irq_get_irqchip_state, + .irq_set_irqchip_state = pruss_intc_irq_set_irqchip_state, }; static int pruss_intc_irq_domain_map(struct irq_domain *d, unsigned int virq, From patchwork Thu Jul 2 14:17:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grzegorz Jaszczyk X-Patchwork-Id: 192242 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1489105ilg; Thu, 2 Jul 2020 07:20:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzEBJ7BLtCirOVZGXSN1hKywbJutzDuQoIADW1Pu13faRhTKfz46S+C79C4KnCIR8W9d4yn X-Received: by 2002:a17:906:6146:: with SMTP id p6mr22160499ejl.433.1593699616271; Thu, 02 Jul 2020 07:20:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593699616; cv=none; d=google.com; s=arc-20160816; b=baAJLsgreVi9TgjF73MKRvrgfzqYBbw1ktXLzWS7RM7xO5nUSwOGXiV9Yr2bq1VN0C CPy5GoyHshvQw50QLcdRZi6rY7n8LuE9PeDwT0s/gi1Tq+XJDf4TuFJw+G7lBmQBfIBv a23XmfKcTrHCx/xGDjvrQ7MWx1H1sUI28GHI5OTB5vtmRLsuh74ErqctdQM8eHMPZCJH KZcf5K9D9ZdEmU5HzwfkcxbGy30vooMdQ9ULYgzhBNwinkXmoTdxJECHQkwNavpn6J+0 gJ64yj4SlYZO7fqL7LUAOtngZJzBHf6nUYUj7+S9GmbHJDFlmS3nsbe699iIBeQEC//3 q/1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=DzB1zREDiJD3kRDNv1aKQ4AZAIoS6L96XnGWausRy9U=; b=OC8G+QcOP5bjgZcHId3EAkkhV9EMkJOftCGbPmdIkVDI9S83twe3CaW4asr2tEzNwy U/PHgz5kv5/N9KuqtZNhNoihM675rrC0/Qy/l71Ye/xPfov5BgyDtNmk+s8vexbWhMof NjEy0KEpYKsce5UOKXwhiDLcDOw9oTTchsmsePFvcHFUKemQ0dxgGQAUB9vvqaBl3xP4 23vpWEdLQcXxZl5MtQ7Z4YNpuvCZu7OJNl4GHep1QGjTPTecmi2eQ0KkGiXpe2BqF1ye pAj/pw040EjKQVtyxQyNATw4NYvXd2D+Wwpg2qFfhpFw2q9GvHKPG4G3lONEBW4yaaaY xbEQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bOopU77G; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l14si5930995edq.355.2020.07.02.07.20.15; Thu, 02 Jul 2020 07:20:16 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bOopU77G; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729784AbgGBOUO (ORCPT + 6 others); Thu, 2 Jul 2020 10:20:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729781AbgGBOUO (ORCPT ); Thu, 2 Jul 2020 10:20:14 -0400 Received: from mail-lj1-x243.google.com (mail-lj1-x243.google.com [IPv6:2a00:1450:4864:20::243]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA6B5C08C5DD for ; Thu, 2 Jul 2020 07:20:13 -0700 (PDT) Received: by mail-lj1-x243.google.com with SMTP id f8so20109679ljc.2 for ; Thu, 02 Jul 2020 07:20:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DzB1zREDiJD3kRDNv1aKQ4AZAIoS6L96XnGWausRy9U=; b=bOopU77GuBJI4E/MWaA5GBIZzUFDTcAmIShyeMPr17bNtJueltJS82Y8wQoBe1XYvs Lq6IV0JRm3aO27hvA+/mqU3Yi1tWzqa2sjiFsFAr4a4c9vf8IlTNg4OycxXFEHHv0exs nEbybCEWFc2gNKNrSCuOPeHXh9SDdh6l55d/zyCWxQosoSx2HNRo+FyJjVFWX/dl49l3 /DEysRFjUogt1WESd+4d38BnpY4tlYDwNJHj2oFFOnxbM0Sq9kRpeFwS3YxvJfCJeQVP 6M+8tao8C/JLVwp/9UjHu+uM+lz65LpvdYmnA0HfyhujBqy5LrpRocBy/U0Y20FFAMT+ 0gOg== 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; bh=DzB1zREDiJD3kRDNv1aKQ4AZAIoS6L96XnGWausRy9U=; b=eOCRgSstJStl+HrqKG7CALT4dAyjWR2BzFFhXvBJhWpTr7aGZBVWy5J5B5BY7aM0Z1 pnB24X4UexPAz3z5HWwUKfo3U6cN5y2kVVQt8isvkD7ik6dhCaT8OlMIrD2YBFDF95fM sRmofCQZpy5q4mLRzFdMTDN7RWt0nxlYwj0MlHa+dOKthFr4HmMz1BR0hg4VtqyAyvGq PZIrfAVhWJQxWIjTBGgmNik6gvB18gDz3DafgRdClOiKWNazgjd1vsCvUJM66peKJLdQ CfbU4JfzbGEuqStE306tYmf6eWYaMcthrJy8TbCQqcKp4LJsclm3KaXtGEvNYDehkOLy 0tEg== X-Gm-Message-State: AOAM530KDdsdKUP/eTbgWhXrE4gutYQ1habSANqGJmOEJsGda5QsybBQ dMxtEGObI+Hcb0oMdPhHCtB9r8zeiRLeZA== X-Received: by 2002:a2e:b5a8:: with SMTP id f8mr15678790ljn.247.1593699612111; Thu, 02 Jul 2020 07:20:12 -0700 (PDT) Received: from gilgamesh.semihalf.com (193-106-246-138.noc.fibertech.net.pl. [193.106.246.138]) by smtp.gmail.com with ESMTPSA id v10sm692581ljg.113.2020.07.02.07.20.10 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Jul 2020 07:20:11 -0700 (PDT) From: Grzegorz Jaszczyk To: tglx@linutronix.de, jason@lakedaemon.net, maz@kernel.org, s-anna@ti.com Cc: grzegorz.jaszczyk@linaro.org, robh+dt@kernel.org, lee.jones@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, david@lechnology.com, wmills@ti.com Subject: [PATCHv3 5/6] irqchip/irq-pruss-intc: Add support for ICSSG INTC on K3 SoCs Date: Thu, 2 Jul 2020 16:17:58 +0200 Message-Id: <1593699479-1445-6-git-send-email-grzegorz.jaszczyk@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> References: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Suman Anna The K3 AM65x and J721E SoCs have the next generation of the PRU-ICSS IP, commonly called ICSSG. The PRUSS INTC present within the ICSSG supports more System Events (160 vs 64), more Interrupt Channels and Host Interrupts (20 vs 10) compared to the previous generation PRUSS INTC instances. The first 2 and the last 10 of these host interrupt lines are used by the PRU and other auxiliary cores and sub-modules within the ICSSG, with 8 host interrupts connected to MPU. The host interrupts 5, 6, 7 are also connected to the other ICSSG instances within the SoC and can be partitioned as per system integration through the board dts files. Enhance the PRUSS INTC driver to add support for this ICSSG INTC instance. This support is added using specific compatible and match data and updating the code to use this data instead of the current hard-coded macros. The INTC config structure is updated to use the higher events and channels on all SoCs, while limiting the actual processing to only the relevant number of events/channels/interrupts. Signed-off-by: Suman Anna Signed-off-by: Grzegorz Jaszczyk --- v2->v3: - Change patch order: use it directly after "irqchip/irq-pruss-intc: Implement irq_{get,set}_irqchip_state ops" and before new "irqchip/irq-pruss-intc: Add event mapping support" in order to reduce diff. v1->v2: - https://patchwork.kernel.org/patch/11069773/ --- drivers/irqchip/Kconfig | 2 +- drivers/irqchip/irq-pruss-intc.c | 101 ++++++++++++++++++++++++++++----------- 2 files changed, 74 insertions(+), 29 deletions(-) -- 2.7.4 diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 733d7ec..9abee84 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -495,7 +495,7 @@ config TI_SCI_INTA_IRQCHIP config TI_PRUSS_INTC tristate "TI PRU-ICSS Interrupt Controller" - depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX || ARCH_KEYSTONE + depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX || ARCH_KEYSTONE || ARCH_K3 select IRQ_DOMAIN help This enables support for the PRU-ICSS Local Interrupt Controller diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index 19b3d38..362aa01 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -7,6 +7,7 @@ * Suman Anna */ +#include #include #include #include @@ -25,9 +26,6 @@ /* minimum starting host interrupt number for MPU */ #define MIN_PRU_HOST_INT 2 -/* maximum number of system events */ -#define MAX_PRU_SYS_EVENTS 64 - /* PRU_ICSS_INTC registers */ #define PRU_INTC_REVID 0x0000 #define PRU_INTC_CR 0x0004 @@ -41,30 +39,42 @@ #define PRU_INTC_HIDISR 0x0038 #define PRU_INTC_GPIR 0x0080 #define PRU_INTC_SRSR(x) (0x0200 + (x) * 4) -#define PRU_INTC_SECR0 0x0280 -#define PRU_INTC_SECR1 0x0284 -#define PRU_INTC_ESR0 0x0300 -#define PRU_INTC_ESR1 0x0304 -#define PRU_INTC_ECR0 0x0380 -#define PRU_INTC_ECR1 0x0384 +#define PRU_INTC_SECR(x) (0x0280 + (x) * 4) +#define PRU_INTC_ESR(x) (0x0300 + (x) * 4) +#define PRU_INTC_ECR(x) (0x0380 + (x) * 4) #define PRU_INTC_CMR(x) (0x0400 + (x) * 4) #define PRU_INTC_HMR(x) (0x0800 + (x) * 4) #define PRU_INTC_HIPIR(x) (0x0900 + (x) * 4) -#define PRU_INTC_SIPR0 0x0d00 -#define PRU_INTC_SIPR1 0x0d04 -#define PRU_INTC_SITR0 0x0d80 -#define PRU_INTC_SITR1 0x0d84 +#define PRU_INTC_SIPR(x) (0x0d00 + (x) * 4) +#define PRU_INTC_SITR(x) (0x0d80 + (x) * 4) #define PRU_INTC_HINLR(x) (0x1100 + (x) * 4) #define PRU_INTC_HIER 0x1500 +/* CMR register bit-field macros */ +#define CMR_EVT_PER_REG 4 + +/* HMR register bit-field macros */ +#define HMR_CH_PER_REG 4 + /* HIPIR register bit-fields */ #define INTC_HIPIR_NONE_HINT 0x80000000 /** + * struct pruss_intc_match_data - match data to handle SoC variations + * @num_system_events: number of input system events handled by the PRUSS INTC + * @num_host_intrs: number of host interrupts supported by the PRUSS INTC + */ +struct pruss_intc_match_data { + u8 num_system_events; + u8 num_host_intrs; +}; + +/** * struct pruss_intc - PRUSS interrupt controller structure * @irqs: kernel irq numbers corresponding to PRUSS host interrupts * @base: base virtual address of INTC register space * @domain: irq domain for this interrupt controller + * @soc_config: cached PRUSS INTC IP configuration data * @shared_intr: bit-map denoting if the MPU host interrupt is shared * @invalid_intr: bit-map denoting if host interrupt is not connected to MPU */ @@ -72,6 +82,7 @@ struct pruss_intc { unsigned int irqs[MAX_NUM_HOST_IRQS]; void __iomem *base; struct irq_domain *domain; + const struct pruss_intc_match_data *soc_config; u16 shared_intr; u16 invalid_intr; }; @@ -89,22 +100,30 @@ static inline void pruss_intc_write_reg(struct pruss_intc *intc, static void pruss_intc_init(struct pruss_intc *intc) { + const struct pruss_intc_match_data *soc_config = intc->soc_config; int i; + int num_chnl_map_regs = DIV_ROUND_UP(soc_config->num_system_events, + CMR_EVT_PER_REG); + int num_host_intr_regs = DIV_ROUND_UP(soc_config->num_host_intrs, + HMR_CH_PER_REG); + int num_event_type_regs = + DIV_ROUND_UP(soc_config->num_system_events, 32); - /* configure polarity to active high for all system interrupts */ - pruss_intc_write_reg(intc, PRU_INTC_SIPR0, 0xffffffff); - pruss_intc_write_reg(intc, PRU_INTC_SIPR1, 0xffffffff); - - /* configure type to pulse interrupt for all system interrupts */ - pruss_intc_write_reg(intc, PRU_INTC_SITR0, 0); - pruss_intc_write_reg(intc, PRU_INTC_SITR1, 0); + /* + * configure polarity (SIPR register) to active high and + * type (SITR register) to pulse interrupt for all system events + */ + for (i = 0; i < num_event_type_regs; i++) { + pruss_intc_write_reg(intc, PRU_INTC_SIPR(i), 0xffffffff); + pruss_intc_write_reg(intc, PRU_INTC_SITR(i), 0); + } - /* clear all 16 interrupt channel map registers */ - for (i = 0; i < 16; i++) + /* clear all interrupt channel map registers, 4 events per register */ + for (i = 0; i < num_chnl_map_regs; i++) pruss_intc_write_reg(intc, PRU_INTC_CMR(i), 0); - /* clear all 3 host interrupt map registers */ - for (i = 0; i < 3; i++) + /* clear all host interrupt map registers, 4 channels per register */ + for (i = 0; i < num_host_intr_regs; i++) pruss_intc_write_reg(intc, PRU_INTC_HMR(i), 0); } @@ -266,11 +285,20 @@ static int pruss_intc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct pruss_intc *intc; int i, irq, count; + const struct pruss_intc_match_data *data; u8 temp_intr[MAX_NUM_HOST_IRQS] = { 0 }; + u8 max_system_events; + + data = of_device_get_match_data(dev); + if (!data) + return -ENODEV; + + max_system_events = data->num_system_events; intc = devm_kzalloc(dev, sizeof(*intc), GFP_KERNEL); if (!intc) return -ENOMEM; + intc->soc_config = data; platform_set_drvdata(pdev, intc); intc->base = devm_platform_ioremap_resource(pdev, 0); @@ -327,8 +355,7 @@ static int pruss_intc_probe(struct platform_device *pdev) pruss_intc_init(intc); - /* always 64 events */ - intc->domain = irq_domain_add_linear(dev->of_node, MAX_PRU_SYS_EVENTS, + intc->domain = irq_domain_add_linear(dev->of_node, max_system_events, &pruss_intc_irq_domain_ops, intc); if (!intc->domain) return -ENOMEM; @@ -369,6 +396,7 @@ static int pruss_intc_probe(struct platform_device *pdev) static int pruss_intc_remove(struct platform_device *pdev) { struct pruss_intc *intc = platform_get_drvdata(pdev); + u8 max_system_events = intc->soc_config->num_system_events; unsigned int hwirq; int i; @@ -378,7 +406,7 @@ static int pruss_intc_remove(struct platform_device *pdev) NULL); } - for (hwirq = 0; hwirq < MAX_PRU_SYS_EVENTS; hwirq++) + for (hwirq = 0; hwirq < max_system_events; hwirq++) irq_dispose_mapping(irq_find_mapping(intc->domain, hwirq)); irq_domain_remove(intc->domain); @@ -386,8 +414,25 @@ static int pruss_intc_remove(struct platform_device *pdev) return 0; } +static const struct pruss_intc_match_data pruss_intc_data = { + .num_system_events = 64, + .num_host_intrs = 10, +}; + +static const struct pruss_intc_match_data icssg_intc_data = { + .num_system_events = 160, + .num_host_intrs = 20, +}; + static const struct of_device_id pruss_intc_of_match[] = { - { .compatible = "ti,pruss-intc", }, + { + .compatible = "ti,pruss-intc", + .data = &pruss_intc_data, + }, + { + .compatible = "ti,icssg-intc", + .data = &icssg_intc_data, + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, pruss_intc_of_match); From patchwork Thu Jul 2 14:17:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grzegorz Jaszczyk X-Patchwork-Id: 192243 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1489191ilg; Thu, 2 Jul 2020 07:20:24 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwMv06+j0cd0wVvDBHzkCI81vu/fLJ/xLv/Aw7HH4nW9LW8lIwz4ePplE6W2cBBoE01WmXq X-Received: by 2002:aa7:da46:: with SMTP id w6mr24105029eds.261.1593699623886; Thu, 02 Jul 2020 07:20:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593699623; cv=none; d=google.com; s=arc-20160816; b=MGH53CDKn5eiJAjXqcONahtRqjGOaNc7tSmhwlmtlGMOqMBQL0a2IEagE4eLB+IHm+ oVyFhcB4fp0Z5XkP3StXyZT5c8ydhtzCj0HJGiD/gb3UiIS7f4TO9OpbsWJQ9puVAqOK vVhka7hkt3Ddbj5wMbpPp31cJYnCjuuCreWii36ZjoPXO1j/lSUTMO3/S/rVKmOdxW2w AF5CGkCjSZgoXkQk7SsUDVGftLYI9yjQld/ihhwL4bRbwu/cI2vmrj7E8gdJlj0f3q2m 6FE9RbtkD/WaFy6I3+vMrcJpid68E1fS94RftuGys/bU39hP6EYySu3vqu+aXBuIRV7j ldmQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=/g1pL3/hSl0fTsy5dL717qIUgAnsVErwAcv2lpeHoaY=; b=uroVFPhvnr3CFm8KUsimvpSxIANZWRdRe0AFErxM+7VK4rNSj54Oby7q3EmrCJFqoE mvp7N0lGI3soxVgVAY8QqWpCbDKA1/iFgankXrWFemL976Go7S7/NQUeo0DWnJ6F8p1s 9nVBcZnMFUHggywuG9jWvDrAzMY1J9Zj/Di9/yetdtgNzvjLyCEAcLTxAhUCiWJxGJg7 xoeRJfHZmun0AUBzeSC1J4imJVidT5YmfHFALXZj0zKcIWrYaFd7D6iN7t+FMV3L+/Po CJ9wPW4Fpl9XNFnlYTFhROthWeQ74gaxVNbRvqoF7gwf8Hcnz3epRH7Re/DmEowjFoPi O9Rw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OPuK0bs8; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bu5si5831808edb.553.2020.07.02.07.20.23; Thu, 02 Jul 2020 07:20:23 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OPuK0bs8; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729805AbgGBOUS (ORCPT + 6 others); Thu, 2 Jul 2020 10:20:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729793AbgGBOUQ (ORCPT ); Thu, 2 Jul 2020 10:20:16 -0400 Received: from mail-lj1-x241.google.com (mail-lj1-x241.google.com [IPv6:2a00:1450:4864:20::241]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B558C08C5C1 for ; Thu, 2 Jul 2020 07:20:16 -0700 (PDT) Received: by mail-lj1-x241.google.com with SMTP id h22so25221848lji.9 for ; Thu, 02 Jul 2020 07:20:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/g1pL3/hSl0fTsy5dL717qIUgAnsVErwAcv2lpeHoaY=; b=OPuK0bs8473Rb8SzUxiI+RRd1mfxCrbbfDTMSxXud0kgnBLJvxe8UrPa/Gy7Rsf914 eG8NvZ5JaT8lKCZYSqk5I8uOrTtFl3DZsPDn1TmiCIWS2YnLwsIU3HQ0E5mpavgpZDjK H8jCw2W4zVXpZFNjIcQ48esa2f5BQVrbAvQReZk/R/yZsKWiG+7Cb0sc6mkgFC4M7xP3 H7jwG7B91xcJuwxQ+/1/eAbJY02ioZ0/q35OAx+3ErCdjiMWv9LD4NfPl2OpU4ZHSodI 3y65FP42qQmy0oL8d1iREkcvNDo/3weTm4BTCyZHQKgrZQFA6OL+0wR+cV3Z+ZQAFHBt 4F5Q== 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; bh=/g1pL3/hSl0fTsy5dL717qIUgAnsVErwAcv2lpeHoaY=; b=pgeC/EIv75QWrynmkxWDh9HW4Urlmhu9dlet8rB8WeKkDb52ZTLVAkpxXEGDcJfk/q jOVG9mC3pCdiJ1fXREfzEd0e5Up5ZJ2HA4o4+zQH1vbeyHN+EXFPCNHW82J72hay0mar jmoES1gKe9UlRFGHJ8ZuAO04u3bgQFqemdzi1XEnQ9JXM3Rp8Xb+zCmiexGEjnMRoIgW eaBtkY6YYmR8Xyu1m5Ei+rHwHqOb26ucr2XsQ+hJyP2scxjm4cuWSdApijPkM1dC3KZs T2BktpluCO7+DzUrI3CW6WMK01ILPvoampG/wLjXRBfrt/rjTQqVv3YasTNY2ivLYDC+ Hbug== X-Gm-Message-State: AOAM531C+hQ2+T4Sa7Vlr1AdngjttGvFsVNK/Pi4VShRvu9zrv+s+jVL /NIiQrpsV3zvRR/+Phh4HXsFZQ== X-Received: by 2002:a2e:9ed0:: with SMTP id h16mr17588908ljk.366.1593699614324; Thu, 02 Jul 2020 07:20:14 -0700 (PDT) Received: from gilgamesh.semihalf.com (193-106-246-138.noc.fibertech.net.pl. [193.106.246.138]) by smtp.gmail.com with ESMTPSA id v10sm692581ljg.113.2020.07.02.07.20.13 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Jul 2020 07:20:13 -0700 (PDT) From: Grzegorz Jaszczyk To: tglx@linutronix.de, jason@lakedaemon.net, maz@kernel.org, s-anna@ti.com Cc: grzegorz.jaszczyk@linaro.org, robh+dt@kernel.org, lee.jones@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, david@lechnology.com, wmills@ti.com Subject: [PATCHv3 6/6] irqchip/irq-pruss-intc: Add event mapping support Date: Thu, 2 Jul 2020 16:17:59 +0200 Message-Id: <1593699479-1445-7-git-send-email-grzegorz.jaszczyk@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> References: <1593699479-1445-1-git-send-email-grzegorz.jaszczyk@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The PRUSS INTC receives a number of system input interrupt source events and supports individual control configuration and hardware prioritization. These input events can be mapped to some output host interrupts through 2 levels of many-to-one mapping i.e. events to channel mapping and channels to host interrupts. This mapping information is provided through the PRU firmware that is loaded onto a PRU core/s or through the device tree node of the PRU application. The mapping configuration is triggered by the PRU remoteproc driver, and is setup before the PRU core is started and cleaned up after the PRU core is stopped. This event mapping configuration logic programs the Channel Map Registers (CMRx) and Host-Interrupt Map Registers (HMRx) only when a new program is being loaded/started and the same events and interrupt channels are reset to zero when stopping a PRU. Reference counting is used to allow multiple system events to share a single channel and to allow multiple channels to share a single host event. The remoteproc driver can register mappings read from a firmware blob as shown below. struct irq_fwspec fwspec; int irq; fwspec.fwnode = of_node_to_fwnode(dev->of_node); fwspec.param_count = 3; fwspec.param[0] = 63; // system event fwspec.param[1] = 5; // channel fwspec.param[2] = 6; // host event irq = irq_create_fwspec_mapping(&fwspec); if (irq < 0) { dev_err(dev, "failed to get irq\n"); return irq; } Suggested-by: David Lechner Signed-off-by: Suman Anna Signed-off-by: Grzegorz Jaszczyk --- v3: - This patch replaces https://patchwork.kernel.org/patch/11069753/ according to received feedback. Instead of exporting custom functions from interrupt driver, the xlate and irq domain map is used for interrupt parsing and mapping. --- drivers/irqchip/irq-pruss-intc.c | 265 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 264 insertions(+), 1 deletion(-) -- 2.7.4 diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index 362aa01..cf40a97 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -51,14 +51,42 @@ #define PRU_INTC_HIER 0x1500 /* CMR register bit-field macros */ +#define CMR_EVT_MAP_MASK 0xf +#define CMR_EVT_MAP_BITS 8 #define CMR_EVT_PER_REG 4 /* HMR register bit-field macros */ +#define HMR_CH_MAP_MASK 0xf +#define HMR_CH_MAP_BITS 8 #define HMR_CH_PER_REG 4 /* HIPIR register bit-fields */ #define INTC_HIPIR_NONE_HINT 0x80000000 +#define MAX_PRU_SYS_EVENTS 160 +#define MAX_PRU_CHANNELS 20 + +/** + * struct pruss_intc_hwirq_data - additional metadata associated with a PRU + * system event + * @channel: The PRU INTC channel that the system event should be mapped to + * @host: The PRU INTC host that the channel should be mapped to + */ +struct pruss_intc_hwirq_data { + u8 channel; + u8 host; +}; + +/** + * struct pruss_intc_map_record - keeps track of actual mapping state + * @value: The currently mapped value (channel or host) + * @ref_count: Keeps track of number of current users of this resource + */ +struct pruss_intc_map_record { + u8 value; + u8 ref_count; +}; + /** * struct pruss_intc_match_data - match data to handle SoC variations * @num_system_events: number of input system events handled by the PRUSS INTC @@ -71,18 +99,29 @@ struct pruss_intc_match_data { /** * struct pruss_intc - PRUSS interrupt controller structure + * @hwirq_data: table of additional mapping data received from device tree + * or PRU firmware + * @event_channel: current state of system event to channel mappings + * @channel_host: current state of channel to host mappings * @irqs: kernel irq numbers corresponding to PRUSS host interrupts * @base: base virtual address of INTC register space * @domain: irq domain for this interrupt controller * @soc_config: cached PRUSS INTC IP configuration data + * @lock: mutex to serialize access to INTC + * @dev: PRUSS INTC device pointer * @shared_intr: bit-map denoting if the MPU host interrupt is shared * @invalid_intr: bit-map denoting if host interrupt is not connected to MPU */ struct pruss_intc { + struct pruss_intc_hwirq_data hwirq_data[MAX_PRU_SYS_EVENTS]; + struct pruss_intc_map_record event_channel[MAX_PRU_SYS_EVENTS]; + struct pruss_intc_map_record channel_host[MAX_PRU_CHANNELS]; unsigned int irqs[MAX_NUM_HOST_IRQS]; void __iomem *base; struct irq_domain *domain; const struct pruss_intc_match_data *soc_config; + struct mutex lock; /* PRUSS INTC lock */ + struct device *dev; u16 shared_intr; u16 invalid_intr; }; @@ -98,6 +137,165 @@ static inline void pruss_intc_write_reg(struct pruss_intc *intc, writel_relaxed(val, intc->base + reg); } +static void pruss_intc_update_cmr(struct pruss_intc *intc, int evt, s8 ch) +{ + u32 idx, offset, val; + + idx = evt / CMR_EVT_PER_REG; + offset = (evt % CMR_EVT_PER_REG) * CMR_EVT_MAP_BITS; + + val = pruss_intc_read_reg(intc, PRU_INTC_CMR(idx)); + val &= ~(CMR_EVT_MAP_MASK << offset); + val |= ch << offset; + pruss_intc_write_reg(intc, PRU_INTC_CMR(idx), val); + + dev_dbg(intc->dev, "SYSEV%u -> CH%d (CMR%d 0x%08x)\n", evt, ch, + idx, pruss_intc_read_reg(intc, PRU_INTC_CMR(idx))); +} + +static void pruss_intc_update_hmr(struct pruss_intc *intc, int ch, s8 host) +{ + u32 idx, offset, val; + + idx = ch / HMR_CH_PER_REG; + offset = (ch % HMR_CH_PER_REG) * HMR_CH_MAP_BITS; + + val = pruss_intc_read_reg(intc, PRU_INTC_HMR(idx)); + val &= ~(HMR_CH_MAP_MASK << offset); + val |= host << offset; + pruss_intc_write_reg(intc, PRU_INTC_HMR(idx), val); + + dev_dbg(intc->dev, "CH%d -> HOST%d (HMR%d 0x%08x)\n", ch, host, idx, + pruss_intc_read_reg(intc, PRU_INTC_HMR(idx))); +} + +/** + * pruss_intc_map() - configure the PRUSS INTC + * @intc: PRUSS interrupt controller pointer + * @hwirq: the system event number + * + * Configures the PRUSS INTC with the provided configuration from the one + * parsed in the xlate function. Any existing event to channel mappings or + * channel to host interrupt mappings are checked to make sure there are no + * conflicting configuration between both the PRU cores. + * + * Returns 0 on success, or a suitable error code otherwise + */ +static int pruss_intc_map(struct pruss_intc *intc, unsigned long hwirq) +{ + struct device *dev = intc->dev; + int ret = 0; + u8 ch, host, reg_idx; + u32 val; + + if (hwirq >= intc->soc_config->num_system_events) + return -EINVAL; + + mutex_lock(&intc->lock); + + ch = intc->hwirq_data[hwirq].channel; + host = intc->hwirq_data[hwirq].host; + + /* check if sysevent already assigned */ + if (intc->event_channel[hwirq].ref_count > 0 && + intc->event_channel[hwirq].value != ch) { + dev_err(dev, "event %lu (req. channel %d) already assigned to channel %d\n", + hwirq, ch, intc->event_channel[hwirq].value); + ret = -EBUSY; + goto unlock; + } + + /* check if channel already assigned */ + if (intc->channel_host[ch].ref_count > 0 && + intc->channel_host[ch].value != host) { + dev_err(dev, "channel %d (req. host %d) already assigned to host %d\n", + ch, host, intc->channel_host[ch].value); + ret = -EBUSY; + goto unlock; + } + + if (++intc->event_channel[hwirq].ref_count == 1) { + intc->event_channel[hwirq].value = ch; + + pruss_intc_update_cmr(intc, hwirq, ch); + + reg_idx = hwirq / 32; + val = BIT(hwirq % 32); + + /* clear and enable system event */ + pruss_intc_write_reg(intc, PRU_INTC_ESR(reg_idx), val); + pruss_intc_write_reg(intc, PRU_INTC_SECR(reg_idx), val); + } + + if (++intc->channel_host[ch].ref_count == 1) { + intc->channel_host[ch].value = host; + + pruss_intc_update_hmr(intc, ch, host); + + /* enable host interrupts */ + pruss_intc_write_reg(intc, PRU_INTC_HIEISR, host); + } + + dev_dbg(dev, "mapped system_event = %lu channel = %d host = %d", + hwirq, ch, host); + + /* global interrupt enable */ + pruss_intc_write_reg(intc, PRU_INTC_GER, 1); + +unlock: + mutex_unlock(&intc->lock); + return ret; +} + +/** + * pruss_intc_unmap() - unconfigure the PRUSS INTC + * @intc: PRUSS interrupt controller pointer + * @hwirq: the system event number + * + * Undo whatever was done in pruss_intc_map() for a PRU core. + * Mappings are reference counted, so resources are only disabled when there + * are no longer any users. + */ +static void pruss_intc_unmap(struct pruss_intc *intc, unsigned long hwirq) +{ + u8 ch, host, reg_idx; + u32 val; + + if (hwirq >= intc->soc_config->num_system_events) + return; + + mutex_lock(&intc->lock); + + ch = intc->event_channel[hwirq].value; + host = intc->channel_host[ch].value; + + if (--intc->channel_host[ch].ref_count == 0) { + /* disable host interrupts */ + pruss_intc_write_reg(intc, PRU_INTC_HIDISR, host); + + /* clear the map using reset value 0 */ + pruss_intc_update_hmr(intc, ch, 0); + } + + if (--intc->event_channel[hwirq].ref_count == 0) { + reg_idx = hwirq / 32; + val = BIT(hwirq % 32); + + /* disable system events */ + pruss_intc_write_reg(intc, PRU_INTC_ECR(reg_idx), val); + /* clear any pending status */ + pruss_intc_write_reg(intc, PRU_INTC_SECR(reg_idx), val); + + /* clear the map using reset value 0 */ + pruss_intc_update_cmr(intc, hwirq, 0); + } + + dev_dbg(intc->dev, "unmapped system_event = %lu channel = %d host = %d\n", + hwirq, ch, host); + + mutex_unlock(&intc->lock); +} + static void pruss_intc_init(struct pruss_intc *intc) { const struct pruss_intc_match_data *soc_config = intc->soc_config; @@ -212,10 +410,67 @@ static struct irq_chip pruss_irqchip = { .irq_set_irqchip_state = pruss_intc_irq_set_irqchip_state, }; +static int +pruss_intc_irq_domain_xlate(struct irq_domain *d, struct device_node *node, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type) +{ + struct pruss_intc *intc = d->host_data; + struct device *dev = intc->dev; + int sys_event, channel, host; + + if (intsize == 1) { + /* + * In case of short version (intsize == 1) verify if sysevent + * already mapped to channel/host irq if not return error + */ + sys_event = intspec[0]; + if (intc->event_channel[sys_event].ref_count) + goto already_mapped; + else + return -EINVAL; + } + + if (intsize < 3) + return -EINVAL; + + sys_event = intspec[0]; + if (sys_event < 0 || sys_event >= intc->soc_config->num_system_events) { + dev_err(dev, "not valid event number\n"); + return -EINVAL; + } + + channel = intspec[1]; + if (channel < 0 || channel >= intc->soc_config->num_host_intrs) { + dev_err(dev, "not valid channel number"); + return -EINVAL; + } + + host = intspec[2]; + if (host < 0 || host >= intc->soc_config->num_host_intrs) { + dev_err(dev, "not valid host irq number\n"); + return -EINVAL; + } + + intc->hwirq_data[sys_event].channel = channel; + intc->hwirq_data[sys_event].host = host; + +already_mapped: + *out_hwirq = sys_event; + *out_type = IRQ_TYPE_NONE; + + return 0; +} + static int pruss_intc_irq_domain_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw) { struct pruss_intc *intc = d->host_data; + int err; + + err = pruss_intc_map(intc, hw); + if (err < 0) + return err; irq_set_chip_data(virq, intc); irq_set_chip_and_handler(virq, &pruss_irqchip, handle_level_irq); @@ -225,12 +480,16 @@ static int pruss_intc_irq_domain_map(struct irq_domain *d, unsigned int virq, static void pruss_intc_irq_domain_unmap(struct irq_domain *d, unsigned int virq) { + struct pruss_intc *intc = d->host_data; + unsigned long hwirq = irqd_to_hwirq(irq_get_irq_data(virq)); + irq_set_chip_and_handler(virq, NULL, NULL); irq_set_chip_data(virq, NULL); + pruss_intc_unmap(intc, hwirq); } static const struct irq_domain_ops pruss_intc_irq_domain_ops = { - .xlate = irq_domain_xlate_onecell, + .xlate = pruss_intc_irq_domain_xlate, .map = pruss_intc_irq_domain_map, .unmap = pruss_intc_irq_domain_unmap, }; @@ -298,6 +557,8 @@ static int pruss_intc_probe(struct platform_device *pdev) intc = devm_kzalloc(dev, sizeof(*intc), GFP_KERNEL); if (!intc) return -ENOMEM; + + intc->dev = dev; intc->soc_config = data; platform_set_drvdata(pdev, intc); @@ -355,6 +616,8 @@ static int pruss_intc_probe(struct platform_device *pdev) pruss_intc_init(intc); + mutex_init(&intc->lock); + intc->domain = irq_domain_add_linear(dev->of_node, max_system_events, &pruss_intc_irq_domain_ops, intc); if (!intc->domain)