From patchwork Mon May 18 12:59:13 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanjun Guo X-Patchwork-Id: 48689 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f199.google.com (mail-wi0-f199.google.com [209.85.212.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 345EA2121F for ; Mon, 18 May 2015 13:00:55 +0000 (UTC) Received: by wivs14 with SMTP id s14sf22863999wiv.1 for ; Mon, 18 May 2015 06:00:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=qSylz8CunALc7CGQS8kXk979A5JRYRp4jSNChu0iJt4=; b=PKngLAlENFPRy3pFYE2nPLDH7yko+Ng6Cy4FxlCnJTjT4eVzq5ar9GK6TvpfZGWjlr c7TMj3sd/NuH/lVXK8CPiF8Xa6LCmekp8uik0B989oo2AUdDr+yj2LEubfWoZiu7PFDu B4V20vA+q6hxZvGg3RmJ38ZlwU9HiddMqFKXkDv5eBmtkm+8PTaXCKNgfvko5V+chTiW 5FXg+uBboq4bbR5ADgDFOWP+NmRB9LKBf1VWKxxcHiQPfGlmwNRXrRxdk/xFpTLueKx+ Z0YJZWCIC/FCsrF+XrvOCCxn9l+HVwIsbHTicTz2H/L2Q4gUFHzRiX5oeYdnsHbN3oXe wu5A== X-Gm-Message-State: ALoCoQmbqrkoLWwTDBOILjB+FJmZ5a1k/1/AgYNloceRPQHB4lOWppHYiizzG0AW/lRicxJlzx4Q X-Received: by 10.180.97.9 with SMTP id dw9mr9869265wib.2.1431954054528; Mon, 18 May 2015 06:00:54 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.22.99 with SMTP id c3ls695912laf.96.gmail; Mon, 18 May 2015 06:00:54 -0700 (PDT) X-Received: by 10.112.136.166 with SMTP id qb6mr2366125lbb.54.1431954054342; Mon, 18 May 2015 06:00:54 -0700 (PDT) Received: from mail-la0-f51.google.com (mail-la0-f51.google.com. [209.85.215.51]) by mx.google.com with ESMTPS id gk6si6637323lbc.173.2015.05.18.06.00.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 May 2015 06:00:54 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) client-ip=209.85.215.51; Received: by laat2 with SMTP id t2so218297035laa.1 for ; Mon, 18 May 2015 06:00:54 -0700 (PDT) X-Received: by 10.112.13.6 with SMTP id d6mr16973785lbc.117.1431954053199; Mon, 18 May 2015 06:00:53 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp67909lbb; Mon, 18 May 2015 06:00:51 -0700 (PDT) X-Received: by 10.68.65.102 with SMTP id w6mr17147185pbs.10.1431954051209; Mon, 18 May 2015 06:00:51 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ga3si15918397pbb.49.2015.05.18.06.00.50; Mon, 18 May 2015 06:00:51 -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; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752866AbbERNAa (ORCPT + 28 others); Mon, 18 May 2015 09:00:30 -0400 Received: from mail-pa0-f50.google.com ([209.85.220.50]:36022 "EHLO mail-pa0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752686AbbERM74 (ORCPT ); Mon, 18 May 2015 08:59:56 -0400 Received: by pabts4 with SMTP id ts4so151390831pab.3 for ; Mon, 18 May 2015 05:59:55 -0700 (PDT) X-Received: by 10.70.51.67 with SMTP id i3mr44038886pdo.145.1431953995866; Mon, 18 May 2015 05:59:55 -0700 (PDT) Received: from localhost ([180.150.148.224]) by mx.google.com with ESMTPSA id v4sm9637836pbs.0.2015.05.18.05.59.54 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 18 May 2015 05:59:55 -0700 (PDT) From: Hanjun Guo To: Marc Zyngier , Jason Cooper , Will Deacon , Catalin Marinas , "Rafael J. Wysocki" Cc: Jiang Liu , Lorenzo Pieralisi , Arnd Bergmann , Tomasz Nowicki , Grant Likely , Thomas Gleixner , Olof Johansson , linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, linaro-acpi@lists.linaro.org, Hanjun Guo Subject: [PATCH 03/11] irqchip / GIC: Add GIC version support in ACPI MADT Date: Mon, 18 May 2015 20:59:13 +0800 Message-Id: <1431953961-22706-4-git-send-email-hanjun.guo@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1431953961-22706-1-git-send-email-hanjun.guo@linaro.org> References: <1431953961-22706-1-git-send-email-hanjun.guo@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: hanjun.guo@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , There is a field added in ACPI MADT table to indicate the GIC version, so parse the table to get its value for later use. If GIC version presented in MADT is 0, we need to fallback to hardware discovery to get the GIC version. Signed-off-by: Hanjun Guo --- arch/arm64/Kconfig | 1 + drivers/acpi/irq.c | 3 + drivers/irqchip/Kconfig | 3 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-gic-acpi.c | 111 +++++++++++++++++++++++++++++++++++ include/linux/irqchip/arm-gic-acpi.h | 2 + 6 files changed, 121 insertions(+) create mode 100644 drivers/irqchip/irq-gic-acpi.c diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 7796af4..9b80428 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -15,6 +15,7 @@ config ARM64 select ARM_AMBA select ARM_ARCH_TIMER select ARM_GIC + select ARM_GIC_ACPI if ACPI select AUDIT_ARCH_COMPAT_GENERIC select ARM_GIC_V2M if PCI_MSI select ARM_GIC_V3 diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c index 65d6b93..855ead9 100644 --- a/drivers/acpi/irq.c +++ b/drivers/acpi/irq.c @@ -32,6 +32,9 @@ void __init acpi_irqchip_init(void) if (acpi_disabled) return; + if (acpi_gic_version_init()) + return; + for (id = __irqchip_acpi_table; id->id[0]; id++) acpi_table_parse(id->id, (acpi_tbl_table_handler)id->data); } diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 6de62a9..0dd64c5 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -46,6 +46,9 @@ config ARM_VIC_NR The maximum number of VICs available in the system, for power management. +config ARM_GIC_ACPI + bool + config ATMEL_AIC_IRQ bool select GENERIC_IRQ_CHIP diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index dda4927..0bd8e49 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o +obj-$(CONFIG_ARM_GIC_ACPI) += irq-gic-acpi.o obj-$(CONFIG_ARM_NVIC) += irq-nvic.o obj-$(CONFIG_ARM_VIC) += irq-vic.o obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c new file mode 100644 index 0000000..53a86ef --- /dev/null +++ b/drivers/irqchip/irq-gic-acpi.c @@ -0,0 +1,111 @@ +/* + * ACPI based support for ARM GIC init + * + * Copyright (C) 2015, Linaro Ltd. + * Author: Hanjun Guo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define pr_fmt(fmt) "ACPI: GIC: " fmt + +#include +#include +#include +#include + +/* GIC version presented in MADT GIC distributor structure */ +static u8 gic_version __initdata = ACPI_MADT_GIC_VER_UNKNOWN; + +static phys_addr_t dist_phy_base __initdata; + +static int __init +acpi_gic_parse_distributor(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_madt_generic_distributor *dist; + + dist = (struct acpi_madt_generic_distributor *)header; + + if (BAD_MADT_ENTRY(dist, end)) + return -EINVAL; + + gic_version = dist->gic_version; + dist_phy_base = dist->base_address; + return 0; +} + +static int __init +match_gic_redist(struct acpi_subtable_header *header, const unsigned long end) +{ + return 0; +} + +static bool __init acpi_gic_redist_is_present(void) +{ + int count; + + /* scan MADT table to find if we have redistributor entries */ + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, + match_gic_redist, 0); + + /* has at least one GIC redistributor entry */ + if (count > 0) + return true; + else + return false; +} + +int __init acpi_gic_version_init(void) +{ + int count; + void __iomem *dist_base; + u32 reg; + + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, + acpi_gic_parse_distributor, 0); + + if (count <= 0) { + pr_err("No valid GIC distributor entry exists\n"); + return -ENODEV; + } + + if (gic_version >= ACPI_MADT_GIC_VER_RESERVED) { + pr_err("Invalid GIC version %d in MADT\n", gic_version); + return -EINVAL; + } + + /* + * when the GIC version is 0, we fallback to hardware discovery. + * this is also needed to keep compatiable with ACPI 5.1, + * which has no gic_version field in distributor structure and + * reserved as 0. + * + * For hardware discovery, the offset for GICv1/2 and GICv3/4 to + * get the GIC version is different (0xFE8 for GICv1/2 and 0xFFE8 + * for GICv3/4), so we need to handle it separately. + */ + if (gic_version == ACPI_MADT_GIC_VER_UNKNOWN) { + /* it's GICv3/v4 if redistributor is present */ + if (acpi_gic_redist_is_present()) { + dist_base = ioremap(dist_phy_base, + ACPI_GICV3_DIST_MEM_SIZE); + if (!dist_base) + return -ENOMEM; + + reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK; + if (reg == GIC_PIDR2_ARCH_GICv3) + gic_version = ACPI_MADT_GIC_VER_V3; + else + gic_version = ACPI_MADT_GIC_VER_V4; + + iounmap(dist_base); + } else { + gic_version = ACPI_MADT_GIC_VER_V2; + } + } + + return 0; +} diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h index de3419e..0d5f204 100644 --- a/include/linux/irqchip/arm-gic-acpi.h +++ b/include/linux/irqchip/arm-gic-acpi.h @@ -19,11 +19,13 @@ */ #define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K) #define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K) +#define ACPI_GICV3_DIST_MEM_SIZE (SZ_64K) struct acpi_table_header; int gic_v2_acpi_init(struct acpi_table_header *table); void acpi_gic_init(void); +int acpi_gic_version_init(void); #else static inline void acpi_gic_init(void) { } #endif