Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp217045iob; Mon, 2 May 2022 17:30:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwdJ1Thf+I8zmbindyRUEl1KuXOPCNFkERSLhu17LZRQzzSHzj/LvNCKHtzbYv3SRJkcrkQ X-Received: by 2002:a17:90b:4b12:b0:1d2:8bda:ef7 with SMTP id lx18-20020a17090b4b1200b001d28bda0ef7mr1938362pjb.174.1651537853886; Mon, 02 May 2022 17:30:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651537853; cv=none; d=google.com; s=arc-20160816; b=PJ7dHBZFMMRUyWdwG29pLLep/bJLtnUuadR0bhU+Avg2kxeeaueWxxuObmTgIPE11r uvzOpw2B85Tro4MEdEZyGu8aIoyYpbNjZEbzsB3dDmQoaZg7Qx9doO/r9gIWxmM/aphP hlCytnngph30gPLrrb0Z6uxjmwo1d/aU3PYLGg2Su4LoBwR46pbQf+BmCYSQUCKS32K0 PoO0irxWVsV6F4LyFfhkYuXfodwVMifwk3EIE0CRuIz8Uj78TTY5rH1UN7F0XnUctpJP rMU/8IhSN2tIGUJYeQCSgTpkQa2tJP7tIxsOQksY4M1m6aX0bazOc/MxPcccfHAQkCOq H58w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=Z/Bhn9GLI3frs+t7cOAhhcT+FIHPacglTGq/IRMd0yA=; b=Q7fybEV7x4SU5uKOyIPtGCXAh04+2kJ5XduGC4o+m3A3BXN0Rm5M8Z3bST6VcSkHF2 QfkLMG9qLWGhBo1P4t/18rsFZl70zx3m0x8knsCVDvZAgKwrRoPwGeVeSNteYkA6LhKU w4VtPBsrQ3wyyAYPRMXOosJb/0bOssO5iuYQ7E3tlIZQZ5kCljXMQZL+V1foN1NKTvbl onuhiG4LuLmqUAR02BHmOVniajXjfh+uFzXjK1W0qDxupp/mA13mnfWm3cVM0voEGF25 OOnRXx1wnuIXN66tjcP9CN4RA5m4EZA3EMPBbd7ubBLhz5fL4IBJS4UY3MB6xrtSBEp8 0P5A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id l62-20020a639141000000b0039da5aa4ed6si5485599pge.710.2022.05.02.17.30.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 May 2022 17:30:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 2047421BA; Mon, 2 May 2022 17:24:52 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236616AbiD3JB7 (ORCPT + 99 others); Sat, 30 Apr 2022 05:01:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229683AbiD3JB5 (ORCPT ); Sat, 30 Apr 2022 05:01:57 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A096E19C35 for ; Sat, 30 Apr 2022 01:58:36 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3F57E60A22 for ; Sat, 30 Apr 2022 08:58:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6DA19C385A7; Sat, 30 Apr 2022 08:58:33 +0000 (UTC) From: Huacai Chen To: Thomas Gleixner , Marc Zyngier Cc: linux-kernel@vger.kernel.org, Xuefeng Li , Huacai Chen , Jiaxun Yang , Huacai Chen Subject: [PATCH V11 05/10] irqchip/loongson-htvec: Add ACPI init support Date: Sat, 30 Apr 2022 16:53:39 +0800 Message-Id: <20220430085344.3127346-6-chenhuacai@loongson.cn> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220430085344.3127346-1-chenhuacai@loongson.cn> References: <20220430085344.3127346-1-chenhuacai@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RDNS_NONE, SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We are preparing to add new Loongson (based on LoongArch, not compatible with old MIPS-based Loongson) support. LoongArch use ACPI other than DT as its boot protocol, so add ACPI init support. HTVECINTC stands for "HyperTransport Interrupts" that described in Section 14.3 of "Loongson 3A5000 Processor Reference Manual". For more information please refer Documentation/loongarch/irq-chip-model.rst. Signed-off-by: Huacai Chen --- drivers/irqchip/irq-loongson-htvec.c | 119 +++++++++++++++++++-------- 1 file changed, 85 insertions(+), 34 deletions(-) diff --git a/drivers/irqchip/irq-loongson-htvec.c b/drivers/irqchip/irq-loongson-htvec.c index 60a335d7e64e..e304374a018c 100644 --- a/drivers/irqchip/irq-loongson-htvec.c +++ b/drivers/irqchip/irq-loongson-htvec.c @@ -20,7 +20,6 @@ /* Registers */ #define HTVEC_EN_OFF 0x20 #define HTVEC_MAX_PARENT_IRQ 8 - #define VEC_COUNT_PER_REG 32 #define VEC_REG_IDX(irq_id) ((irq_id) / VEC_COUNT_PER_REG) #define VEC_REG_BIT(irq_id) ((irq_id) % VEC_COUNT_PER_REG) @@ -30,8 +29,11 @@ struct htvec { void __iomem *base; struct irq_domain *htvec_domain; raw_spinlock_t htvec_lock; + struct fwnode_handle *domain_handle; }; +static struct htvec *htvec_priv; + static void htvec_irq_dispatch(struct irq_desc *desc) { int i; @@ -155,64 +157,113 @@ static void htvec_reset(struct htvec *priv) } } -static int htvec_of_init(struct device_node *node, - struct device_node *parent) +static int htvec_init(phys_addr_t addr, unsigned long size, + int num_parents, int parent_irq[], struct fwnode_handle *domain_handle) { + int i; struct htvec *priv; - int err, parent_irq[8], i; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + priv->num_parents = num_parents; + priv->base = ioremap(addr, size); + priv->domain_handle = domain_handle; raw_spin_lock_init(&priv->htvec_lock); - priv->base = of_iomap(node, 0); - if (!priv->base) { - err = -ENOMEM; - goto free_priv; - } - - /* Interrupt may come from any of the 8 interrupt lines */ - for (i = 0; i < HTVEC_MAX_PARENT_IRQ; i++) { - parent_irq[i] = irq_of_parse_and_map(node, i); - if (parent_irq[i] <= 0) - break; - - priv->num_parents++; - } - if (!priv->num_parents) { - pr_err("Failed to get parent irqs\n"); - err = -ENODEV; - goto iounmap_base; - } - - priv->htvec_domain = irq_domain_create_linear(of_node_to_fwnode(node), + /* Setup IRQ domain */ + priv->htvec_domain = irq_domain_create_linear(priv->domain_handle, (VEC_COUNT_PER_REG * priv->num_parents), &htvec_domain_ops, priv); if (!priv->htvec_domain) { - pr_err("Failed to create IRQ domain\n"); - err = -ENOMEM; - goto irq_dispose; + pr_err("loongson-htvec: cannot add IRQ domain\n"); + goto iounmap_base; } htvec_reset(priv); - for (i = 0; i < priv->num_parents; i++) + for (i = 0; i < priv->num_parents; i++) { irq_set_chained_handler_and_data(parent_irq[i], htvec_irq_dispatch, priv); + } + + htvec_priv = priv; return 0; -irq_dispose: - for (; i > 0; i--) - irq_dispose_mapping(parent_irq[i - 1]); iounmap_base: iounmap(priv->base); -free_priv: + priv->domain_handle = NULL; kfree(priv); - return err; + return -EINVAL; +} + +#ifdef CONFIG_OF + +static int htvec_of_init(struct device_node *node, + struct device_node *parent) +{ + int i, err; + int parent_irq[8]; + int num_parents = 0; + struct resource res; + + if (of_address_to_resource(node, 0, &res)) + return -EINVAL; + + /* Interrupt may come from any of the 8 interrupt lines */ + for (i = 0; i < HTVEC_MAX_PARENT_IRQ; i++) { + parent_irq[i] = irq_of_parse_and_map(node, i); + if (parent_irq[i] <= 0) + break; + + num_parents++; + } + + err = htvec_init(res.start, resource_size(&res), + num_parents, parent_irq, of_node_to_fwnode(node)); + if (err < 0) + return err; + + return 0; } IRQCHIP_DECLARE(htvec, "loongson,htvec-1.0", htvec_of_init); + +#endif + +#ifdef CONFIG_ACPI + +struct irq_domain *htvec_acpi_init(struct irq_domain *parent, + struct acpi_madt_ht_pic *acpi_htvec) +{ + int i, ret; + int num_parents, parent_irq[8]; + struct fwnode_handle *domain_handle; + + if (!acpi_htvec) + return NULL; + + num_parents = HTVEC_MAX_PARENT_IRQ; + + domain_handle = irq_domain_alloc_fwnode((phys_addr_t *)acpi_htvec); + if (!domain_handle) { + pr_err("Unable to allocate domain handle\n"); + return NULL; + } + + /* Interrupt may come from any of the 8 interrupt lines */ + for (i = 0; i < HTVEC_MAX_PARENT_IRQ; i++) + parent_irq[i] = irq_create_mapping(parent, acpi_htvec->cascade[i]); + + ret = htvec_init(acpi_htvec->address, acpi_htvec->size, + num_parents, parent_irq, domain_handle); + if (ret < 0) + return NULL; + + return irq_find_matching_fwnode(domain_handle, DOMAIN_BUS_ANY); +} + +#endif -- 2.27.0