From patchwork Mon Jul 8 03:52:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suman Anna X-Patchwork-Id: 168600 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp6586348ilk; Sun, 7 Jul 2019 20:54:07 -0700 (PDT) X-Google-Smtp-Source: APXvYqzBK9CvaB/NYGwJnRHsPpTdixCc/QQIupbJfM8FjsDgYGCPDJeb+zPaIxkNFDS9/ZRXuKAZ X-Received: by 2002:a63:d210:: with SMTP id a16mr20284891pgg.77.1562558047135; Sun, 07 Jul 2019 20:54:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562558047; cv=none; d=google.com; s=arc-20160816; b=OAbRcEm6YSCCZabtA5xW/NdGa6Dw7nS7/COvtgD66MqK4DAn/c2KnrxRZnjoDB79xj 5KvmJEOzpLSHz2DerRrKo7zCsk5q59ZoiIwnIFtLPRDrmJYD/VZrxdGn8d4MiDa4LCam PWCfPOu4o4lP8PCwKAuWZSlOePaEVv9c2kka+4myQan7nl33F6sO7J9unXA0EyXVTmGq r/R4S0F1xVgy52oEDyRxunLxdimre6ErhPjPDYwpC/8OV8FWRT+Os2+XAJr7d6E4kFa6 4rmNZyV950tqdpLZ/6Glc+j8XuR18T3aaaKmS+mvNsYtikDObri22wbeJNkJAMN1TE8f PoRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=EcFLJFC2+wvayMjqstbhNZltmYBb5S5lX7Fn2k8pbl0=; b=c7CoMvJLvYlDH+Vp8ygx3rW/DXuyN8uoiK0fZmxtxfKIVqNWw0iL8aNorbeK3ZTSvD ZGz+TJf32GA0fds8t41sAdMUFDSCE1lN6cyM57MgXmcct8+ouuVjgcrzzERkm3YqKcPI 39L2Hs8IOv/cqa2eF3UU9VCeeZ+RlE48NhTtxDWVav/tB0YkRjD1K+YfFBKDzuqN7GJZ 1xart2R6w4NxVAhHTfZKuHxzu90p5MVAGIna32vYckq08k/J/6tN6iGpPEiRXgm8mYUq +163gnLEnIOGZdweT1X4tA8TePWdPpDKvv20Iz4gt9ITWBeW/vh86sruVGRHFon32mjQ jlTA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b="mTMxLCa/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y20si16482591plp.335.2019.07.07.20.54.06; Sun, 07 Jul 2019 20:54:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b="mTMxLCa/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729008AbfGHDyF (ORCPT + 30 others); Sun, 7 Jul 2019 23:54:05 -0400 Received: from fllv0015.ext.ti.com ([198.47.19.141]:39818 "EHLO fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728958AbfGHDx7 (ORCPT ); Sun, 7 Jul 2019 23:53:59 -0400 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id x683qkKH073380; Sun, 7 Jul 2019 22:52:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1562557966; bh=EcFLJFC2+wvayMjqstbhNZltmYBb5S5lX7Fn2k8pbl0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=mTMxLCa/fwW2j/kg1ssLNIzmpF7ibPiqLDHvf4TWz8rRFUGFABerB8tIfkNEWbCx3 D11kqcIy0uucnGLzcW8O7/at4tj5/xinfYjz7hv9Qc/GjhhHv9Y33Bi6vGtK6rvhuV UXkyTwvcD+1qWUV/HaIFOZStDT7xOFW/Pn7R/P+E= Received: from DFLE115.ent.ti.com (dfle115.ent.ti.com [10.64.6.36]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x683qkfh016576 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Sun, 7 Jul 2019 22:52:46 -0500 Received: from DFLE109.ent.ti.com (10.64.6.30) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Sun, 7 Jul 2019 22:52:45 -0500 Received: from fllv0040.itg.ti.com (10.64.41.20) by DFLE109.ent.ti.com (10.64.6.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Sun, 7 Jul 2019 22:52:45 -0500 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by fllv0040.itg.ti.com (8.15.2/8.15.2) with ESMTP id x683qjDX026300; Sun, 7 Jul 2019 22:52:45 -0500 Received: from localhost (irmo.dhcp.ti.com [128.247.58.153]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id x683qjm26433; Sun, 7 Jul 2019 22:52:45 -0500 (CDT) From: Suman Anna To: Marc Zyngier , Rob Herring , Thomas Gleixner , Jason Cooper CC: Tony Lindgren , "Andrew F. Davis" , Roger Quadros , Lokesh Vutla , Grygorii Strashko , Sekhar Nori , David Lechner , Murali Karicheri , , , , , Suman Anna Subject: [PATCH 1/6] dt-bindings: irqchip: Add PRUSS interrupt controller bindings Date: Sun, 7 Jul 2019 22:52:38 -0500 Message-ID: <20190708035243.12170-2-s-anna@ti.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190708035243.12170-1-s-anna@ti.com> References: <20190708035243.12170-1-s-anna@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The Programmable Real-Time Unit Subsystem (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 hardware prioritization. These events are mapped onto 10 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 --- Prior version: https://patchwork.kernel.org/patch/10795771/ .../interrupt-controller/ti,pruss-intc.txt | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.txt -- 2.22.0 diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.txt new file mode 100644 index 000000000000..020073c07a92 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.txt @@ -0,0 +1,92 @@ +PRU ICSS INTC on TI SoCs +======================== + +Each PRUSS has a single interrupt controller instance that is common to both +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 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 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". +Please see the overall PRUSS bindings document for additional details +including a complete example, + Documentation/devicetree/bindings/soc/ti/ti,pruss.txt + +Required Properties: +-------------------- +- compatible : should be one of the following, + "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 + "ti,icssg-intc" for K3 AM65x & J721E family of SoCs +- reg : base address and size for the PRUSS INTC sub-module +- interrupts : 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 GIC + parent interrupt controller. A shared interrupt can + be skipped if the desired destination and usage is by + a different processor/device. +- interrupt-names : should use one of the following names for each valid + interrupt connected to ARM GIC, the name should match + the corresponding host interrupt number, + "host0", "host1", "host2", "host3", "host4", + "host5", "host6" or "host7" +- interrupt-controller : mark this node as an interrupt controller +- #interrupt-cells : should be 1. 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 + +Optional Properties: +-------------------- +The following properties are _required_ only for some SoCs. If none of the below +properties are defined, it implies that all the host interrupts 2 through 9 are +connected exclusively to the ARM GIC. + +- ti,irqs-reserved : 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 GIC. + Eg: AM437x and 66AK2G SoCs do not have "host5" + interrupt connected to MPU +- ti,irqs-shared : 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 "host5", "host6" and + "host7" interrupts connected to MPU, and other + ICSSG instances + + +Example: +-------- + +1. /* AM33xx PRU-ICSS */ + pruss: pruss@0 { + compatible = "ti,am3356-pruss"; + reg = <0x0 0x80000>; + #address-cells = <1>; + #size-cells = <1>; + ... + + pruss_intc: interrupt-controller@20000 { + compatible = "ti,pruss-intc"; + reg = <0x20000 0x2000>; + interrupts = <20 21 22 23 24 25 26 27>; + interrupt-names = "host0", "host1", "host2", + "host3", "host4", "host5", + "host6", "host7"; + interrupt-controller; + #interrupt-cells = <1>; + ti,irqs-shared = /bits/ 8 <0 6 7>; + }; + }; From patchwork Mon Jul 8 03:52:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suman Anna X-Patchwork-Id: 168602 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp6586569ilk; Sun, 7 Jul 2019 20:54:21 -0700 (PDT) X-Google-Smtp-Source: APXvYqwMe574u6cKbHWv8KXlfAFwvR1hY0Ess4bmOqE1BCELTCHPytUgFJwb0YE7qE9gPaDEO6L4 X-Received: by 2002:a17:90a:d817:: with SMTP id a23mr21997955pjv.54.1562558061243; Sun, 07 Jul 2019 20:54:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562558061; cv=none; d=google.com; s=arc-20160816; b=aOigYzMSiT+dg9/jOrkw4ZCb2Hw7q7u18kPxn+zpLlym2e2nDhfb0+dW27waRdJP8h fufShEOZdnglTe4It+P4hap8wOAygj2aXoNuz2pWEmWFprDaAdw5qtoLteueGNgrpQ7c jmxdrPCwRCjgR1oGw6t4LT8N5fTRisltJYazb1JYeyez9B33zF87wX3WvKZNBDRv8PuJ LwH2pno+oBUwv6d24wSnSbbdiajKqashZhnDmQs8WQ1TzgTuG+rDeBId6grY2EKcqwqa tUZjdrk8TyKy+T20MT/6J1O2VtzM2MP8ixEJJbPWpp3pY0cdMVntJPP7pElMRSaOKDnV oHfg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=0frDprr6mFGJ9Tw1xlMqTJaMNs6+o4FICJuO/EOBWdw=; b=0Cu3K3sRjEexE5R5pAsfM2/Wz/rinJ8GQOp7dZ3WD3g1R4AeUBY/YFLWguFI+80Yx4 g4O97385Eo+LfkqXibXUSVXKRzQxkXQrL7+7oqNVOuHvVAJD2JxMh9894sevPla57Z7a VuA4gsqDmP2hPpn2xpd2I09tyMoXxX/Utdk/dy7BEgCMC3OoPVkBsbpdWKprq48zJRJ/ TnQJCYVXLn0hRcmbf6F2tAJdBIwQWZIxmWkNCx2UNa3L6+/FKbO9328duo0Js4jL+rWg LN/RMKGOBVsLAUau8wh48vD1bIqFnNt1VxWkdjctt3MSEaRUjpgti3sXUvi7EG3DI2Tg 1brA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=tgmTgs+0; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bh2si16122377plb.116.2019.07.07.20.54.20; Sun, 07 Jul 2019 20:54:21 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=tgmTgs+0; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729021AbfGHDyT (ORCPT + 30 others); Sun, 7 Jul 2019 23:54:19 -0400 Received: from fllv0016.ext.ti.com ([198.47.19.142]:46572 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727778AbfGHDxz (ORCPT ); Sun, 7 Jul 2019 23:53:55 -0400 Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id x683qkYZ017977; Sun, 7 Jul 2019 22:52:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1562557966; bh=0frDprr6mFGJ9Tw1xlMqTJaMNs6+o4FICJuO/EOBWdw=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=tgmTgs+0SqkD0J3qGeKuaLLvWVdbWmhaZiIeHqry6h06CVk/w7Q5cPQvBv4b5HWiM 003P6SR1tX5rnVdYkkln8A07jlQ/qoCBm6X0LM5xRibaMHZjQFKEIOw5BOsL0+6tfR fwushiGxyFlOYUNEDqQZ+GBVv6CQVK0spATHqsPk= Received: from DLEE115.ent.ti.com (dlee115.ent.ti.com [157.170.170.26]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x683qkMW102647 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Sun, 7 Jul 2019 22:52:46 -0500 Received: from DLEE106.ent.ti.com (157.170.170.36) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Sun, 7 Jul 2019 22:52:46 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Sun, 7 Jul 2019 22:52:46 -0500 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id x683qkv7130108; Sun, 7 Jul 2019 22:52:46 -0500 Received: from localhost (irmo.dhcp.ti.com [128.247.58.153]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id x683qkm26441; Sun, 7 Jul 2019 22:52:46 -0500 (CDT) From: Suman Anna To: Marc Zyngier , Rob Herring , Thomas Gleixner , Jason Cooper CC: Tony Lindgren , "Andrew F. Davis" , Roger Quadros , Lokesh Vutla , Grygorii Strashko , Sekhar Nori , David Lechner , Murali Karicheri , , , , , Suman Anna Subject: [PATCH 3/6] irqchip/irq-pruss-intc: Add support for shared and invalid interrupts Date: Sun, 7 Jul 2019 22:52:40 -0500 Message-ID: <20190708035243.12170-4-s-anna@ti.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190708035243.12170-1-s-anna@ti.com> References: <20190708035243.12170-1-s-anna@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 GIC. Some SoCs have some interrupt lines not connected to the ARM GIC 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 --- drivers/irqchip/irq-pruss-intc.c | 44 +++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) -- 2.22.0 diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index d62186ad1be4..142d01b434e0 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -68,6 +68,8 @@ * @domain: irq domain for this interrupt controller * @lock: mutex to serialize access to INTC * @host_mask: indicate which HOST IRQs are enabled + * @shared_intr: bit-map denoting if the MPU host interrupt is shared + * @invalid_intr: bit-map denoting if host interrupt is connected to MPU */ struct pruss_intc { unsigned int irqs[MAX_NUM_HOST_IRQS]; @@ -76,6 +78,8 @@ struct pruss_intc { struct irq_domain *domain; struct mutex lock; /* PRUSS INTC lock */ u32 host_mask; + u16 shared_intr; + u16 invalid_intr; }; static inline u32 pruss_intc_read_reg(struct pruss_intc *intc, unsigned int reg) @@ -243,7 +247,8 @@ static int pruss_intc_probe(struct platform_device *pdev) struct pruss_intc *intc; struct resource *res; struct irq_chip *irqchip; - 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) @@ -260,6 +265,39 @@ static int pruss_intc_probe(struct platform_device *pdev) dev_dbg(dev, "intc memory: pa %pa size 0x%zx va %pK\n", &res->start, (size_t)resource_size(res), intc->base); + count = of_property_read_variable_u8_array(dev->of_node, + "ti,irqs-reserved", + temp_intr, 0, + MAX_NUM_HOST_IRQS); + if (count < 0 && count != -EINVAL) + return count; + count = (count == -EINVAL ? 0 : count); + for (i = 0; i < count; i++) { + if (temp_intr[i] < MAX_NUM_HOST_IRQS) { + intc->invalid_intr |= BIT(temp_intr[i]); + } else { + dev_warn(dev, "ignoring invalid reserved irq %d\n", + temp_intr[i]); + } + temp_intr[i] = 0; + } + + count = of_property_read_variable_u8_array(dev->of_node, + "ti,irqs-shared", + temp_intr, 0, + MAX_NUM_HOST_IRQS); + if (count < 0 && count != -EINVAL) + return count; + count = (count == -EINVAL ? 0 : count); + for (i = 0; i < count; i++) { + if (temp_intr[i] < MAX_NUM_HOST_IRQS) { + intc->shared_intr |= BIT(temp_intr[i]); + } else { + dev_warn(dev, "ignoring invalid reserved irq %d\n", + temp_intr[i]); + } + } + mutex_init(&intc->lock); pruss_intc_init(intc); @@ -286,6 +324,10 @@ static int pruss_intc_probe(struct platform_device *pdev) for (i = 0; i < MAX_NUM_HOST_IRQS; i++) { irq = platform_get_irq_byname(pdev, irq_names[i]); if (irq < 0) { + if (intc->shared_intr & BIT(i) || + intc->invalid_intr & BIT(i)) + continue; + dev_err(dev->parent, "platform_get_irq_byname failed for %s : %d\n", irq_names[i], irq); goto fail_irq; From patchwork Mon Jul 8 03:52:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suman Anna X-Patchwork-Id: 168601 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp6586386ilk; Sun, 7 Jul 2019 20:54:10 -0700 (PDT) X-Google-Smtp-Source: APXvYqx2Q2jL8PN/WrAiid9wCIlJxV54e/Ugvmfp2+fbs3bkPHCtBuM3pNgYu+ciIhhoMopMDTs1 X-Received: by 2002:a17:90a:d80b:: with SMTP id a11mr21336192pjv.53.1562558050293; Sun, 07 Jul 2019 20:54:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562558050; cv=none; d=google.com; s=arc-20160816; b=Nc2VJ7k9Mn7gzccIUJDcRgYC2TnV9Hv5D8ZemZ9bJZpyddwOhHZc+sbfzNPzItmrnb ZsGAKOB++jY2vZEpeByfKlDUtQAIczlqbz/d75USWBORTdt/P+QfCAEyZCuKhVNyhzb9 NFNpCcyzs84V+OdY7oL45sbW+eX/hrZtTheAMePM8GxKBIYhfuwCGKqb+VLNldNqBf1Z g2UPIdE2zssoT1YVO9+swqEqwaxImZtuMJSsLShOSIWXUfOdaI2Yc69sz6Y0zh/sth7B keASAQHYES1k0Q65YmqIypEjkfKhJlk6m3HFzneV72J12jAl7r74orbTmxGMYFflx/o0 ssOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=P69LeJyM5ZYJAAX1YsH9Z3wtJkPkjOYhdxTmMljKVK4=; b=RjARn6okRbhG+kZvG5YaPoIGHuf7/NWq2uJeFoTcdAo8arZIVdF1ltYiQwB55D8iAS iqaGQRHyb7YRkhRJBmnewHd9zGqlC/H/OXJVrNKIS4NwGtBVDjdtHGKRiIKL6y+tGfHy +TFaSllf8GeBIrj07Zhf2qZ2fJ+KyLg+hXPERIk3AFGy76LmjMwalc2FtrU+5+aWQlGp QKzbXVPb4LT8gviroohW/RSmLyktlwbQ7SARl8on08QCowjVG9YlO/juUi2WZBwQkuLM mm0T+75FohotpeOn62PaU2MBczjxPUa74EwTjkBXW2QHKErrKwvLg4G9DsakZ+sRYQGT FM9A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b="W+c/42+f"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y20si16482591plp.335.2019.07.07.20.54.10; Sun, 07 Jul 2019 20:54:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b="W+c/42+f"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728997AbfGHDyF (ORCPT + 30 others); Sun, 7 Jul 2019 23:54:05 -0400 Received: from lelv0142.ext.ti.com ([198.47.23.249]:60218 "EHLO lelv0142.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728940AbfGHDx4 (ORCPT ); Sun, 7 Jul 2019 23:53:56 -0400 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id x683qli6025054; Sun, 7 Jul 2019 22:52:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1562557967; bh=P69LeJyM5ZYJAAX1YsH9Z3wtJkPkjOYhdxTmMljKVK4=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=W+c/42+fvKX3GCdPrEPgKdpXuCteYaRIugu5NPSgKXHWYvXBVlswBKZMhiWl7jrLz uGKtrM2TbztPRnDx0xA2vc4XfOQE4+tvdAqWQ5rFg2weuK6xPFr01AYJgWGaAnEmV4 Gs5yw2d7Bpdu0FQH4N5iAgh2OsoXSaYhVCq3rcqQ= Received: from DLEE114.ent.ti.com (dlee114.ent.ti.com [157.170.170.25]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x683qlTv043695 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Sun, 7 Jul 2019 22:52:47 -0500 Received: from DLEE110.ent.ti.com (157.170.170.21) by DLEE114.ent.ti.com (157.170.170.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Sun, 7 Jul 2019 22:52:46 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE110.ent.ti.com (157.170.170.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Sun, 7 Jul 2019 22:52:46 -0500 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id x683qkjv122101; Sun, 7 Jul 2019 22:52:46 -0500 Received: from localhost (irmo.dhcp.ti.com [128.247.58.153]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id x683qkm26445; Sun, 7 Jul 2019 22:52:46 -0500 (CDT) From: Suman Anna To: Marc Zyngier , Rob Herring , Thomas Gleixner , Jason Cooper CC: Tony Lindgren , "Andrew F. Davis" , Roger Quadros , Lokesh Vutla , Grygorii Strashko , Sekhar Nori , David Lechner , Murali Karicheri , , , , , Suman Anna Subject: [PATCH 4/6] irqchip/irq-pruss-intc: Add helper functions to configure internal mapping Date: Sun, 7 Jul 2019 22:52:41 -0500 Message-ID: <20190708035243.12170-5-s-anna@ti.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190708035243.12170-1-s-anna@ti.com> References: <20190708035243.12170-1-s-anna@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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 is configured 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 is optimized to program the Channel Map Registers (CMRx) and Host-Interrupt Map Registers (HMRx) only when a new program is being loaded/started and simply disables the same events and interrupt channels without zeroing out the corresponding map registers when stopping a PRU. Add two helper functions: pruss_intc_configure() & pruss_intc_unconfigure() that the PRU remoteproc driver can use to configure the PRUSS INTC. Signed-off-by: Suman Anna Signed-off-by: Andrew F. Davis Signed-off-by: Roger Quadros --- drivers/irqchip/irq-pruss-intc.c | 258 ++++++++++++++++++++++++- include/linux/irqchip/irq-pruss-intc.h | 33 ++++ 2 files changed, 289 insertions(+), 2 deletions(-) create mode 100644 include/linux/irqchip/irq-pruss-intc.h -- 2.22.0 diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index 142d01b434e0..8118c2a2ac43 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -24,8 +25,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 +/* maximum number of host interrupts */ +#define MAX_PRU_HOST_INT 10 /* PRU_ICSS_INTC registers */ #define PRU_INTC_REVID 0x0000 @@ -57,15 +58,29 @@ #define PRU_INTC_HINLR(x) (0x1100 + (x) * 4) #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 +/* use -1 to mark unassigned events and channels */ +#define FREE -1 + /** * struct pruss_intc - PRUSS interrupt controller structure * @irqs: kernel irq numbers corresponding to PRUSS host interrupts * @base: base virtual address of INTC register space * @irqchip: irq chip for this interrupt controller * @domain: irq domain for this interrupt controller + * @config_map: stored INTC configuration mapping data * @lock: mutex to serialize access to INTC * @host_mask: indicate which HOST IRQs are enabled * @shared_intr: bit-map denoting if the MPU host interrupt is shared @@ -76,6 +91,7 @@ struct pruss_intc { void __iomem *base; struct irq_chip *irqchip; struct irq_domain *domain; + struct pruss_intc_config config_map; struct mutex lock; /* PRUSS INTC lock */ u32 host_mask; u16 shared_intr; @@ -107,6 +123,238 @@ static int pruss_intc_check_write(struct pruss_intc *intc, unsigned int reg, return 0; } +static struct pruss_intc *to_pruss_intc(struct device *pru_dev) +{ + struct device_node *np; + struct platform_device *pdev; + struct device *pruss_dev = pru_dev->parent; + struct pruss_intc *intc = ERR_PTR(-ENODEV); + + np = of_get_child_by_name(pruss_dev->of_node, "interrupt-controller"); + if (!np) { + dev_err(pruss_dev, "pruss does not have an interrupt-controller node\n"); + return intc; + } + + pdev = of_find_device_by_node(np); + if (!pdev) { + dev_err(pruss_dev, "no associated platform device\n"); + goto out; + } + + intc = platform_get_drvdata(pdev); + if (!intc) { + dev_err(pruss_dev, "pruss intc device probe failed?\n"); + intc = ERR_PTR(-EINVAL); + } + +out: + of_node_put(np); + return intc; +} + +/** + * pruss_intc_configure() - configure the PRUSS INTC + * @dev: pru device pointer + * @intc_config: PRU core-specific INTC configuration + * + * Configures the PRUSS INTC with the provided configuration from + * a PRU core. 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. The function + * is intended to be used only by the PRU remoteproc driver. + * + * Returns 0 on success, or a suitable error code otherwise + */ +int pruss_intc_configure(struct device *dev, + struct pruss_intc_config *intc_config) +{ + struct pruss_intc *intc; + int i, idx, ret; + s8 ch, host; + u64 sysevt_mask = 0; + u32 ch_mask = 0; + u32 host_mask = 0; + u32 val; + + intc = to_pruss_intc(dev); + if (IS_ERR(intc)) + return PTR_ERR(intc); + + mutex_lock(&intc->lock); + + /* + * configure channel map registers - each register holds map info + * for 4 events, with each event occupying the lower nibble in + * a register byte address in little-endian fashion + */ + for (i = 0; i < ARRAY_SIZE(intc_config->sysev_to_ch); i++) { + ch = intc_config->sysev_to_ch[i]; + if (ch < 0) + continue; + + /* check if sysevent already assigned */ + if (intc->config_map.sysev_to_ch[i] != FREE) { + dev_err(dev, "event %d (req. channel %d) already assigned to channel %d\n", + i, ch, intc->config_map.sysev_to_ch[i]); + ret = -EEXIST; + goto unlock; + } + + intc->config_map.sysev_to_ch[i] = ch; + + idx = i / CMR_EVT_PER_REG; + val = pruss_intc_read_reg(intc, PRU_INTC_CMR(idx)); + val &= ~(CMR_EVT_MAP_MASK << + ((i % CMR_EVT_PER_REG) * CMR_EVT_MAP_BITS)); + val |= ch << ((i % CMR_EVT_PER_REG) * CMR_EVT_MAP_BITS); + pruss_intc_write_reg(intc, PRU_INTC_CMR(idx), val); + sysevt_mask |= BIT_ULL(i); + ch_mask |= BIT(ch); + + dev_dbg(dev, "SYSEV%d -> CH%d (CMR%d 0x%08x)\n", i, ch, idx, + pruss_intc_read_reg(intc, PRU_INTC_CMR(idx))); + } + + /* + * set host map registers - each register holds map info for + * 4 channels, with each channel occupying the lower nibble in + * a register byte address in little-endian fashion + */ + for (i = 0; i < ARRAY_SIZE(intc_config->ch_to_host); i++) { + host = intc_config->ch_to_host[i]; + if (host < 0) + continue; + + /* check if channel already assigned */ + if (intc->config_map.ch_to_host[i] != FREE) { + dev_err(dev, "channel %d (req. intr_no %d) already assigned to intr_no %d\n", + i, host, intc->config_map.ch_to_host[i]); + ret = -EEXIST; + goto unlock; + } + + /* check if host intr is already in use by other PRU */ + if (intc->host_mask & (1U << host)) { + dev_err(dev, "%s: host intr %d already in use\n", + __func__, host); + ret = -EEXIST; + goto unlock; + } + + intc->config_map.ch_to_host[i] = host; + + idx = i / HMR_CH_PER_REG; + + val = pruss_intc_read_reg(intc, PRU_INTC_HMR(idx)); + val &= ~(HMR_CH_MAP_MASK << + ((i % HMR_CH_PER_REG) * HMR_CH_MAP_BITS)); + val |= host << ((i % HMR_CH_PER_REG) * HMR_CH_MAP_BITS); + pruss_intc_write_reg(intc, PRU_INTC_HMR(idx), val); + + ch_mask |= BIT(i); + host_mask |= BIT(host); + + dev_dbg(dev, "CH%d -> HOST%d (HMR%d 0x%08x)\n", i, host, idx, + pruss_intc_read_reg(intc, PRU_INTC_HMR(idx))); + } + + dev_info(dev, "configured system_events = 0x%016llx intr_channels = 0x%08x host_intr = 0x%08x\n", + sysevt_mask, ch_mask, host_mask); + + /* enable system events, writing 0 has no-effect */ + pruss_intc_write_reg(intc, PRU_INTC_ESR0, lower_32_bits(sysevt_mask)); + pruss_intc_write_reg(intc, PRU_INTC_SECR0, lower_32_bits(sysevt_mask)); + pruss_intc_write_reg(intc, PRU_INTC_ESR1, upper_32_bits(sysevt_mask)); + pruss_intc_write_reg(intc, PRU_INTC_SECR1, upper_32_bits(sysevt_mask)); + + /* enable host interrupts */ + for (i = 0; i < MAX_PRU_HOST_INT; i++) { + if (host_mask & BIT(i)) + pruss_intc_write_reg(intc, PRU_INTC_HIEISR, i); + } + + /* global interrupt enable */ + pruss_intc_write_reg(intc, PRU_INTC_GER, 1); + + intc->host_mask |= host_mask; + + mutex_unlock(&intc->lock); + return 0; + +unlock: + mutex_unlock(&intc->lock); + return ret; +} +EXPORT_SYMBOL_GPL(pruss_intc_configure); + +/** + * pruss_intc_unconfigure() - unconfigure the PRUSS INTC + * @dev: pru device pointer + * @intc_config: PRU core specific INTC configuration + * + * Undo whatever was done in pruss_intc_configure() for a PRU core. + * It should be sufficient to just mark the resources free in the + * global map and disable the host interrupts and sysevents. + */ +int pruss_intc_unconfigure(struct device *dev, + struct pruss_intc_config *intc_config) +{ + struct pruss_intc *intc; + int i; + s8 ch, host; + u64 sysevt_mask = 0; + u32 host_mask = 0; + + intc = to_pruss_intc(dev); + if (IS_ERR(intc)) + return PTR_ERR(intc); + + mutex_lock(&intc->lock); + + for (i = 0; i < ARRAY_SIZE(intc_config->sysev_to_ch); i++) { + ch = intc_config->sysev_to_ch[i]; + if (ch < 0) + continue; + + /* mark sysevent free in global map */ + intc->config_map.sysev_to_ch[i] = FREE; + sysevt_mask |= BIT_ULL(i); + } + + for (i = 0; i < ARRAY_SIZE(intc_config->ch_to_host); i++) { + host = intc_config->ch_to_host[i]; + if (host < 0) + continue; + + /* mark channel free in global map */ + intc->config_map.ch_to_host[i] = FREE; + host_mask |= BIT(host); + } + + dev_info(dev, "unconfigured system_events = 0x%016llx host_intr = 0x%08x\n", + sysevt_mask, host_mask); + + /* disable system events, writing 0 has no-effect */ + pruss_intc_write_reg(intc, PRU_INTC_ECR0, lower_32_bits(sysevt_mask)); + pruss_intc_write_reg(intc, PRU_INTC_ECR1, upper_32_bits(sysevt_mask)); + /* clear any pending status */ + pruss_intc_write_reg(intc, PRU_INTC_SECR0, lower_32_bits(sysevt_mask)); + pruss_intc_write_reg(intc, PRU_INTC_SECR1, upper_32_bits(sysevt_mask)); + + /* disable host interrupts */ + for (i = 0; i < MAX_PRU_HOST_INT; i++) { + if (host_mask & BIT(i)) + pruss_intc_write_reg(intc, PRU_INTC_HIDISR, i); + } + + intc->host_mask &= ~host_mask; + mutex_unlock(&intc->lock); + + return 0; +} +EXPORT_SYMBOL_GPL(pruss_intc_unconfigure); + static void pruss_intc_init(struct pruss_intc *intc) { int i; @@ -300,6 +548,12 @@ static int pruss_intc_probe(struct platform_device *pdev) mutex_init(&intc->lock); + for (i = 0; i < ARRAY_SIZE(intc->config_map.sysev_to_ch); i++) + intc->config_map.sysev_to_ch[i] = FREE; + + for (i = 0; i < ARRAY_SIZE(intc->config_map.ch_to_host); i++) + intc->config_map.ch_to_host[i] = FREE; + pruss_intc_init(intc); irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL); diff --git a/include/linux/irqchip/irq-pruss-intc.h b/include/linux/irqchip/irq-pruss-intc.h new file mode 100644 index 000000000000..f1f1bb150100 --- /dev/null +++ b/include/linux/irqchip/irq-pruss-intc.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * PRU-ICSS sub-system private interfaces + * + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ + * Suman Anna + */ + +#ifndef __LINUX_IRQ_PRUSS_INTC_H +#define __LINUX_IRQ_PRUSS_INTC_H + +/* maximum number of system events */ +#define MAX_PRU_SYS_EVENTS 64 + +/* maximum number of interrupt channels */ +#define MAX_PRU_CHANNELS 10 + +/** + * struct pruss_intc_config - INTC configuration info + * @sysev_to_ch: system events to channel mapping information + * @ch_to_host: interrupt channel to host interrupt information + */ +struct pruss_intc_config { + s8 sysev_to_ch[MAX_PRU_SYS_EVENTS]; + s8 ch_to_host[MAX_PRU_CHANNELS]; +}; + +int pruss_intc_configure(struct device *dev, + struct pruss_intc_config *intc_config); +int pruss_intc_unconfigure(struct device *dev, + struct pruss_intc_config *intc_config); + +#endif /* __LINUX_IRQ_PRUSS_INTC_H */ From patchwork Mon Jul 8 03:52:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suman Anna X-Patchwork-Id: 168599 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp6586289ilk; Sun, 7 Jul 2019 20:54:04 -0700 (PDT) X-Google-Smtp-Source: APXvYqw6dvCqCrNzyq3ZbwVvNB3wvoKwUfLKIQc4DehcrXu3abTO2J0kkX/ioS2+FG4nwLp2EsQM X-Received: by 2002:a17:90a:bf02:: with SMTP id c2mr22406274pjs.73.1562558044128; Sun, 07 Jul 2019 20:54:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562558044; cv=none; d=google.com; s=arc-20160816; b=bNpQr3KlZhC9Mr2+H0o6d5VyRAh6i0C2sdLccbi7cRVcGtu+vSud2RIyYNF7qJONYU U8gdnKHT2iKDeP/QypQ2i9u7l3K294LGFcCRcBTS/DSGkgh0+mCPi57yQqzLe+ULCnml 3rj7HNxh2gFFgH8PJ8M67peK7yqONwfPYZfewAtCWCnq9AH2UeoGc+Qd3MxzpfCgDfbX N79ei8fAXjbbq1RqT40R+A4aFbRBiQaae/nI95xpQhbAJLx/T90z6aeYz8EbH3i2+ylu zRNe2Ms78aIwRCYRcxpOuiaXh1hx4YOSto6mjfZRcuQuU8JzzlrdjEF+7tZvFfVYVqAA Sc7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=/PxbsYKEc7J+gcuFg4Za6foR6b99A27G9weDbwBQOME=; b=IC2PDZBDgFr3YU3XcAG4j9ztGwwMlbfOLhNT0iOY7KZfarpX+vSUk0yKe9wK5XTf9K m6Z3t1SLuawZNB5UBSMc9TEAmYMmfEoMjhbdUFNNSWFah+dxNyMN5HdHjgThXf29HQFM GZeuygksMK/6EYAttF0sNANqc9OoLu0DOO72K93rx4aXF4AAjFb4WC/vYFuYLyY0VN/x n01eO70UXHa8O5RS3xs1jxFasDqZTqPdhm9yNcgRQ3AjSRszDTtKkr5X4o1IjUMZisXv kPytH9qHyMPwrWCvvupXqDF5PQEFoN3QszvJEnQ6xdZTN09HP09Ax2qbitOk9h94aTvs 7Y8g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=mce7VKr7; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y20si16482591plp.335.2019.07.07.20.54.03; Sun, 07 Jul 2019 20:54:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=mce7VKr7; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728987AbfGHDyC (ORCPT + 30 others); Sun, 7 Jul 2019 23:54:02 -0400 Received: from lelv0143.ext.ti.com ([198.47.23.248]:37224 "EHLO lelv0143.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727741AbfGHDx4 (ORCPT ); Sun, 7 Jul 2019 23:53:56 -0400 Received: from fllv0035.itg.ti.com ([10.64.41.0]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id x683qlHi073187; Sun, 7 Jul 2019 22:52:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1562557967; bh=/PxbsYKEc7J+gcuFg4Za6foR6b99A27G9weDbwBQOME=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=mce7VKr7jsguyzB9oW2SHO37YJcu552fbsgGA7zMkVnF3ox4rMW1MMrHrC2CQQQhV 5TPqVuGn0+M78BPTnfUsB88AbtMKPesy79hUK40yQeMWi67MsZlBHPTjlNyrjOzXrj WhAx03h+sWS9LMSYDP1ubhrQnYFmkmI2Y4Yaa5VE= Received: from DFLE105.ent.ti.com (dfle105.ent.ti.com [10.64.6.26]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x683qlun102653 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Sun, 7 Jul 2019 22:52:47 -0500 Received: from DFLE102.ent.ti.com (10.64.6.23) by DFLE105.ent.ti.com (10.64.6.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Sun, 7 Jul 2019 22:52:46 -0500 Received: from fllv0039.itg.ti.com (10.64.41.19) by DFLE102.ent.ti.com (10.64.6.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Sun, 7 Jul 2019 22:52:47 -0500 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id x683qkEP036231; Sun, 7 Jul 2019 22:52:46 -0500 Received: from localhost (irmo.dhcp.ti.com [128.247.58.153]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id x683qkm26449; Sun, 7 Jul 2019 22:52:46 -0500 (CDT) From: Suman Anna To: Marc Zyngier , Rob Herring , Thomas Gleixner , Jason Cooper CC: Tony Lindgren , "Andrew F. Davis" , Roger Quadros , Lokesh Vutla , Grygorii Strashko , Sekhar Nori , David Lechner , Murali Karicheri , , , , , Suman Anna Subject: [PATCH 5/6] irqchip/irq-pruss-intc: Add API to trigger a PRU sysevent Date: Sun, 7 Jul 2019 22:52:42 -0500 Message-ID: <20190708035243.12170-6-s-anna@ti.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190708035243.12170-1-s-anna@ti.com> References: <20190708035243.12170-1-s-anna@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Andrew F. Davis" The PRUSS INTC can generate an interrupt to various processor subsystems on the SoC through a set of 64 possible PRU system events. These system events can be used by PRU client drivers or applications for event notifications/signalling between PRUs and MPU or other processors. A new API, pruss_intc_trigger() is provided to MPU-side PRU client drivers/applications to be able to trigger an event/interrupt using IRQ numbers provided by the PRUSS-INTC irqdomain chip. Signed-off-by: Andrew F. Davis Signed-off-by: Suman Anna Signed-off-by: Roger Quadros --- drivers/irqchip/irq-pruss-intc.c | 31 +++++++++++++++++++++++++++++++ include/linux/pruss_intc.h | 26 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 include/linux/pruss_intc.h -- 2.22.0 diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index 8118c2a2ac43..a0ad50b95cd5 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -421,6 +421,37 @@ static void pruss_intc_irq_relres(struct irq_data *data) module_put(THIS_MODULE); } +/** + * pruss_intc_trigger() - trigger a PRU system event + * @irq: linux IRQ number associated with a PRU system event + * + * Trigger an interrupt by signalling a specific PRU system event. + * This can be used by PRUSS client users to raise/send an event to + * a PRU or any other core that is listening on the host interrupt + * mapped to that specific PRU system event. The @irq variable is the + * Linux IRQ number associated with a specific PRU system event that + * a client user/application uses. The interrupt mappings for this is + * provided by the PRUSS INTC irqchip instance. + * + * Returns 0 on success, or an error value upon failure. + */ +int pruss_intc_trigger(unsigned int irq) +{ + struct irq_desc *desc; + + if (irq <= 0) + return -EINVAL; + + desc = irq_to_desc(irq); + if (!desc) + return -EINVAL; + + pruss_intc_irq_retrigger(&desc->irq_data); + + return 0; +} +EXPORT_SYMBOL_GPL(pruss_intc_trigger); + static int pruss_intc_irq_domain_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw) { diff --git a/include/linux/pruss_intc.h b/include/linux/pruss_intc.h new file mode 100644 index 000000000000..84aa7f7edf42 --- /dev/null +++ b/include/linux/pruss_intc.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/** + * TI PRU-ICSS Subsystem user interfaces + * + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com + * Andrew F. Davis + * Suman Anna + */ + +#ifndef __LINUX_PRUSS_INTC_H +#define __LINUX_PRUSS_INTC_H + +#if IS_ENABLED(CONFIG_TI_PRUSS_INTC) + +int pruss_intc_trigger(unsigned int irq); + +#else + +static inline int pruss_intc_trigger(unsigned int irq) +{ + return -ENOTSUPP; +} + +#endif /* CONFIG_TI_PRUSS_INTC */ + +#endif /* __LINUX_PRUSS_INTC_H */ From patchwork Mon Jul 8 03:52:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suman Anna X-Patchwork-Id: 168598 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp6586238ilk; Sun, 7 Jul 2019 20:54:01 -0700 (PDT) X-Google-Smtp-Source: APXvYqwt5euAAdJuPgN7gse4wn4wuV5GcO1Acp843yQLRRTR4cjaHgeRtTwz3UZiAuxV+am/HZoQ X-Received: by 2002:a17:902:b196:: with SMTP id s22mr19733620plr.245.1562558041728; Sun, 07 Jul 2019 20:54:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562558041; cv=none; d=google.com; s=arc-20160816; b=slYLEkUX7+bPoJLuDQZoEQYiZZypNq92o644KNnJUYX5Rd9oinYUdFw8icQ6Qsbb1r P3w6YLquPHUYUR6fs4UzL+ctitC+0gT9kZDMmxmpFkJDbOJSHvOT1xcHfKyxY5Ub9Y77 mWumrlP0BkNHIjcvfQpyqmkJfMbel4A6FoFtn/unBa4BO4Tu/kUyOyjZenWlgkrG6WtZ iNejmWDN9PMYqELQ0VCYK3Rxa6D/KcoOl3QCQtD3FEWg2fov/K9DUMJOgUzXJktngryX TEmFf7GMimvyni7iPpjGxzBsXDlqRv278tRwP1yMfo2KJ+LNcdOWkJo06Pl/18/OUJXi S7qA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1XHpXY1f+dtlv5bPSxDeBLj5zQS/NqH4f3yZcY65A4w=; b=Cbs52PVeS5+QR9tg3vbhO/8qsUO71Rnbz3CBe36gEw8Rzz+u+UkY4RDnAnFSQniIax +7jHyq9RyMc3gfIviNUj28hBlnXcgjlnpIUbklRUceAhyjNcLaQ8glSBUmbhn7qW12HA YCLuhj8Lbrgc0NdsrbVIDcNYIVa4fqXliBz2uBI1O/9riB85bWB/MTG0f9i4k6zpSdNk /SuRmvDfXUJnJPqzYgSjWoNd+y150A0YYt7lO254Q6zs/VoYUuLXY0JOx0Ho9Uvae0Sj Gef9M8QPN4PORf6dOrASu9sxAjEXDSuWV/87PpSpG9OvSYrsbwrPfq1z30A2zyY1WVPA qQeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=cnZXbLlY; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o12si15631834pgn.390.2019.07.07.20.54.01; Sun, 07 Jul 2019 20:54:01 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=cnZXbLlY; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728953AbfGHDx4 (ORCPT + 30 others); Sun, 7 Jul 2019 23:53:56 -0400 Received: from fllv0016.ext.ti.com ([198.47.19.142]:46570 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727741AbfGHDxz (ORCPT ); Sun, 7 Jul 2019 23:53:55 -0400 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id x683qlNJ017985; Sun, 7 Jul 2019 22:52:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1562557967; bh=1XHpXY1f+dtlv5bPSxDeBLj5zQS/NqH4f3yZcY65A4w=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=cnZXbLlYPfjgvpQWlprB0Fk39rRNq06dlp9ycL8zcLw8wqnvlcLsXXkThzBtjZosf mbqV4L8eO95baG/G/Efs37kO8fpYbqXSPDHPcYB6Z3NYeOad0VhEWTGYOlEVcUFoOq suUTByDpBOCCqIvbSMcIi8DjIyeRHWXzyLE6L1n4= Received: from DFLE103.ent.ti.com (dfle103.ent.ti.com [10.64.6.24]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x683qlfQ016593 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Sun, 7 Jul 2019 22:52:47 -0500 Received: from DFLE113.ent.ti.com (10.64.6.34) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Sun, 7 Jul 2019 22:52:47 -0500 Received: from fllv0040.itg.ti.com (10.64.41.20) by DFLE113.ent.ti.com (10.64.6.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Sun, 7 Jul 2019 22:52:47 -0500 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by fllv0040.itg.ti.com (8.15.2/8.15.2) with ESMTP id x683qlmA026311; Sun, 7 Jul 2019 22:52:47 -0500 Received: from localhost (irmo.dhcp.ti.com [128.247.58.153]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id x683qkm26453; Sun, 7 Jul 2019 22:52:46 -0500 (CDT) From: Suman Anna To: Marc Zyngier , Rob Herring , Thomas Gleixner , Jason Cooper CC: Tony Lindgren , "Andrew F. Davis" , Roger Quadros , Lokesh Vutla , Grygorii Strashko , Sekhar Nori , David Lechner , Murali Karicheri , , , , , Suman Anna Subject: [PATCH 6/6] irqchip/irq-pruss-intc: Add support for ICSSG INTC on K3 SoCs Date: Sun, 7 Jul 2019 22:52:43 -0500 Message-ID: <20190708035243.12170-7-s-anna@ti.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190708035243.12170-1-s-anna@ti.com> References: <20190708035243.12170-1-s-anna@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- drivers/irqchip/Kconfig | 2 +- drivers/irqchip/irq-pruss-intc.c | 172 +++++++++++++++++-------- include/linux/irqchip/irq-pruss-intc.h | 4 +- 3 files changed, 124 insertions(+), 54 deletions(-) -- 2.22.0 diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index b0a9479d527c..9f36a6252302 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -449,7 +449,7 @@ config TI_SCI_INTA_IRQCHIP config TI_PRUSS_INTC tristate "TI PRU-ICSS Interrupt Controller" - depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM437X || SOC_DRA7XX || ARCH_KEYSTONE + depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM437X || 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 a0ad50b95cd5..702b1c120b21 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 host interrupts */ -#define MAX_PRU_HOST_INT 10 - /* PRU_ICSS_INTC registers */ #define PRU_INTC_REVID 0x0000 #define PRU_INTC_CR 0x0004 @@ -40,21 +38,23 @@ #define PRU_INTC_HIEISR 0x0034 #define PRU_INTC_HIDISR 0x0038 #define PRU_INTC_GPIR 0x0080 +#define PRU_INTC_SRSR(x) (0x0200 + (x) * 4) #define PRU_INTC_SRSR0 0x0200 #define PRU_INTC_SRSR1 0x0204 +#define PRU_INTC_SECR(x) (0x0280 + (x) * 4) #define PRU_INTC_SECR0 0x0280 #define PRU_INTC_SECR1 0x0284 +#define PRU_INTC_ESR(x) (0x0300 + (x) * 4) #define PRU_INTC_ESR0 0x0300 #define PRU_INTC_ESR1 0x0304 +#define PRU_INTC_ECR(x) (0x0380 + (x) * 4) #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_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 @@ -74,12 +74,23 @@ /* use -1 to mark unassigned events and channels */ #define FREE -1 +/** + * 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 * @irqchip: irq chip for this interrupt controller * @domain: irq domain for this interrupt controller + * @data: cached PRUSS INTC IP configuration data * @config_map: stored INTC configuration mapping data * @lock: mutex to serialize access to INTC * @host_mask: indicate which HOST IRQs are enabled @@ -91,6 +102,7 @@ struct pruss_intc { void __iomem *base; struct irq_chip *irqchip; struct irq_domain *domain; + const struct pruss_intc_match_data *data; struct pruss_intc_config config_map; struct mutex lock; /* PRUSS INTC lock */ u32 host_mask; @@ -115,7 +127,7 @@ static int pruss_intc_check_write(struct pruss_intc *intc, unsigned int reg, if (!intc) return -EINVAL; - if (sysevent >= MAX_PRU_SYS_EVENTS) + if (sysevent >= intc->data->num_system_events) return -EINVAL; pruss_intc_write_reg(intc, reg, sysevent); @@ -170,17 +182,29 @@ int pruss_intc_configure(struct device *dev, struct pruss_intc_config *intc_config) { struct pruss_intc *intc; - int i, idx, ret; + int i, idx; s8 ch, host; - u64 sysevt_mask = 0; + u32 num_events, num_intrs, num_regs; + unsigned long *sysevt_bitmap; + u32 *sysevts; u32 ch_mask = 0; u32 host_mask = 0; + int ret = 0; u32 val; intc = to_pruss_intc(dev); if (IS_ERR(intc)) return PTR_ERR(intc); + num_events = intc->data->num_system_events; + num_intrs = intc->data->num_host_intrs; + num_regs = DIV_ROUND_UP(num_events, 32); + + sysevt_bitmap = bitmap_zalloc(num_events, GFP_KERNEL); + if (!sysevt_bitmap) + return -ENOMEM; + sysevts = (u32 *)sysevt_bitmap; + mutex_lock(&intc->lock); /* @@ -188,7 +212,7 @@ int pruss_intc_configure(struct device *dev, * for 4 events, with each event occupying the lower nibble in * a register byte address in little-endian fashion */ - for (i = 0; i < ARRAY_SIZE(intc_config->sysev_to_ch); i++) { + for (i = 0; i < num_events; i++) { ch = intc_config->sysev_to_ch[i]; if (ch < 0) continue; @@ -209,7 +233,7 @@ int pruss_intc_configure(struct device *dev, ((i % CMR_EVT_PER_REG) * CMR_EVT_MAP_BITS)); val |= ch << ((i % CMR_EVT_PER_REG) * CMR_EVT_MAP_BITS); pruss_intc_write_reg(intc, PRU_INTC_CMR(idx), val); - sysevt_mask |= BIT_ULL(i); + bitmap_set(sysevt_bitmap, i, 1); ch_mask |= BIT(ch); dev_dbg(dev, "SYSEV%d -> CH%d (CMR%d 0x%08x)\n", i, ch, idx, @@ -221,7 +245,7 @@ int pruss_intc_configure(struct device *dev, * 4 channels, with each channel occupying the lower nibble in * a register byte address in little-endian fashion */ - for (i = 0; i < ARRAY_SIZE(intc_config->ch_to_host); i++) { + for (i = 0; i < num_intrs; i++) { host = intc_config->ch_to_host[i]; if (host < 0) continue; @@ -259,17 +283,19 @@ int pruss_intc_configure(struct device *dev, pruss_intc_read_reg(intc, PRU_INTC_HMR(idx))); } - dev_info(dev, "configured system_events = 0x%016llx intr_channels = 0x%08x host_intr = 0x%08x\n", - sysevt_mask, ch_mask, host_mask); + dev_info(dev, "configured system_events[%d-0] = %*pb\n", + num_events - 1, num_events, sysevt_bitmap); + dev_info(dev, "configured intr_channels = 0x%08x host_intr = 0x%08x\n", + ch_mask, host_mask); /* enable system events, writing 0 has no-effect */ - pruss_intc_write_reg(intc, PRU_INTC_ESR0, lower_32_bits(sysevt_mask)); - pruss_intc_write_reg(intc, PRU_INTC_SECR0, lower_32_bits(sysevt_mask)); - pruss_intc_write_reg(intc, PRU_INTC_ESR1, upper_32_bits(sysevt_mask)); - pruss_intc_write_reg(intc, PRU_INTC_SECR1, upper_32_bits(sysevt_mask)); + for (i = 0; i < num_regs; i++) { + pruss_intc_write_reg(intc, PRU_INTC_ESR(i), sysevts[i]); + pruss_intc_write_reg(intc, PRU_INTC_SECR(i), sysevts[i]); + } /* enable host interrupts */ - for (i = 0; i < MAX_PRU_HOST_INT; i++) { + for (i = 0; i < num_intrs; i++) { if (host_mask & BIT(i)) pruss_intc_write_reg(intc, PRU_INTC_HIEISR, i); } @@ -279,11 +305,9 @@ int pruss_intc_configure(struct device *dev, intc->host_mask |= host_mask; - mutex_unlock(&intc->lock); - return 0; - unlock: mutex_unlock(&intc->lock); + bitmap_free(sysevt_bitmap); return ret; } EXPORT_SYMBOL_GPL(pruss_intc_configure); @@ -303,26 +327,37 @@ int pruss_intc_unconfigure(struct device *dev, struct pruss_intc *intc; int i; s8 ch, host; - u64 sysevt_mask = 0; + u32 num_events, num_intrs, num_regs; + unsigned long *sysevt_bitmap; + u32 *sysevts; u32 host_mask = 0; intc = to_pruss_intc(dev); if (IS_ERR(intc)) return PTR_ERR(intc); + num_events = intc->data->num_system_events; + num_intrs = intc->data->num_host_intrs; + num_regs = DIV_ROUND_UP(num_events, 32); + + sysevt_bitmap = bitmap_zalloc(num_events, GFP_KERNEL); + if (!sysevt_bitmap) + return -ENOMEM; + sysevts = (u32 *)sysevt_bitmap; + mutex_lock(&intc->lock); - for (i = 0; i < ARRAY_SIZE(intc_config->sysev_to_ch); i++) { + for (i = 0; i < num_events; i++) { ch = intc_config->sysev_to_ch[i]; if (ch < 0) continue; /* mark sysevent free in global map */ intc->config_map.sysev_to_ch[i] = FREE; - sysevt_mask |= BIT_ULL(i); + bitmap_set(sysevt_bitmap, i, 1); } - for (i = 0; i < ARRAY_SIZE(intc_config->ch_to_host); i++) { + for (i = 0; i < num_intrs; i++) { host = intc_config->ch_to_host[i]; if (host < 0) continue; @@ -332,24 +367,26 @@ int pruss_intc_unconfigure(struct device *dev, host_mask |= BIT(host); } - dev_info(dev, "unconfigured system_events = 0x%016llx host_intr = 0x%08x\n", - sysevt_mask, host_mask); + dev_info(dev, "unconfigured system_events[%d-0] = %*pb\n", + num_events - 1, num_events, sysevt_bitmap); + dev_info(dev, "unconfigured host_intr = 0x%08x\n", host_mask); - /* disable system events, writing 0 has no-effect */ - pruss_intc_write_reg(intc, PRU_INTC_ECR0, lower_32_bits(sysevt_mask)); - pruss_intc_write_reg(intc, PRU_INTC_ECR1, upper_32_bits(sysevt_mask)); - /* clear any pending status */ - pruss_intc_write_reg(intc, PRU_INTC_SECR0, lower_32_bits(sysevt_mask)); - pruss_intc_write_reg(intc, PRU_INTC_SECR1, upper_32_bits(sysevt_mask)); + for (i = 0; i < num_regs; i++) { + /* disable system events, writing 0 has no-effect */ + pruss_intc_write_reg(intc, PRU_INTC_ECR(i), sysevts[i]); + /* clear any pending status */ + pruss_intc_write_reg(intc, PRU_INTC_SECR(i), sysevts[i]); + } /* disable host interrupts */ - for (i = 0; i < MAX_PRU_HOST_INT; i++) { + for (i = 0; i < num_intrs; i++) { if (host_mask & BIT(i)) pruss_intc_write_reg(intc, PRU_INTC_HIDISR, i); } intc->host_mask &= ~host_mask; mutex_unlock(&intc->lock); + bitmap_free(sysevt_bitmap); return 0; } @@ -358,21 +395,28 @@ EXPORT_SYMBOL_GPL(pruss_intc_unconfigure); static void pruss_intc_init(struct pruss_intc *intc) { int i; + int num_chnl_map_regs = DIV_ROUND_UP(intc->data->num_system_events, + CMR_EVT_PER_REG); + int num_host_intr_regs = DIV_ROUND_UP(intc->data->num_host_intrs, + HMR_CH_PER_REG); + int num_event_type_regs = + DIV_ROUND_UP(intc->data->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); } @@ -527,11 +571,20 @@ static int pruss_intc_probe(struct platform_device *pdev) struct resource *res; struct irq_chip *irqchip; 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->data = data; platform_set_drvdata(pdev, intc); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -600,8 +653,7 @@ static int pruss_intc_probe(struct platform_device *pdev) irqchip->name = dev_name(dev); intc->irqchip = irqchip; - /* 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; @@ -638,6 +690,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->data->num_system_events; unsigned int hwirq; int i; @@ -648,7 +701,7 @@ static int pruss_intc_remove(struct platform_device *pdev) } if (intc->domain) { - 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); @@ -657,8 +710,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); diff --git a/include/linux/irqchip/irq-pruss-intc.h b/include/linux/irqchip/irq-pruss-intc.h index f1f1bb150100..40ba6e0d2dad 100644 --- a/include/linux/irqchip/irq-pruss-intc.h +++ b/include/linux/irqchip/irq-pruss-intc.h @@ -10,10 +10,10 @@ #define __LINUX_IRQ_PRUSS_INTC_H /* maximum number of system events */ -#define MAX_PRU_SYS_EVENTS 64 +#define MAX_PRU_SYS_EVENTS 160 /* maximum number of interrupt channels */ -#define MAX_PRU_CHANNELS 10 +#define MAX_PRU_CHANNELS 20 /** * struct pruss_intc_config - INTC configuration info