From patchwork Fri Jan 23 00:44:39 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Stone X-Patchwork-Id: 43557 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ee0-f70.google.com (mail-ee0-f70.google.com [74.125.83.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2C780218DB for ; Fri, 23 Jan 2015 00:45:05 +0000 (UTC) Received: by mail-ee0-f70.google.com with SMTP id c13sf3266566eek.1 for ; Thu, 22 Jan 2015 16:45:04 -0800 (PST) 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:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=0m+zYIfKuwfjN0QkcjgO4pRfzz3e6ktLE9f6idb2olQ=; b=N6FO1qQc1jX6kWht7vc6E9VBzF7e7Tb0PS44tiH9iRiM2RF3w/T1Lh5MNBYY6Rgxgq HMQFmxpRCjchox8P8V91yQNI+Prkh7NR+yWenVo+hFR6V26XwRQUFpG+aQ6XvpOEUP0J Th8v8638BVdTrTSKUhhUB8TxWB4R5raWgYkxSTI1llf7Xw7DDJoAYVHJy4yrMEb5daXF WwRjVKDB5ImEDD/ZKep8HSRAPRc2rohtrCYMpTQ//BWwcdXeYdMopckDHgPu+wDamgoa Kweqlvzqfop0EC08Kt4mRfj5rpXEWM/2dy74UJoE31UlZ8EwWaobWkT3tqzlpZHbaPsk /jNg== X-Gm-Message-State: ALoCoQmNCuhl4dk+BR6XOZo/HXfWt3O35FZ/whHZFAYdrAXDUgycpjyiwkd60EL3T5pnROhPu4NF X-Received: by 10.180.93.165 with SMTP id cv5mr744235wib.6.1421973904371; Thu, 22 Jan 2015 16:45:04 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.42.133 with SMTP id o5ls196127lal.78.gmail; Thu, 22 Jan 2015 16:45:04 -0800 (PST) X-Received: by 10.112.151.4 with SMTP id um4mr4726775lbb.50.1421973904208; Thu, 22 Jan 2015 16:45:04 -0800 (PST) Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com. [209.85.217.181]) by mx.google.com with ESMTPS id dd11si23429995lac.130.2015.01.22.16.45.04 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Jan 2015 16:45:04 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) client-ip=209.85.217.181; Received: by mail-lb0-f181.google.com with SMTP id u10so4518225lbd.12 for ; Thu, 22 Jan 2015 16:45:04 -0800 (PST) X-Received: by 10.112.64.35 with SMTP id l3mr4559602lbs.82.1421973904059; Thu, 22 Jan 2015 16:45:04 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.9.200 with SMTP id c8csp71000lbb; Thu, 22 Jan 2015 16:45:02 -0800 (PST) X-Received: by 10.107.36.210 with SMTP id k201mr1051387iok.80.1421973901407; Thu, 22 Jan 2015 16:45:01 -0800 (PST) Received: from mail-ie0-f178.google.com (mail-ie0-f178.google.com. [209.85.223.178]) by mx.google.com with ESMTPS id t5si4009373igm.14.2015.01.22.16.45.00 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Jan 2015 16:45:01 -0800 (PST) Received-SPF: pass (google.com: domain of al.stone@linaro.org designates 209.85.223.178 as permitted sender) client-ip=209.85.223.178; Received: by mail-ie0-f178.google.com with SMTP id rp18so4603731iec.9 for ; Thu, 22 Jan 2015 16:45:00 -0800 (PST) X-Received: by 10.42.239.145 with SMTP id kw17mr6468503icb.55.1421973900614; Thu, 22 Jan 2015 16:45:00 -0800 (PST) Received: from fidelio.ahs3.com (c-50-134-239-249.hsd1.co.comcast.net. [50.134.239.249]) by mx.google.com with ESMTPSA id k18sm4026037igt.5.2015.01.22.16.44.58 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Jan 2015 16:44:59 -0800 (PST) From: al.stone@linaro.org To: tony.luck@intel.com, fenghua.yu@intel.com, rjw@rjwysocki.net, catalin.marinas@arm.com, will.deacon@arm.com, tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com, lenb@kernel.org, robert.moore@intel.com Cc: linux-ia64@vger.kernel.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devel@acpica.org, linaro-acpi@lists.linaro.org, linaro-kernel@lists.linaro.org, patches@linaro.org Subject: [PATCH 2/7] arm64: ACPI: move kernel acpi files to a directory Date: Thu, 22 Jan 2015 17:44:39 -0700 Message-Id: <1421973884-13029-3-git-send-email-al.stone@linaro.org> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1421973884-13029-1-git-send-email-al.stone@linaro.org> References: <1421973884-13029-1-git-send-email-al.stone@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: al.stone@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.217.181 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Al Stone In preparation for adding some additional arch-dependent ACPI files, move the existing ones to a directory to try to keep clutter down in the arch/arm64/kernel directory. There is no functional change. This patch only moves source files. Signed-off-by: Al Stone --- arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/acpi.c | 359 ---------------------------------------- arch/arm64/kernel/acpi/Makefile | 1 + arch/arm64/kernel/acpi/acpi.c | 359 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 361 insertions(+), 360 deletions(-) delete mode 100644 arch/arm64/kernel/acpi.c create mode 100644 arch/arm64/kernel/acpi/Makefile create mode 100644 arch/arm64/kernel/acpi/acpi.c diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 8bdc6bd..d7d622f 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -34,7 +34,7 @@ arm64-obj-$(CONFIG_KGDB) += kgdb.o arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o arm64-obj-$(CONFIG_PCI) += pci.o arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o -arm64-obj-$(CONFIG_ACPI) += acpi.o +arm64-obj-$(CONFIG_ACPI) += acpi/ obj-y += $(arm64-obj-y) vdso/ obj-m += $(arm64-obj-m) diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c deleted file mode 100644 index ea3c9fc..0000000 --- a/arch/arm64/kernel/acpi.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * ARM64 Specific Low-Level ACPI Boot Support - * - * Copyright (C) 2013-2014, Linaro Ltd. - * Author: Al Stone - * Author: Graeme Gregory - * Author: Hanjun Guo - * Author: Tomasz Nowicki - * Author: Naresh Bhat - * - * 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: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -int acpi_noirq; /* skip ACPI IRQ initialization */ -int acpi_disabled; -EXPORT_SYMBOL(acpi_disabled); - -int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */ -EXPORT_SYMBOL(acpi_pci_disabled); - -static int enabled_cpus; /* Processors (GICC) with enabled flag in MADT */ - -/* - * Since we're on ARM, the default interrupt routing model - * clearly has to be GIC. - */ -enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_GIC; - -/* - * __acpi_map_table() will be called before page_init(), so early_ioremap() - * or early_memremap() should be called here to for ACPI table mapping. - */ -char *__init __acpi_map_table(unsigned long phys, unsigned long size) -{ - if (!phys || !size) - return NULL; - - return early_memremap(phys, size); -} - -void __init __acpi_unmap_table(char *map, unsigned long size) -{ - if (!map || !size) - return; - - early_memunmap(map, size); -} - -/** - * acpi_map_gic_cpu_interface - generates a logical cpu number - * and map to MPIDR represented by GICC structure - * @mpidr: CPU's hardware id to register, MPIDR represented in MADT - * @enabled: this cpu is enabled or not - * - * Returns the logical cpu number which maps to MPIDR - */ -static int acpi_map_gic_cpu_interface(u64 mpidr, u8 enabled) -{ - int cpu; - - if (mpidr == INVALID_HWID) { - pr_info("Skip MADT cpu entry with invalid MPIDR\n"); - return -EINVAL; - } - - total_cpus++; - if (!enabled) - return -EINVAL; - - if (enabled_cpus >= NR_CPUS) { - pr_warn("NR_CPUS limit of %d reached, Processor %d/0x%llx ignored.\n", - NR_CPUS, total_cpus, mpidr); - return -EINVAL; - } - - /* No need to check duplicate MPIDRs for the first CPU */ - if (enabled_cpus) { - /* - * Duplicate MPIDRs are a recipe for disaster. Scan - * all initialized entries and check for - * duplicates. If any is found just ignore the CPU. - */ - for_each_possible_cpu(cpu) { - if (cpu_logical_map(cpu) == mpidr) { - pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n", - mpidr); - return -EINVAL; - } - } - - /* allocate a logical cpu id for the new comer */ - cpu = cpumask_next_zero(-1, cpu_possible_mask); - } else { - /* - * First GICC entry must be BSP as ACPI spec said - * in section 5.2.12.15 - */ - if (cpu_logical_map(0) != mpidr) { - pr_err("First GICC entry with MPIDR 0x%llx is not BSP\n", - mpidr); - return -EINVAL; - } - - /* - * boot_cpu_init() already hold bit 0 in cpu_present_mask - * for BSP, no need to allocate again. - */ - cpu = 0; - } - - /* CPU 0 was already initialized */ - if (cpu) { - cpu_ops[cpu] = cpu_get_ops(acpi_psci_present() ? "psci" : NULL); - if (!cpu_ops[cpu]) - return -EINVAL; - - if (cpu_ops[cpu]->cpu_init(NULL, cpu)) - return -EOPNOTSUPP; - - /* map the logical cpu id to cpu MPIDR */ - cpu_logical_map(cpu) = mpidr; - - set_cpu_possible(cpu, true); - } else { - /* get cpu0's ops, no need to return if ops is null */ - cpu_ops[0] = cpu_get_ops(acpi_psci_present() ? "psci" : NULL); - } - - enabled_cpus++; - return cpu; -} - -static int __init -acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header, - const unsigned long end) -{ - struct acpi_madt_generic_interrupt *processor; - - processor = (struct acpi_madt_generic_interrupt *)header; - - if (BAD_MADT_ENTRY(processor, end)) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - acpi_map_gic_cpu_interface(processor->arm_mpidr & MPIDR_HWID_BITMASK, - processor->flags & ACPI_MADT_ENABLED); - - return 0; -} - -/* Parse GIC cpu interface entries in MADT for SMP init */ -void __init acpi_smp_init_cpus(void) -{ - int count; - - /* - * do a partial walk of MADT to determine how many CPUs - * we have including disabled CPUs, and get information - * we need for SMP init - */ - count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, - acpi_parse_gic_cpu_interface, 0); - - if (!count) { - pr_err("No GIC CPU interface entries present\n"); - return; - } else if (count < 0) { - pr_err("Error parsing GIC CPU interface entry\n"); - return; - } - - /* Make boot-up look pretty */ - pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); -} - -int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) -{ - *irq = irq_find_mapping(NULL, gsi); - - return 0; -} -EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); - -/* - * success: return IRQ number (>0) - * failure: return =< 0 - */ -int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) -{ - unsigned int irq; - unsigned int irq_type; - - /* - * ACPI have no bindings to indicate SPI or PPI, so we - * use different mappings from DT in ACPI. - * - * For FDT - * PPI interrupt: in the range [0, 15]; - * SPI interrupt: in the range [0, 987]; - * - * For ACPI, GSI should be unique so using - * the hwirq directly for the mapping: - * PPI interrupt: in the range [16, 31]; - * SPI interrupt: in the range [32, 1019]; - */ - - if (trigger == ACPI_EDGE_SENSITIVE && - polarity == ACPI_ACTIVE_LOW) - irq_type = IRQ_TYPE_EDGE_FALLING; - else if (trigger == ACPI_EDGE_SENSITIVE && - polarity == ACPI_ACTIVE_HIGH) - irq_type = IRQ_TYPE_EDGE_RISING; - else if (trigger == ACPI_LEVEL_SENSITIVE && - polarity == ACPI_ACTIVE_LOW) - irq_type = IRQ_TYPE_LEVEL_LOW; - else if (trigger == ACPI_LEVEL_SENSITIVE && - polarity == ACPI_ACTIVE_HIGH) - irq_type = IRQ_TYPE_LEVEL_HIGH; - else - irq_type = IRQ_TYPE_NONE; - - /* - * Since only one GIC is supported in ACPI 5.0, we can - * create mapping refer to the default domain - */ - irq = irq_create_mapping(NULL, gsi); - if (!irq) - return irq; - - /* Set irq type if specified and different than the current one */ - if (irq_type != IRQ_TYPE_NONE && - irq_type != irq_get_trigger_type(irq)) - irq_set_irq_type(irq, irq_type); - return irq; -} -EXPORT_SYMBOL_GPL(acpi_register_gsi); - -void acpi_unregister_gsi(u32 gsi) -{ -} -EXPORT_SYMBOL_GPL(acpi_unregister_gsi); - -static int __init acpi_parse_fadt(struct acpi_table_header *table) -{ - struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; - - /* - * Revision in table header is the FADT Major revision, - * and there is a minor revision of FADT which was introduced - * by ACPI 5.1, we only deal with ACPI 5.1 or newer revision - * to get arm boot flags, or we will disable ACPI. - */ - if (table->revision > 5 || - (table->revision == 5 && fadt->minor_revision >= 1)) { - /* - * ACPI 5.1 only has two explicit methods to boot up SMP, - * PSCI and Parking protocol, but the Parking protocol is - * only specified for ARMv7 now, so make PSCI as the only - * way for the SMP boot protocol before some updates for - * the ACPI spec or the Parking protocol spec. - */ - if (acpi_psci_present()) - return 0; - - pr_warn("No PSCI support, will not bring up secondary CPUs\n"); - return -EOPNOTSUPP; - } - - pr_warn("Unsupported FADT revision %d.%d, should be 5.1+, will disable ACPI\n", - table->revision, fadt->minor_revision); - disable_acpi(); - - return -EINVAL; -} - -/* - * acpi_boot_table_init() called from setup_arch(), always. - * 1. find RSDP and get its address, and then find XSDT - * 2. extract all tables and checksums them all - * 3. check ACPI FADT revision - * - * We can parse ACPI boot-time tables such as MADT after - * this function is called. - */ -void __init acpi_boot_table_init(void) -{ - /* If acpi_disabled, bail out */ - if (acpi_disabled) - return; - - /* Initialize the ACPI boot-time table parser. */ - if (acpi_table_init()) { - disable_acpi(); - return; - } - - if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt)) - pr_err("Can't find FADT or error happened during parsing FADT\n"); -} - -void __init acpi_gic_init(void) -{ - struct acpi_table_header *table; - acpi_status status; - acpi_size tbl_size; - int err; - - if (acpi_disabled) - return; - - status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size); - if (ACPI_FAILURE(status)) { - const char *msg = acpi_format_exception(status); - - pr_err("Failed to get MADT table, %s\n", msg); - return; - } - - err = gic_v2_acpi_init(table); - if (err) - pr_err("Failed to initialize GIC IRQ controller"); - - early_acpi_os_unmap_memory((char *)table, tbl_size); -} - -static int __init parse_acpi(char *arg) -{ - if (!arg) - return -EINVAL; - - /* "acpi=off" disables both ACPI table parsing and interpreter */ - if (strcmp(arg, "off") == 0) - disable_acpi(); - else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */ - enable_acpi(); - else - return -EINVAL; /* Core will print when we return error */ - - return 0; -} -early_param("acpi", parse_acpi); diff --git a/arch/arm64/kernel/acpi/Makefile b/arch/arm64/kernel/acpi/Makefile new file mode 100644 index 0000000..e049f94 --- /dev/null +++ b/arch/arm64/kernel/acpi/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ACPI) += acpi.o diff --git a/arch/arm64/kernel/acpi/acpi.c b/arch/arm64/kernel/acpi/acpi.c new file mode 100644 index 0000000..ea3c9fc --- /dev/null +++ b/arch/arm64/kernel/acpi/acpi.c @@ -0,0 +1,359 @@ +/* + * ARM64 Specific Low-Level ACPI Boot Support + * + * Copyright (C) 2013-2014, Linaro Ltd. + * Author: Al Stone + * Author: Graeme Gregory + * Author: Hanjun Guo + * Author: Tomasz Nowicki + * Author: Naresh Bhat + * + * 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: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int acpi_noirq; /* skip ACPI IRQ initialization */ +int acpi_disabled; +EXPORT_SYMBOL(acpi_disabled); + +int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */ +EXPORT_SYMBOL(acpi_pci_disabled); + +static int enabled_cpus; /* Processors (GICC) with enabled flag in MADT */ + +/* + * Since we're on ARM, the default interrupt routing model + * clearly has to be GIC. + */ +enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_GIC; + +/* + * __acpi_map_table() will be called before page_init(), so early_ioremap() + * or early_memremap() should be called here to for ACPI table mapping. + */ +char *__init __acpi_map_table(unsigned long phys, unsigned long size) +{ + if (!phys || !size) + return NULL; + + return early_memremap(phys, size); +} + +void __init __acpi_unmap_table(char *map, unsigned long size) +{ + if (!map || !size) + return; + + early_memunmap(map, size); +} + +/** + * acpi_map_gic_cpu_interface - generates a logical cpu number + * and map to MPIDR represented by GICC structure + * @mpidr: CPU's hardware id to register, MPIDR represented in MADT + * @enabled: this cpu is enabled or not + * + * Returns the logical cpu number which maps to MPIDR + */ +static int acpi_map_gic_cpu_interface(u64 mpidr, u8 enabled) +{ + int cpu; + + if (mpidr == INVALID_HWID) { + pr_info("Skip MADT cpu entry with invalid MPIDR\n"); + return -EINVAL; + } + + total_cpus++; + if (!enabled) + return -EINVAL; + + if (enabled_cpus >= NR_CPUS) { + pr_warn("NR_CPUS limit of %d reached, Processor %d/0x%llx ignored.\n", + NR_CPUS, total_cpus, mpidr); + return -EINVAL; + } + + /* No need to check duplicate MPIDRs for the first CPU */ + if (enabled_cpus) { + /* + * Duplicate MPIDRs are a recipe for disaster. Scan + * all initialized entries and check for + * duplicates. If any is found just ignore the CPU. + */ + for_each_possible_cpu(cpu) { + if (cpu_logical_map(cpu) == mpidr) { + pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n", + mpidr); + return -EINVAL; + } + } + + /* allocate a logical cpu id for the new comer */ + cpu = cpumask_next_zero(-1, cpu_possible_mask); + } else { + /* + * First GICC entry must be BSP as ACPI spec said + * in section 5.2.12.15 + */ + if (cpu_logical_map(0) != mpidr) { + pr_err("First GICC entry with MPIDR 0x%llx is not BSP\n", + mpidr); + return -EINVAL; + } + + /* + * boot_cpu_init() already hold bit 0 in cpu_present_mask + * for BSP, no need to allocate again. + */ + cpu = 0; + } + + /* CPU 0 was already initialized */ + if (cpu) { + cpu_ops[cpu] = cpu_get_ops(acpi_psci_present() ? "psci" : NULL); + if (!cpu_ops[cpu]) + return -EINVAL; + + if (cpu_ops[cpu]->cpu_init(NULL, cpu)) + return -EOPNOTSUPP; + + /* map the logical cpu id to cpu MPIDR */ + cpu_logical_map(cpu) = mpidr; + + set_cpu_possible(cpu, true); + } else { + /* get cpu0's ops, no need to return if ops is null */ + cpu_ops[0] = cpu_get_ops(acpi_psci_present() ? "psci" : NULL); + } + + enabled_cpus++; + return cpu; +} + +static int __init +acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_madt_generic_interrupt *processor; + + processor = (struct acpi_madt_generic_interrupt *)header; + + if (BAD_MADT_ENTRY(processor, end)) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + acpi_map_gic_cpu_interface(processor->arm_mpidr & MPIDR_HWID_BITMASK, + processor->flags & ACPI_MADT_ENABLED); + + return 0; +} + +/* Parse GIC cpu interface entries in MADT for SMP init */ +void __init acpi_smp_init_cpus(void) +{ + int count; + + /* + * do a partial walk of MADT to determine how many CPUs + * we have including disabled CPUs, and get information + * we need for SMP init + */ + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, + acpi_parse_gic_cpu_interface, 0); + + if (!count) { + pr_err("No GIC CPU interface entries present\n"); + return; + } else if (count < 0) { + pr_err("Error parsing GIC CPU interface entry\n"); + return; + } + + /* Make boot-up look pretty */ + pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); +} + +int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) +{ + *irq = irq_find_mapping(NULL, gsi); + + return 0; +} +EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); + +/* + * success: return IRQ number (>0) + * failure: return =< 0 + */ +int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) +{ + unsigned int irq; + unsigned int irq_type; + + /* + * ACPI have no bindings to indicate SPI or PPI, so we + * use different mappings from DT in ACPI. + * + * For FDT + * PPI interrupt: in the range [0, 15]; + * SPI interrupt: in the range [0, 987]; + * + * For ACPI, GSI should be unique so using + * the hwirq directly for the mapping: + * PPI interrupt: in the range [16, 31]; + * SPI interrupt: in the range [32, 1019]; + */ + + if (trigger == ACPI_EDGE_SENSITIVE && + polarity == ACPI_ACTIVE_LOW) + irq_type = IRQ_TYPE_EDGE_FALLING; + else if (trigger == ACPI_EDGE_SENSITIVE && + polarity == ACPI_ACTIVE_HIGH) + irq_type = IRQ_TYPE_EDGE_RISING; + else if (trigger == ACPI_LEVEL_SENSITIVE && + polarity == ACPI_ACTIVE_LOW) + irq_type = IRQ_TYPE_LEVEL_LOW; + else if (trigger == ACPI_LEVEL_SENSITIVE && + polarity == ACPI_ACTIVE_HIGH) + irq_type = IRQ_TYPE_LEVEL_HIGH; + else + irq_type = IRQ_TYPE_NONE; + + /* + * Since only one GIC is supported in ACPI 5.0, we can + * create mapping refer to the default domain + */ + irq = irq_create_mapping(NULL, gsi); + if (!irq) + return irq; + + /* Set irq type if specified and different than the current one */ + if (irq_type != IRQ_TYPE_NONE && + irq_type != irq_get_trigger_type(irq)) + irq_set_irq_type(irq, irq_type); + return irq; +} +EXPORT_SYMBOL_GPL(acpi_register_gsi); + +void acpi_unregister_gsi(u32 gsi) +{ +} +EXPORT_SYMBOL_GPL(acpi_unregister_gsi); + +static int __init acpi_parse_fadt(struct acpi_table_header *table) +{ + struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table; + + /* + * Revision in table header is the FADT Major revision, + * and there is a minor revision of FADT which was introduced + * by ACPI 5.1, we only deal with ACPI 5.1 or newer revision + * to get arm boot flags, or we will disable ACPI. + */ + if (table->revision > 5 || + (table->revision == 5 && fadt->minor_revision >= 1)) { + /* + * ACPI 5.1 only has two explicit methods to boot up SMP, + * PSCI and Parking protocol, but the Parking protocol is + * only specified for ARMv7 now, so make PSCI as the only + * way for the SMP boot protocol before some updates for + * the ACPI spec or the Parking protocol spec. + */ + if (acpi_psci_present()) + return 0; + + pr_warn("No PSCI support, will not bring up secondary CPUs\n"); + return -EOPNOTSUPP; + } + + pr_warn("Unsupported FADT revision %d.%d, should be 5.1+, will disable ACPI\n", + table->revision, fadt->minor_revision); + disable_acpi(); + + return -EINVAL; +} + +/* + * acpi_boot_table_init() called from setup_arch(), always. + * 1. find RSDP and get its address, and then find XSDT + * 2. extract all tables and checksums them all + * 3. check ACPI FADT revision + * + * We can parse ACPI boot-time tables such as MADT after + * this function is called. + */ +void __init acpi_boot_table_init(void) +{ + /* If acpi_disabled, bail out */ + if (acpi_disabled) + return; + + /* Initialize the ACPI boot-time table parser. */ + if (acpi_table_init()) { + disable_acpi(); + return; + } + + if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt)) + pr_err("Can't find FADT or error happened during parsing FADT\n"); +} + +void __init acpi_gic_init(void) +{ + struct acpi_table_header *table; + acpi_status status; + acpi_size tbl_size; + int err; + + if (acpi_disabled) + return; + + status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size); + if (ACPI_FAILURE(status)) { + const char *msg = acpi_format_exception(status); + + pr_err("Failed to get MADT table, %s\n", msg); + return; + } + + err = gic_v2_acpi_init(table); + if (err) + pr_err("Failed to initialize GIC IRQ controller"); + + early_acpi_os_unmap_memory((char *)table, tbl_size); +} + +static int __init parse_acpi(char *arg) +{ + if (!arg) + return -EINVAL; + + /* "acpi=off" disables both ACPI table parsing and interpreter */ + if (strcmp(arg, "off") == 0) + disable_acpi(); + else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */ + enable_acpi(); + else + return -EINVAL; /* Core will print when we return error */ + + return 0; +} +early_param("acpi", parse_acpi);