Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp1343207pxb; Thu, 16 Sep 2021 05:36:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzE5PIiIOnCRQgE0YwVQ/GzW+YIEL+G1ftA66/Xk7nMroTLclmcd5Pc+oIRTM3AdCKjnO8n X-Received: by 2002:a17:906:781:: with SMTP id l1mr6109793ejc.289.1631795771106; Thu, 16 Sep 2021 05:36:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631795771; cv=none; d=google.com; s=arc-20160816; b=CU36qwQPwt3mr2jBhnmuufsZXLc1BFdHD+8DAhWe7IuFcCEMJjwkYMtpCCQiYcurPD qBeUazZunSCeLlSPGbZWP7ZbyiEmdbO5BZDhuDp21b5gx33DOpnTaWSI4Yj59dZo/5rc SLQpaMhFe4SV00mDfgiFCWf0C1XoL1G9Mv+Im9x0/pJjajpSTzpQaPT5rQtaE0hFxXh+ 5F8aToFHjOFyLNJoZLld5Dq5NdmRxgx7d8kAacE1grBDZ/x7mupm4MyqfTpxWff/vcpq U6wwBIcWXFKG82fJGjHPRTVeqP8zi9v8uN6cpWotIUlvb/zHvQR1rERMVOlu2+uUOs6H 0ZKQ== 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=BOpx+eQtj6XPaXvp4R79NIdEg0sJeDbjpG+qTbr2zeA=; b=xhReWobU3TVG0hHc2K/5h8KyQks38nQNAbQjvPHoWlWHP4FNzp0bheSjgUquJ2MWLB uJ6Jf3ZIT5YWla9O5IStVNQOdnXqNnVLch2BXBE1x8YmrMVsbJrm6QZyWG0HFQjz6RRy /a9l38PmOWS2AjEGI2oAm9i0XajzhiT93TpBQ1iCBALzr+nrbaq/KP28MA6z3YRqyTw6 Rb+jkMoRRT0jHhxSGn8zNJEPTL4P+TUpGjvQs6WB5p7MTGDcT3GYkl/J60ySSaQ52z08 LPA94XF0aAfMej+8MFfe4w/tTPXUpIk5oqSMaot4wdsh9uLZX12g7GQakReqzT5zMEqd 65KQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c16si3356760edr.514.2021.09.16.05.35.47; Thu, 16 Sep 2021 05:36:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239510AbhIPMfT (ORCPT + 99 others); Thu, 16 Sep 2021 08:35:19 -0400 Received: from mail.kernel.org ([198.145.29.99]:39262 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230299AbhIPMfS (ORCPT ); Thu, 16 Sep 2021 08:35:18 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 03C2A60231; Thu, 16 Sep 2021 12:33:55 +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 V5 02/10] irqchip/loongson-pch-pic: Add ACPI init support Date: Thu, 16 Sep 2021 20:31:30 +0800 Message-Id: <20210916123138.3490474-3-chenhuacai@loongson.cn> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210916123138.3490474-1-chenhuacai@loongson.cn> References: <20210916123138.3490474-1-chenhuacai@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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. Signed-off-by: Huacai Chen --- drivers/irqchip/irq-loongson-pch-pic.c | 105 ++++++++++++++++++------- 1 file changed, 78 insertions(+), 27 deletions(-) diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c index a4eb8a2181c7..6fd0c983e02a 100644 --- a/drivers/irqchip/irq-loongson-pch-pic.c +++ b/drivers/irqchip/irq-loongson-pch-pic.c @@ -33,13 +33,18 @@ #define PIC_REG_IDX(irq_id) ((irq_id) / PIC_COUNT_PER_REG) #define PIC_REG_BIT(irq_id) ((irq_id) % PIC_COUNT_PER_REG) +static int nr_pics; + struct pch_pic { void __iomem *base; struct irq_domain *pic_domain; + struct fwnode_handle *domain_handle; u32 ht_vec_base; raw_spinlock_t pic_lock; }; +struct pch_pic *pch_pic_priv[2]; + static void pch_pic_bitset(struct pch_pic *priv, int offset, int bit) { u32 reg; @@ -180,7 +185,7 @@ static void pch_pic_reset(struct pch_pic *priv) int i; for (i = 0; i < PIC_COUNT; i++) { - /* Write vectored ID */ + /* Write vector ID */ writeb(priv->ht_vec_base + i, priv->base + PCH_INT_HTVEC(i)); /* Hardcode route to HT0 Lo */ writeb(1, priv->base + PCH_INT_ROUTE(i)); @@ -198,50 +203,37 @@ static void pch_pic_reset(struct pch_pic *priv) } } -static int pch_pic_of_init(struct device_node *node, - struct device_node *parent) +static int pch_pic_init(phys_addr_t addr, unsigned long size, int vec_base, + struct irq_domain *parent_domain, struct fwnode_handle *domain_handle) { + int vec_count; struct pch_pic *priv; - struct irq_domain *parent_domain; - int err; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; raw_spin_lock_init(&priv->pic_lock); - priv->base = of_iomap(node, 0); - if (!priv->base) { - err = -ENOMEM; + priv->base = ioremap(addr, size); + if (!priv->base) goto free_priv; - } - parent_domain = irq_find_host(parent); - if (!parent_domain) { - pr_err("Failed to find the parent domain\n"); - err = -ENXIO; - goto iounmap_base; - } + priv->domain_handle = domain_handle; - if (of_property_read_u32(node, "loongson,pic-base-vec", - &priv->ht_vec_base)) { - pr_err("Failed to determine pic-base-vec\n"); - err = -EINVAL; - goto iounmap_base; - } + priv->ht_vec_base = vec_base; + vec_count = ((readq(priv->base) >> 48) & 0xff) + 1; priv->pic_domain = irq_domain_create_hierarchy(parent_domain, 0, - PIC_COUNT, - of_node_to_fwnode(node), - &pch_pic_domain_ops, - priv); + vec_count, priv->domain_handle, + &pch_pic_domain_ops, priv); + if (!priv->pic_domain) { pr_err("Failed to create IRQ domain\n"); - err = -ENOMEM; goto iounmap_base; } pch_pic_reset(priv); + pch_pic_priv[nr_pics++] = priv; return 0; @@ -250,7 +242,66 @@ static int pch_pic_of_init(struct device_node *node, free_priv: kfree(priv); - return err; + return -EINVAL; +} + +#ifdef CONFIG_OF + +static int pch_pic_of_init(struct device_node *node, + struct device_node *parent) +{ + int err, vec_base; + struct resource res; + struct irq_domain *parent_domain; + + if (of_address_to_resource(node, 0, &res)) + return -EINVAL; + + parent_domain = irq_find_host(parent); + if (!parent_domain) { + pr_err("Failed to find the parent domain\n"); + return -ENXIO; + } + + if (of_property_read_u32(node, "loongson,pic-base-vec", &vec_base)) { + pr_err("Failed to determine pic-base-vec\n"); + return -EINVAL; + } + + err = pch_pic_init(res.start, resource_size(&res), vec_base, + parent_domain, of_node_to_fwnode(node)); + if (err < 0) + return err; + + return 0; } IRQCHIP_DECLARE(pch_pic, "loongson,pch-pic-1.0", pch_pic_of_init); + +#endif + +#ifdef CONFIG_ACPI + +struct irq_domain *pch_pic_acpi_init(struct irq_domain *parent, + struct acpi_madt_bio_pic *acpi_pchpic) +{ + int ret, vec_base; + struct fwnode_handle *domain_handle; + + vec_base = acpi_pchpic->gsi_base - GSI_MIN_PCH_IRQ; + + domain_handle = irq_domain_alloc_fwnode((phys_addr_t *)acpi_pchpic); + if (!domain_handle) { + pr_err("Unable to allocate domain handle\n"); + return NULL; + } + + ret = pch_pic_init(acpi_pchpic->address, acpi_pchpic->size, + vec_base, parent, domain_handle); + if (ret < 0) + return NULL; + + return irq_find_matching_fwnode(domain_handle, DOMAIN_BUS_ANY); +} + +#endif -- 2.27.0