All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
@ 2014-08-04 15:28 ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

ACPI 5.1 has been released and now be freely available for  
download [1]. It fixed some major gaps to run ACPI on ARM,
this patch just follow the ACPI 5.1 spec and prepare the
code to run ACPI on ARM64.

ACPI 5.1 has some major changes for the following tables and
method which are essential for ARM platforms:

1) MADT table updates.
New fields were introduced to cover MPIDR and virtualization in
GICC, and introduce GICR and GIC MSI frame structure to cover
GICv3 and GICv2m (this patch set only cover GICv2).

2) FADT updates for PSCI
New fields were introduced to cover PSCI and ACPI can use psci
to boot SMP and other PSCI related functions.

3) GTDT
GTDT was updated to support arch timer, memory-mapped tiemr,
SBSA watchdog timer, in this patch, only arch timer tested on
Juno board, so only arch timer init is available.

4) _DSD
_DSD (Device Specific Data) will provide some key values which
presented by FDT before, it makes possible that some devices can
be emumerated in ACPI way, please refer to the document provided
in this patch set for detail.

This patch set is the ARM64 ACPI core patches covered MADT, FADT
and GTDT, _DSD is not covered in this patch set. We first introduce
acpi.c and its related head file which are needed by ACPI core, and
then get RSDP to extract all the ACPI boot-time tables.

When all the boot-time tables (FADT, MADT, GTDT) are ready, then
parse them to init the sytem when booted. Specifically, 
a) we use FADT to init PSCI and use PSCI to boot SMP;
b) Use MADT for GIC init and SMP init;
c) GTDT for arch timer init.

This patch set is based on Rafael's linux-pm tree/linux-next branch,
and I already compiled it OK with:
a) each patch applied on ARM64 with CONFIG_ACPI=y;
b) CONFIG_ACPI=n on ARM64;
c) CONFIG_ACPI=y on x86.

Updates since v1:
  - Set ACPI default off on ARM64 suggested by Olof;
  - Rebase the patch set on top of linux-next branch/linux-pm tree which
    includes the ACPICA for full ACPI 5.1 support.
  - Update the document as suggested;
  - Adress lots of comments from Mark, Sudeep, Randy, Naresh, Olof, Geoff
    and more...

[1]
http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf


Al Stone (3):
  ARM64 / ACPI: Get RSDP and ACPI boot-time tables
  ARM64 / ACPI: Select ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on
    ARM64
  ARM64 / ACPI: Introduce early_param for "acpi" and set ACPI default
    off

Ashwin Chaugule (1):
  ACPI / table: Add new function to get table entries

Graeme Gregory (4):
  ARM64 / ACPI: Introduce lowlevel suspend function
  ARM64 / ACPI: If we chose to boot from acpi then disable FDT
  ARM64 / ACPI: Enable ARM64 in Kconfig
  Documentation: ACPI for ARM64

Hanjun Guo (9):
  ARM64: Move the init of cpu_logical_map(0) before
    unflatten_device_tree()
  ARM64 / ACPI: Make PCI optional for ACPI on ARM64
  ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get
    cpu_possible/present_map
  ACPI / table: Print GIC information when MADT is parsed
  ARM64 / ACPI: Get the enable method for SMP initialization in ACPI
    way
  ACPI / processor: Make it possible to get CPU hardware ID via GICC
  ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
  ARM64 / ACPI: Parse GTDT to initialize arch timer

Tomasz Nowicki (1):
  ARM64 / ACPI: Add GICv2 specific ACPI boot support

 Documentation/arm64/arm-acpi.txt     |  215 +++++++++++++++++++
 Documentation/kernel-parameters.txt  |    5 +-
 arch/arm64/Kconfig                   |    3 +
 arch/arm64/include/asm/acenv.h       |   18 ++
 arch/arm64/include/asm/acpi.h        |  113 ++++++++++
 arch/arm64/include/asm/cpu.h         |   11 +
 arch/arm64/include/asm/pci.h         |   11 +
 arch/arm64/include/asm/smp.h         |    3 +-
 arch/arm64/kernel/Makefile           |    1 +
 arch/arm64/kernel/acpi.c             |  380 ++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/cpu_ops.c          |   62 +++++-
 arch/arm64/kernel/irq.c              |    5 +
 arch/arm64/kernel/psci.c             |   89 ++++++--
 arch/arm64/kernel/setup.c            |   13 +-
 arch/arm64/kernel/smp.c              |   37 +++-
 arch/arm64/kernel/time.c             |    7 +
 drivers/acpi/Kconfig                 |    6 +-
 drivers/acpi/Makefile                |    2 +-
 drivers/acpi/bus.c                   |    3 +
 drivers/acpi/internal.h              |    5 +
 drivers/acpi/processor_core.c        |   37 ++++
 drivers/acpi/tables.c                |  109 ++++++++--
 drivers/clocksource/arm_arch_timer.c |  117 +++++++++--
 drivers/irqchip/irq-gic.c            |  114 ++++++++++
 include/linux/acpi.h                 |    5 +
 include/linux/clocksource.h          |    6 +
 include/linux/irqchip/arm-gic-acpi.h |   36 ++++
 include/linux/pci.h                  |   37 +++-
 28 files changed, 1359 insertions(+), 91 deletions(-)
 create mode 100644 Documentation/arm64/arm-acpi.txt
 create mode 100644 arch/arm64/include/asm/acenv.h
 create mode 100644 arch/arm64/include/asm/acpi.h
 create mode 100644 arch/arm64/include/asm/cpu.h
 create mode 100644 arch/arm64/include/asm/pci.h
 create mode 100644 arch/arm64/kernel/acpi.c
 create mode 100644 include/linux/irqchip/arm-gic-acpi.h

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
@ 2014-08-04 15:28 ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

ACPI 5.1 has been released and now be freely available for  
download [1]. It fixed some major gaps to run ACPI on ARM,
this patch just follow the ACPI 5.1 spec and prepare the
code to run ACPI on ARM64.

ACPI 5.1 has some major changes for the following tables and
method which are essential for ARM platforms:

1) MADT table updates.
New fields were introduced to cover MPIDR and virtualization in
GICC, and introduce GICR and GIC MSI frame structure to cover
GICv3 and GICv2m (this patch set only cover GICv2).

2) FADT updates for PSCI
New fields were introduced to cover PSCI and ACPI can use psci
to boot SMP and other PSCI related functions.

3) GTDT
GTDT was updated to support arch timer, memory-mapped tiemr,
SBSA watchdog timer, in this patch, only arch timer tested on
Juno board, so only arch timer init is available.

4) _DSD
_DSD (Device Specific Data) will provide some key values which
presented by FDT before, it makes possible that some devices can
be emumerated in ACPI way, please refer to the document provided
in this patch set for detail.

This patch set is the ARM64 ACPI core patches covered MADT, FADT
and GTDT, _DSD is not covered in this patch set. We first introduce
acpi.c and its related head file which are needed by ACPI core, and
then get RSDP to extract all the ACPI boot-time tables.

When all the boot-time tables (FADT, MADT, GTDT) are ready, then
parse them to init the sytem when booted. Specifically, 
a) we use FADT to init PSCI and use PSCI to boot SMP;
b) Use MADT for GIC init and SMP init;
c) GTDT for arch timer init.

This patch set is based on Rafael's linux-pm tree/linux-next branch,
and I already compiled it OK with:
a) each patch applied on ARM64 with CONFIG_ACPI=y;
b) CONFIG_ACPI=n on ARM64;
c) CONFIG_ACPI=y on x86.

Updates since v1:
  - Set ACPI default off on ARM64 suggested by Olof;
  - Rebase the patch set on top of linux-next branch/linux-pm tree which
    includes the ACPICA for full ACPI 5.1 support.
  - Update the document as suggested;
  - Adress lots of comments from Mark, Sudeep, Randy, Naresh, Olof, Geoff
    and more...

[1]
http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf


Al Stone (3):
  ARM64 / ACPI: Get RSDP and ACPI boot-time tables
  ARM64 / ACPI: Select ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on
    ARM64
  ARM64 / ACPI: Introduce early_param for "acpi" and set ACPI default
    off

Ashwin Chaugule (1):
  ACPI / table: Add new function to get table entries

Graeme Gregory (4):
  ARM64 / ACPI: Introduce lowlevel suspend function
  ARM64 / ACPI: If we chose to boot from acpi then disable FDT
  ARM64 / ACPI: Enable ARM64 in Kconfig
  Documentation: ACPI for ARM64

Hanjun Guo (9):
  ARM64: Move the init of cpu_logical_map(0) before
    unflatten_device_tree()
  ARM64 / ACPI: Make PCI optional for ACPI on ARM64
  ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get
    cpu_possible/present_map
  ACPI / table: Print GIC information when MADT is parsed
  ARM64 / ACPI: Get the enable method for SMP initialization in ACPI
    way
  ACPI / processor: Make it possible to get CPU hardware ID via GICC
  ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
  ARM64 / ACPI: Parse GTDT to initialize arch timer

Tomasz Nowicki (1):
  ARM64 / ACPI: Add GICv2 specific ACPI boot support

 Documentation/arm64/arm-acpi.txt     |  215 +++++++++++++++++++
 Documentation/kernel-parameters.txt  |    5 +-
 arch/arm64/Kconfig                   |    3 +
 arch/arm64/include/asm/acenv.h       |   18 ++
 arch/arm64/include/asm/acpi.h        |  113 ++++++++++
 arch/arm64/include/asm/cpu.h         |   11 +
 arch/arm64/include/asm/pci.h         |   11 +
 arch/arm64/include/asm/smp.h         |    3 +-
 arch/arm64/kernel/Makefile           |    1 +
 arch/arm64/kernel/acpi.c             |  380 ++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/cpu_ops.c          |   62 +++++-
 arch/arm64/kernel/irq.c              |    5 +
 arch/arm64/kernel/psci.c             |   89 ++++++--
 arch/arm64/kernel/setup.c            |   13 +-
 arch/arm64/kernel/smp.c              |   37 +++-
 arch/arm64/kernel/time.c             |    7 +
 drivers/acpi/Kconfig                 |    6 +-
 drivers/acpi/Makefile                |    2 +-
 drivers/acpi/bus.c                   |    3 +
 drivers/acpi/internal.h              |    5 +
 drivers/acpi/processor_core.c        |   37 ++++
 drivers/acpi/tables.c                |  109 ++++++++--
 drivers/clocksource/arm_arch_timer.c |  117 +++++++++--
 drivers/irqchip/irq-gic.c            |  114 ++++++++++
 include/linux/acpi.h                 |    5 +
 include/linux/clocksource.h          |    6 +
 include/linux/irqchip/arm-gic-acpi.h |   36 ++++
 include/linux/pci.h                  |   37 +++-
 28 files changed, 1359 insertions(+), 91 deletions(-)
 create mode 100644 Documentation/arm64/arm-acpi.txt
 create mode 100644 arch/arm64/include/asm/acenv.h
 create mode 100644 arch/arm64/include/asm/acpi.h
 create mode 100644 arch/arm64/include/asm/cpu.h
 create mode 100644 arch/arm64/include/asm/pci.h
 create mode 100644 arch/arm64/kernel/acpi.c
 create mode 100644 include/linux/irqchip/arm-gic-acpi.h

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 01/18] ARM64: Move the init of cpu_logical_map(0) before unflatten_device_tree()
  2014-08-04 15:28 ` Hanjun Guo
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

It always make sense to initialize CPU0's logical map entry from the
hardware values, so move the initialization of cpu_logical_map(0)
before unflatten_device_tree() which is needed by ACPI code later.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/kernel/setup.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 46d1125..fc50461 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -390,11 +390,11 @@ void __init setup_arch(char **cmdline_p)
 
 	efi_idmap_init();
 
+	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
 	unflatten_device_tree();
 
 	psci_init();
 
-	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
 	cpu_read_bootcpu_ops();
 #ifdef CONFIG_SMP
 	smp_init_cpus();
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 01/18] ARM64: Move the init of cpu_logical_map(0) before unflatten_device_tree()
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

It always make sense to initialize CPU0's logical map entry from the
hardware values, so move the initialization of cpu_logical_map(0)
before unflatten_device_tree() which is needed by ACPI code later.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/kernel/setup.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 46d1125..fc50461 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -390,11 +390,11 @@ void __init setup_arch(char **cmdline_p)
 
 	efi_idmap_init();
 
+	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
 	unflatten_device_tree();
 
 	psci_init();
 
-	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
 	cpu_read_bootcpu_ops();
 #ifdef CONFIG_SMP
 	smp_init_cpus();
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
  2014-08-04 15:28 ` Hanjun Guo
  (?)
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Tomasz Nowicki

From: Al Stone <al.stone@linaro.org>

As we want to get ACPI tables to parse and then use the information
for system initialization, we should get the RSDP (Root System
Description Pointer) first, it then locates Extended Root Description
Table (XSDT) which contains all the 64-bit physical address that
pointer to other boot-time tables.

Introduce acpi.c and its related head file in this patch to provide
fundamental needs of extern variables and functions for ACPI core,
and then get boot-time tables as needed.
  - asm/cpu.h need for ACPI core and will be updated in the future to
    add definitions for arch_(un)register_cpu which are required for
    ACPI based physical CPU hotplug;
  - asm/acenv.h for arch specific ACPICA environments and
    implementation;
  - asm/acpi.h for arch specific variables and functions needed by
    ACPI driver core;
  - acpi.c for ARM64 related ACPI implementation for ACPI driver
    core;

acpi_boot_table_init() is introduced to get RSDP and boot-time tables,
it will be called in setup_arch() before paging_init(), so we should
use eary_memremap() mechanism here to get the RSDP and all the table
pointers.

Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acenv.h |   18 +++++++++++
 arch/arm64/include/asm/acpi.h  |   45 ++++++++++++++++++++++++++
 arch/arm64/include/asm/cpu.h   |   11 +++++++
 arch/arm64/kernel/Makefile     |    1 +
 arch/arm64/kernel/acpi.c       |   69 ++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/setup.c      |    4 +++
 6 files changed, 148 insertions(+)
 create mode 100644 arch/arm64/include/asm/acenv.h
 create mode 100644 arch/arm64/include/asm/acpi.h
 create mode 100644 arch/arm64/include/asm/cpu.h
 create mode 100644 arch/arm64/kernel/acpi.c

diff --git a/arch/arm64/include/asm/acenv.h b/arch/arm64/include/asm/acenv.h
new file mode 100644
index 0000000..3899ee6
--- /dev/null
+++ b/arch/arm64/include/asm/acenv.h
@@ -0,0 +1,18 @@
+/*
+ * ARM64 specific ACPICA environments and implementation
+ *
+ * Copyright (C) 2014, Linaro Ltd.
+ *   Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *   Author: Graeme Gregory <graeme.gregory@linaro.org>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_ACENV_H
+#define _ASM_ACENV_H
+
+#define ACPI_FLUSH_CPU_CACHE() WARN_ONCE(1, "Not currently supported on ARM64")
+
+#endif /* _ASM_ACENV_H */
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
new file mode 100644
index 0000000..e06da63
--- /dev/null
+++ b/arch/arm64/include/asm/acpi.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) 2013-2014, Linaro Ltd.
+ *	Author: Al Stone <al.stone@linaro.org>
+ *	Author: Graeme Gregory <graeme.gregory@linaro.org>
+ *	Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ *  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;
+ */
+
+#ifndef _ASM_ACPI_H
+#define _ASM_ACPI_H
+
+/* Basic configuration for ACPI */
+#ifdef	CONFIG_ACPI
+#define acpi_strict 1	/* No out-of-spec workarounds on ARM64 */
+extern int acpi_disabled;
+extern int acpi_noirq;
+extern int acpi_pci_disabled;
+
+static inline void disable_acpi(void)
+{
+	acpi_disabled = 1;
+	acpi_pci_disabled = 1;
+	acpi_noirq = 1;
+}
+
+/*
+ * Checking for the posibility that the CPU can be initialized from the MADT.
+ * It's used from ACPI core in crash kernel case where boot CPU is not
+ * necessarily CPU0 like spec demands. Since MADT must provide at least one
+ * GICC structure for GIC initialization, CPU will be always available in
+ * MADT on ARM64.
+ */
+static inline bool acpi_has_cpu_in_madt(void)
+{
+	return 1;
+}
+
+static inline void arch_fix_phys_package_id(int num, u32 slot) { }
+
+#endif /* CONFIG_ACPI */
+
+#endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
new file mode 100644
index 0000000..cee7d3f
--- /dev/null
+++ b/arch/arm64/include/asm/cpu.h
@@ -0,0 +1,11 @@
+/*
+ *  Copyright (C) 2013-2014 ARM Ltd.
+ *
+ * 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.
+ */
+#ifndef __ASM_CPU_H
+#define __ASM_CPU_H
+
+#endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index cdaedad..b568c26 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
+arm64-obj-$(CONFIG_ACPI)		+= acpi.o
 
 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
new file mode 100644
index 0000000..395778c
--- /dev/null
+++ b/arch/arm64/kernel/acpi.c
@@ -0,0 +1,69 @@
+/*
+ *  ARM64 Specific Low-Level ACPI Boot Support
+ *
+ *  Copyright (C) 2013-2014, Linaro Ltd.
+ *	Author: Al Stone <al.stone@linaro.org>
+ *	Author: Graeme Gregory <graeme.gregory@linaro.org>
+ *	Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ *  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.
+ */
+
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/cpumask.h>
+#include <linux/memblock.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/bootmem.h>
+#include <linux/smp.h>
+
+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);
+
+/*
+ * __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_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
+ *
+ * We can parse ACPI boot-time tables such as FADT, 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;
+	}
+}
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index fc50461..85c6326 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -43,6 +43,7 @@
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
 #include <linux/efi.h>
+#include <linux/acpi.h>
 
 #include <asm/fixmap.h>
 #include <asm/cputype.h>
@@ -385,6 +386,9 @@ void __init setup_arch(char **cmdline_p)
 	efi_init();
 	arm64_memblock_init();
 
+	/* Parse the ACPI tables for possible boot-time configuration */
+	acpi_boot_table_init();
+
 	paging_init();
 	request_standard_resources();
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Tomasz Nowicki, Hanjun Guo

From: Al Stone <al.stone@linaro.org>

As we want to get ACPI tables to parse and then use the information
for system initialization, we should get the RSDP (Root System
Description Pointer) first, it then locates Extended Root Description
Table (XSDT) which contains all the 64-bit physical address that
pointer to other boot-time tables.

Introduce acpi.c and its related head file in this patch to provide
fundamental needs of extern variables and functions for ACPI core,
and then get boot-time tables as needed.
  - asm/cpu.h need for ACPI core and will be updated in the future to
    add definitions for arch_(un)register_cpu which are required for
    ACPI based physical CPU hotplug;
  - asm/acenv.h for arch specific ACPICA environments and
    implementation;
  - asm/acpi.h for arch specific variables and functions needed by
    ACPI driver core;
  - acpi.c for ARM64 related ACPI implementation for ACPI driver
    core;

acpi_boot_table_init() is introduced to get RSDP and boot-time tables,
it will be called in setup_arch() before paging_init(), so we should
use eary_memremap() mechanism here to get the RSDP and all the table
pointers.

Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acenv.h |   18 +++++++++++
 arch/arm64/include/asm/acpi.h  |   45 ++++++++++++++++++++++++++
 arch/arm64/include/asm/cpu.h   |   11 +++++++
 arch/arm64/kernel/Makefile     |    1 +
 arch/arm64/kernel/acpi.c       |   69 ++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/setup.c      |    4 +++
 6 files changed, 148 insertions(+)
 create mode 100644 arch/arm64/include/asm/acenv.h
 create mode 100644 arch/arm64/include/asm/acpi.h
 create mode 100644 arch/arm64/include/asm/cpu.h
 create mode 100644 arch/arm64/kernel/acpi.c

diff --git a/arch/arm64/include/asm/acenv.h b/arch/arm64/include/asm/acenv.h
new file mode 100644
index 0000000..3899ee6
--- /dev/null
+++ b/arch/arm64/include/asm/acenv.h
@@ -0,0 +1,18 @@
+/*
+ * ARM64 specific ACPICA environments and implementation
+ *
+ * Copyright (C) 2014, Linaro Ltd.
+ *   Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *   Author: Graeme Gregory <graeme.gregory@linaro.org>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_ACENV_H
+#define _ASM_ACENV_H
+
+#define ACPI_FLUSH_CPU_CACHE() WARN_ONCE(1, "Not currently supported on ARM64")
+
+#endif /* _ASM_ACENV_H */
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
new file mode 100644
index 0000000..e06da63
--- /dev/null
+++ b/arch/arm64/include/asm/acpi.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) 2013-2014, Linaro Ltd.
+ *	Author: Al Stone <al.stone@linaro.org>
+ *	Author: Graeme Gregory <graeme.gregory@linaro.org>
+ *	Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ *  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;
+ */
+
+#ifndef _ASM_ACPI_H
+#define _ASM_ACPI_H
+
+/* Basic configuration for ACPI */
+#ifdef	CONFIG_ACPI
+#define acpi_strict 1	/* No out-of-spec workarounds on ARM64 */
+extern int acpi_disabled;
+extern int acpi_noirq;
+extern int acpi_pci_disabled;
+
+static inline void disable_acpi(void)
+{
+	acpi_disabled = 1;
+	acpi_pci_disabled = 1;
+	acpi_noirq = 1;
+}
+
+/*
+ * Checking for the posibility that the CPU can be initialized from the MADT.
+ * It's used from ACPI core in crash kernel case where boot CPU is not
+ * necessarily CPU0 like spec demands. Since MADT must provide at least one
+ * GICC structure for GIC initialization, CPU will be always available in
+ * MADT on ARM64.
+ */
+static inline bool acpi_has_cpu_in_madt(void)
+{
+	return 1;
+}
+
+static inline void arch_fix_phys_package_id(int num, u32 slot) { }
+
+#endif /* CONFIG_ACPI */
+
+#endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
new file mode 100644
index 0000000..cee7d3f
--- /dev/null
+++ b/arch/arm64/include/asm/cpu.h
@@ -0,0 +1,11 @@
+/*
+ *  Copyright (C) 2013-2014 ARM Ltd.
+ *
+ * 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.
+ */
+#ifndef __ASM_CPU_H
+#define __ASM_CPU_H
+
+#endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index cdaedad..b568c26 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
+arm64-obj-$(CONFIG_ACPI)		+= acpi.o
 
 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
new file mode 100644
index 0000000..395778c
--- /dev/null
+++ b/arch/arm64/kernel/acpi.c
@@ -0,0 +1,69 @@
+/*
+ *  ARM64 Specific Low-Level ACPI Boot Support
+ *
+ *  Copyright (C) 2013-2014, Linaro Ltd.
+ *	Author: Al Stone <al.stone@linaro.org>
+ *	Author: Graeme Gregory <graeme.gregory@linaro.org>
+ *	Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ *  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.
+ */
+
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/cpumask.h>
+#include <linux/memblock.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/bootmem.h>
+#include <linux/smp.h>
+
+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);
+
+/*
+ * __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_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
+ *
+ * We can parse ACPI boot-time tables such as FADT, 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;
+	}
+}
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index fc50461..85c6326 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -43,6 +43,7 @@
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
 #include <linux/efi.h>
+#include <linux/acpi.h>
 
 #include <asm/fixmap.h>
 #include <asm/cputype.h>
@@ -385,6 +386,9 @@ void __init setup_arch(char **cmdline_p)
 	efi_init();
 	arm64_memblock_init();
 
+	/* Parse the ACPI tables for possible boot-time configuration */
+	acpi_boot_table_init();
+
 	paging_init();
 	request_standard_resources();
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Al Stone <al.stone@linaro.org>

As we want to get ACPI tables to parse and then use the information
for system initialization, we should get the RSDP (Root System
Description Pointer) first, it then locates Extended Root Description
Table (XSDT) which contains all the 64-bit physical address that
pointer to other boot-time tables.

Introduce acpi.c and its related head file in this patch to provide
fundamental needs of extern variables and functions for ACPI core,
and then get boot-time tables as needed.
  - asm/cpu.h need for ACPI core and will be updated in the future to
    add definitions for arch_(un)register_cpu which are required for
    ACPI based physical CPU hotplug;
  - asm/acenv.h for arch specific ACPICA environments and
    implementation;
  - asm/acpi.h for arch specific variables and functions needed by
    ACPI driver core;
  - acpi.c for ARM64 related ACPI implementation for ACPI driver
    core;

acpi_boot_table_init() is introduced to get RSDP and boot-time tables,
it will be called in setup_arch() before paging_init(), so we should
use eary_memremap() mechanism here to get the RSDP and all the table
pointers.

Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acenv.h |   18 +++++++++++
 arch/arm64/include/asm/acpi.h  |   45 ++++++++++++++++++++++++++
 arch/arm64/include/asm/cpu.h   |   11 +++++++
 arch/arm64/kernel/Makefile     |    1 +
 arch/arm64/kernel/acpi.c       |   69 ++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/setup.c      |    4 +++
 6 files changed, 148 insertions(+)
 create mode 100644 arch/arm64/include/asm/acenv.h
 create mode 100644 arch/arm64/include/asm/acpi.h
 create mode 100644 arch/arm64/include/asm/cpu.h
 create mode 100644 arch/arm64/kernel/acpi.c

diff --git a/arch/arm64/include/asm/acenv.h b/arch/arm64/include/asm/acenv.h
new file mode 100644
index 0000000..3899ee6
--- /dev/null
+++ b/arch/arm64/include/asm/acenv.h
@@ -0,0 +1,18 @@
+/*
+ * ARM64 specific ACPICA environments and implementation
+ *
+ * Copyright (C) 2014, Linaro Ltd.
+ *   Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *   Author: Graeme Gregory <graeme.gregory@linaro.org>
+ *
+ * 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.
+ */
+
+#ifndef _ASM_ACENV_H
+#define _ASM_ACENV_H
+
+#define ACPI_FLUSH_CPU_CACHE() WARN_ONCE(1, "Not currently supported on ARM64")
+
+#endif /* _ASM_ACENV_H */
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
new file mode 100644
index 0000000..e06da63
--- /dev/null
+++ b/arch/arm64/include/asm/acpi.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) 2013-2014, Linaro Ltd.
+ *	Author: Al Stone <al.stone@linaro.org>
+ *	Author: Graeme Gregory <graeme.gregory@linaro.org>
+ *	Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ *  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;
+ */
+
+#ifndef _ASM_ACPI_H
+#define _ASM_ACPI_H
+
+/* Basic configuration for ACPI */
+#ifdef	CONFIG_ACPI
+#define acpi_strict 1	/* No out-of-spec workarounds on ARM64 */
+extern int acpi_disabled;
+extern int acpi_noirq;
+extern int acpi_pci_disabled;
+
+static inline void disable_acpi(void)
+{
+	acpi_disabled = 1;
+	acpi_pci_disabled = 1;
+	acpi_noirq = 1;
+}
+
+/*
+ * Checking for the posibility that the CPU can be initialized from the MADT.
+ * It's used from ACPI core in crash kernel case where boot CPU is not
+ * necessarily CPU0 like spec demands. Since MADT must provide at least one
+ * GICC structure for GIC initialization, CPU will be always available in
+ * MADT on ARM64.
+ */
+static inline bool acpi_has_cpu_in_madt(void)
+{
+	return 1;
+}
+
+static inline void arch_fix_phys_package_id(int num, u32 slot) { }
+
+#endif /* CONFIG_ACPI */
+
+#endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
new file mode 100644
index 0000000..cee7d3f
--- /dev/null
+++ b/arch/arm64/include/asm/cpu.h
@@ -0,0 +1,11 @@
+/*
+ *  Copyright (C) 2013-2014 ARM Ltd.
+ *
+ * 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.
+ */
+#ifndef __ASM_CPU_H
+#define __ASM_CPU_H
+
+#endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index cdaedad..b568c26 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
+arm64-obj-$(CONFIG_ACPI)		+= acpi.o
 
 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
new file mode 100644
index 0000000..395778c
--- /dev/null
+++ b/arch/arm64/kernel/acpi.c
@@ -0,0 +1,69 @@
+/*
+ *  ARM64 Specific Low-Level ACPI Boot Support
+ *
+ *  Copyright (C) 2013-2014, Linaro Ltd.
+ *	Author: Al Stone <al.stone@linaro.org>
+ *	Author: Graeme Gregory <graeme.gregory@linaro.org>
+ *	Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ *  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.
+ */
+
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/cpumask.h>
+#include <linux/memblock.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/bootmem.h>
+#include <linux/smp.h>
+
+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);
+
+/*
+ * __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_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
+ *
+ * We can parse ACPI boot-time tables such as FADT, 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;
+	}
+}
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index fc50461..85c6326 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -43,6 +43,7 @@
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
 #include <linux/efi.h>
+#include <linux/acpi.h>
 
 #include <asm/fixmap.h>
 #include <asm/cputype.h>
@@ -385,6 +386,9 @@ void __init setup_arch(char **cmdline_p)
 	efi_init();
 	arm64_memblock_init();
 
+	/* Parse the ACPI tables for possible boot-time configuration */
+	acpi_boot_table_init();
+
 	paging_init();
 	request_standard_resources();
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 03/18] ARM64 / ACPI: Introduce lowlevel suspend function
  2014-08-04 15:28 ` Hanjun Guo
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

From: Graeme Gregory <graeme.gregory@linaro.org>

acpi_wakeup_address is used on x86 as the address bios jumps into
when machine wakes up from suspend. As arm64 does not have such a
bios this mechanism will be provided by other means. But the define
is still required inside the acpi core.

Introduce a null stub for acpi_suspend_lowlevel as this is also
required by core. This will be filled in when standards are
defined for arm64 ACPI global power states.

Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acpi.h |   12 ++++++++++++
 arch/arm64/kernel/acpi.c      |    7 +++++++
 2 files changed, 19 insertions(+)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index e06da63..6400312 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -40,6 +40,18 @@ static inline bool acpi_has_cpu_in_madt(void)
 
 static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 
+/* Low-level suspend routine.
+ *
+ * ACPI S-states for ARM64 have to be defined
+ * and approved before doing anything else, maybe
+ * we need update the ACPI spec, here we
+ * just introduce function and macro needed by
+ * ACPI core as IA64 did, and revisit them when
+ * the spec is ready.
+ */
+extern int (*acpi_suspend_lowlevel)(void);
+#define acpi_wakeup_address 0
+
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 395778c..9cf9127 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -67,3 +67,10 @@ void __init acpi_boot_table_init(void)
 		return;
 	}
 }
+
+/*
+ * acpi_suspend_lowlevel() - save kernel state and suspend.
+ *
+ * TBD when ARM/ARM64 starts to support suspend...
+ */
+int (*acpi_suspend_lowlevel)(void) = NULL;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 03/18] ARM64 / ACPI: Introduce lowlevel suspend function
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Graeme Gregory <graeme.gregory@linaro.org>

acpi_wakeup_address is used on x86 as the address bios jumps into
when machine wakes up from suspend. As arm64 does not have such a
bios this mechanism will be provided by other means. But the define
is still required inside the acpi core.

Introduce a null stub for acpi_suspend_lowlevel as this is also
required by core. This will be filled in when standards are
defined for arm64 ACPI global power states.

Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acpi.h |   12 ++++++++++++
 arch/arm64/kernel/acpi.c      |    7 +++++++
 2 files changed, 19 insertions(+)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index e06da63..6400312 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -40,6 +40,18 @@ static inline bool acpi_has_cpu_in_madt(void)
 
 static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 
+/* Low-level suspend routine.
+ *
+ * ACPI S-states for ARM64 have to be defined
+ * and approved before doing anything else, maybe
+ * we need update the ACPI spec, here we
+ * just introduce function and macro needed by
+ * ACPI core as IA64 did, and revisit them when
+ * the spec is ready.
+ */
+extern int (*acpi_suspend_lowlevel)(void);
+#define acpi_wakeup_address 0
+
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 395778c..9cf9127 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -67,3 +67,10 @@ void __init acpi_boot_table_init(void)
 		return;
 	}
 }
+
+/*
+ * acpi_suspend_lowlevel() - save kernel state and suspend.
+ *
+ * TBD when ARM/ARM64 starts to support suspend...
+ */
+int (*acpi_suspend_lowlevel)(void) = NULL;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 04/18] ARM64 / ACPI: Make PCI optional for ACPI on ARM64
  2014-08-04 15:28 ` Hanjun Guo
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

As PCI for ARM64 is not ready, so introduce some stub functions
to make PCI optional for ACPI, and make ACPI core run without
CONFIG_PCI on ARM64.

Since ACPI on X86 and IA64 depends on PCI and this patch only makes
PCI optional for ARM64, it will not break anything on X86 and IA64.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/pci.h |   11 +++++++++++
 drivers/acpi/Makefile        |    2 +-
 drivers/acpi/internal.h      |    5 +++++
 include/linux/pci.h          |   37 +++++++++++++++++++++++++++----------
 4 files changed, 44 insertions(+), 11 deletions(-)
 create mode 100644 arch/arm64/include/asm/pci.h

diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
new file mode 100644
index 0000000..250cd24
--- /dev/null
+++ b/arch/arm64/include/asm/pci.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_PCI_H
+#define __ASM_PCI_H
+#ifdef __KERNEL__
+
+/*
+ * PCI address space differs from physical memory address space
+ */
+#define PCI_DMA_BUS_IS_PHYS	(0)
+
+#endif  /* __KERNEL__ */
+#endif  /* __ASM_PCI_H */
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 505d4d7..8e9bbe6 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -39,7 +39,7 @@ acpi-y				+= processor_core.o
 acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o
 acpi-y				+= ec.o
 acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
-acpi-y				+= pci_root.o pci_link.o pci_irq.o
+acpi-$(CONFIG_PCI)		+= pci_root.o pci_link.o pci_irq.o
 acpi-y				+= acpi_lpss.o
 acpi-y				+= acpi_platform.o
 acpi-y				+= acpi_pnp.o
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 4c5cf77..e1e6487 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -26,8 +26,13 @@
 acpi_status acpi_os_initialize1(void);
 int init_acpi_device_notify(void);
 int acpi_scan_init(void);
+#ifdef CONFIG_PCI
 void acpi_pci_root_init(void);
 void acpi_pci_link_init(void);
+#else
+static inline void acpi_pci_root_init(void) {}
+static inline void acpi_pci_link_init(void) {}
+#endif
 void acpi_processor_init(void);
 void acpi_platform_init(void);
 void acpi_pnp_init(void);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 466bcd1..8e83281 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -558,15 +558,6 @@ struct pci_ops {
 	int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
 };
 
-/*
- * ACPI needs to be able to access PCI config space before we've done a
- * PCI bus scan and created pci_bus structures.
- */
-int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
-		 int reg, int len, u32 *val);
-int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
-		  int reg, int len, u32 val);
-
 struct pci_bus_region {
 	dma_addr_t start;
 	dma_addr_t end;
@@ -1293,6 +1284,16 @@ typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
 		      unsigned int command_bits, u32 flags);
 void pci_register_set_vga_state(arch_set_vga_state_t func);
 
+/*
+ * ACPI needs to be able to access PCI config space before we've done a
+ * PCI bus scan and created pci_bus structures.
+ */
+int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
+		 int reg, int len, u32 *val);
+int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
+		  int reg, int len, u32 val);
+void pcibios_penalize_isa_irq(int irq, int active);
+
 #else /* CONFIG_PCI is not enabled */
 
 /*
@@ -1394,6 +1395,23 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
 						unsigned int devfn)
 { return NULL; }
 
+static inline struct pci_bus *pci_find_bus(int domain, int busnr)
+{ return NULL; }
+
+static inline int pci_bus_write_config_byte(struct pci_bus *bus,
+				unsigned int devfn, int where, u8 val)
+{ return -ENOSYS; }
+
+static inline int raw_pci_read(unsigned int domain, unsigned int bus,
+			unsigned int devfn, int reg, int len, u32 *val)
+{ return -ENOSYS; }
+
+static inline int raw_pci_write(unsigned int domain, unsigned int bus,
+			unsigned int devfn, int reg, int len, u32 val)
+{ return -ENOSYS; }
+
+static inline void pcibios_penalize_isa_irq(int irq, int active) { }
+
 static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
 static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
 
@@ -1597,7 +1615,6 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev,
 				 enum pcie_reset_state state);
 int pcibios_add_device(struct pci_dev *dev);
 void pcibios_release_device(struct pci_dev *dev);
-void pcibios_penalize_isa_irq(int irq, int active);
 
 #ifdef CONFIG_HIBERNATE_CALLBACKS
 extern struct dev_pm_ops pcibios_pm_ops;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 04/18] ARM64 / ACPI: Make PCI optional for ACPI on ARM64
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

As PCI for ARM64 is not ready, so introduce some stub functions
to make PCI optional for ACPI, and make ACPI core run without
CONFIG_PCI on ARM64.

Since ACPI on X86 and IA64 depends on PCI and this patch only makes
PCI optional for ARM64, it will not break anything on X86 and IA64.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/pci.h |   11 +++++++++++
 drivers/acpi/Makefile        |    2 +-
 drivers/acpi/internal.h      |    5 +++++
 include/linux/pci.h          |   37 +++++++++++++++++++++++++++----------
 4 files changed, 44 insertions(+), 11 deletions(-)
 create mode 100644 arch/arm64/include/asm/pci.h

diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
new file mode 100644
index 0000000..250cd24
--- /dev/null
+++ b/arch/arm64/include/asm/pci.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_PCI_H
+#define __ASM_PCI_H
+#ifdef __KERNEL__
+
+/*
+ * PCI address space differs from physical memory address space
+ */
+#define PCI_DMA_BUS_IS_PHYS	(0)
+
+#endif  /* __KERNEL__ */
+#endif  /* __ASM_PCI_H */
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 505d4d7..8e9bbe6 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -39,7 +39,7 @@ acpi-y				+= processor_core.o
 acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o
 acpi-y				+= ec.o
 acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
-acpi-y				+= pci_root.o pci_link.o pci_irq.o
+acpi-$(CONFIG_PCI)		+= pci_root.o pci_link.o pci_irq.o
 acpi-y				+= acpi_lpss.o
 acpi-y				+= acpi_platform.o
 acpi-y				+= acpi_pnp.o
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 4c5cf77..e1e6487 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -26,8 +26,13 @@
 acpi_status acpi_os_initialize1(void);
 int init_acpi_device_notify(void);
 int acpi_scan_init(void);
+#ifdef CONFIG_PCI
 void acpi_pci_root_init(void);
 void acpi_pci_link_init(void);
+#else
+static inline void acpi_pci_root_init(void) {}
+static inline void acpi_pci_link_init(void) {}
+#endif
 void acpi_processor_init(void);
 void acpi_platform_init(void);
 void acpi_pnp_init(void);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 466bcd1..8e83281 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -558,15 +558,6 @@ struct pci_ops {
 	int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
 };
 
-/*
- * ACPI needs to be able to access PCI config space before we've done a
- * PCI bus scan and created pci_bus structures.
- */
-int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
-		 int reg, int len, u32 *val);
-int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
-		  int reg, int len, u32 val);
-
 struct pci_bus_region {
 	dma_addr_t start;
 	dma_addr_t end;
@@ -1293,6 +1284,16 @@ typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
 		      unsigned int command_bits, u32 flags);
 void pci_register_set_vga_state(arch_set_vga_state_t func);
 
+/*
+ * ACPI needs to be able to access PCI config space before we've done a
+ * PCI bus scan and created pci_bus structures.
+ */
+int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
+		 int reg, int len, u32 *val);
+int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
+		  int reg, int len, u32 val);
+void pcibios_penalize_isa_irq(int irq, int active);
+
 #else /* CONFIG_PCI is not enabled */
 
 /*
@@ -1394,6 +1395,23 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
 						unsigned int devfn)
 { return NULL; }
 
+static inline struct pci_bus *pci_find_bus(int domain, int busnr)
+{ return NULL; }
+
+static inline int pci_bus_write_config_byte(struct pci_bus *bus,
+				unsigned int devfn, int where, u8 val)
+{ return -ENOSYS; }
+
+static inline int raw_pci_read(unsigned int domain, unsigned int bus,
+			unsigned int devfn, int reg, int len, u32 *val)
+{ return -ENOSYS; }
+
+static inline int raw_pci_write(unsigned int domain, unsigned int bus,
+			unsigned int devfn, int reg, int len, u32 val)
+{ return -ENOSYS; }
+
+static inline void pcibios_penalize_isa_irq(int irq, int active) { }
+
 static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
 static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
 
@@ -1597,7 +1615,6 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev,
 				 enum pcie_reset_state state);
 int pcibios_add_device(struct pci_dev *dev);
 void pcibios_release_device(struct pci_dev *dev);
-void pcibios_penalize_isa_irq(int irq, int active);
 
 #ifdef CONFIG_HIBERNATE_CALLBACKS
 extern struct dev_pm_ops pcibios_pm_ops;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-04 15:28 ` Hanjun Guo
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
the former signals to the OS that the hardware is PSCI compliant.
The latter selects the appropriate conduit for PSCI calls by
toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
(SMC).

FADT table contains such information, parse FADT to get the flags
for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
function IDs, which means that only PSCI 0.2+ is supported in ACPI.

At the same time, only ACPI 5.1 or higher verison supports PSCI,
and FADT Major.Minor version was introduced in ACPI 5.1, so we
will check the version and only parse FADT table with version >= 5.1.

If firmware provides ACPI tables with ACPI version less than 5.1,
OS will be messed up with those information and have no way to
bring up secondery CPUs, so disable ACPI if we get an FADT table
with version less that 5.1.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
---
 arch/arm64/include/asm/acpi.h |   12 ++++++
 arch/arm64/kernel/acpi.c      |   37 +++++++++++++++++
 arch/arm64/kernel/psci.c      |   89 ++++++++++++++++++++++++++++++-----------
 arch/arm64/kernel/setup.c     |    2 +
 4 files changed, 117 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 6400312..6e04868 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -19,6 +19,18 @@ extern int acpi_disabled;
 extern int acpi_noirq;
 extern int acpi_pci_disabled;
 
+/* 1 to indicate PSCI 0.2+ is implemented */
+static inline bool acpi_psci_present(void)
+{
+	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
+}
+
+/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
+static inline bool acpi_psci_use_hvc(void)
+{
+	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
+}
+
 static inline void disable_acpi(void)
 {
 	acpi_disabled = 1;
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 9cf9127..69a315d 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -11,6 +11,8 @@
  *  published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) "ACPI: " fmt
+
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <linux/cpumask.h>
@@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
 	early_memunmap(map, size);
 }
 
+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 version,
+	 * and there is a minor version of FADT which was introduced
+	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
+	 * to get arm boot flags, or we will disable ACPI.
+	 */
+	if (table->revision < 5 || fadt->minor_revision < 1) {
+		pr_info("FADT version is %d.%d, no PSCI support, should be 5.1 or higher\n",
+			table->revision, fadt->minor_revision);
+		disable_acpi();
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /*
  * acpi_boot_table_init() called from setup_arch(), always.
  *	1. find RSDP and get its address, and then find XSDT
@@ -68,6 +90,21 @@ void __init acpi_boot_table_init(void)
 	}
 }
 
+int __init acpi_boot_init(void)
+{
+	int err = 0;
+
+	/* If acpi_disabled, bail out */
+	if (acpi_disabled)
+		return -ENODEV;
+
+	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
+	if (err)
+		pr_err("Can't find FADT\n");
+
+	return err;
+}
+
 /*
  * acpi_suspend_lowlevel() - save kernel state and suspend.
  *
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 9e9798f..2ad2084 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -15,6 +15,7 @@
 
 #define pr_fmt(fmt) "psci: " fmt
 
+#include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/smp.h>
@@ -231,6 +232,33 @@ static void psci_sys_poweroff(void)
 	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
 }
 
+static void psci_0_2_set_functions(void)
+{
+	pr_info("Using standard PSCI v0.2 function IDs\n");
+	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
+	psci_ops.cpu_suspend = psci_cpu_suspend;
+
+	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
+	psci_ops.cpu_off = psci_cpu_off;
+
+	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
+	psci_ops.cpu_on = psci_cpu_on;
+
+	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
+	psci_ops.migrate = psci_migrate;
+
+	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
+	psci_ops.affinity_info = psci_affinity_info;
+
+	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
+		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
+	psci_ops.migrate_info_type = psci_migrate_info_type;
+
+	arm_pm_restart = psci_sys_reset;
+
+	pm_power_off = psci_sys_poweroff;
+}
+
 /*
  * PSCI Function IDs for v0.2+ are well defined so use
  * standard values.
@@ -264,29 +292,7 @@ static int psci_0_2_init(struct device_node *np)
 		}
 	}
 
-	pr_info("Using standard PSCI v0.2 function IDs\n");
-	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
-	psci_ops.cpu_suspend = psci_cpu_suspend;
-
-	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
-	psci_ops.cpu_off = psci_cpu_off;
-
-	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
-	psci_ops.cpu_on = psci_cpu_on;
-
-	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
-	psci_ops.migrate = psci_migrate;
-
-	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
-	psci_ops.affinity_info = psci_affinity_info;
-
-	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
-		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
-	psci_ops.migrate_info_type = psci_migrate_info_type;
-
-	arm_pm_restart = psci_sys_reset;
-
-	pm_power_off = psci_sys_poweroff;
+	psci_0_2_set_functions();
 
 out_put_node:
 	of_node_put(np);
@@ -333,6 +339,40 @@ out_put_node:
 	return err;
 }
 
+#ifdef CONFIG_ACPI
+static int get_set_conduit_method_acpi(void)
+{
+	pr_info("probing for conduit method from ACPI.\n");
+
+	if (acpi_psci_use_hvc())
+		invoke_psci_fn = __invoke_psci_fn_hvc;
+	else
+		invoke_psci_fn = __invoke_psci_fn_smc;
+
+	return 0;
+}
+
+/* We use PSCI 0.2+ when ACPI is deployed */
+static int psci_0_2_init_acpi(void)
+{
+	if (!acpi_psci_present()) {
+		pr_info("is not implemented in ACPI.\n");
+		return -EOPNOTSUPP;
+	}
+
+	get_set_conduit_method_acpi();
+
+	psci_0_2_set_functions();
+
+	return 0;
+}
+#else
+static inline int psci_0_2_init_acpi(void)
+{
+	return -ENODEV;
+}
+#endif
+
 static const struct of_device_id psci_of_match[] __initconst = {
 	{ .compatible = "arm,psci",	.data = psci_0_1_init},
 	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
@@ -345,6 +385,9 @@ int __init psci_init(void)
 	const struct of_device_id *matched_np;
 	psci_initcall_t init_fn;
 
+	if (!acpi_disabled)
+		return psci_0_2_init_acpi();
+
 	np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
 
 	if (!np)
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 85c6326..dfc4e4f3 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
 	efi_idmap_init();
 
 	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
+	acpi_boot_init();
+
 	unflatten_device_tree();
 
 	psci_init();
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
the former signals to the OS that the hardware is PSCI compliant.
The latter selects the appropriate conduit for PSCI calls by
toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
(SMC).

FADT table contains such information, parse FADT to get the flags
for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
function IDs, which means that only PSCI 0.2+ is supported in ACPI.

At the same time, only ACPI 5.1 or higher verison supports PSCI,
and FADT Major.Minor version was introduced in ACPI 5.1, so we
will check the version and only parse FADT table with version >= 5.1.

If firmware provides ACPI tables with ACPI version less than 5.1,
OS will be messed up with those information and have no way to
bring up secondery CPUs, so disable ACPI if we get an FADT table
with version less that 5.1.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
---
 arch/arm64/include/asm/acpi.h |   12 ++++++
 arch/arm64/kernel/acpi.c      |   37 +++++++++++++++++
 arch/arm64/kernel/psci.c      |   89 ++++++++++++++++++++++++++++++-----------
 arch/arm64/kernel/setup.c     |    2 +
 4 files changed, 117 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 6400312..6e04868 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -19,6 +19,18 @@ extern int acpi_disabled;
 extern int acpi_noirq;
 extern int acpi_pci_disabled;
 
+/* 1 to indicate PSCI 0.2+ is implemented */
+static inline bool acpi_psci_present(void)
+{
+	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
+}
+
+/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
+static inline bool acpi_psci_use_hvc(void)
+{
+	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
+}
+
 static inline void disable_acpi(void)
 {
 	acpi_disabled = 1;
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 9cf9127..69a315d 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -11,6 +11,8 @@
  *  published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) "ACPI: " fmt
+
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <linux/cpumask.h>
@@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
 	early_memunmap(map, size);
 }
 
+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 version,
+	 * and there is a minor version of FADT which was introduced
+	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
+	 * to get arm boot flags, or we will disable ACPI.
+	 */
+	if (table->revision < 5 || fadt->minor_revision < 1) {
+		pr_info("FADT version is %d.%d, no PSCI support, should be 5.1 or higher\n",
+			table->revision, fadt->minor_revision);
+		disable_acpi();
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /*
  * acpi_boot_table_init() called from setup_arch(), always.
  *	1. find RSDP and get its address, and then find XSDT
@@ -68,6 +90,21 @@ void __init acpi_boot_table_init(void)
 	}
 }
 
+int __init acpi_boot_init(void)
+{
+	int err = 0;
+
+	/* If acpi_disabled, bail out */
+	if (acpi_disabled)
+		return -ENODEV;
+
+	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
+	if (err)
+		pr_err("Can't find FADT\n");
+
+	return err;
+}
+
 /*
  * acpi_suspend_lowlevel() - save kernel state and suspend.
  *
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 9e9798f..2ad2084 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -15,6 +15,7 @@
 
 #define pr_fmt(fmt) "psci: " fmt
 
+#include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/smp.h>
@@ -231,6 +232,33 @@ static void psci_sys_poweroff(void)
 	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
 }
 
+static void psci_0_2_set_functions(void)
+{
+	pr_info("Using standard PSCI v0.2 function IDs\n");
+	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
+	psci_ops.cpu_suspend = psci_cpu_suspend;
+
+	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
+	psci_ops.cpu_off = psci_cpu_off;
+
+	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
+	psci_ops.cpu_on = psci_cpu_on;
+
+	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
+	psci_ops.migrate = psci_migrate;
+
+	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
+	psci_ops.affinity_info = psci_affinity_info;
+
+	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
+		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
+	psci_ops.migrate_info_type = psci_migrate_info_type;
+
+	arm_pm_restart = psci_sys_reset;
+
+	pm_power_off = psci_sys_poweroff;
+}
+
 /*
  * PSCI Function IDs for v0.2+ are well defined so use
  * standard values.
@@ -264,29 +292,7 @@ static int psci_0_2_init(struct device_node *np)
 		}
 	}
 
-	pr_info("Using standard PSCI v0.2 function IDs\n");
-	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
-	psci_ops.cpu_suspend = psci_cpu_suspend;
-
-	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
-	psci_ops.cpu_off = psci_cpu_off;
-
-	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
-	psci_ops.cpu_on = psci_cpu_on;
-
-	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
-	psci_ops.migrate = psci_migrate;
-
-	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
-	psci_ops.affinity_info = psci_affinity_info;
-
-	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
-		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
-	psci_ops.migrate_info_type = psci_migrate_info_type;
-
-	arm_pm_restart = psci_sys_reset;
-
-	pm_power_off = psci_sys_poweroff;
+	psci_0_2_set_functions();
 
 out_put_node:
 	of_node_put(np);
@@ -333,6 +339,40 @@ out_put_node:
 	return err;
 }
 
+#ifdef CONFIG_ACPI
+static int get_set_conduit_method_acpi(void)
+{
+	pr_info("probing for conduit method from ACPI.\n");
+
+	if (acpi_psci_use_hvc())
+		invoke_psci_fn = __invoke_psci_fn_hvc;
+	else
+		invoke_psci_fn = __invoke_psci_fn_smc;
+
+	return 0;
+}
+
+/* We use PSCI 0.2+ when ACPI is deployed */
+static int psci_0_2_init_acpi(void)
+{
+	if (!acpi_psci_present()) {
+		pr_info("is not implemented in ACPI.\n");
+		return -EOPNOTSUPP;
+	}
+
+	get_set_conduit_method_acpi();
+
+	psci_0_2_set_functions();
+
+	return 0;
+}
+#else
+static inline int psci_0_2_init_acpi(void)
+{
+	return -ENODEV;
+}
+#endif
+
 static const struct of_device_id psci_of_match[] __initconst = {
 	{ .compatible = "arm,psci",	.data = psci_0_1_init},
 	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
@@ -345,6 +385,9 @@ int __init psci_init(void)
 	const struct of_device_id *matched_np;
 	psci_initcall_t init_fn;
 
+	if (!acpi_disabled)
+		return psci_0_2_init_acpi();
+
 	np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
 
 	if (!np)
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 85c6326..dfc4e4f3 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
 	efi_idmap_init();
 
 	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
+	acpi_boot_init();
+
 	unflatten_device_tree();
 
 	psci_init();
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
  2014-08-04 15:28 ` Hanjun Guo
  (?)
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo,
	Tomasz Nowicki

MADT contains the information for MPIDR which is essential for
SMP initialization, parse the GIC cpu interface structures to
get the MPIDR value and map it to cpu_logical_map(), and add
enabled cpu with valid MPIDR into cpu_possible_map and
cpu_present_map.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/arm64/include/asm/acpi.h |    2 +
 arch/arm64/kernel/acpi.c      |  129 ++++++++++++++++++++++++++++++++++++++++-
 arch/arm64/kernel/smp.c       |   10 +++-
 3 files changed, 138 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 6e04868..e877967 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 extern int (*acpi_suspend_lowlevel)(void);
 #define acpi_wakeup_address 0
 
+#define MAX_GIC_CPU_INTERFACE 65535
+
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 69a315d..9e07d99 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -22,6 +22,9 @@
 #include <linux/bootmem.h>
 #include <linux/smp.h>
 
+#include <asm/smp_plat.h>
+#include <asm/cputype.h>
+
 int acpi_noirq;			/* skip ACPI IRQ initialization */
 int acpi_disabled;
 EXPORT_SYMBOL(acpi_disabled);
@@ -29,6 +32,8 @@ 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 */
+
 /*
  * __acpi_map_table() will be called before page_init(), so early_ioremap()
  * or early_memremap() should be called here to for ACPI table mapping.
@@ -49,6 +54,122 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
 	early_memunmap(map, size);
 }
 
+/**
+ * acpi_register_gic_cpu_interface - register a gic cpu interface and
+ * generates a logical cpu number
+ * @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 the gic cpu interface
+ */
+static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
+{
+	int cpu;
+
+	if (mpidr == INVALID_HWID) {
+		pr_info("Skip invalid cpu hardware ID\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;
+	}
+
+	/* If it is the first CPU, no need to check duplicate MPIDRs */
+	if (!enabled_cpus)
+		goto skip_mpidr_check;
+
+	/*
+	 * 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_present_cpu(cpu) {
+		if (cpu_logical_map(cpu) == mpidr) {
+			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
+			       mpidr);
+			return -EINVAL;
+		}
+	}
+
+skip_mpidr_check:
+	enabled_cpus++;
+
+	/* allocate a logical cpu id for the new comer */
+	if (cpu_logical_map(0) == mpidr) {
+		/*
+		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
+		 * for BSP, no need to allocate again.
+		 */
+		cpu = 0;
+	} else {
+		cpu = cpumask_next_zero(-1, cpu_present_mask);
+	}
+
+	/* map the logical cpu id to cpu MPIDR */
+	cpu_logical_map(cpu) = mpidr;
+
+	set_cpu_possible(cpu, true);
+	set_cpu_present(cpu, true);
+
+	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_register_gic_cpu_interface(processor->arm_mpidr,
+		processor->flags & ACPI_MADT_ENABLED);
+
+	return 0;
+}
+
+/*
+ * Parse GIC cpu interface related entries in MADT
+ * returns 0 on success, < 0 on error
+ */
+static int __init acpi_parse_madt_gic_cpu_interface_entries(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, MAX_GIC_CPU_INTERFACE);
+
+	if (!count) {
+		pr_err("No GIC CPU interface entries present\n");
+		return -ENODEV;
+	} else if (count < 0) {
+		pr_err("Error parsing GIC CPU interface entry\n");
+		return count;
+	}
+
+	/* Make boot-up look pretty */
+	pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);
+
+	return 0;
+}
+
 static int __init acpi_parse_fadt(struct acpi_table_header *table)
 {
 	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
@@ -99,8 +220,12 @@ int __init acpi_boot_init(void)
 		return -ENODEV;
 
 	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
-	if (err)
-		pr_err("Can't find FADT\n");
+	if (err) {
+		pr_err("Can't find FADT or error happened during parsing FADT\n");
+		return err;
+	}
+
+	err = acpi_parse_madt_gic_cpu_interface_entries();
 
 	return err;
 }
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 40f38f4..8f1d37c 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -36,6 +36,7 @@
 #include <linux/completion.h>
 #include <linux/of.h>
 #include <linux/irq_work.h>
+#include <linux/acpi.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
@@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 		if (err)
 			continue;
 
-		set_cpu_present(cpu, true);
+		/*
+		 * In ACPI mode, cpu_present_map was initialised when
+		 * MADT table was parsed which before this function
+		 * is called.
+		 */
+		if (acpi_disabled)
+			set_cpu_present(cpu, true);
+
 		max_cpus--;
 	}
 }
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo,
	Tomasz Nowicki

MADT contains the information for MPIDR which is essential for
SMP initialization, parse the GIC cpu interface structures to
get the MPIDR value and map it to cpu_logical_map(), and add
enabled cpu with valid MPIDR into cpu_possible_map and
cpu_present_map.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/arm64/include/asm/acpi.h |    2 +
 arch/arm64/kernel/acpi.c      |  129 ++++++++++++++++++++++++++++++++++++++++-
 arch/arm64/kernel/smp.c       |   10 +++-
 3 files changed, 138 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 6e04868..e877967 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 extern int (*acpi_suspend_lowlevel)(void);
 #define acpi_wakeup_address 0
 
+#define MAX_GIC_CPU_INTERFACE 65535
+
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 69a315d..9e07d99 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -22,6 +22,9 @@
 #include <linux/bootmem.h>
 #include <linux/smp.h>
 
+#include <asm/smp_plat.h>
+#include <asm/cputype.h>
+
 int acpi_noirq;			/* skip ACPI IRQ initialization */
 int acpi_disabled;
 EXPORT_SYMBOL(acpi_disabled);
@@ -29,6 +32,8 @@ 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 */
+
 /*
  * __acpi_map_table() will be called before page_init(), so early_ioremap()
  * or early_memremap() should be called here to for ACPI table mapping.
@@ -49,6 +54,122 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
 	early_memunmap(map, size);
 }
 
+/**
+ * acpi_register_gic_cpu_interface - register a gic cpu interface and
+ * generates a logical cpu number
+ * @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 the gic cpu interface
+ */
+static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
+{
+	int cpu;
+
+	if (mpidr == INVALID_HWID) {
+		pr_info("Skip invalid cpu hardware ID\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;
+	}
+
+	/* If it is the first CPU, no need to check duplicate MPIDRs */
+	if (!enabled_cpus)
+		goto skip_mpidr_check;
+
+	/*
+	 * 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_present_cpu(cpu) {
+		if (cpu_logical_map(cpu) == mpidr) {
+			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
+			       mpidr);
+			return -EINVAL;
+		}
+	}
+
+skip_mpidr_check:
+	enabled_cpus++;
+
+	/* allocate a logical cpu id for the new comer */
+	if (cpu_logical_map(0) == mpidr) {
+		/*
+		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
+		 * for BSP, no need to allocate again.
+		 */
+		cpu = 0;
+	} else {
+		cpu = cpumask_next_zero(-1, cpu_present_mask);
+	}
+
+	/* map the logical cpu id to cpu MPIDR */
+	cpu_logical_map(cpu) = mpidr;
+
+	set_cpu_possible(cpu, true);
+	set_cpu_present(cpu, true);
+
+	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_register_gic_cpu_interface(processor->arm_mpidr,
+		processor->flags & ACPI_MADT_ENABLED);
+
+	return 0;
+}
+
+/*
+ * Parse GIC cpu interface related entries in MADT
+ * returns 0 on success, < 0 on error
+ */
+static int __init acpi_parse_madt_gic_cpu_interface_entries(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, MAX_GIC_CPU_INTERFACE);
+
+	if (!count) {
+		pr_err("No GIC CPU interface entries present\n");
+		return -ENODEV;
+	} else if (count < 0) {
+		pr_err("Error parsing GIC CPU interface entry\n");
+		return count;
+	}
+
+	/* Make boot-up look pretty */
+	pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);
+
+	return 0;
+}
+
 static int __init acpi_parse_fadt(struct acpi_table_header *table)
 {
 	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
@@ -99,8 +220,12 @@ int __init acpi_boot_init(void)
 		return -ENODEV;
 
 	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
-	if (err)
-		pr_err("Can't find FADT\n");
+	if (err) {
+		pr_err("Can't find FADT or error happened during parsing FADT\n");
+		return err;
+	}
+
+	err = acpi_parse_madt_gic_cpu_interface_entries();
 
 	return err;
 }
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 40f38f4..8f1d37c 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -36,6 +36,7 @@
 #include <linux/completion.h>
 #include <linux/of.h>
 #include <linux/irq_work.h>
+#include <linux/acpi.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
@@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 		if (err)
 			continue;
 
-		set_cpu_present(cpu, true);
+		/*
+		 * In ACPI mode, cpu_present_map was initialised when
+		 * MADT table was parsed which before this function
+		 * is called.
+		 */
+		if (acpi_disabled)
+			set_cpu_present(cpu, true);
+
 		max_cpus--;
 	}
 }
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

MADT contains the information for MPIDR which is essential for
SMP initialization, parse the GIC cpu interface structures to
get the MPIDR value and map it to cpu_logical_map(), and add
enabled cpu with valid MPIDR into cpu_possible_map and
cpu_present_map.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/arm64/include/asm/acpi.h |    2 +
 arch/arm64/kernel/acpi.c      |  129 ++++++++++++++++++++++++++++++++++++++++-
 arch/arm64/kernel/smp.c       |   10 +++-
 3 files changed, 138 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 6e04868..e877967 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 extern int (*acpi_suspend_lowlevel)(void);
 #define acpi_wakeup_address 0
 
+#define MAX_GIC_CPU_INTERFACE 65535
+
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 69a315d..9e07d99 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -22,6 +22,9 @@
 #include <linux/bootmem.h>
 #include <linux/smp.h>
 
+#include <asm/smp_plat.h>
+#include <asm/cputype.h>
+
 int acpi_noirq;			/* skip ACPI IRQ initialization */
 int acpi_disabled;
 EXPORT_SYMBOL(acpi_disabled);
@@ -29,6 +32,8 @@ 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 */
+
 /*
  * __acpi_map_table() will be called before page_init(), so early_ioremap()
  * or early_memremap() should be called here to for ACPI table mapping.
@@ -49,6 +54,122 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
 	early_memunmap(map, size);
 }
 
+/**
+ * acpi_register_gic_cpu_interface - register a gic cpu interface and
+ * generates a logical cpu number
+ * @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 the gic cpu interface
+ */
+static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
+{
+	int cpu;
+
+	if (mpidr == INVALID_HWID) {
+		pr_info("Skip invalid cpu hardware ID\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;
+	}
+
+	/* If it is the first CPU, no need to check duplicate MPIDRs */
+	if (!enabled_cpus)
+		goto skip_mpidr_check;
+
+	/*
+	 * 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_present_cpu(cpu) {
+		if (cpu_logical_map(cpu) == mpidr) {
+			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
+			       mpidr);
+			return -EINVAL;
+		}
+	}
+
+skip_mpidr_check:
+	enabled_cpus++;
+
+	/* allocate a logical cpu id for the new comer */
+	if (cpu_logical_map(0) == mpidr) {
+		/*
+		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
+		 * for BSP, no need to allocate again.
+		 */
+		cpu = 0;
+	} else {
+		cpu = cpumask_next_zero(-1, cpu_present_mask);
+	}
+
+	/* map the logical cpu id to cpu MPIDR */
+	cpu_logical_map(cpu) = mpidr;
+
+	set_cpu_possible(cpu, true);
+	set_cpu_present(cpu, true);
+
+	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_register_gic_cpu_interface(processor->arm_mpidr,
+		processor->flags & ACPI_MADT_ENABLED);
+
+	return 0;
+}
+
+/*
+ * Parse GIC cpu interface related entries in MADT
+ * returns 0 on success, < 0 on error
+ */
+static int __init acpi_parse_madt_gic_cpu_interface_entries(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, MAX_GIC_CPU_INTERFACE);
+
+	if (!count) {
+		pr_err("No GIC CPU interface entries present\n");
+		return -ENODEV;
+	} else if (count < 0) {
+		pr_err("Error parsing GIC CPU interface entry\n");
+		return count;
+	}
+
+	/* Make boot-up look pretty */
+	pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);
+
+	return 0;
+}
+
 static int __init acpi_parse_fadt(struct acpi_table_header *table)
 {
 	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
@@ -99,8 +220,12 @@ int __init acpi_boot_init(void)
 		return -ENODEV;
 
 	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
-	if (err)
-		pr_err("Can't find FADT\n");
+	if (err) {
+		pr_err("Can't find FADT or error happened during parsing FADT\n");
+		return err;
+	}
+
+	err = acpi_parse_madt_gic_cpu_interface_entries();
 
 	return err;
 }
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 40f38f4..8f1d37c 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -36,6 +36,7 @@
 #include <linux/completion.h>
 #include <linux/of.h>
 #include <linux/irq_work.h>
+#include <linux/acpi.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
@@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 		if (err)
 			continue;
 
-		set_cpu_present(cpu, true);
+		/*
+		 * In ACPI mode, cpu_present_map was initialised when
+		 * MADT table was parsed which before this function
+		 * is called.
+		 */
+		if (acpi_disabled)
+			set_cpu_present(cpu, true);
+
 		max_cpus--;
 	}
 }
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 07/18] ACPI / table: Print GIC information when MADT is parsed
  2014-08-04 15:28 ` Hanjun Guo
  (?)
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo,
	Tomasz Nowicki

When MADT is parsed, print GIC information to make the boot
log look pretty.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 drivers/acpi/tables.c |   39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 6d5a6cd..77f8bb1 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -183,6 +183,44 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 		}
 		break;
 
+	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+		{
+			struct acpi_madt_generic_interrupt *p =
+				(struct acpi_madt_generic_interrupt *)header;
+			pr_info("GICC (acpi_id[0x%04x] address[0x%08llx] MPDIR[0x%llx] %s)\n",
+				p->uid, p->base_address, p->arm_mpidr,
+				(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
+
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+		{
+			struct acpi_madt_generic_distributor *p =
+				(struct acpi_madt_generic_distributor *)header;
+			pr_info("GIC Distributor (gic_id[0x%04x] address[0x%08llx] gsi_base[%d])\n",
+				p->gic_id, p->base_address, p->global_irq_base);
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
+		{
+			struct acpi_madt_generic_msi_frame *p =
+				(struct acpi_madt_generic_msi_frame *)header;
+			pr_info("GIC MSI Frame (msi_fame_id[%d] address[0x%08llx])\n",
+				p->msi_frame_id, p->base_address);
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
+		{
+			struct acpi_madt_generic_redistributor *p =
+				(struct acpi_madt_generic_redistributor *)header;
+			pr_info("GIC Redistributor (address[0x%08llx] region_size[0x%x])\n",
+				p->base_address, p->length);
+		}
+		break;
+
 	default:
 		pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
 			header->type);
@@ -190,7 +228,6 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
-
 int __init
 acpi_table_parse_entries(char *id,
 			     unsigned long table_size,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 07/18] ACPI / table: Print GIC information when MADT is parsed
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo,
	Tomasz Nowicki

When MADT is parsed, print GIC information to make the boot
log look pretty.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 drivers/acpi/tables.c |   39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 6d5a6cd..77f8bb1 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -183,6 +183,44 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 		}
 		break;
 
+	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+		{
+			struct acpi_madt_generic_interrupt *p =
+				(struct acpi_madt_generic_interrupt *)header;
+			pr_info("GICC (acpi_id[0x%04x] address[0x%08llx] MPDIR[0x%llx] %s)\n",
+				p->uid, p->base_address, p->arm_mpidr,
+				(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
+
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+		{
+			struct acpi_madt_generic_distributor *p =
+				(struct acpi_madt_generic_distributor *)header;
+			pr_info("GIC Distributor (gic_id[0x%04x] address[0x%08llx] gsi_base[%d])\n",
+				p->gic_id, p->base_address, p->global_irq_base);
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
+		{
+			struct acpi_madt_generic_msi_frame *p =
+				(struct acpi_madt_generic_msi_frame *)header;
+			pr_info("GIC MSI Frame (msi_fame_id[%d] address[0x%08llx])\n",
+				p->msi_frame_id, p->base_address);
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
+		{
+			struct acpi_madt_generic_redistributor *p =
+				(struct acpi_madt_generic_redistributor *)header;
+			pr_info("GIC Redistributor (address[0x%08llx] region_size[0x%x])\n",
+				p->base_address, p->length);
+		}
+		break;
+
 	default:
 		pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
 			header->type);
@@ -190,7 +228,6 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
-
 int __init
 acpi_table_parse_entries(char *id,
 			     unsigned long table_size,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 07/18] ACPI / table: Print GIC information when MADT is parsed
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

When MADT is parsed, print GIC information to make the boot
log look pretty.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 drivers/acpi/tables.c |   39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 6d5a6cd..77f8bb1 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -183,6 +183,44 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 		}
 		break;
 
+	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+		{
+			struct acpi_madt_generic_interrupt *p =
+				(struct acpi_madt_generic_interrupt *)header;
+			pr_info("GICC (acpi_id[0x%04x] address[0x%08llx] MPDIR[0x%llx] %s)\n",
+				p->uid, p->base_address, p->arm_mpidr,
+				(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
+
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+		{
+			struct acpi_madt_generic_distributor *p =
+				(struct acpi_madt_generic_distributor *)header;
+			pr_info("GIC Distributor (gic_id[0x%04x] address[0x%08llx] gsi_base[%d])\n",
+				p->gic_id, p->base_address, p->global_irq_base);
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
+		{
+			struct acpi_madt_generic_msi_frame *p =
+				(struct acpi_madt_generic_msi_frame *)header;
+			pr_info("GIC MSI Frame (msi_fame_id[%d] address[0x%08llx])\n",
+				p->msi_frame_id, p->base_address);
+		}
+		break;
+
+	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
+		{
+			struct acpi_madt_generic_redistributor *p =
+				(struct acpi_madt_generic_redistributor *)header;
+			pr_info("GIC Redistributor (address[0x%08llx] region_size[0x%x])\n",
+				p->base_address, p->length);
+		}
+		break;
+
 	default:
 		pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
 			header->type);
@@ -190,7 +228,6 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
-
 int __init
 acpi_table_parse_entries(char *id,
 			     unsigned long table_size,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-04 15:28 ` Hanjun Guo
  (?)
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo,
	Tomasz Nowicki

ACPI 5.1 only has two explicit methods to boot up SMP,
PSCI and Parking protocol, but the Parking protocol is
only suitable 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.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/arm64/include/asm/acpi.h |   21 ++++++++++++++
 arch/arm64/include/asm/smp.h  |    3 +-
 arch/arm64/kernel/acpi.c      |    9 ++++++
 arch/arm64/kernel/cpu_ops.c   |   62 ++++++++++++++++++++++++++++++++++++-----
 arch/arm64/kernel/smp.c       |   27 +++++++++++++++++-
 5 files changed, 113 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index e877967..022f4ad 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -14,6 +14,27 @@
 
 /* Basic configuration for ACPI */
 #ifdef	CONFIG_ACPI
+/*
+ * ACPI 5.1 only has two explicit methods to
+ * boot up SMP, PSCI and Parking protocol,
+ * but the Parking protocol is only defined
+ * 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.
+ *
+ * This enum is intend to make the boot method
+ * scalable when above updates are happended,
+ * which NOT means to support all of them.
+ */
+enum acpi_smp_boot_protocol {
+	ACPI_SMP_BOOT_PSCI,
+	ACPI_SMP_BOOT_PARKING_PROTOCOL,
+	ACPI_SMP_BOOT_PROTOCOL_MAX
+};
+
+enum acpi_smp_boot_protocol smp_boot_protocol(void);
+
 #define acpi_strict 1	/* No out-of-spec workarounds on ARM64 */
 extern int acpi_disabled;
 extern int acpi_noirq;
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index a498f2c..282932c2 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -39,7 +39,8 @@ extern void show_ipi_list(struct seq_file *p, int prec);
 extern void handle_IPI(int ipinr, struct pt_regs *regs);
 
 /*
- * Setup the set of possible CPUs (via set_cpu_possible)
+ * Discover the set of possible CPUs and determine their
+ * SMP operations.
  */
 extern void smp_init_cpus(void);
 
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 9e07d99..8a54b4e 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -170,6 +170,15 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
 	return 0;
 }
 
+/* Protocol to bring up secondary CPUs */
+enum acpi_smp_boot_protocol smp_boot_protocol(void)
+{
+	if (acpi_psci_present())
+		return ACPI_SMP_BOOT_PSCI;
+	else
+		return ACPI_SMP_BOOT_PARKING_PROTOCOL;
+}
+
 static int __init acpi_parse_fadt(struct acpi_table_header *table)
 {
 	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
index d62d12f..05bc314 100644
--- a/arch/arm64/kernel/cpu_ops.c
+++ b/arch/arm64/kernel/cpu_ops.c
@@ -16,11 +16,13 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <asm/cpu_ops.h>
-#include <asm/smp_plat.h>
 #include <linux/errno.h>
 #include <linux/of.h>
 #include <linux/string.h>
+#include <linux/acpi.h>
+
+#include <asm/cpu_ops.h>
+#include <asm/smp_plat.h>
 
 extern const struct cpu_operations smp_spin_table_ops;
 extern const struct cpu_operations cpu_psci_ops;
@@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
 	return NULL;
 }
 
+#ifdef CONFIG_ACPI
+/*
+ * Get a cpu's boot method in the ACPI way.
+ */
+static char * __init acpi_get_cpu_boot_method(void)
+{
+	/*
+	 * For ACPI 5.1, only two kind of methods are provided,
+	 * Parking protocol and PSCI, but Parking protocol is
+	 * specified for ARMv7 only, so make PSCI as the only method
+	 * for SMP initialization before the ACPI spec or Parking
+	 * protocol spec is updated.
+	 */
+	switch (smp_boot_protocol()) {
+	case ACPI_SMP_BOOT_PSCI:
+		return "psci";
+	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
+	default:
+		return NULL;
+	}
+}
+#else
+static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
+#endif
+
 /*
- * Read a cpu's enable method from the device tree and record it in cpu_ops.
+ * Read a cpu's enable method and record it in cpu_ops.
  */
 int __init cpu_read_ops(struct device_node *dn, int cpu)
 {
-	const char *enable_method = of_get_property(dn, "enable-method", NULL);
+	const char *enable_method;
+
+	if (!acpi_disabled) {
+		enable_method = acpi_get_cpu_boot_method();
+		goto get_ops;
+	}
+
+	enable_method = of_get_property(dn, "enable-method", NULL);
 	if (!enable_method) {
 		/*
 		 * The boot CPU may not have an enable method (e.g. when
@@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
 		return -ENOENT;
 	}
 
+get_ops:
 	cpu_ops[cpu] = cpu_get_ops(enable_method);
 	if (!cpu_ops[cpu]) {
-		pr_warn("%s: unsupported enable-method property: %s\n",
-			dn->full_name, enable_method);
+		if (acpi_disabled) {
+			pr_warn("%s: unsupported enable-method property: %s\n",
+				dn->full_name, enable_method);
+		} else {
+			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
+				cpu);
+		}
+
 		return -EOPNOTSUPP;
 	}
 
@@ -78,7 +119,14 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
 
 void __init cpu_read_bootcpu_ops(void)
 {
-	struct device_node *dn = of_get_cpu_node(0, NULL);
+	struct device_node *dn;
+
+	if (!acpi_disabled) {
+		cpu_read_ops(NULL, 0);
+		return;
+	}
+
+	dn = of_get_cpu_node(0, NULL);
 	if (!dn) {
 		pr_err("Failed to find device node for boot cpu\n");
 		return;
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 8f1d37c..e21bbc9 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -315,7 +315,7 @@ static void (*smp_cross_call)(const struct cpumask *, unsigned int);
  * cpu logical map array containing MPIDR values related to logical
  * cpus. Assumes that cpu_logical_map(0) has already been initialized.
  */
-void __init smp_init_cpus(void)
+static void __init of_smp_init_cpus(void)
 {
 	struct device_node *dn = NULL;
 	unsigned int i, cpu = 1;
@@ -418,6 +418,31 @@ next:
 			set_cpu_possible(i, true);
 }
 
+/*
+ * In ACPI mode, the cpu possible map was enumerated before SMP
+ * initialization when MADT table was parsed, so we can get the
+ * possible map here to initialize CPUs.
+ */
+static void __init acpi_smp_init_cpus(void)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		if (cpu_read_ops(NULL, cpu) != 0)
+			continue;
+
+		cpu_ops[cpu]->cpu_init(NULL, cpu);
+	}
+}
+
+void __init smp_init_cpus(void)
+{
+	if (acpi_disabled)
+		of_smp_init_cpus();
+	else
+		acpi_smp_init_cpus();
+}
+
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
 	int err;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo,
	Tomasz Nowicki

ACPI 5.1 only has two explicit methods to boot up SMP,
PSCI and Parking protocol, but the Parking protocol is
only suitable 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.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/arm64/include/asm/acpi.h |   21 ++++++++++++++
 arch/arm64/include/asm/smp.h  |    3 +-
 arch/arm64/kernel/acpi.c      |    9 ++++++
 arch/arm64/kernel/cpu_ops.c   |   62 ++++++++++++++++++++++++++++++++++++-----
 arch/arm64/kernel/smp.c       |   27 +++++++++++++++++-
 5 files changed, 113 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index e877967..022f4ad 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -14,6 +14,27 @@
 
 /* Basic configuration for ACPI */
 #ifdef	CONFIG_ACPI
+/*
+ * ACPI 5.1 only has two explicit methods to
+ * boot up SMP, PSCI and Parking protocol,
+ * but the Parking protocol is only defined
+ * 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.
+ *
+ * This enum is intend to make the boot method
+ * scalable when above updates are happended,
+ * which NOT means to support all of them.
+ */
+enum acpi_smp_boot_protocol {
+	ACPI_SMP_BOOT_PSCI,
+	ACPI_SMP_BOOT_PARKING_PROTOCOL,
+	ACPI_SMP_BOOT_PROTOCOL_MAX
+};
+
+enum acpi_smp_boot_protocol smp_boot_protocol(void);
+
 #define acpi_strict 1	/* No out-of-spec workarounds on ARM64 */
 extern int acpi_disabled;
 extern int acpi_noirq;
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index a498f2c..282932c2 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -39,7 +39,8 @@ extern void show_ipi_list(struct seq_file *p, int prec);
 extern void handle_IPI(int ipinr, struct pt_regs *regs);
 
 /*
- * Setup the set of possible CPUs (via set_cpu_possible)
+ * Discover the set of possible CPUs and determine their
+ * SMP operations.
  */
 extern void smp_init_cpus(void);
 
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 9e07d99..8a54b4e 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -170,6 +170,15 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
 	return 0;
 }
 
+/* Protocol to bring up secondary CPUs */
+enum acpi_smp_boot_protocol smp_boot_protocol(void)
+{
+	if (acpi_psci_present())
+		return ACPI_SMP_BOOT_PSCI;
+	else
+		return ACPI_SMP_BOOT_PARKING_PROTOCOL;
+}
+
 static int __init acpi_parse_fadt(struct acpi_table_header *table)
 {
 	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
index d62d12f..05bc314 100644
--- a/arch/arm64/kernel/cpu_ops.c
+++ b/arch/arm64/kernel/cpu_ops.c
@@ -16,11 +16,13 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <asm/cpu_ops.h>
-#include <asm/smp_plat.h>
 #include <linux/errno.h>
 #include <linux/of.h>
 #include <linux/string.h>
+#include <linux/acpi.h>
+
+#include <asm/cpu_ops.h>
+#include <asm/smp_plat.h>
 
 extern const struct cpu_operations smp_spin_table_ops;
 extern const struct cpu_operations cpu_psci_ops;
@@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
 	return NULL;
 }
 
+#ifdef CONFIG_ACPI
+/*
+ * Get a cpu's boot method in the ACPI way.
+ */
+static char * __init acpi_get_cpu_boot_method(void)
+{
+	/*
+	 * For ACPI 5.1, only two kind of methods are provided,
+	 * Parking protocol and PSCI, but Parking protocol is
+	 * specified for ARMv7 only, so make PSCI as the only method
+	 * for SMP initialization before the ACPI spec or Parking
+	 * protocol spec is updated.
+	 */
+	switch (smp_boot_protocol()) {
+	case ACPI_SMP_BOOT_PSCI:
+		return "psci";
+	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
+	default:
+		return NULL;
+	}
+}
+#else
+static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
+#endif
+
 /*
- * Read a cpu's enable method from the device tree and record it in cpu_ops.
+ * Read a cpu's enable method and record it in cpu_ops.
  */
 int __init cpu_read_ops(struct device_node *dn, int cpu)
 {
-	const char *enable_method = of_get_property(dn, "enable-method", NULL);
+	const char *enable_method;
+
+	if (!acpi_disabled) {
+		enable_method = acpi_get_cpu_boot_method();
+		goto get_ops;
+	}
+
+	enable_method = of_get_property(dn, "enable-method", NULL);
 	if (!enable_method) {
 		/*
 		 * The boot CPU may not have an enable method (e.g. when
@@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
 		return -ENOENT;
 	}
 
+get_ops:
 	cpu_ops[cpu] = cpu_get_ops(enable_method);
 	if (!cpu_ops[cpu]) {
-		pr_warn("%s: unsupported enable-method property: %s\n",
-			dn->full_name, enable_method);
+		if (acpi_disabled) {
+			pr_warn("%s: unsupported enable-method property: %s\n",
+				dn->full_name, enable_method);
+		} else {
+			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
+				cpu);
+		}
+
 		return -EOPNOTSUPP;
 	}
 
@@ -78,7 +119,14 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
 
 void __init cpu_read_bootcpu_ops(void)
 {
-	struct device_node *dn = of_get_cpu_node(0, NULL);
+	struct device_node *dn;
+
+	if (!acpi_disabled) {
+		cpu_read_ops(NULL, 0);
+		return;
+	}
+
+	dn = of_get_cpu_node(0, NULL);
 	if (!dn) {
 		pr_err("Failed to find device node for boot cpu\n");
 		return;
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 8f1d37c..e21bbc9 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -315,7 +315,7 @@ static void (*smp_cross_call)(const struct cpumask *, unsigned int);
  * cpu logical map array containing MPIDR values related to logical
  * cpus. Assumes that cpu_logical_map(0) has already been initialized.
  */
-void __init smp_init_cpus(void)
+static void __init of_smp_init_cpus(void)
 {
 	struct device_node *dn = NULL;
 	unsigned int i, cpu = 1;
@@ -418,6 +418,31 @@ next:
 			set_cpu_possible(i, true);
 }
 
+/*
+ * In ACPI mode, the cpu possible map was enumerated before SMP
+ * initialization when MADT table was parsed, so we can get the
+ * possible map here to initialize CPUs.
+ */
+static void __init acpi_smp_init_cpus(void)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		if (cpu_read_ops(NULL, cpu) != 0)
+			continue;
+
+		cpu_ops[cpu]->cpu_init(NULL, cpu);
+	}
+}
+
+void __init smp_init_cpus(void)
+{
+	if (acpi_disabled)
+		of_smp_init_cpus();
+	else
+		acpi_smp_init_cpus();
+}
+
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
 	int err;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

ACPI 5.1 only has two explicit methods to boot up SMP,
PSCI and Parking protocol, but the Parking protocol is
only suitable 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.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 arch/arm64/include/asm/acpi.h |   21 ++++++++++++++
 arch/arm64/include/asm/smp.h  |    3 +-
 arch/arm64/kernel/acpi.c      |    9 ++++++
 arch/arm64/kernel/cpu_ops.c   |   62 ++++++++++++++++++++++++++++++++++++-----
 arch/arm64/kernel/smp.c       |   27 +++++++++++++++++-
 5 files changed, 113 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index e877967..022f4ad 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -14,6 +14,27 @@
 
 /* Basic configuration for ACPI */
 #ifdef	CONFIG_ACPI
+/*
+ * ACPI 5.1 only has two explicit methods to
+ * boot up SMP, PSCI and Parking protocol,
+ * but the Parking protocol is only defined
+ * 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.
+ *
+ * This enum is intend to make the boot method
+ * scalable when above updates are happended,
+ * which NOT means to support all of them.
+ */
+enum acpi_smp_boot_protocol {
+	ACPI_SMP_BOOT_PSCI,
+	ACPI_SMP_BOOT_PARKING_PROTOCOL,
+	ACPI_SMP_BOOT_PROTOCOL_MAX
+};
+
+enum acpi_smp_boot_protocol smp_boot_protocol(void);
+
 #define acpi_strict 1	/* No out-of-spec workarounds on ARM64 */
 extern int acpi_disabled;
 extern int acpi_noirq;
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index a498f2c..282932c2 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -39,7 +39,8 @@ extern void show_ipi_list(struct seq_file *p, int prec);
 extern void handle_IPI(int ipinr, struct pt_regs *regs);
 
 /*
- * Setup the set of possible CPUs (via set_cpu_possible)
+ * Discover the set of possible CPUs and determine their
+ * SMP operations.
  */
 extern void smp_init_cpus(void);
 
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 9e07d99..8a54b4e 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -170,6 +170,15 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
 	return 0;
 }
 
+/* Protocol to bring up secondary CPUs */
+enum acpi_smp_boot_protocol smp_boot_protocol(void)
+{
+	if (acpi_psci_present())
+		return ACPI_SMP_BOOT_PSCI;
+	else
+		return ACPI_SMP_BOOT_PARKING_PROTOCOL;
+}
+
 static int __init acpi_parse_fadt(struct acpi_table_header *table)
 {
 	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
index d62d12f..05bc314 100644
--- a/arch/arm64/kernel/cpu_ops.c
+++ b/arch/arm64/kernel/cpu_ops.c
@@ -16,11 +16,13 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <asm/cpu_ops.h>
-#include <asm/smp_plat.h>
 #include <linux/errno.h>
 #include <linux/of.h>
 #include <linux/string.h>
+#include <linux/acpi.h>
+
+#include <asm/cpu_ops.h>
+#include <asm/smp_plat.h>
 
 extern const struct cpu_operations smp_spin_table_ops;
 extern const struct cpu_operations cpu_psci_ops;
@@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
 	return NULL;
 }
 
+#ifdef CONFIG_ACPI
+/*
+ * Get a cpu's boot method in the ACPI way.
+ */
+static char * __init acpi_get_cpu_boot_method(void)
+{
+	/*
+	 * For ACPI 5.1, only two kind of methods are provided,
+	 * Parking protocol and PSCI, but Parking protocol is
+	 * specified for ARMv7 only, so make PSCI as the only method
+	 * for SMP initialization before the ACPI spec or Parking
+	 * protocol spec is updated.
+	 */
+	switch (smp_boot_protocol()) {
+	case ACPI_SMP_BOOT_PSCI:
+		return "psci";
+	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
+	default:
+		return NULL;
+	}
+}
+#else
+static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
+#endif
+
 /*
- * Read a cpu's enable method from the device tree and record it in cpu_ops.
+ * Read a cpu's enable method and record it in cpu_ops.
  */
 int __init cpu_read_ops(struct device_node *dn, int cpu)
 {
-	const char *enable_method = of_get_property(dn, "enable-method", NULL);
+	const char *enable_method;
+
+	if (!acpi_disabled) {
+		enable_method = acpi_get_cpu_boot_method();
+		goto get_ops;
+	}
+
+	enable_method = of_get_property(dn, "enable-method", NULL);
 	if (!enable_method) {
 		/*
 		 * The boot CPU may not have an enable method (e.g. when
@@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
 		return -ENOENT;
 	}
 
+get_ops:
 	cpu_ops[cpu] = cpu_get_ops(enable_method);
 	if (!cpu_ops[cpu]) {
-		pr_warn("%s: unsupported enable-method property: %s\n",
-			dn->full_name, enable_method);
+		if (acpi_disabled) {
+			pr_warn("%s: unsupported enable-method property: %s\n",
+				dn->full_name, enable_method);
+		} else {
+			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
+				cpu);
+		}
+
 		return -EOPNOTSUPP;
 	}
 
@@ -78,7 +119,14 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
 
 void __init cpu_read_bootcpu_ops(void)
 {
-	struct device_node *dn = of_get_cpu_node(0, NULL);
+	struct device_node *dn;
+
+	if (!acpi_disabled) {
+		cpu_read_ops(NULL, 0);
+		return;
+	}
+
+	dn = of_get_cpu_node(0, NULL);
 	if (!dn) {
 		pr_err("Failed to find device node for boot cpu\n");
 		return;
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 8f1d37c..e21bbc9 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -315,7 +315,7 @@ static void (*smp_cross_call)(const struct cpumask *, unsigned int);
  * cpu logical map array containing MPIDR values related to logical
  * cpus. Assumes that cpu_logical_map(0) has already been initialized.
  */
-void __init smp_init_cpus(void)
+static void __init of_smp_init_cpus(void)
 {
 	struct device_node *dn = NULL;
 	unsigned int i, cpu = 1;
@@ -418,6 +418,31 @@ next:
 			set_cpu_possible(i, true);
 }
 
+/*
+ * In ACPI mode, the cpu possible map was enumerated before SMP
+ * initialization when MADT table was parsed, so we can get the
+ * possible map here to initialize CPUs.
+ */
+static void __init acpi_smp_init_cpus(void)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		if (cpu_read_ops(NULL, cpu) != 0)
+			continue;
+
+		cpu_ops[cpu]->cpu_init(NULL, cpu);
+	}
+}
+
+void __init smp_init_cpus(void)
+{
+	if (acpi_disabled)
+		of_smp_init_cpus();
+	else
+		acpi_smp_init_cpus();
+}
+
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
 	int err;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
  2014-08-04 15:28 ` Hanjun Guo
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

Introduce a new function map_gicc_mpidr() to allow MPIDRs to be obtained
from the GICC Structure introduced by ACPI 5.1.

MPIDR is the CPU hardware ID as local APIC ID on x86 platform, so we use
MPIDR not the GIC CPU interface ID to identify CPUs.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acpi.h |   14 ++++++++++++++
 arch/arm64/kernel/acpi.c      |   21 ++++++++++++++++++++-
 drivers/acpi/processor_core.c |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 022f4ad..a81898d 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -12,6 +12,8 @@
 #ifndef _ASM_ACPI_H
 #define _ASM_ACPI_H
 
+#include <asm/smp_plat.h>
+
 /* Basic configuration for ACPI */
 #ifdef	CONFIG_ACPI
 /*
@@ -59,6 +61,18 @@ static inline void disable_acpi(void)
 	acpi_noirq = 1;
 }
 
+u32 pack_mpidr_into_32_bits(u64 mpidr);
+
+/*
+ * The ACPI processor driver for ACPI core code needs this macro
+ * to find out this cpu was already mapped (mapping from CPU hardware
+ * ID to CPU logical ID) or not.
+ *
+ * cpu_logical_map(cpu) is the mapping of MPIDR and the logical cpu,
+ * and MPIDR is the cpu hardware ID we needed.
+ */
+#define cpu_physical_id(cpu) pack_mpidr_into_32_bits(cpu_logical_map(cpu))
+
 /*
  * Checking for the posibility that the CPU can be initialized from the MADT.
  * It's used from ACPI core in crash kernel case where boot CPU is not
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 8a54b4e..ac7ab34 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -22,7 +22,6 @@
 #include <linux/bootmem.h>
 #include <linux/smp.h>
 
-#include <asm/smp_plat.h>
 #include <asm/cputype.h>
 
 int acpi_noirq;			/* skip ACPI IRQ initialization */
@@ -239,6 +238,26 @@ int __init acpi_boot_init(void)
 	return err;
 }
 
+/* MPIDR value provided in GICC structure is 64 bits, but
+ * the acpi processor driver use the 32 bits cpu hardware
+ * ID (apic_id on intel platform) everywhere, it is pretty
+ * hard to modify the acpi processor driver to accept the
+ * 64 bits MPIDR value, at the same time, only 32 bits of
+ * the MPIDR is used in the 64 bits MPIDR, just pack the
+ * Affx fields into a single 32 bit identifier to accommodate
+ * the acpi processor drivers.
+ */
+u32 pack_mpidr_into_32_bits(u64 mpidr)
+{
+	/*
+	 * Bits [0:7] Aff0;
+	 * Bits [8:15] Aff1;
+	 * Bits [16:23] Aff2;
+	 * Bits [32:39] Aff3;
+	 */
+	return (u32) ((mpidr & 0xff00000000) >> 8) | mpidr;
+}
+
 /*
  * acpi_suspend_lowlevel() - save kernel state and suspend.
  *
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index e32321c..4007313 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
 	return 0;
 }
 
+/*
+ * On ARM platform, MPIDR value is the hardware ID as apic ID
+ * on Intel platforms
+ */
+static int map_gicc_mpidr(struct acpi_subtable_header *entry,
+		int device_declaration, u32 acpi_id, int *mpidr)
+{
+	struct acpi_madt_generic_interrupt *gicc =
+	    container_of(entry, struct acpi_madt_generic_interrupt, header);
+
+	if (!(gicc->flags & ACPI_MADT_ENABLED))
+		return -ENODEV;
+
+	/* In the GIC interrupt model, logical processors are
+	 * required to have a Processor Device object in the DSDT,
+	 * so we should check device_declaration here
+	 */
+	if (device_declaration && (gicc->uid == acpi_id)) {
+		/*
+		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
+		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
+		 * fields into a single 32 bit identifier to accommodate the
+		 * acpi processor drivers.
+		 */
+		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
+			 | gicc->arm_mpidr;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static int map_madt_entry(int type, u32 acpi_id)
 {
 	unsigned long madt_end, entry;
@@ -99,6 +131,9 @@ static int map_madt_entry(int type, u32 acpi_id)
 		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
 			if (!map_lsapic_id(header, type, acpi_id, &apic_id))
 				break;
+		} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
+			if (!map_gicc_mpidr(header, type, acpi_id, &apic_id))
+				break;
 		}
 		entry += header->length;
 	}
@@ -131,6 +166,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
 		map_lsapic_id(header, type, acpi_id, &apic_id);
 	} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
 		map_x2apic_id(header, type, acpi_id, &apic_id);
+	} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
+		map_gicc_mpidr(header, type, acpi_id, &apic_id);
 	}
 
 exit:
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce a new function map_gicc_mpidr() to allow MPIDRs to be obtained
from the GICC Structure introduced by ACPI 5.1.

MPIDR is the CPU hardware ID as local APIC ID on x86 platform, so we use
MPIDR not the GIC CPU interface ID to identify CPUs.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acpi.h |   14 ++++++++++++++
 arch/arm64/kernel/acpi.c      |   21 ++++++++++++++++++++-
 drivers/acpi/processor_core.c |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 022f4ad..a81898d 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -12,6 +12,8 @@
 #ifndef _ASM_ACPI_H
 #define _ASM_ACPI_H
 
+#include <asm/smp_plat.h>
+
 /* Basic configuration for ACPI */
 #ifdef	CONFIG_ACPI
 /*
@@ -59,6 +61,18 @@ static inline void disable_acpi(void)
 	acpi_noirq = 1;
 }
 
+u32 pack_mpidr_into_32_bits(u64 mpidr);
+
+/*
+ * The ACPI processor driver for ACPI core code needs this macro
+ * to find out this cpu was already mapped (mapping from CPU hardware
+ * ID to CPU logical ID) or not.
+ *
+ * cpu_logical_map(cpu) is the mapping of MPIDR and the logical cpu,
+ * and MPIDR is the cpu hardware ID we needed.
+ */
+#define cpu_physical_id(cpu) pack_mpidr_into_32_bits(cpu_logical_map(cpu))
+
 /*
  * Checking for the posibility that the CPU can be initialized from the MADT.
  * It's used from ACPI core in crash kernel case where boot CPU is not
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 8a54b4e..ac7ab34 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -22,7 +22,6 @@
 #include <linux/bootmem.h>
 #include <linux/smp.h>
 
-#include <asm/smp_plat.h>
 #include <asm/cputype.h>
 
 int acpi_noirq;			/* skip ACPI IRQ initialization */
@@ -239,6 +238,26 @@ int __init acpi_boot_init(void)
 	return err;
 }
 
+/* MPIDR value provided in GICC structure is 64 bits, but
+ * the acpi processor driver use the 32 bits cpu hardware
+ * ID (apic_id on intel platform) everywhere, it is pretty
+ * hard to modify the acpi processor driver to accept the
+ * 64 bits MPIDR value, at the same time, only 32 bits of
+ * the MPIDR is used in the 64 bits MPIDR, just pack the
+ * Affx fields into a single 32 bit identifier to accommodate
+ * the acpi processor drivers.
+ */
+u32 pack_mpidr_into_32_bits(u64 mpidr)
+{
+	/*
+	 * Bits [0:7] Aff0;
+	 * Bits [8:15] Aff1;
+	 * Bits [16:23] Aff2;
+	 * Bits [32:39] Aff3;
+	 */
+	return (u32) ((mpidr & 0xff00000000) >> 8) | mpidr;
+}
+
 /*
  * acpi_suspend_lowlevel() - save kernel state and suspend.
  *
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index e32321c..4007313 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
 	return 0;
 }
 
+/*
+ * On ARM platform, MPIDR value is the hardware ID as apic ID
+ * on Intel platforms
+ */
+static int map_gicc_mpidr(struct acpi_subtable_header *entry,
+		int device_declaration, u32 acpi_id, int *mpidr)
+{
+	struct acpi_madt_generic_interrupt *gicc =
+	    container_of(entry, struct acpi_madt_generic_interrupt, header);
+
+	if (!(gicc->flags & ACPI_MADT_ENABLED))
+		return -ENODEV;
+
+	/* In the GIC interrupt model, logical processors are
+	 * required to have a Processor Device object in the DSDT,
+	 * so we should check device_declaration here
+	 */
+	if (device_declaration && (gicc->uid == acpi_id)) {
+		/*
+		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
+		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
+		 * fields into a single 32 bit identifier to accommodate the
+		 * acpi processor drivers.
+		 */
+		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
+			 | gicc->arm_mpidr;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static int map_madt_entry(int type, u32 acpi_id)
 {
 	unsigned long madt_end, entry;
@@ -99,6 +131,9 @@ static int map_madt_entry(int type, u32 acpi_id)
 		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
 			if (!map_lsapic_id(header, type, acpi_id, &apic_id))
 				break;
+		} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
+			if (!map_gicc_mpidr(header, type, acpi_id, &apic_id))
+				break;
 		}
 		entry += header->length;
 	}
@@ -131,6 +166,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
 		map_lsapic_id(header, type, acpi_id, &apic_id);
 	} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
 		map_x2apic_id(header, type, acpi_id, &apic_id);
+	} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
+		map_gicc_mpidr(header, type, acpi_id, &apic_id);
 	}
 
 exit:
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 10/18] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
  2014-08-04 15:28 ` Hanjun Guo
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
used, and then register device's gsi with the core IRQ subsystem.

acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
since gsi is unique in the system, so use hwirq number directly
for the mapping.

Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/kernel/acpi.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/bus.c       |    3 ++
 include/linux/acpi.h     |    1 +
 3 files changed, 77 insertions(+)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index ac7ab34..621ced8 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -34,6 +34,12 @@ 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.
  */
@@ -169,6 +175,73 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
 	return 0;
 }
 
+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);
+
 /* Protocol to bring up secondary CPUs */
 enum acpi_smp_boot_protocol smp_boot_protocol(void)
 {
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 8581f5b..d132c1b 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -458,6 +458,9 @@ static int __init acpi_bus_init_irq(void)
 	case ACPI_IRQ_MODEL_IOSAPIC:
 		message = "IOSAPIC";
 		break;
+	case ACPI_IRQ_MODEL_GIC:
+		message = "GIC";
+		break;
 	case ACPI_IRQ_MODEL_PLATFORM:
 		message = "platform specific model";
 		break;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 5320153..e4b6e9a 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -71,6 +71,7 @@ enum acpi_irq_model_id {
 	ACPI_IRQ_MODEL_IOAPIC,
 	ACPI_IRQ_MODEL_IOSAPIC,
 	ACPI_IRQ_MODEL_PLATFORM,
+	ACPI_IRQ_MODEL_GIC,
 	ACPI_IRQ_MODEL_COUNT
 };
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 10/18] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
used, and then register device's gsi with the core IRQ subsystem.

acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
since gsi is unique in the system, so use hwirq number directly
for the mapping.

Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/kernel/acpi.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/bus.c       |    3 ++
 include/linux/acpi.h     |    1 +
 3 files changed, 77 insertions(+)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index ac7ab34..621ced8 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -34,6 +34,12 @@ 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.
  */
@@ -169,6 +175,73 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
 	return 0;
 }
 
+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);
+
 /* Protocol to bring up secondary CPUs */
 enum acpi_smp_boot_protocol smp_boot_protocol(void)
 {
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 8581f5b..d132c1b 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -458,6 +458,9 @@ static int __init acpi_bus_init_irq(void)
 	case ACPI_IRQ_MODEL_IOSAPIC:
 		message = "IOSAPIC";
 		break;
+	case ACPI_IRQ_MODEL_GIC:
+		message = "GIC";
+		break;
 	case ACPI_IRQ_MODEL_PLATFORM:
 		message = "platform specific model";
 		break;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 5320153..e4b6e9a 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -71,6 +71,7 @@ enum acpi_irq_model_id {
 	ACPI_IRQ_MODEL_IOAPIC,
 	ACPI_IRQ_MODEL_IOSAPIC,
 	ACPI_IRQ_MODEL_PLATFORM,
+	ACPI_IRQ_MODEL_GIC,
 	ACPI_IRQ_MODEL_COUNT
 };
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 11/18] ACPI / table: Add new function to get table entries
  2014-08-04 15:28 ` Hanjun Guo
  (?)
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Ashwin Chaugule,
	Hanjun

From: Ashwin Chaugule <ashwin.chaugule@linaro.org>

The acpi_table_parse() function has a callback that
passes a pointer to a table_header. Add a new function
which takes this pointer and parses its entries. This
eliminates the need to re-traverse all the tables for
each call. e.g. as in acpi_table_parse_madt() which is
normally called after acpi_table_parse().

Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/tables.c |   70 +++++++++++++++++++++++++++++++++++--------------
 include/linux/acpi.h  |    4 +++
 2 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 77f8bb1..a58fce4 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -229,17 +229,14 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 }
 
 int __init
-acpi_table_parse_entries(char *id,
-			     unsigned long table_size,
-			     int entry_id,
-			     acpi_tbl_entry_handler handler,
-			     unsigned int max_entries)
+acpi_parse_entries(unsigned long table_size,
+		acpi_tbl_entry_handler handler,
+		struct acpi_table_header *table_header,
+		int entry_id, unsigned int max_entries)
 {
-	struct acpi_table_header *table_header = NULL;
 	struct acpi_subtable_header *entry;
-	unsigned int count = 0;
+	int count = 0;
 	unsigned long table_end;
-	acpi_size tbl_size;
 
 	if (acpi_disabled)
 		return -ENODEV;
@@ -247,13 +244,11 @@ acpi_table_parse_entries(char *id,
 	if (!handler)
 		return -EINVAL;
 
-	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
-	else
-		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
+	if (!table_size)
+		return -EINVAL;
 
 	if (!table_header) {
-		pr_warn("%4.4s not present\n", id);
+		pr_warn("Table header not present\n");
 		return -ENODEV;
 	}
 
@@ -268,31 +263,66 @@ acpi_table_parse_entries(char *id,
 	       table_end) {
 		if (entry->type == entry_id
 		    && (!max_entries || count++ < max_entries))
-			if (handler(entry, table_end))
+			if (handler(entry, table_end)) {
+				count = -EINVAL;
 				goto err;
+		}
 
 		/*
 		 * If entry->length is 0, break from this loop to avoid
 		 * infinite loop.
 		 */
 		if (entry->length == 0) {
-			pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+			pr_err("[0x%02x] Invalid zero length\n", entry_id);
+			count = -EINVAL;
 			goto err;
 		}
 
 		entry = (struct acpi_subtable_header *)
 		    ((unsigned long)entry + entry->length);
 	}
+
 	if (max_entries && count > max_entries) {
-		pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
-			id, entry_id, count - max_entries, count);
+		pr_warn("[0x%02x] ignored %i entries of %i found\n",
+			entry_id, count - max_entries, count);
 	}
 
-	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
-	return count;
 err:
+	return count;
+}
+
+int __init
+acpi_table_parse_entries(char *id,
+			 unsigned long table_size,
+			 int entry_id,
+			 acpi_tbl_entry_handler handler,
+			 unsigned int max_entries)
+{
+	struct acpi_table_header *table_header = NULL;
+	acpi_size tbl_size;
+	int count;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	if (!handler)
+		return -EINVAL;
+
+	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
+		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
+	else
+		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
+
+	if (!table_header) {
+		pr_warn("%4.4s not present\n", id);
+		return -ENODEV;
+	}
+
+	count = acpi_parse_entries(table_size, handler, table_header,
+			entry_id, max_entries);
+
 	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
-	return -EINVAL;
+	return count;
 }
 
 int __init
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index e4b6e9a..18ed9f4 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -124,6 +124,10 @@ int acpi_numa_init (void);
 
 int acpi_table_init (void);
 int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
+int __init acpi_parse_entries(unsigned long table_size,
+		acpi_tbl_entry_handler handler,
+		struct acpi_table_header *table_header,
+		int entry_id, unsigned int max_entries);
 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
 				    int entry_id,
 				    acpi_tbl_entry_handler handler,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 11/18] ACPI / table: Add new function to get table entries
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Ashwin Chaugule,
	Hanjun Guo

From: Ashwin Chaugule <ashwin.chaugule@linaro.org>

The acpi_table_parse() function has a callback that
passes a pointer to a table_header. Add a new function
which takes this pointer and parses its entries. This
eliminates the need to re-traverse all the tables for
each call. e.g. as in acpi_table_parse_madt() which is
normally called after acpi_table_parse().

Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/tables.c |   70 +++++++++++++++++++++++++++++++++++--------------
 include/linux/acpi.h  |    4 +++
 2 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 77f8bb1..a58fce4 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -229,17 +229,14 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 }
 
 int __init
-acpi_table_parse_entries(char *id,
-			     unsigned long table_size,
-			     int entry_id,
-			     acpi_tbl_entry_handler handler,
-			     unsigned int max_entries)
+acpi_parse_entries(unsigned long table_size,
+		acpi_tbl_entry_handler handler,
+		struct acpi_table_header *table_header,
+		int entry_id, unsigned int max_entries)
 {
-	struct acpi_table_header *table_header = NULL;
 	struct acpi_subtable_header *entry;
-	unsigned int count = 0;
+	int count = 0;
 	unsigned long table_end;
-	acpi_size tbl_size;
 
 	if (acpi_disabled)
 		return -ENODEV;
@@ -247,13 +244,11 @@ acpi_table_parse_entries(char *id,
 	if (!handler)
 		return -EINVAL;
 
-	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
-	else
-		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
+	if (!table_size)
+		return -EINVAL;
 
 	if (!table_header) {
-		pr_warn("%4.4s not present\n", id);
+		pr_warn("Table header not present\n");
 		return -ENODEV;
 	}
 
@@ -268,31 +263,66 @@ acpi_table_parse_entries(char *id,
 	       table_end) {
 		if (entry->type == entry_id
 		    && (!max_entries || count++ < max_entries))
-			if (handler(entry, table_end))
+			if (handler(entry, table_end)) {
+				count = -EINVAL;
 				goto err;
+		}
 
 		/*
 		 * If entry->length is 0, break from this loop to avoid
 		 * infinite loop.
 		 */
 		if (entry->length == 0) {
-			pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+			pr_err("[0x%02x] Invalid zero length\n", entry_id);
+			count = -EINVAL;
 			goto err;
 		}
 
 		entry = (struct acpi_subtable_header *)
 		    ((unsigned long)entry + entry->length);
 	}
+
 	if (max_entries && count > max_entries) {
-		pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
-			id, entry_id, count - max_entries, count);
+		pr_warn("[0x%02x] ignored %i entries of %i found\n",
+			entry_id, count - max_entries, count);
 	}
 
-	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
-	return count;
 err:
+	return count;
+}
+
+int __init
+acpi_table_parse_entries(char *id,
+			 unsigned long table_size,
+			 int entry_id,
+			 acpi_tbl_entry_handler handler,
+			 unsigned int max_entries)
+{
+	struct acpi_table_header *table_header = NULL;
+	acpi_size tbl_size;
+	int count;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	if (!handler)
+		return -EINVAL;
+
+	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
+		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
+	else
+		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
+
+	if (!table_header) {
+		pr_warn("%4.4s not present\n", id);
+		return -ENODEV;
+	}
+
+	count = acpi_parse_entries(table_size, handler, table_header,
+			entry_id, max_entries);
+
 	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
-	return -EINVAL;
+	return count;
 }
 
 int __init
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index e4b6e9a..18ed9f4 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -124,6 +124,10 @@ int acpi_numa_init (void);
 
 int acpi_table_init (void);
 int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
+int __init acpi_parse_entries(unsigned long table_size,
+		acpi_tbl_entry_handler handler,
+		struct acpi_table_header *table_header,
+		int entry_id, unsigned int max_entries);
 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
 				    int entry_id,
 				    acpi_tbl_entry_handler handler,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 11/18] ACPI / table: Add new function to get table entries
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ashwin Chaugule <ashwin.chaugule@linaro.org>

The acpi_table_parse() function has a callback that
passes a pointer to a table_header. Add a new function
which takes this pointer and parses its entries. This
eliminates the need to re-traverse all the tables for
each call. e.g. as in acpi_table_parse_madt() which is
normally called after acpi_table_parse().

Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/tables.c |   70 +++++++++++++++++++++++++++++++++++--------------
 include/linux/acpi.h  |    4 +++
 2 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 77f8bb1..a58fce4 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -229,17 +229,14 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 }
 
 int __init
-acpi_table_parse_entries(char *id,
-			     unsigned long table_size,
-			     int entry_id,
-			     acpi_tbl_entry_handler handler,
-			     unsigned int max_entries)
+acpi_parse_entries(unsigned long table_size,
+		acpi_tbl_entry_handler handler,
+		struct acpi_table_header *table_header,
+		int entry_id, unsigned int max_entries)
 {
-	struct acpi_table_header *table_header = NULL;
 	struct acpi_subtable_header *entry;
-	unsigned int count = 0;
+	int count = 0;
 	unsigned long table_end;
-	acpi_size tbl_size;
 
 	if (acpi_disabled)
 		return -ENODEV;
@@ -247,13 +244,11 @@ acpi_table_parse_entries(char *id,
 	if (!handler)
 		return -EINVAL;
 
-	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
-	else
-		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
+	if (!table_size)
+		return -EINVAL;
 
 	if (!table_header) {
-		pr_warn("%4.4s not present\n", id);
+		pr_warn("Table header not present\n");
 		return -ENODEV;
 	}
 
@@ -268,31 +263,66 @@ acpi_table_parse_entries(char *id,
 	       table_end) {
 		if (entry->type == entry_id
 		    && (!max_entries || count++ < max_entries))
-			if (handler(entry, table_end))
+			if (handler(entry, table_end)) {
+				count = -EINVAL;
 				goto err;
+		}
 
 		/*
 		 * If entry->length is 0, break from this loop to avoid
 		 * infinite loop.
 		 */
 		if (entry->length == 0) {
-			pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+			pr_err("[0x%02x] Invalid zero length\n", entry_id);
+			count = -EINVAL;
 			goto err;
 		}
 
 		entry = (struct acpi_subtable_header *)
 		    ((unsigned long)entry + entry->length);
 	}
+
 	if (max_entries && count > max_entries) {
-		pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
-			id, entry_id, count - max_entries, count);
+		pr_warn("[0x%02x] ignored %i entries of %i found\n",
+			entry_id, count - max_entries, count);
 	}
 
-	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
-	return count;
 err:
+	return count;
+}
+
+int __init
+acpi_table_parse_entries(char *id,
+			 unsigned long table_size,
+			 int entry_id,
+			 acpi_tbl_entry_handler handler,
+			 unsigned int max_entries)
+{
+	struct acpi_table_header *table_header = NULL;
+	acpi_size tbl_size;
+	int count;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	if (!handler)
+		return -EINVAL;
+
+	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
+		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
+	else
+		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
+
+	if (!table_header) {
+		pr_warn("%4.4s not present\n", id);
+		return -ENODEV;
+	}
+
+	count = acpi_parse_entries(table_size, handler, table_header,
+			entry_id, max_entries);
+
 	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
-	return -EINVAL;
+	return count;
 }
 
 int __init
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index e4b6e9a..18ed9f4 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -124,6 +124,10 @@ int acpi_numa_init (void);
 
 int acpi_table_init (void);
 int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
+int __init acpi_parse_entries(unsigned long table_size,
+		acpi_tbl_entry_handler handler,
+		struct acpi_table_header *table_header,
+		int entry_id, unsigned int max_entries);
 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
 				    int entry_id,
 				    acpi_tbl_entry_handler handler,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 12/18] ARM64 / ACPI: Add GICv2 specific ACPI boot support
  2014-08-04 15:28 ` Hanjun Guo
  (?)
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Tomasz Nowicki

From: Tomasz Nowicki <tomasz.nowicki@linaro.org>

ACPI kernel uses MADT table for proper GIC initialization. It needs to
parse GIC related subtables, collect CPU interface and distributor
addresses and call driver initialization function (which is hardware
abstraction agnostic). In a similar way, FDT initialize GICv1/2.

NOTE: This commit allow to initialize GICv1/2 only.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acpi.h        |    2 -
 arch/arm64/kernel/acpi.c             |   26 +++++++-
 arch/arm64/kernel/irq.c              |    5 ++
 drivers/irqchip/irq-gic.c            |  114 ++++++++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-acpi.h |   36 +++++++++++
 5 files changed, 180 insertions(+), 3 deletions(-)
 create mode 100644 include/linux/irqchip/arm-gic-acpi.h

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index a81898d..009303d 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -99,8 +99,6 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 extern int (*acpi_suspend_lowlevel)(void);
 #define acpi_wakeup_address 0
 
-#define MAX_GIC_CPU_INTERFACE 65535
-
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 621ced8..988fea2 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -21,6 +21,7 @@
 #include <linux/irqdomain.h>
 #include <linux/bootmem.h>
 #include <linux/smp.h>
+#include <linux/irqchip/arm-gic-acpi.h>
 
 #include <asm/cputype.h>
 
@@ -159,7 +160,8 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
 	 * we need for SMP init
 	 */
 	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
-			acpi_parse_gic_cpu_interface, MAX_GIC_CPU_INTERFACE);
+				      acpi_parse_gic_cpu_interface,
+				      ACPI_GIC_MAX_CPU_INTERFACE);
 
 	if (!count) {
 		pr_err("No GIC CPU interface entries present\n");
@@ -311,6 +313,28 @@ int __init acpi_boot_init(void)
 	return err;
 }
 
+void __init acpi_gic_init(void)
+{
+	struct acpi_table_header *table;
+	acpi_status status;
+	acpi_size tbl_size;
+	int err;
+
+	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);
+}
+
 /* MPIDR value provided in GICC structure is 64 bits, but
  * the acpi processor driver use the 32 bits cpu hardware
  * ID (apic_id on intel platform) everywhere, it is pretty
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index 0f08dfd..c074d60 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -28,6 +28,7 @@
 #include <linux/irqchip.h>
 #include <linux/seq_file.h>
 #include <linux/ratelimit.h>
+#include <linux/irqchip/arm-gic-acpi.h>
 
 unsigned long irq_err_count;
 
@@ -78,6 +79,10 @@ void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
 void __init init_IRQ(void)
 {
 	irqchip_init();
+
+	if (!handle_arch_irq)
+		acpi_gic_init();
+
 	if (!handle_arch_irq)
 		panic("No interrupt controller found.");
 }
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 7c131cf..25860f0 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -35,12 +35,14 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/acpi.h>
 #include <linux/irqdomain.h>
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
 #include <linux/slab.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqchip/arm-gic.h>
+#include <linux/irqchip/arm-gic-acpi.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -1082,3 +1084,115 @@ IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
 IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
 
 #endif
+
+#ifdef CONFIG_ACPI
+static u64 dist_phy_base, cpu_phy_base = ULONG_MAX;
+
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_interrupt *processor;
+	u64 gic_cpu_base;
+
+	processor = (struct acpi_madt_generic_interrupt *)header;
+
+	if (BAD_MADT_ENTRY(processor, end))
+		return -EINVAL;
+
+	gic_cpu_base = processor->base_address;
+	if (!gic_cpu_base)
+		return -EFAULT;
+
+	/*
+	 * There is no support for non-banked GICv1/2 register in ACPI spec.
+	 * All CPU interface addresses have to be the same.
+	 */
+	if (cpu_phy_base != ULONG_MAX && gic_cpu_base != cpu_phy_base)
+		return -EFAULT;
+
+	cpu_phy_base = gic_cpu_base;
+	return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_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;
+
+	dist_phy_base = dist->base_address;
+	if (!dist_phy_base)
+		return -EFAULT;
+
+	return 0;
+}
+
+int __init
+gic_v2_acpi_init(struct acpi_table_header *table)
+{
+	void __iomem *cpu_base, *dist_base;
+	int count;
+
+	/* Collect CPU base addresses */
+	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
+				   gic_acpi_parse_madt_cpu, table,
+				   ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+				   ACPI_GIC_MAX_CPU_INTERFACE);
+	if (count < 0) {
+		pr_err("Error during GICC entries parsing\n");
+		return -EFAULT;
+	} else if (!count) {
+		/* No GICC entries provided, use address from MADT header */
+		struct acpi_table_madt *madt = (struct acpi_table_madt *)table;
+
+		if (!madt->address)
+			return -EFAULT;
+
+		cpu_phy_base = (u64)madt->address;
+	}
+
+	/*
+	 * Find distributor base address. We expect one distributor entry since
+	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
+	 */
+	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
+				   gic_acpi_parse_madt_distributor, table,
+				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+				   ACPI_GIC_MAX_DISTRIBUTOR);
+	if (count <= 0) {
+		pr_err("Error during GICD entries parsing\n");
+		return -EFAULT;
+	} else if (count > 1) {
+		pr_err("More than one GICD entry detected\n");
+		return -EINVAL;
+	}
+
+	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
+	if (!cpu_base) {
+		pr_err("Unable to map GICC registers\n");
+		return -ENOMEM;
+	}
+
+	dist_base = ioremap(dist_phy_base, ACPI_GIC_DIST_MEM_SIZE);
+	if (!dist_base) {
+		pr_err("Unable to map GICD registers\n");
+		iounmap(cpu_base);
+		return -ENOMEM;
+	}
+
+	/*
+	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
+	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
+	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
+	 */
+	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
+	irq_set_default_host(gic_data[0].domain);
+	return 0;
+}
+#endif
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
new file mode 100644
index 0000000..ffcfeb2
--- /dev/null
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014, Linaro Ltd.
+ *	Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
+ *
+ * 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.
+ */
+
+#ifndef ARM_GIC_ACPI_H_
+#define ARM_GIC_ACPI_H_
+
+#include <linux/acpi.h>
+
+#ifdef CONFIG_ACPI
+#define ACPI_GIC_MAX_CPU_INTERFACE	65535
+#define ACPI_GIC_MAX_DISTRIBUTOR	1
+
+/*
+ * Hard code here, we can not get memory size from MADT (but FDT does),
+ * Actually no need to do that, because this size can be inferred
+ * from GIC spec.
+ */
+#define ACPI_GIC_DIST_MEM_SIZE		(SZ_64K)
+#define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
+
+void acpi_gic_init(void);
+int gic_v2_acpi_init(struct acpi_table_header *table);
+#else
+static inline void acpi_gic_init(void)
+{
+
+}
+#endif
+
+#endif /* ARM_GIC_ACPI_H_ */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 12/18] ARM64 / ACPI: Add GICv2 specific ACPI boot support
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Tomasz Nowicki,
	Hanjun Guo

From: Tomasz Nowicki <tomasz.nowicki@linaro.org>

ACPI kernel uses MADT table for proper GIC initialization. It needs to
parse GIC related subtables, collect CPU interface and distributor
addresses and call driver initialization function (which is hardware
abstraction agnostic). In a similar way, FDT initialize GICv1/2.

NOTE: This commit allow to initialize GICv1/2 only.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acpi.h        |    2 -
 arch/arm64/kernel/acpi.c             |   26 +++++++-
 arch/arm64/kernel/irq.c              |    5 ++
 drivers/irqchip/irq-gic.c            |  114 ++++++++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-acpi.h |   36 +++++++++++
 5 files changed, 180 insertions(+), 3 deletions(-)
 create mode 100644 include/linux/irqchip/arm-gic-acpi.h

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index a81898d..009303d 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -99,8 +99,6 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 extern int (*acpi_suspend_lowlevel)(void);
 #define acpi_wakeup_address 0
 
-#define MAX_GIC_CPU_INTERFACE 65535
-
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 621ced8..988fea2 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -21,6 +21,7 @@
 #include <linux/irqdomain.h>
 #include <linux/bootmem.h>
 #include <linux/smp.h>
+#include <linux/irqchip/arm-gic-acpi.h>
 
 #include <asm/cputype.h>
 
@@ -159,7 +160,8 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
 	 * we need for SMP init
 	 */
 	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
-			acpi_parse_gic_cpu_interface, MAX_GIC_CPU_INTERFACE);
+				      acpi_parse_gic_cpu_interface,
+				      ACPI_GIC_MAX_CPU_INTERFACE);
 
 	if (!count) {
 		pr_err("No GIC CPU interface entries present\n");
@@ -311,6 +313,28 @@ int __init acpi_boot_init(void)
 	return err;
 }
 
+void __init acpi_gic_init(void)
+{
+	struct acpi_table_header *table;
+	acpi_status status;
+	acpi_size tbl_size;
+	int err;
+
+	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);
+}
+
 /* MPIDR value provided in GICC structure is 64 bits, but
  * the acpi processor driver use the 32 bits cpu hardware
  * ID (apic_id on intel platform) everywhere, it is pretty
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index 0f08dfd..c074d60 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -28,6 +28,7 @@
 #include <linux/irqchip.h>
 #include <linux/seq_file.h>
 #include <linux/ratelimit.h>
+#include <linux/irqchip/arm-gic-acpi.h>
 
 unsigned long irq_err_count;
 
@@ -78,6 +79,10 @@ void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
 void __init init_IRQ(void)
 {
 	irqchip_init();
+
+	if (!handle_arch_irq)
+		acpi_gic_init();
+
 	if (!handle_arch_irq)
 		panic("No interrupt controller found.");
 }
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 7c131cf..25860f0 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -35,12 +35,14 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/acpi.h>
 #include <linux/irqdomain.h>
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
 #include <linux/slab.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqchip/arm-gic.h>
+#include <linux/irqchip/arm-gic-acpi.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -1082,3 +1084,115 @@ IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
 IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
 
 #endif
+
+#ifdef CONFIG_ACPI
+static u64 dist_phy_base, cpu_phy_base = ULONG_MAX;
+
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_interrupt *processor;
+	u64 gic_cpu_base;
+
+	processor = (struct acpi_madt_generic_interrupt *)header;
+
+	if (BAD_MADT_ENTRY(processor, end))
+		return -EINVAL;
+
+	gic_cpu_base = processor->base_address;
+	if (!gic_cpu_base)
+		return -EFAULT;
+
+	/*
+	 * There is no support for non-banked GICv1/2 register in ACPI spec.
+	 * All CPU interface addresses have to be the same.
+	 */
+	if (cpu_phy_base != ULONG_MAX && gic_cpu_base != cpu_phy_base)
+		return -EFAULT;
+
+	cpu_phy_base = gic_cpu_base;
+	return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_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;
+
+	dist_phy_base = dist->base_address;
+	if (!dist_phy_base)
+		return -EFAULT;
+
+	return 0;
+}
+
+int __init
+gic_v2_acpi_init(struct acpi_table_header *table)
+{
+	void __iomem *cpu_base, *dist_base;
+	int count;
+
+	/* Collect CPU base addresses */
+	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
+				   gic_acpi_parse_madt_cpu, table,
+				   ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+				   ACPI_GIC_MAX_CPU_INTERFACE);
+	if (count < 0) {
+		pr_err("Error during GICC entries parsing\n");
+		return -EFAULT;
+	} else if (!count) {
+		/* No GICC entries provided, use address from MADT header */
+		struct acpi_table_madt *madt = (struct acpi_table_madt *)table;
+
+		if (!madt->address)
+			return -EFAULT;
+
+		cpu_phy_base = (u64)madt->address;
+	}
+
+	/*
+	 * Find distributor base address. We expect one distributor entry since
+	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
+	 */
+	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
+				   gic_acpi_parse_madt_distributor, table,
+				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+				   ACPI_GIC_MAX_DISTRIBUTOR);
+	if (count <= 0) {
+		pr_err("Error during GICD entries parsing\n");
+		return -EFAULT;
+	} else if (count > 1) {
+		pr_err("More than one GICD entry detected\n");
+		return -EINVAL;
+	}
+
+	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
+	if (!cpu_base) {
+		pr_err("Unable to map GICC registers\n");
+		return -ENOMEM;
+	}
+
+	dist_base = ioremap(dist_phy_base, ACPI_GIC_DIST_MEM_SIZE);
+	if (!dist_base) {
+		pr_err("Unable to map GICD registers\n");
+		iounmap(cpu_base);
+		return -ENOMEM;
+	}
+
+	/*
+	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
+	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
+	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
+	 */
+	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
+	irq_set_default_host(gic_data[0].domain);
+	return 0;
+}
+#endif
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
new file mode 100644
index 0000000..ffcfeb2
--- /dev/null
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014, Linaro Ltd.
+ *	Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
+ *
+ * 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.
+ */
+
+#ifndef ARM_GIC_ACPI_H_
+#define ARM_GIC_ACPI_H_
+
+#include <linux/acpi.h>
+
+#ifdef CONFIG_ACPI
+#define ACPI_GIC_MAX_CPU_INTERFACE	65535
+#define ACPI_GIC_MAX_DISTRIBUTOR	1
+
+/*
+ * Hard code here, we can not get memory size from MADT (but FDT does),
+ * Actually no need to do that, because this size can be inferred
+ * from GIC spec.
+ */
+#define ACPI_GIC_DIST_MEM_SIZE		(SZ_64K)
+#define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
+
+void acpi_gic_init(void);
+int gic_v2_acpi_init(struct acpi_table_header *table);
+#else
+static inline void acpi_gic_init(void)
+{
+
+}
+#endif
+
+#endif /* ARM_GIC_ACPI_H_ */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 12/18] ARM64 / ACPI: Add GICv2 specific ACPI boot support
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tomasz Nowicki <tomasz.nowicki@linaro.org>

ACPI kernel uses MADT table for proper GIC initialization. It needs to
parse GIC related subtables, collect CPU interface and distributor
addresses and call driver initialization function (which is hardware
abstraction agnostic). In a similar way, FDT initialize GICv1/2.

NOTE: This commit allow to initialize GICv1/2 only.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/include/asm/acpi.h        |    2 -
 arch/arm64/kernel/acpi.c             |   26 +++++++-
 arch/arm64/kernel/irq.c              |    5 ++
 drivers/irqchip/irq-gic.c            |  114 ++++++++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-acpi.h |   36 +++++++++++
 5 files changed, 180 insertions(+), 3 deletions(-)
 create mode 100644 include/linux/irqchip/arm-gic-acpi.h

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index a81898d..009303d 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -99,8 +99,6 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 extern int (*acpi_suspend_lowlevel)(void);
 #define acpi_wakeup_address 0
 
-#define MAX_GIC_CPU_INTERFACE 65535
-
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 621ced8..988fea2 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -21,6 +21,7 @@
 #include <linux/irqdomain.h>
 #include <linux/bootmem.h>
 #include <linux/smp.h>
+#include <linux/irqchip/arm-gic-acpi.h>
 
 #include <asm/cputype.h>
 
@@ -159,7 +160,8 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
 	 * we need for SMP init
 	 */
 	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
-			acpi_parse_gic_cpu_interface, MAX_GIC_CPU_INTERFACE);
+				      acpi_parse_gic_cpu_interface,
+				      ACPI_GIC_MAX_CPU_INTERFACE);
 
 	if (!count) {
 		pr_err("No GIC CPU interface entries present\n");
@@ -311,6 +313,28 @@ int __init acpi_boot_init(void)
 	return err;
 }
 
+void __init acpi_gic_init(void)
+{
+	struct acpi_table_header *table;
+	acpi_status status;
+	acpi_size tbl_size;
+	int err;
+
+	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);
+}
+
 /* MPIDR value provided in GICC structure is 64 bits, but
  * the acpi processor driver use the 32 bits cpu hardware
  * ID (apic_id on intel platform) everywhere, it is pretty
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index 0f08dfd..c074d60 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -28,6 +28,7 @@
 #include <linux/irqchip.h>
 #include <linux/seq_file.h>
 #include <linux/ratelimit.h>
+#include <linux/irqchip/arm-gic-acpi.h>
 
 unsigned long irq_err_count;
 
@@ -78,6 +79,10 @@ void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
 void __init init_IRQ(void)
 {
 	irqchip_init();
+
+	if (!handle_arch_irq)
+		acpi_gic_init();
+
 	if (!handle_arch_irq)
 		panic("No interrupt controller found.");
 }
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 7c131cf..25860f0 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -35,12 +35,14 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/acpi.h>
 #include <linux/irqdomain.h>
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
 #include <linux/slab.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqchip/arm-gic.h>
+#include <linux/irqchip/arm-gic-acpi.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -1082,3 +1084,115 @@ IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
 IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
 
 #endif
+
+#ifdef CONFIG_ACPI
+static u64 dist_phy_base, cpu_phy_base = ULONG_MAX;
+
+static int __init
+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_interrupt *processor;
+	u64 gic_cpu_base;
+
+	processor = (struct acpi_madt_generic_interrupt *)header;
+
+	if (BAD_MADT_ENTRY(processor, end))
+		return -EINVAL;
+
+	gic_cpu_base = processor->base_address;
+	if (!gic_cpu_base)
+		return -EFAULT;
+
+	/*
+	 * There is no support for non-banked GICv1/2 register in ACPI spec.
+	 * All CPU interface addresses have to be the same.
+	 */
+	if (cpu_phy_base != ULONG_MAX && gic_cpu_base != cpu_phy_base)
+		return -EFAULT;
+
+	cpu_phy_base = gic_cpu_base;
+	return 0;
+}
+
+static int __init
+gic_acpi_parse_madt_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;
+
+	dist_phy_base = dist->base_address;
+	if (!dist_phy_base)
+		return -EFAULT;
+
+	return 0;
+}
+
+int __init
+gic_v2_acpi_init(struct acpi_table_header *table)
+{
+	void __iomem *cpu_base, *dist_base;
+	int count;
+
+	/* Collect CPU base addresses */
+	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
+				   gic_acpi_parse_madt_cpu, table,
+				   ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+				   ACPI_GIC_MAX_CPU_INTERFACE);
+	if (count < 0) {
+		pr_err("Error during GICC entries parsing\n");
+		return -EFAULT;
+	} else if (!count) {
+		/* No GICC entries provided, use address from MADT header */
+		struct acpi_table_madt *madt = (struct acpi_table_madt *)table;
+
+		if (!madt->address)
+			return -EFAULT;
+
+		cpu_phy_base = (u64)madt->address;
+	}
+
+	/*
+	 * Find distributor base address. We expect one distributor entry since
+	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
+	 */
+	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
+				   gic_acpi_parse_madt_distributor, table,
+				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+				   ACPI_GIC_MAX_DISTRIBUTOR);
+	if (count <= 0) {
+		pr_err("Error during GICD entries parsing\n");
+		return -EFAULT;
+	} else if (count > 1) {
+		pr_err("More than one GICD entry detected\n");
+		return -EINVAL;
+	}
+
+	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
+	if (!cpu_base) {
+		pr_err("Unable to map GICC registers\n");
+		return -ENOMEM;
+	}
+
+	dist_base = ioremap(dist_phy_base, ACPI_GIC_DIST_MEM_SIZE);
+	if (!dist_base) {
+		pr_err("Unable to map GICD registers\n");
+		iounmap(cpu_base);
+		return -ENOMEM;
+	}
+
+	/*
+	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
+	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
+	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
+	 */
+	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
+	irq_set_default_host(gic_data[0].domain);
+	return 0;
+}
+#endif
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
new file mode 100644
index 0000000..ffcfeb2
--- /dev/null
+++ b/include/linux/irqchip/arm-gic-acpi.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014, Linaro Ltd.
+ *	Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
+ *
+ * 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.
+ */
+
+#ifndef ARM_GIC_ACPI_H_
+#define ARM_GIC_ACPI_H_
+
+#include <linux/acpi.h>
+
+#ifdef CONFIG_ACPI
+#define ACPI_GIC_MAX_CPU_INTERFACE	65535
+#define ACPI_GIC_MAX_DISTRIBUTOR	1
+
+/*
+ * Hard code here, we can not get memory size from MADT (but FDT does),
+ * Actually no need to do that, because this size can be inferred
+ * from GIC spec.
+ */
+#define ACPI_GIC_DIST_MEM_SIZE		(SZ_64K)
+#define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
+
+void acpi_gic_init(void);
+int gic_v2_acpi_init(struct acpi_table_header *table);
+#else
+static inline void acpi_gic_init(void)
+{
+
+}
+#endif
+
+#endif /* ARM_GIC_ACPI_H_ */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 13/18] ARM64 / ACPI: Parse GTDT to initialize arch timer
  2014-08-04 15:28 ` Hanjun Guo
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

Using the information presented by GTDT to initialize the arch
timer (not memory-mapped).

Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/kernel/time.c             |    7 ++
 drivers/clocksource/arm_arch_timer.c |  117 ++++++++++++++++++++++++++++------
 include/linux/clocksource.h          |    6 ++
 3 files changed, 111 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index 1a7125c..42f9195 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/clocksource.h>
 #include <linux/clk-provider.h>
+#include <linux/acpi.h>
 
 #include <clocksource/arm_arch_timer.h>
 
@@ -72,6 +73,12 @@ void __init time_init(void)
 
 	tick_setup_hrtimer_broadcast();
 
+	/*
+	 * Since ACPI or FDT will only one be available in the system,
+	 * we can use acpi_generic_timer_init() here safely
+	 */
+	acpi_generic_timer_init();
+
 	arch_timer_rate = arch_timer_get_rate();
 	if (!arch_timer_rate)
 		panic("Unable to initialise architected timer.\n");
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 5163ec1..397783f 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/sched_clock.h>
+#include <linux/acpi.h>
 
 #include <asm/arch_timer.h>
 #include <asm/virt.h>
@@ -338,8 +339,12 @@ arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
 	if (arch_timer_rate)
 		return;
 
-	/* Try to determine the frequency from the device tree or CNTFRQ */
-	if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
+	/*
+	 * Try to determine the frequency from the device tree or CNTFRQ,
+	 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
+	 */
+	if (!acpi_disabled ||
+	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
 		if (cntbase)
 			arch_timer_rate = readl_relaxed(cntbase + CNTFRQ);
 		else
@@ -635,20 +640,8 @@ static void __init arch_timer_common_init(void)
 	arch_timer_arch_init();
 }
 
-static void __init arch_timer_init(struct device_node *np)
+static void __init arch_timer_init(void)
 {
-	int i;
-
-	if (arch_timers_present & ARCH_CP15_TIMER) {
-		pr_warn("arch_timer: multiple nodes in dt, skipping\n");
-		return;
-	}
-
-	arch_timers_present |= ARCH_CP15_TIMER;
-	for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
-		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
-	arch_timer_detect_rate(NULL, np);
-
 	/*
 	 * If HYP mode is available, we know that the physical timer
 	 * has been configured to be accessible from PL1. Use it, so
@@ -667,13 +660,31 @@ static void __init arch_timer_init(struct device_node *np)
 		}
 	}
 
-	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
-
 	arch_timer_register();
 	arch_timer_common_init();
 }
-CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init);
-CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init);
+
+static void __init arch_timer_of_init(struct device_node *np)
+{
+	int i;
+
+	if (arch_timers_present & ARCH_CP15_TIMER) {
+		pr_warn("arch_timer: multiple nodes in dt, skipping\n");
+		return;
+	}
+
+	arch_timers_present |= ARCH_CP15_TIMER;
+	for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
+		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
+
+	arch_timer_detect_rate(NULL, np);
+
+	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
+
+	arch_timer_init();
+}
+CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
+CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init);
 
 static void __init arch_timer_mem_init(struct device_node *np)
 {
@@ -740,3 +751,71 @@ static void __init arch_timer_mem_init(struct device_node *np)
 }
 CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
 		       arch_timer_mem_init);
+
+#ifdef CONFIG_ACPI
+static int __init
+map_generic_timer_interrupt(u32 interrupt, u32 flags)
+{
+	int trigger, polarity;
+
+	if (!interrupt)
+		return 0;
+
+	trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
+			: ACPI_LEVEL_SENSITIVE;
+
+	polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
+			: ACPI_ACTIVE_HIGH;
+
+	return acpi_register_gsi(NULL, interrupt, trigger, polarity);
+}
+
+/* Initialize per-processor generic timer */
+static int __init arch_timer_acpi_init(struct acpi_table_header *table)
+{
+	struct acpi_table_gtdt *gtdt;
+
+	if (arch_timers_present & ARCH_CP15_TIMER) {
+		pr_warn("arch_timer: already initialized, skipping\n");
+		return -EINVAL;
+	}
+
+	gtdt = container_of(table, struct acpi_table_gtdt, header);
+
+	arch_timers_present |= ARCH_CP15_TIMER;
+
+	arch_timer_ppi[PHYS_SECURE_PPI] =
+		map_generic_timer_interrupt(gtdt->secure_el1_interrupt,
+		gtdt->secure_el1_flags);
+
+	arch_timer_ppi[PHYS_NONSECURE_PPI] =
+		map_generic_timer_interrupt(gtdt->non_secure_el1_interrupt,
+		gtdt->non_secure_el1_flags);
+
+	arch_timer_ppi[VIRT_PPI] =
+		map_generic_timer_interrupt(gtdt->virtual_timer_interrupt,
+		gtdt->virtual_timer_flags);
+
+	arch_timer_ppi[HYP_PPI] =
+		map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt,
+		gtdt->non_secure_el2_flags);
+
+	/* Get the frequency from CNTFRQ */
+	arch_timer_detect_rate(NULL, NULL);
+
+	/* Always-on capability */
+	arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
+
+	arch_timer_init();
+	return 0;
+}
+
+/* Initialize all the generic timers presented in GTDT */
+void __init acpi_generic_timer_init(void)
+{
+	if (acpi_disabled)
+		return;
+
+	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
+}
+#endif
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index a16b497..544e298 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -348,4 +348,10 @@ extern void clocksource_of_init(void);
 static inline void clocksource_of_init(void) {}
 #endif
 
+#ifdef CONFIG_ACPI
+void acpi_generic_timer_init(void);
+#else
+static inline void acpi_generic_timer_init(void) {}
+#endif
+
 #endif /* _LINUX_CLOCKSOURCE_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 13/18] ARM64 / ACPI: Parse GTDT to initialize arch timer
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

Using the information presented by GTDT to initialize the arch
timer (not memory-mapped).

Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/kernel/time.c             |    7 ++
 drivers/clocksource/arm_arch_timer.c |  117 ++++++++++++++++++++++++++++------
 include/linux/clocksource.h          |    6 ++
 3 files changed, 111 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index 1a7125c..42f9195 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/clocksource.h>
 #include <linux/clk-provider.h>
+#include <linux/acpi.h>
 
 #include <clocksource/arm_arch_timer.h>
 
@@ -72,6 +73,12 @@ void __init time_init(void)
 
 	tick_setup_hrtimer_broadcast();
 
+	/*
+	 * Since ACPI or FDT will only one be available in the system,
+	 * we can use acpi_generic_timer_init() here safely
+	 */
+	acpi_generic_timer_init();
+
 	arch_timer_rate = arch_timer_get_rate();
 	if (!arch_timer_rate)
 		panic("Unable to initialise architected timer.\n");
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 5163ec1..397783f 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/sched_clock.h>
+#include <linux/acpi.h>
 
 #include <asm/arch_timer.h>
 #include <asm/virt.h>
@@ -338,8 +339,12 @@ arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
 	if (arch_timer_rate)
 		return;
 
-	/* Try to determine the frequency from the device tree or CNTFRQ */
-	if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
+	/*
+	 * Try to determine the frequency from the device tree or CNTFRQ,
+	 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
+	 */
+	if (!acpi_disabled ||
+	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
 		if (cntbase)
 			arch_timer_rate = readl_relaxed(cntbase + CNTFRQ);
 		else
@@ -635,20 +640,8 @@ static void __init arch_timer_common_init(void)
 	arch_timer_arch_init();
 }
 
-static void __init arch_timer_init(struct device_node *np)
+static void __init arch_timer_init(void)
 {
-	int i;
-
-	if (arch_timers_present & ARCH_CP15_TIMER) {
-		pr_warn("arch_timer: multiple nodes in dt, skipping\n");
-		return;
-	}
-
-	arch_timers_present |= ARCH_CP15_TIMER;
-	for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
-		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
-	arch_timer_detect_rate(NULL, np);
-
 	/*
 	 * If HYP mode is available, we know that the physical timer
 	 * has been configured to be accessible from PL1. Use it, so
@@ -667,13 +660,31 @@ static void __init arch_timer_init(struct device_node *np)
 		}
 	}
 
-	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
-
 	arch_timer_register();
 	arch_timer_common_init();
 }
-CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init);
-CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init);
+
+static void __init arch_timer_of_init(struct device_node *np)
+{
+	int i;
+
+	if (arch_timers_present & ARCH_CP15_TIMER) {
+		pr_warn("arch_timer: multiple nodes in dt, skipping\n");
+		return;
+	}
+
+	arch_timers_present |= ARCH_CP15_TIMER;
+	for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
+		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
+
+	arch_timer_detect_rate(NULL, np);
+
+	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
+
+	arch_timer_init();
+}
+CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
+CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init);
 
 static void __init arch_timer_mem_init(struct device_node *np)
 {
@@ -740,3 +751,71 @@ static void __init arch_timer_mem_init(struct device_node *np)
 }
 CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
 		       arch_timer_mem_init);
+
+#ifdef CONFIG_ACPI
+static int __init
+map_generic_timer_interrupt(u32 interrupt, u32 flags)
+{
+	int trigger, polarity;
+
+	if (!interrupt)
+		return 0;
+
+	trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
+			: ACPI_LEVEL_SENSITIVE;
+
+	polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
+			: ACPI_ACTIVE_HIGH;
+
+	return acpi_register_gsi(NULL, interrupt, trigger, polarity);
+}
+
+/* Initialize per-processor generic timer */
+static int __init arch_timer_acpi_init(struct acpi_table_header *table)
+{
+	struct acpi_table_gtdt *gtdt;
+
+	if (arch_timers_present & ARCH_CP15_TIMER) {
+		pr_warn("arch_timer: already initialized, skipping\n");
+		return -EINVAL;
+	}
+
+	gtdt = container_of(table, struct acpi_table_gtdt, header);
+
+	arch_timers_present |= ARCH_CP15_TIMER;
+
+	arch_timer_ppi[PHYS_SECURE_PPI] =
+		map_generic_timer_interrupt(gtdt->secure_el1_interrupt,
+		gtdt->secure_el1_flags);
+
+	arch_timer_ppi[PHYS_NONSECURE_PPI] =
+		map_generic_timer_interrupt(gtdt->non_secure_el1_interrupt,
+		gtdt->non_secure_el1_flags);
+
+	arch_timer_ppi[VIRT_PPI] =
+		map_generic_timer_interrupt(gtdt->virtual_timer_interrupt,
+		gtdt->virtual_timer_flags);
+
+	arch_timer_ppi[HYP_PPI] =
+		map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt,
+		gtdt->non_secure_el2_flags);
+
+	/* Get the frequency from CNTFRQ */
+	arch_timer_detect_rate(NULL, NULL);
+
+	/* Always-on capability */
+	arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
+
+	arch_timer_init();
+	return 0;
+}
+
+/* Initialize all the generic timers presented in GTDT */
+void __init acpi_generic_timer_init(void)
+{
+	if (acpi_disabled)
+		return;
+
+	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
+}
+#endif
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index a16b497..544e298 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -348,4 +348,10 @@ extern void clocksource_of_init(void);
 static inline void clocksource_of_init(void) {}
 #endif
 
+#ifdef CONFIG_ACPI
+void acpi_generic_timer_init(void);
+#else
+static inline void acpi_generic_timer_init(void) {}
+#endif
+
 #endif /* _LINUX_CLOCKSOURCE_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 14/18] ARM64 / ACPI: Select ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on ARM64
  2014-08-04 15:28 ` Hanjun Guo
  (?)
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Hanjun Guo

From: Al Stone <al.stone@linaro.org>

ACPI reduced hardware mode is disabled by default, but ARM64
can only run properly in ACPI hardware reduced mode, so select
ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on ARM64.

Reviewed-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 839f48c..95835bc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,5 +1,6 @@
 config ARM64
 	def_bool y
+	select ACPI_REDUCED_HARDWARE_ONLY if ACPI
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_OPP
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 14/18] ARM64 / ACPI: Select ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on ARM64
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Hanjun Guo

From: Al Stone <al.stone@linaro.org>

ACPI reduced hardware mode is disabled by default, but ARM64
can only run properly in ACPI hardware reduced mode, so select
ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on ARM64.

Reviewed-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 839f48c..95835bc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,5 +1,6 @@
 config ARM64
 	def_bool y
+	select ACPI_REDUCED_HARDWARE_ONLY if ACPI
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_OPP
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 14/18] ARM64 / ACPI: Select ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on ARM64
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Al Stone <al.stone@linaro.org>

ACPI reduced hardware mode is disabled by default, but ARM64
can only run properly in ACPI hardware reduced mode, so select
ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on ARM64.

Reviewed-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 839f48c..95835bc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,5 +1,6 @@
 config ARM64
 	def_bool y
+	select ACPI_REDUCED_HARDWARE_ONLY if ACPI
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_OPP
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 15/18] ARM64 / ACPI: Introduce early_param for "acpi" and set ACPI default off
  2014-08-04 15:28 ` Hanjun Guo
  (?)
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Hanjun Guo

From: Al Stone <al.stone@linaro.org>

Introduce one early parameters "on" for "acpi" to enable ACPI on
ARM64.

Disable ACPI before early parameters parsed, and enable it to pass
"acpi=on" if people want use ACPI on ARM64.

Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 Documentation/kernel-parameters.txt |    5 +++--
 arch/arm64/include/asm/acpi.h       |    9 +++++++++
 arch/arm64/kernel/acpi.c            |   17 +++++++++++++++++
 arch/arm64/kernel/setup.c           |    3 +++
 4 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index b7fa2f5..1f63156 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -165,9 +165,9 @@ multipliers 'Kilo', 'Mega', and 'Giga', equalling 2^10, 2^20, and 2^30
 bytes respectively. Such letter suffixes can also be entirely omitted.
 
 
-	acpi=		[HW,ACPI,X86]
+	acpi=		[HW,ACPI,X86,ARM]
 			Advanced Configuration and Power Interface
-			Format: { force | off | strict | noirq | rsdt }
+			Format: { force | off | strict | noirq | rsdt | on}
 			force -- enable ACPI if default was off
 			off -- disable ACPI if default was on
 			noirq -- do not use ACPI for IRQ routing
@@ -175,6 +175,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 				strictly ACPI specification compliant.
 			rsdt -- prefer RSDT over (default) XSDT
 			copy_dsdt -- copy DSDT to memory
+			"acpi=on" is ONLY available for ARM64.
 
 			See also Documentation/power/runtime_pm.txt, pci=noacpi
 
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 009303d..0f2c51a 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -61,6 +61,13 @@ static inline void disable_acpi(void)
 	acpi_noirq = 1;
 }
 
+static inline void enable_acpi(void)
+{
+	acpi_disabled = 0;
+	acpi_pci_disabled = 0;
+	acpi_noirq = 0;
+}
+
 u32 pack_mpidr_into_32_bits(u64 mpidr);
 
 /*
@@ -99,6 +106,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 extern int (*acpi_suspend_lowlevel)(void);
 #define acpi_wakeup_address 0
 
+#else
+static inline void disable_acpi(void) {}
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 988fea2..585d08c 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -361,3 +361,20 @@ u32 pack_mpidr_into_32_bits(u64 mpidr)
  * TBD when ARM/ARM64 starts to support suspend...
  */
 int (*acpi_suspend_lowlevel)(void) = NULL;
+
+static int __init parse_acpi(char *arg)
+{
+	if (!arg)
+		return -EINVAL;
+
+	/* "acpi=on" enables both ACPI table parsing and interpreter */
+	if (strcmp(arg, "on") == 0) {
+		enable_acpi();
+	} else {
+		/* Core will printk when we return error */
+		return -EINVAL;
+	}
+
+	return 0;
+}
+early_param("acpi", parse_acpi);
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index dfc4e4f3..056e2e1 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -59,6 +59,7 @@
 #include <asm/memblock.h>
 #include <asm/psci.h>
 #include <asm/efi.h>
+#include <asm/acpi.h>
 
 unsigned int processor_id;
 EXPORT_SYMBOL(processor_id);
@@ -380,6 +381,8 @@ void __init setup_arch(char **cmdline_p)
 	*cmdline_p = boot_command_line;
 
 	early_ioremap_init();
+	
+	disable_acpi();
 
 	parse_early_param();
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 15/18] ARM64 / ACPI: Introduce early_param for "acpi" and set ACPI default off
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Hanjun Guo

From: Al Stone <al.stone@linaro.org>

Introduce one early parameters "on" for "acpi" to enable ACPI on
ARM64.

Disable ACPI before early parameters parsed, and enable it to pass
"acpi=on" if people want use ACPI on ARM64.

Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 Documentation/kernel-parameters.txt |    5 +++--
 arch/arm64/include/asm/acpi.h       |    9 +++++++++
 arch/arm64/kernel/acpi.c            |   17 +++++++++++++++++
 arch/arm64/kernel/setup.c           |    3 +++
 4 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index b7fa2f5..1f63156 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -165,9 +165,9 @@ multipliers 'Kilo', 'Mega', and 'Giga', equalling 2^10, 2^20, and 2^30
 bytes respectively. Such letter suffixes can also be entirely omitted.
 
 
-	acpi=		[HW,ACPI,X86]
+	acpi=		[HW,ACPI,X86,ARM]
 			Advanced Configuration and Power Interface
-			Format: { force | off | strict | noirq | rsdt }
+			Format: { force | off | strict | noirq | rsdt | on}
 			force -- enable ACPI if default was off
 			off -- disable ACPI if default was on
 			noirq -- do not use ACPI for IRQ routing
@@ -175,6 +175,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 				strictly ACPI specification compliant.
 			rsdt -- prefer RSDT over (default) XSDT
 			copy_dsdt -- copy DSDT to memory
+			"acpi=on" is ONLY available for ARM64.
 
 			See also Documentation/power/runtime_pm.txt, pci=noacpi
 
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 009303d..0f2c51a 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -61,6 +61,13 @@ static inline void disable_acpi(void)
 	acpi_noirq = 1;
 }
 
+static inline void enable_acpi(void)
+{
+	acpi_disabled = 0;
+	acpi_pci_disabled = 0;
+	acpi_noirq = 0;
+}
+
 u32 pack_mpidr_into_32_bits(u64 mpidr);
 
 /*
@@ -99,6 +106,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 extern int (*acpi_suspend_lowlevel)(void);
 #define acpi_wakeup_address 0
 
+#else
+static inline void disable_acpi(void) {}
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 988fea2..585d08c 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -361,3 +361,20 @@ u32 pack_mpidr_into_32_bits(u64 mpidr)
  * TBD when ARM/ARM64 starts to support suspend...
  */
 int (*acpi_suspend_lowlevel)(void) = NULL;
+
+static int __init parse_acpi(char *arg)
+{
+	if (!arg)
+		return -EINVAL;
+
+	/* "acpi=on" enables both ACPI table parsing and interpreter */
+	if (strcmp(arg, "on") == 0) {
+		enable_acpi();
+	} else {
+		/* Core will printk when we return error */
+		return -EINVAL;
+	}
+
+	return 0;
+}
+early_param("acpi", parse_acpi);
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index dfc4e4f3..056e2e1 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -59,6 +59,7 @@
 #include <asm/memblock.h>
 #include <asm/psci.h>
 #include <asm/efi.h>
+#include <asm/acpi.h>
 
 unsigned int processor_id;
 EXPORT_SYMBOL(processor_id);
@@ -380,6 +381,8 @@ void __init setup_arch(char **cmdline_p)
 	*cmdline_p = boot_command_line;
 
 	early_ioremap_init();
+	
+	disable_acpi();
 
 	parse_early_param();
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 15/18] ARM64 / ACPI: Introduce early_param for "acpi" and set ACPI default off
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Al Stone <al.stone@linaro.org>

Introduce one early parameters "on" for "acpi" to enable ACPI on
ARM64.

Disable ACPI before early parameters parsed, and enable it to pass
"acpi=on" if people want use ACPI on ARM64.

Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 Documentation/kernel-parameters.txt |    5 +++--
 arch/arm64/include/asm/acpi.h       |    9 +++++++++
 arch/arm64/kernel/acpi.c            |   17 +++++++++++++++++
 arch/arm64/kernel/setup.c           |    3 +++
 4 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index b7fa2f5..1f63156 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -165,9 +165,9 @@ multipliers 'Kilo', 'Mega', and 'Giga', equalling 2^10, 2^20, and 2^30
 bytes respectively. Such letter suffixes can also be entirely omitted.
 
 
-	acpi=		[HW,ACPI,X86]
+	acpi=		[HW,ACPI,X86,ARM]
 			Advanced Configuration and Power Interface
-			Format: { force | off | strict | noirq | rsdt }
+			Format: { force | off | strict | noirq | rsdt | on}
 			force -- enable ACPI if default was off
 			off -- disable ACPI if default was on
 			noirq -- do not use ACPI for IRQ routing
@@ -175,6 +175,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 				strictly ACPI specification compliant.
 			rsdt -- prefer RSDT over (default) XSDT
 			copy_dsdt -- copy DSDT to memory
+			"acpi=on" is ONLY available for ARM64.
 
 			See also Documentation/power/runtime_pm.txt, pci=noacpi
 
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 009303d..0f2c51a 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -61,6 +61,13 @@ static inline void disable_acpi(void)
 	acpi_noirq = 1;
 }
 
+static inline void enable_acpi(void)
+{
+	acpi_disabled = 0;
+	acpi_pci_disabled = 0;
+	acpi_noirq = 0;
+}
+
 u32 pack_mpidr_into_32_bits(u64 mpidr);
 
 /*
@@ -99,6 +106,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 extern int (*acpi_suspend_lowlevel)(void);
 #define acpi_wakeup_address 0
 
+#else
+static inline void disable_acpi(void) {}
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 988fea2..585d08c 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -361,3 +361,20 @@ u32 pack_mpidr_into_32_bits(u64 mpidr)
  * TBD when ARM/ARM64 starts to support suspend...
  */
 int (*acpi_suspend_lowlevel)(void) = NULL;
+
+static int __init parse_acpi(char *arg)
+{
+	if (!arg)
+		return -EINVAL;
+
+	/* "acpi=on" enables both ACPI table parsing and interpreter */
+	if (strcmp(arg, "on") == 0) {
+		enable_acpi();
+	} else {
+		/* Core will printk when we return error */
+		return -EINVAL;
+	}
+
+	return 0;
+}
+early_param("acpi", parse_acpi);
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index dfc4e4f3..056e2e1 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -59,6 +59,7 @@
 #include <asm/memblock.h>
 #include <asm/psci.h>
 #include <asm/efi.h>
+#include <asm/acpi.h>
 
 unsigned int processor_id;
 EXPORT_SYMBOL(processor_id);
@@ -380,6 +381,8 @@ void __init setup_arch(char **cmdline_p)
 	*cmdline_p = boot_command_line;
 
 	early_ioremap_init();
+	
+	disable_acpi();
 
 	parse_early_param();
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 16/18] ARM64 / ACPI: If we chose to boot from acpi then disable FDT
  2014-08-04 15:28 ` Hanjun Guo
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

From: Graeme Gregory <graeme.gregory@linaro.org>

If the early boot methods of acpi are happy that we have valid ACPI
tables and acpi=on has been passed. Then do not unflat devicetree
effectively disabling further hardware probing from DT.

Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/kernel/setup.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 056e2e1..0742e8c 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -399,8 +399,8 @@ void __init setup_arch(char **cmdline_p)
 
 	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
 	acpi_boot_init();
-
-	unflatten_device_tree();
+	if (acpi_disabled)
+		unflatten_device_tree();
 
 	psci_init();
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 16/18] ARM64 / ACPI: If we chose to boot from acpi then disable FDT
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Graeme Gregory <graeme.gregory@linaro.org>

If the early boot methods of acpi are happy that we have valid ACPI
tables and acpi=on has been passed. Then do not unflat devicetree
effectively disabling further hardware probing from DT.

Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/kernel/setup.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 056e2e1..0742e8c 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -399,8 +399,8 @@ void __init setup_arch(char **cmdline_p)
 
 	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
 	acpi_boot_init();
-
-	unflatten_device_tree();
+	if (acpi_disabled)
+		unflatten_device_tree();
 
 	psci_init();
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 17/18] ARM64 / ACPI: Enable ARM64 in Kconfig
  2014-08-04 15:28 ` Hanjun Guo
  (?)
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Hanjun Guo

From: Graeme Gregory <graeme.gregory@linaro.org>

Add Kconfigs to build ACPI on ARM64, and make ACPI available on ARM64.

acpi_idle driver is x86/IA64 dependent now, so make CONFIG_ACPI_PROCESSOR
depend on X86 || IA64, and implement it on ARM64 in the future.

Reviewed-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/Kconfig   |    2 ++
 drivers/acpi/Kconfig |    6 +++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 95835bc..1e0ca19 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -362,6 +362,8 @@ source "drivers/Kconfig"
 
 source "drivers/firmware/Kconfig"
 
+source "drivers/acpi/Kconfig"
+
 source "fs/Kconfig"
 
 source "arch/arm64/kvm/Kconfig"
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 3f5f745..f6b6791 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -5,8 +5,7 @@
 menuconfig ACPI
 	bool "ACPI (Advanced Configuration and Power Interface) Support"
 	depends on !IA64_HP_SIM
-	depends on IA64 || X86
-	depends on PCI
+	depends on ((IA64 || X86) && PCI) || ARM64
 	select PNP
 	default y
 	help
@@ -163,6 +162,7 @@ config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
 	select CPU_IDLE
+	depends on X86 || IA64
 	default y
 	help
 	  This driver installs ACPI as the idle handler for Linux and uses
@@ -263,7 +263,7 @@ config ACPI_DEBUG
 
 config ACPI_PCI_SLOT
 	bool "PCI slot detection driver"
-	depends on SYSFS
+	depends on SYSFS && PCI
 	default n
 	help
 	  This driver creates entries in /sys/bus/pci/slots/ for all PCI
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 17/18] ARM64 / ACPI: Enable ARM64 in Kconfig
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Hanjun Guo

From: Graeme Gregory <graeme.gregory@linaro.org>

Add Kconfigs to build ACPI on ARM64, and make ACPI available on ARM64.

acpi_idle driver is x86/IA64 dependent now, so make CONFIG_ACPI_PROCESSOR
depend on X86 || IA64, and implement it on ARM64 in the future.

Reviewed-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/Kconfig   |    2 ++
 drivers/acpi/Kconfig |    6 +++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 95835bc..1e0ca19 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -362,6 +362,8 @@ source "drivers/Kconfig"
 
 source "drivers/firmware/Kconfig"
 
+source "drivers/acpi/Kconfig"
+
 source "fs/Kconfig"
 
 source "arch/arm64/kvm/Kconfig"
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 3f5f745..f6b6791 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -5,8 +5,7 @@
 menuconfig ACPI
 	bool "ACPI (Advanced Configuration and Power Interface) Support"
 	depends on !IA64_HP_SIM
-	depends on IA64 || X86
-	depends on PCI
+	depends on ((IA64 || X86) && PCI) || ARM64
 	select PNP
 	default y
 	help
@@ -163,6 +162,7 @@ config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
 	select CPU_IDLE
+	depends on X86 || IA64
 	default y
 	help
 	  This driver installs ACPI as the idle handler for Linux and uses
@@ -263,7 +263,7 @@ config ACPI_DEBUG
 
 config ACPI_PCI_SLOT
 	bool "PCI slot detection driver"
-	depends on SYSFS
+	depends on SYSFS && PCI
 	default n
 	help
 	  This driver creates entries in /sys/bus/pci/slots/ for all PCI
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 17/18] ARM64 / ACPI: Enable ARM64 in Kconfig
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Graeme Gregory <graeme.gregory@linaro.org>

Add Kconfigs to build ACPI on ARM64, and make ACPI available on ARM64.

acpi_idle driver is x86/IA64 dependent now, so make CONFIG_ACPI_PROCESSOR
depend on X86 || IA64, and implement it on ARM64 in the future.

Reviewed-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 arch/arm64/Kconfig   |    2 ++
 drivers/acpi/Kconfig |    6 +++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 95835bc..1e0ca19 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -362,6 +362,8 @@ source "drivers/Kconfig"
 
 source "drivers/firmware/Kconfig"
 
+source "drivers/acpi/Kconfig"
+
 source "fs/Kconfig"
 
 source "arch/arm64/kvm/Kconfig"
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 3f5f745..f6b6791 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -5,8 +5,7 @@
 menuconfig ACPI
 	bool "ACPI (Advanced Configuration and Power Interface) Support"
 	depends on !IA64_HP_SIM
-	depends on IA64 || X86
-	depends on PCI
+	depends on ((IA64 || X86) && PCI) || ARM64
 	select PNP
 	default y
 	help
@@ -163,6 +162,7 @@ config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
 	select CPU_IDLE
+	depends on X86 || IA64
 	default y
 	help
 	  This driver installs ACPI as the idle handler for Linux and uses
@@ -263,7 +263,7 @@ config ACPI_DEBUG
 
 config ACPI_PCI_SLOT
 	bool "PCI slot detection driver"
-	depends on SYSFS
+	depends on SYSFS && PCI
 	default n
 	help
 	  This driver creates entries in /sys/bus/pci/slots/ for all PCI
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 18/18] Documentation: ACPI for ARM64
  2014-08-04 15:28 ` Hanjun Guo
@ 2014-08-04 15:28   ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles.Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Hanjun Guo

From: Graeme Gregory <graeme.gregory@linaro.org>

Add documentation for the guidelines of how to use ACPI
on ARM64.

Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 Documentation/arm64/arm-acpi.txt |  215 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 215 insertions(+)
 create mode 100644 Documentation/arm64/arm-acpi.txt

diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt
new file mode 100644
index 0000000..a6e14a2
--- /dev/null
+++ b/Documentation/arm64/arm-acpi.txt
@@ -0,0 +1,215 @@
+ACPI on ARMv8 Servers
+---------------------
+
+ACPI can be used for ARMv8 general purpose servers designed to follow
+the SBSA specification (currently available to people with an ARM login at
+http://silver.arm.com).
+
+The kernel will implement minimum ACPI version is 5.1 + errata as released by
+the UEFI Forum, which is available at <http://www.uefi.org/acpi/specs>.
+
+If the machine does not meet the requirements of the SBSA, or cannot be
+described in the required ACPI specifications then it is likely that Device Tree
+(DT) is more suitable for the hardware.
+
+Relationship with Device Tree
+-----------------------------
+
+ACPI support in drivers and subsystems for ARMv8 should never be mutually
+exclusive with DT support at compile time.
+
+At boot time the kernel will only use one description method depending on
+parameters passed from the bootloader (including kernel bootargs).
+
+Regardless of whether DT or ACPI is used, the kernel must always be capable
+of booting with either scheme (in kernels with both schemes enabled at compile
+time).
+
+When booting using ACPI tables the /chosen node in DT will still be parsed
+to extract the kernel command line and initrd path. No other section of
+the DT will be used.
+
+Booting using ACPI tables
+-------------------------
+
+Currently, the only defined method to pass ACPI tables to the kernel on ARMv8
+is via the UEFI system configuration table.
+
+The UEFI implementation MUST set the ACPI_20_TABLE_GUID to point to the
+RSDP table (the table with the ACPI signature "RSD PTR ").
+
+The pointer to the RSDP table will be retrieved from EFI by the ACPI core.
+
+Processing of ACPI tables may be disabled by passing acpi=off on the kernel
+command line.
+
+DO use an XSDT; RSDTs are deprecated and should not be used on arm64. They
+only allow for 32-bit addresses.
+
+DO NOT use the 32-bit address fields in the FADT; they are deprecated. The
+64-bit alternatives MUST be used.
+
+The minimum set of tables MUST include RSDP, XSDT, FACS, FADT, DSDT, MADT
+and GTDT. If PCI is used the MCFG table MUST also be present.
+
+ACPI Detection
+--------------
+
+Drivers should determine their probe() type by checking for ACPI_HANDLE,
+or .of_node, or other information in the device structure. This is
+detailed further in the "Driver Recommendations" section.
+
+In non-driver code If the presence of ACPI needs to be detected at runtime,
+then check the value of acpi_disabled. If CONFIG_ACPI not being set,
+acpi_disabled will always be 1.
+
+Device Enumeration
+------------------
+
+Device descriptions in ACPI should use standard recognized ACPI interfaces.
+These are far simpler than the information provided via Device Tree. Drivers
+should take into account this simplicity and work with sensible defaults.
+
+On no account should a Device Tree attempt to be replicated in ASL using such
+constructs as Name(KEY0, "Value1") type constructs. Additional driver specific
+data should be passed in the appropriate _DSM (ACPI Section 9.14.1) method or
+_DSD (ACPI Section 6.2.5).
+
+This data should be rare and not OS specific. For x86 ACPI has taken to
+identifying itself as Windows because it was found that only one path was
+routinely tested. For ARMv8 it would be preferable to have only one well
+tested path.
+
+_DSD covers more than the generic server case and care should be taken not to
+replicate highly specific embedded behaviour from DT into generic servers.
+
+Common _DSD bindings should be submitted to ASWG to be included in the
+document :-
+
+http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
+
+If these bindings are mirrored from DT care should be taken to ensure they are
+reviewed as DT bindings before submission to limit divergance in bindings.
+
+Programmable Power Control Resources
+------------------------------------
+
+Programmable power control resources include such resources as voltage/current
+providers (regulators) and clock sources.
+
+For power control of these resources they should be represented with Power
+Resource Objects (ACPI Section 7.1). The ACPI core will then handle correctly
+enabling/disabling of resources as they are needed.
+
+The ACPI 5.1 specification does not contain any standard binding for these
+objects to enable programmable levels or rates so this should be avoided if
+possible and the resources set to appropriate levels by the firmware. If this is
+not possible then any manipulation should be abstracted in ASL.
+
+Each device in ACPI has D-states and these can be controlled through
+the optional methods _PS0..._PS3 where _PS0 is full on and _PS3 is full off.
+
+If either _PS0 or _PS3 is implemented, then the other method must also be
+implemented.
+
+If a device requires usage or setup of a power resource when on, the ASL
+should organize that it is allocated/enabled using the _PS0 method.
+
+Resources allocated/enabled in the _PS0 method should be disabled/de-allocated
+in the _PS3 method.
+
+Such code in _PS? methods will of course be very platform specific but
+should allow the driver to operate the device without special non-standard
+values being read from ASL. Further, abstracting the use of these resources
+allows hardware revisions without requiring updates to the kernel.
+
+Clocks
+------
+
+Like clocks that are part of the power resources there is no standard way
+to represent a clock tree in ACPI 5.1 in a similar manner to how it is
+described in DT.
+
+Devices affected by this include things like UARTs, SoC driven LCD displays,
+etc.
+
+The firmware (for example, UEFI) should initialize these clocks to fixed working
+values before the kernel is executed.
+
+Driver Recommendations
+----------------------
+
+DO NOT remove any FDT handling when adding ACPI support for a driver. Different
+systems may use the same device.
+
+DO try and keep complex sections of ACPI and DT functionality separate. This
+may mean a patch to break out some complex DT to another function before
+the patch to add ACPI. This may happen in other functions but is most likely
+in probe function. This gives a clearer flow of data for reviewing driver
+source.
+
+probe() :-
+
+static int device_probe_dt(struct platform_device *pdev)
+{
+	/* DT specific functionality */
+	...
+}
+
+static int device_probe_acpi(struct platform_device *pdev)
+{
+	/* ACPI specific functionality */
+	...
+}
+
+static int device_probe(stuct platform_device *pdev)
+{
+	...
+	struct device_node node = pdev->dev.of_node;
+	...
+
+	if (node)
+		ret = device_probe_dt(pdev);
+	else if (ACPI_HANDLE(&pdev->dev))
+		ret = device_probe_acpi(pdev);
+	else
+		/* other initialization */
+		...
+	/* Continue with any generic probe operations */
+	...
+}
+
+DO keep the MODULE_DEVICE_TABLE entries together in the driver to make it clear
+the different names the driver is probed for, both from DT and from ACPI.
+
+module device tables :-
+
+static struct of_device_id virtio_mmio_match[] = {
+        { .compatible = "virtio,mmio", },
+        { }
+};
+MODULE_DEVICE_TABLE(of, virtio_mmio_match);
+
+static const struct acpi_device_id virtio_mmio_acpi_match[] = {
+        { "LNRO0005", },
+        { }
+};
+MODULE_DEVICE_TABLE(acpi, virtio_mmio_acpi_match);
+
+ASWG
+----
+
+The following areas are not yet well defined for ARM in the current ACPI
+specification and are expected to be worked through in the UEFI ACPI
+Specification Working Group (ASWG) <http://www.uefi.org/workinggroups>.
+Participation in this group is open to all UEFI members.
+
+	- ACPI based CPU topology
+	- ACPI based Power management
+	- CPU idle control based on PSCI
+	- CPU performance control (CPPC)
+
+No code shall be accepted into the kernel unless it complies with the released
+standards from UEFI ASWG. If there are features missing from ACPI to make it
+function on a platform, ECRs should be submitted to ASWG and go through the
+approval process.
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 180+ messages in thread

* [PATCH v2 18/18] Documentation: ACPI for ARM64
@ 2014-08-04 15:28   ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-04 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Graeme Gregory <graeme.gregory@linaro.org>

Add documentation for the guidelines of how to use ACPI
on ARM64.

Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 Documentation/arm64/arm-acpi.txt |  215 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 215 insertions(+)
 create mode 100644 Documentation/arm64/arm-acpi.txt

diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt
new file mode 100644
index 0000000..a6e14a2
--- /dev/null
+++ b/Documentation/arm64/arm-acpi.txt
@@ -0,0 +1,215 @@
+ACPI on ARMv8 Servers
+---------------------
+
+ACPI can be used for ARMv8 general purpose servers designed to follow
+the SBSA specification (currently available to people with an ARM login at
+http://silver.arm.com).
+
+The kernel will implement minimum ACPI version is 5.1 + errata as released by
+the UEFI Forum, which is available at <http://www.uefi.org/acpi/specs>.
+
+If the machine does not meet the requirements of the SBSA, or cannot be
+described in the required ACPI specifications then it is likely that Device Tree
+(DT) is more suitable for the hardware.
+
+Relationship with Device Tree
+-----------------------------
+
+ACPI support in drivers and subsystems for ARMv8 should never be mutually
+exclusive with DT support at compile time.
+
+At boot time the kernel will only use one description method depending on
+parameters passed from the bootloader (including kernel bootargs).
+
+Regardless of whether DT or ACPI is used, the kernel must always be capable
+of booting with either scheme (in kernels with both schemes enabled at compile
+time).
+
+When booting using ACPI tables the /chosen node in DT will still be parsed
+to extract the kernel command line and initrd path. No other section of
+the DT will be used.
+
+Booting using ACPI tables
+-------------------------
+
+Currently, the only defined method to pass ACPI tables to the kernel on ARMv8
+is via the UEFI system configuration table.
+
+The UEFI implementation MUST set the ACPI_20_TABLE_GUID to point to the
+RSDP table (the table with the ACPI signature "RSD PTR ").
+
+The pointer to the RSDP table will be retrieved from EFI by the ACPI core.
+
+Processing of ACPI tables may be disabled by passing acpi=off on the kernel
+command line.
+
+DO use an XSDT; RSDTs are deprecated and should not be used on arm64. They
+only allow for 32-bit addresses.
+
+DO NOT use the 32-bit address fields in the FADT; they are deprecated. The
+64-bit alternatives MUST be used.
+
+The minimum set of tables MUST include RSDP, XSDT, FACS, FADT, DSDT, MADT
+and GTDT. If PCI is used the MCFG table MUST also be present.
+
+ACPI Detection
+--------------
+
+Drivers should determine their probe() type by checking for ACPI_HANDLE,
+or .of_node, or other information in the device structure. This is
+detailed further in the "Driver Recommendations" section.
+
+In non-driver code If the presence of ACPI needs to be detected at runtime,
+then check the value of acpi_disabled. If CONFIG_ACPI not being set,
+acpi_disabled will always be 1.
+
+Device Enumeration
+------------------
+
+Device descriptions in ACPI should use standard recognized ACPI interfaces.
+These are far simpler than the information provided via Device Tree. Drivers
+should take into account this simplicity and work with sensible defaults.
+
+On no account should a Device Tree attempt to be replicated in ASL using such
+constructs as Name(KEY0, "Value1") type constructs. Additional driver specific
+data should be passed in the appropriate _DSM (ACPI Section 9.14.1) method or
+_DSD (ACPI Section 6.2.5).
+
+This data should be rare and not OS specific. For x86 ACPI has taken to
+identifying itself as Windows because it was found that only one path was
+routinely tested. For ARMv8 it would be preferable to have only one well
+tested path.
+
+_DSD covers more than the generic server case and care should be taken not to
+replicate highly specific embedded behaviour from DT into generic servers.
+
+Common _DSD bindings should be submitted to ASWG to be included in the
+document :-
+
+http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
+
+If these bindings are mirrored from DT care should be taken to ensure they are
+reviewed as DT bindings before submission to limit divergance in bindings.
+
+Programmable Power Control Resources
+------------------------------------
+
+Programmable power control resources include such resources as voltage/current
+providers (regulators) and clock sources.
+
+For power control of these resources they should be represented with Power
+Resource Objects (ACPI Section 7.1). The ACPI core will then handle correctly
+enabling/disabling of resources as they are needed.
+
+The ACPI 5.1 specification does not contain any standard binding for these
+objects to enable programmable levels or rates so this should be avoided if
+possible and the resources set to appropriate levels by the firmware. If this is
+not possible then any manipulation should be abstracted in ASL.
+
+Each device in ACPI has D-states and these can be controlled through
+the optional methods _PS0..._PS3 where _PS0 is full on and _PS3 is full off.
+
+If either _PS0 or _PS3 is implemented, then the other method must also be
+implemented.
+
+If a device requires usage or setup of a power resource when on, the ASL
+should organize that it is allocated/enabled using the _PS0 method.
+
+Resources allocated/enabled in the _PS0 method should be disabled/de-allocated
+in the _PS3 method.
+
+Such code in _PS? methods will of course be very platform specific but
+should allow the driver to operate the device without special non-standard
+values being read from ASL. Further, abstracting the use of these resources
+allows hardware revisions without requiring updates to the kernel.
+
+Clocks
+------
+
+Like clocks that are part of the power resources there is no standard way
+to represent a clock tree in ACPI 5.1 in a similar manner to how it is
+described in DT.
+
+Devices affected by this include things like UARTs, SoC driven LCD displays,
+etc.
+
+The firmware (for example, UEFI) should initialize these clocks to fixed working
+values before the kernel is executed.
+
+Driver Recommendations
+----------------------
+
+DO NOT remove any FDT handling when adding ACPI support for a driver. Different
+systems may use the same device.
+
+DO try and keep complex sections of ACPI and DT functionality separate. This
+may mean a patch to break out some complex DT to another function before
+the patch to add ACPI. This may happen in other functions but is most likely
+in probe function. This gives a clearer flow of data for reviewing driver
+source.
+
+probe() :-
+
+static int device_probe_dt(struct platform_device *pdev)
+{
+	/* DT specific functionality */
+	...
+}
+
+static int device_probe_acpi(struct platform_device *pdev)
+{
+	/* ACPI specific functionality */
+	...
+}
+
+static int device_probe(stuct platform_device *pdev)
+{
+	...
+	struct device_node node = pdev->dev.of_node;
+	...
+
+	if (node)
+		ret = device_probe_dt(pdev);
+	else if (ACPI_HANDLE(&pdev->dev))
+		ret = device_probe_acpi(pdev);
+	else
+		/* other initialization */
+		...
+	/* Continue with any generic probe operations */
+	...
+}
+
+DO keep the MODULE_DEVICE_TABLE entries together in the driver to make it clear
+the different names the driver is probed for, both from DT and from ACPI.
+
+module device tables :-
+
+static struct of_device_id virtio_mmio_match[] = {
+        { .compatible = "virtio,mmio", },
+        { }
+};
+MODULE_DEVICE_TABLE(of, virtio_mmio_match);
+
+static const struct acpi_device_id virtio_mmio_acpi_match[] = {
+        { "LNRO0005", },
+        { }
+};
+MODULE_DEVICE_TABLE(acpi, virtio_mmio_acpi_match);
+
+ASWG
+----
+
+The following areas are not yet well defined for ARM in the current ACPI
+specification and are expected to be worked through in the UEFI ACPI
+Specification Working Group (ASWG) <http://www.uefi.org/workinggroups>.
+Participation in this group is open to all UEFI members.
+
+	- ACPI based CPU topology
+	- ACPI based Power management
+	- CPU idle control based on PSCI
+	- CPU performance control (CPPC)
+
+No code shall be accepted into the kernel unless it complies with the released
+standards from UEFI ASWG. If there are features missing from ACPI to make it
+function on a platform, ECRs should be submitted to ASWG and go through the
+approval process.
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 18/18] Documentation: ACPI for ARM64
  2014-08-04 15:28   ` Hanjun Guo
@ 2014-08-04 20:48     ` Randy Dunlap
  -1 siblings, 0 replies; 180+ messages in thread
From: Randy Dunlap @ 2014-08-04 20:48 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Charles.Garcia-Tobin, linux-acpi, linux-arm-kernel,
	linux-kernel, linaro-acpi

On 08/04/14 08:28, Hanjun Guo wrote:
> From: Graeme Gregory <graeme.gregory@linaro.org>
> 
> Add documentation for the guidelines of how to use ACPI
> on ARM64.
> 
> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  Documentation/arm64/arm-acpi.txt |  215 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 215 insertions(+)
>  create mode 100644 Documentation/arm64/arm-acpi.txt
> 
> diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt
> new file mode 100644
> index 0000000..a6e14a2
> --- /dev/null
> +++ b/Documentation/arm64/arm-acpi.txt
> @@ -0,0 +1,215 @@
> +ACPI on ARMv8 Servers
> +---------------------
> +

...

> +
> +ACPI Detection
> +--------------
> +
> +Drivers should determine their probe() type by checking for ACPI_HANDLE,
> +or .of_node, or other information in the device structure. This is
> +detailed further in the "Driver Recommendations" section.
> +
> +In non-driver code If the presence of ACPI needs to be detected at runtime,
> +then check the value of acpi_disabled. If CONFIG_ACPI not being set,

                                          If CONFIG_ACPI is not set,

> +acpi_disabled will always be 1.
> +
> +Device Enumeration
> +------------------


-- 
~Randy

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 18/18] Documentation: ACPI for ARM64
@ 2014-08-04 20:48     ` Randy Dunlap
  0 siblings, 0 replies; 180+ messages in thread
From: Randy Dunlap @ 2014-08-04 20:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/04/14 08:28, Hanjun Guo wrote:
> From: Graeme Gregory <graeme.gregory@linaro.org>
> 
> Add documentation for the guidelines of how to use ACPI
> on ARM64.
> 
> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  Documentation/arm64/arm-acpi.txt |  215 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 215 insertions(+)
>  create mode 100644 Documentation/arm64/arm-acpi.txt
> 
> diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt
> new file mode 100644
> index 0000000..a6e14a2
> --- /dev/null
> +++ b/Documentation/arm64/arm-acpi.txt
> @@ -0,0 +1,215 @@
> +ACPI on ARMv8 Servers
> +---------------------
> +

...

> +
> +ACPI Detection
> +--------------
> +
> +Drivers should determine their probe() type by checking for ACPI_HANDLE,
> +or .of_node, or other information in the device structure. This is
> +detailed further in the "Driver Recommendations" section.
> +
> +In non-driver code If the presence of ACPI needs to be detected at runtime,
> +then check the value of acpi_disabled. If CONFIG_ACPI not being set,

                                          If CONFIG_ACPI is not set,

> +acpi_disabled will always be 1.
> +
> +Device Enumeration
> +------------------


-- 
~Randy

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
       [not found] ` <CAJRNFK+UfJhGR65tOecy=X+YdHQHiNPZ4p_p8LUxhRL3GW5gFw@mail.gmail.com>
  2014-08-05  3:34     ` Hanjun Guo
@ 2014-08-05  3:34     ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-05  3:34 UTC (permalink / raw)
  To: Alexander Spyridakis
  Cc: Mark Rutland, Rafael J. Wysocki, Randy Dunlap, Robert Richter,
	Jason Cooper, Arnd Bergmann, linaro-acpi, Marc Zyngier,
	Catalin Marinas, Daniel Lezcano, Liviu Dudau, Robert Moore,
	Will Deacon, linux-kernel, linux-acpi, Mark Brown, Lv Zheng,
	Bjorn Helgaas, Rob Herring, linux-arm-kernel, Olof Johansson

On 2014-8-5 1:30, Alexander Spyridakis wrote:
> On 4 August 2014 17:28, Hanjun Guo <hanjun.guo@linaro.org
> <mailto:hanjun.guo@linaro.org>> wrote:
>>
>> ACPI 5.1 has been released and now be freely available for
>> download [1]. It fixed some major gaps to run ACPI on ARM,
>> this patch just follow the ACPI 5.1 spec and prepare the
>> code to run ACPI on ARM64.
> 
> Hello,

Hi,

> 
> Is this work still reproducible on Foundation and/or ARMv8 FVP models, as
> described in the following wiki page?
> https://wiki.linaro.org/LEG/Engineering/Kernel/ACPI

Yes, I think so. If you meet any problem , please let us know, and we will
update the wiki.

> 
> Should I assume that UEFI is mandatory (alternative being the aarch64
> bootwrapper), as described in Documentation/arm64/arm-acpi.txt?

Yes, UEFI is mandatory if you want to use ACPI.

> 
> Thanks in advance.

You are welcome :)

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
@ 2014-08-05  3:34     ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-05  3:34 UTC (permalink / raw)
  To: Alexander Spyridakis
  Cc: Catalin Marinas, Rafael J. Wysocki, Mark Rutland, linaro-acpi,
	Liviu Dudau, Lv Zheng, Rob Herring, Daniel Lezcano, Robert Moore,
	linux-acpi, Robert Richter, Jason Cooper, Arnd Bergmann,
	Marc Zyngier, Will Deacon, Mark Brown, Bjorn Helgaas,
	linux-arm-kernel, Randy Dunlap, linux-kernel, Olof Johansson

On 2014-8-5 1:30, Alexander Spyridakis wrote:
> On 4 August 2014 17:28, Hanjun Guo <hanjun.guo@linaro.org
> <mailto:hanjun.guo@linaro.org>> wrote:
>>
>> ACPI 5.1 has been released and now be freely available for
>> download [1]. It fixed some major gaps to run ACPI on ARM,
>> this patch just follow the ACPI 5.1 spec and prepare the
>> code to run ACPI on ARM64.
> 
> Hello,

Hi,

> 
> Is this work still reproducible on Foundation and/or ARMv8 FVP models, as
> described in the following wiki page?
> https://wiki.linaro.org/LEG/Engineering/Kernel/ACPI

Yes, I think so. If you meet any problem , please let us know, and we will
update the wiki.

> 
> Should I assume that UEFI is mandatory (alternative being the aarch64
> bootwrapper), as described in Documentation/arm64/arm-acpi.txt?

Yes, UEFI is mandatory if you want to use ACPI.

> 
> Thanks in advance.

You are welcome :)

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
@ 2014-08-05  3:34     ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-05  3:34 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-5 1:30, Alexander Spyridakis wrote:
> On 4 August 2014 17:28, Hanjun Guo <hanjun.guo@linaro.org
> <mailto:hanjun.guo@linaro.org>> wrote:
>>
>> ACPI 5.1 has been released and now be freely available for
>> download [1]. It fixed some major gaps to run ACPI on ARM,
>> this patch just follow the ACPI 5.1 spec and prepare the
>> code to run ACPI on ARM64.
> 
> Hello,

Hi,

> 
> Is this work still reproducible on Foundation and/or ARMv8 FVP models, as
> described in the following wiki page?
> https://wiki.linaro.org/LEG/Engineering/Kernel/ACPI

Yes, I think so. If you meet any problem , please let us know, and we will
update the wiki.

> 
> Should I assume that UEFI is mandatory (alternative being the aarch64
> bootwrapper), as described in Documentation/arm64/arm-acpi.txt?

Yes, UEFI is mandatory if you want to use ACPI.

> 
> Thanks in advance.

You are welcome :)

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 18/18] Documentation: ACPI for ARM64
  2014-08-04 20:48     ` Randy Dunlap
  (?)
@ 2014-08-05  3:36       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-05  3:36 UTC (permalink / raw)
  To: Randy Dunlap, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: linaro-acpi, Liviu Dudau, Lv Zheng, Rob Herring,
	Lorenzo Pieralisi, Daniel Lezcano, Robert Moore, linux-acpi,
	Grant Likely, Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Mark Brown,
	Bjorn Helgaas, linux-arm-kernel, Graeme Gregory, linux-kernel,
	Sudeep Holla, Olof Johansson

On 2014-8-5 4:48, Randy Dunlap wrote:
> On 08/04/14 08:28, Hanjun Guo wrote:
>> From: Graeme Gregory <graeme.gregory@linaro.org>
>>
>> Add documentation for the guidelines of how to use ACPI
>> on ARM64.
>>
>> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  Documentation/arm64/arm-acpi.txt |  215 ++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 215 insertions(+)
>>  create mode 100644 Documentation/arm64/arm-acpi.txt
>>
>> diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt
>> new file mode 100644
>> index 0000000..a6e14a2
>> --- /dev/null
>> +++ b/Documentation/arm64/arm-acpi.txt
>> @@ -0,0 +1,215 @@
>> +ACPI on ARMv8 Servers
>> +---------------------
>> +
> 
> ...
> 
>> +
>> +ACPI Detection
>> +--------------
>> +
>> +Drivers should determine their probe() type by checking for ACPI_HANDLE,
>> +or .of_node, or other information in the device structure. This is
>> +detailed further in the "Driver Recommendations" section.
>> +
>> +In non-driver code If the presence of ACPI needs to be detected at runtime,
>> +then check the value of acpi_disabled. If CONFIG_ACPI not being set,
> 
>                                           If CONFIG_ACPI is not set,

Good catch, We will update it.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 18/18] Documentation: ACPI for ARM64
@ 2014-08-05  3:36       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-05  3:36 UTC (permalink / raw)
  To: Randy Dunlap, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Graeme Gregory, Arnd Bergmann, Olof Johansson, Grant Likely,
	Sudeep Holla, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Charles.Garcia-Tobin, linux-acpi, linux-arm-kernel,
	linux-kernel, linaro-acpi

On 2014-8-5 4:48, Randy Dunlap wrote:
> On 08/04/14 08:28, Hanjun Guo wrote:
>> From: Graeme Gregory <graeme.gregory@linaro.org>
>>
>> Add documentation for the guidelines of how to use ACPI
>> on ARM64.
>>
>> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  Documentation/arm64/arm-acpi.txt |  215 ++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 215 insertions(+)
>>  create mode 100644 Documentation/arm64/arm-acpi.txt
>>
>> diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt
>> new file mode 100644
>> index 0000000..a6e14a2
>> --- /dev/null
>> +++ b/Documentation/arm64/arm-acpi.txt
>> @@ -0,0 +1,215 @@
>> +ACPI on ARMv8 Servers
>> +---------------------
>> +
> 
> ...
> 
>> +
>> +ACPI Detection
>> +--------------
>> +
>> +Drivers should determine their probe() type by checking for ACPI_HANDLE,
>> +or .of_node, or other information in the device structure. This is
>> +detailed further in the "Driver Recommendations" section.
>> +
>> +In non-driver code If the presence of ACPI needs to be detected at runtime,
>> +then check the value of acpi_disabled. If CONFIG_ACPI not being set,
> 
>                                           If CONFIG_ACPI is not set,

Good catch, We will update it.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 18/18] Documentation: ACPI for ARM64
@ 2014-08-05  3:36       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-05  3:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-5 4:48, Randy Dunlap wrote:
> On 08/04/14 08:28, Hanjun Guo wrote:
>> From: Graeme Gregory <graeme.gregory@linaro.org>
>>
>> Add documentation for the guidelines of how to use ACPI
>> on ARM64.
>>
>> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  Documentation/arm64/arm-acpi.txt |  215 ++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 215 insertions(+)
>>  create mode 100644 Documentation/arm64/arm-acpi.txt
>>
>> diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt
>> new file mode 100644
>> index 0000000..a6e14a2
>> --- /dev/null
>> +++ b/Documentation/arm64/arm-acpi.txt
>> @@ -0,0 +1,215 @@
>> +ACPI on ARMv8 Servers
>> +---------------------
>> +
> 
> ...
> 
>> +
>> +ACPI Detection
>> +--------------
>> +
>> +Drivers should determine their probe() type by checking for ACPI_HANDLE,
>> +or .of_node, or other information in the device structure. This is
>> +detailed further in the "Driver Recommendations" section.
>> +
>> +In non-driver code If the presence of ACPI needs to be detected at runtime,
>> +then check the value of acpi_disabled. If CONFIG_ACPI not being set,
> 
>                                           If CONFIG_ACPI is not set,

Good catch, We will update it.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* RE: [PATCH v2 07/18] ACPI / table: Print GIC information when MADT is parsed
  2014-08-04 15:28   ` Hanjun Guo
@ 2014-08-07  1:41     ` Zheng, Lv
  -1 siblings, 0 replies; 180+ messages in thread
From: Zheng, Lv @ 2014-08-07  1:41 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: linaro-acpi, Liviu Dudau, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Moore, Robert, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap, linux-k

Hi,

> From: Hanjun Guo [mailto:hanjun.guo@linaro.org]
> Sent: Monday, August 04, 2014 11:28 PM
> To: Catalin Marinas; Rafael J. Wysocki; Mark Rutland
> 
> When MADT is parsed, print GIC information to make the boot
> log look pretty.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>  drivers/acpi/tables.c |   39 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
> index 6d5a6cd..77f8bb1 100644
> --- a/drivers/acpi/tables.c
> +++ b/drivers/acpi/tables.c
> @@ -183,6 +183,44 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>  		}
>  		break;
> 
> +	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
> +		{
> +			struct acpi_madt_generic_interrupt *p =
> +				(struct acpi_madt_generic_interrupt *)header;
> +			pr_info("GICC (acpi_id[0x%04x] address[0x%08llx] MPDIR[0x%llx] %s)\n",
> +				p->uid, p->base_address, p->arm_mpidr,

Just reminders.
The acpi_id looks vague, is it a UID for the processor?
Should 0x%08llx for base_address be %p?

> +				(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
> +
> +		}
> +		break;
> +
> +	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
> +		{
> +			struct acpi_madt_generic_distributor *p =
> +				(struct acpi_madt_generic_distributor *)header;
> +			pr_info("GIC Distributor (gic_id[0x%04x] address[0x%08llx] gsi_base[%d])\n",
> +				p->gic_id, p->base_address, p->global_irq_base);
> +		}
> +		break;

Same question for base_address.

> +
> +	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
> +		{
> +			struct acpi_madt_generic_msi_frame *p =
> +				(struct acpi_madt_generic_msi_frame *)header;
> +			pr_info("GIC MSI Frame (msi_fame_id[%d] address[0x%08llx])\n",
> +				p->msi_frame_id, p->base_address);

Ditto.

> +		}
> +		break;
> +
> +	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
> +		{
> +			struct acpi_madt_generic_redistributor *p =
> +				(struct acpi_madt_generic_redistributor *)header;
> +			pr_info("GIC Redistributor (address[0x%08llx] region_size[0x%x])\n",
> +				p->base_address, p->length);

Ditto.

> +		}
> +		break;
> +
>  	default:
>  		pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
>  			header->type);
> @@ -190,7 +228,6 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>  	}
>  }
> 
> -
>  int __init
>  acpi_table_parse_entries(char *id,
>  			     unsigned long table_size,

This block shouldn't be a part of this patch.

Thanks and best regards
-Lv

> --
> 1.7.9.5

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 07/18] ACPI / table: Print GIC information when MADT is parsed
@ 2014-08-07  1:41     ` Zheng, Lv
  0 siblings, 0 replies; 180+ messages in thread
From: Zheng, Lv @ 2014-08-07  1:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> From: Hanjun Guo [mailto:hanjun.guo at linaro.org]
> Sent: Monday, August 04, 2014 11:28 PM
> To: Catalin Marinas; Rafael J. Wysocki; Mark Rutland
> 
> When MADT is parsed, print GIC information to make the boot
> log look pretty.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>  drivers/acpi/tables.c |   39 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
> index 6d5a6cd..77f8bb1 100644
> --- a/drivers/acpi/tables.c
> +++ b/drivers/acpi/tables.c
> @@ -183,6 +183,44 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>  		}
>  		break;
> 
> +	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
> +		{
> +			struct acpi_madt_generic_interrupt *p =
> +				(struct acpi_madt_generic_interrupt *)header;
> +			pr_info("GICC (acpi_id[0x%04x] address[0x%08llx] MPDIR[0x%llx] %s)\n",
> +				p->uid, p->base_address, p->arm_mpidr,

Just reminders.
The acpi_id looks vague, is it a UID for the processor?
Should 0x%08llx for base_address be %p?

> +				(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
> +
> +		}
> +		break;
> +
> +	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
> +		{
> +			struct acpi_madt_generic_distributor *p =
> +				(struct acpi_madt_generic_distributor *)header;
> +			pr_info("GIC Distributor (gic_id[0x%04x] address[0x%08llx] gsi_base[%d])\n",
> +				p->gic_id, p->base_address, p->global_irq_base);
> +		}
> +		break;

Same question for base_address.

> +
> +	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
> +		{
> +			struct acpi_madt_generic_msi_frame *p =
> +				(struct acpi_madt_generic_msi_frame *)header;
> +			pr_info("GIC MSI Frame (msi_fame_id[%d] address[0x%08llx])\n",
> +				p->msi_frame_id, p->base_address);

Ditto.

> +		}
> +		break;
> +
> +	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
> +		{
> +			struct acpi_madt_generic_redistributor *p =
> +				(struct acpi_madt_generic_redistributor *)header;
> +			pr_info("GIC Redistributor (address[0x%08llx] region_size[0x%x])\n",
> +				p->base_address, p->length);

Ditto.

> +		}
> +		break;
> +
>  	default:
>  		pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
>  			header->type);
> @@ -190,7 +228,6 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>  	}
>  }
> 
> -
>  int __init
>  acpi_table_parse_entries(char *id,
>  			     unsigned long table_size,

This block shouldn't be a part of this patch.

Thanks and best regards
-Lv

> --
> 1.7.9.5

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 07/18] ACPI / table: Print GIC information when MADT is parsed
  2014-08-07  1:41     ` Zheng, Lv
@ 2014-08-07 10:28       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-07 10:28 UTC (permalink / raw)
  To: Zheng, Lv, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: linaro-acpi, Liviu Dudau, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Moore, Robert, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap, linux-k

On 2014-8-7 9:41, Zheng, Lv wrote:
> Hi,

Hi Lv,

> 
>> From: Hanjun Guo [mailto:hanjun.guo@linaro.org]
>> Sent: Monday, August 04, 2014 11:28 PM
>> To: Catalin Marinas; Rafael J. Wysocki; Mark Rutland
>>
>> When MADT is parsed, print GIC information to make the boot
>> log look pretty.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>> ---
>>  drivers/acpi/tables.c |   39 ++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 38 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
>> index 6d5a6cd..77f8bb1 100644
>> --- a/drivers/acpi/tables.c
>> +++ b/drivers/acpi/tables.c
>> @@ -183,6 +183,44 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>>  		}
>>  		break;
>>
>> +	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
>> +		{
>> +			struct acpi_madt_generic_interrupt *p =
>> +				(struct acpi_madt_generic_interrupt *)header;
>> +			pr_info("GICC (acpi_id[0x%04x] address[0x%08llx] MPDIR[0x%llx] %s)\n",
>> +				p->uid, p->base_address, p->arm_mpidr,
> 
> Just reminders.
> The acpi_id looks vague, is it a UID for the processor?

Yes, it is the UID of processor object in DSDT, How about use
acpi_uid instead?

> Should 0x%08llx for base_address be %p?

Yes, %p should be better, I will update the code and all the
address field you pointed out below.

> 
>> +				(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
>> +
>> +		}
>> +		break;
>> +
>> +	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
>> +		{
>> +			struct acpi_madt_generic_distributor *p =
>> +				(struct acpi_madt_generic_distributor *)header;
>> +			pr_info("GIC Distributor (gic_id[0x%04x] address[0x%08llx] gsi_base[%d])\n",
>> +				p->gic_id, p->base_address, p->global_irq_base);
>> +		}
>> +		break;
> 
> Same question for base_address.
> 
>> +
>> +	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
>> +		{
>> +			struct acpi_madt_generic_msi_frame *p =
>> +				(struct acpi_madt_generic_msi_frame *)header;
>> +			pr_info("GIC MSI Frame (msi_fame_id[%d] address[0x%08llx])\n",
>> +				p->msi_frame_id, p->base_address);
> 
> Ditto.
> 
>> +		}
>> +		break;
>> +
>> +	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
>> +		{
>> +			struct acpi_madt_generic_redistributor *p =
>> +				(struct acpi_madt_generic_redistributor *)header;
>> +			pr_info("GIC Redistributor (address[0x%08llx] region_size[0x%x])\n",
>> +				p->base_address, p->length);
> 
> Ditto.
> 
>> +		}
>> +		break;
>> +
>>  	default:
>>  		pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
>>  			header->type);
>> @@ -190,7 +228,6 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>>  	}
>>  }
>>
>> -
>>  int __init
>>  acpi_table_parse_entries(char *id,
>>  			     unsigned long table_size,
> 
> This block shouldn't be a part of this patch.

Ok, I will remove that from this patch.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 07/18] ACPI / table: Print GIC information when MADT is parsed
@ 2014-08-07 10:28       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-07 10:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-7 9:41, Zheng, Lv wrote:
> Hi,

Hi Lv,

> 
>> From: Hanjun Guo [mailto:hanjun.guo at linaro.org]
>> Sent: Monday, August 04, 2014 11:28 PM
>> To: Catalin Marinas; Rafael J. Wysocki; Mark Rutland
>>
>> When MADT is parsed, print GIC information to make the boot
>> log look pretty.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>> ---
>>  drivers/acpi/tables.c |   39 ++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 38 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
>> index 6d5a6cd..77f8bb1 100644
>> --- a/drivers/acpi/tables.c
>> +++ b/drivers/acpi/tables.c
>> @@ -183,6 +183,44 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>>  		}
>>  		break;
>>
>> +	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
>> +		{
>> +			struct acpi_madt_generic_interrupt *p =
>> +				(struct acpi_madt_generic_interrupt *)header;
>> +			pr_info("GICC (acpi_id[0x%04x] address[0x%08llx] MPDIR[0x%llx] %s)\n",
>> +				p->uid, p->base_address, p->arm_mpidr,
> 
> Just reminders.
> The acpi_id looks vague, is it a UID for the processor?

Yes, it is the UID of processor object in DSDT, How about use
acpi_uid instead?

> Should 0x%08llx for base_address be %p?

Yes, %p should be better, I will update the code and all the
address field you pointed out below.

> 
>> +				(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
>> +
>> +		}
>> +		break;
>> +
>> +	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
>> +		{
>> +			struct acpi_madt_generic_distributor *p =
>> +				(struct acpi_madt_generic_distributor *)header;
>> +			pr_info("GIC Distributor (gic_id[0x%04x] address[0x%08llx] gsi_base[%d])\n",
>> +				p->gic_id, p->base_address, p->global_irq_base);
>> +		}
>> +		break;
> 
> Same question for base_address.
> 
>> +
>> +	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
>> +		{
>> +			struct acpi_madt_generic_msi_frame *p =
>> +				(struct acpi_madt_generic_msi_frame *)header;
>> +			pr_info("GIC MSI Frame (msi_fame_id[%d] address[0x%08llx])\n",
>> +				p->msi_frame_id, p->base_address);
> 
> Ditto.
> 
>> +		}
>> +		break;
>> +
>> +	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
>> +		{
>> +			struct acpi_madt_generic_redistributor *p =
>> +				(struct acpi_madt_generic_redistributor *)header;
>> +			pr_info("GIC Redistributor (address[0x%08llx] region_size[0x%x])\n",
>> +				p->base_address, p->length);
> 
> Ditto.
> 
>> +		}
>> +		break;
>> +
>>  	default:
>>  		pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
>>  			header->type);
>> @@ -190,7 +228,6 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>>  	}
>>  }
>>
>> -
>>  int __init
>>  acpi_table_parse_entries(char *id,
>>  			     unsigned long table_size,
> 
> This block shouldn't be a part of this patch.

Ok, I will remove that from this patch.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-04 15:28   ` Hanjun Guo
@ 2014-08-18 14:27     ` Catalin Marinas
  -1 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Mark Rutland, linaro-acpi, Will Deacon, Lv Zheng, Rob Herring,
	Lorenzo Pieralisi, Daniel Lezcano, Robert Moore, linux-acpi,
	grant.likely, Charles Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Liviu Dudau, Mark Brown,
	Bjorn Helgaas, linux-arm-kernel, graeme.gregory, Randy

On Mon, Aug 04, 2014 at 04:28:12PM +0100, Hanjun Guo wrote:
> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
> the former signals to the OS that the hardware is PSCI compliant.

Actually it signals that the firmware is PSCI compliant. The hardware
doesn't care much.

> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6400312..6e04868 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -19,6 +19,18 @@ extern int acpi_disabled;
>  extern int acpi_noirq;
>  extern int acpi_pci_disabled;
>  
> +/* 1 to indicate PSCI 0.2+ is implemented */
> +static inline bool acpi_psci_present(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
> +}
> +
> +/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
> +static inline bool acpi_psci_use_hvc(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
> +}

Do we actually need !! here? Shouldn't the compiler figure out
conversion to bool automatically?

> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 9cf9127..69a315d 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -11,6 +11,8 @@
>   *  published by the Free Software Foundation.
>   */
>  
> +#define pr_fmt(fmt) "ACPI: " fmt
> +
>  #include <linux/init.h>
>  #include <linux/acpi.h>
>  #include <linux/cpumask.h>
> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>  	early_memunmap(map, size);
>  }
>  
> +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 version,
> +	 * and there is a minor version of FADT which was introduced
> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> +	 * to get arm boot flags, or we will disable ACPI.
> +	 */
> +	if (table->revision < 5 || fadt->minor_revision < 1) {

If we ever get revision 6.0, this would trigger.

> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 85c6326..dfc4e4f3 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>  	efi_idmap_init();
>  
>  	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
> +	acpi_boot_init();
> +
>  	unflatten_device_tree();

Unless that's changed in a subsequent patch, do we still need to call
unflatten_device_tree() if ACPI was successful?

>  	psci_init();

I would also rename this to something like psci_dt_init() and move the
acpi_disabled check here rather than in the callee.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-18 14:27     ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 04, 2014 at 04:28:12PM +0100, Hanjun Guo wrote:
> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
> the former signals to the OS that the hardware is PSCI compliant.

Actually it signals that the firmware is PSCI compliant. The hardware
doesn't care much.

> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6400312..6e04868 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -19,6 +19,18 @@ extern int acpi_disabled;
>  extern int acpi_noirq;
>  extern int acpi_pci_disabled;
>  
> +/* 1 to indicate PSCI 0.2+ is implemented */
> +static inline bool acpi_psci_present(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
> +}
> +
> +/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
> +static inline bool acpi_psci_use_hvc(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
> +}

Do we actually need !! here? Shouldn't the compiler figure out
conversion to bool automatically?

> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 9cf9127..69a315d 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -11,6 +11,8 @@
>   *  published by the Free Software Foundation.
>   */
>  
> +#define pr_fmt(fmt) "ACPI: " fmt
> +
>  #include <linux/init.h>
>  #include <linux/acpi.h>
>  #include <linux/cpumask.h>
> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>  	early_memunmap(map, size);
>  }
>  
> +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 version,
> +	 * and there is a minor version of FADT which was introduced
> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> +	 * to get arm boot flags, or we will disable ACPI.
> +	 */
> +	if (table->revision < 5 || fadt->minor_revision < 1) {

If we ever get revision 6.0, this would trigger.

> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 85c6326..dfc4e4f3 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>  	efi_idmap_init();
>  
>  	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
> +	acpi_boot_init();
> +
>  	unflatten_device_tree();

Unless that's changed in a subsequent patch, do we still need to call
unflatten_device_tree() if ACPI was successful?

>  	psci_init();

I would also rename this to something like psci_dt_init() and move the
acpi_disabled check here rather than in the callee.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
  2014-08-04 15:28   ` Hanjun Guo
@ 2014-08-18 14:27     ` Catalin Marinas
  -1 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Mark Rutland, linaro-acpi, Will Deacon, Lv Zheng, Rob Herring,
	Lorenzo Pieralisi, Daniel Lezcano, Robert Moore, linux-acpi,
	grant.likely, Charles Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Liviu Dudau, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, graeme.gregory

On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6e04868..e877967 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>  extern int (*acpi_suspend_lowlevel)(void);
>  #define acpi_wakeup_address 0
>  
> +#define MAX_GIC_CPU_INTERFACE 65535

Does this need to be more than NR_CPUS?

> +/**
> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
> + * generates a logical cpu number
> + * @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 the gic cpu interface
> + */
> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
> +{
> +	int cpu;
> +
> +	if (mpidr == INVALID_HWID) {
> +		pr_info("Skip invalid cpu hardware ID\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;
> +	}
> +
> +	/* If it is the first CPU, no need to check duplicate MPIDRs */
> +	if (!enabled_cpus)
> +		goto skip_mpidr_check;
> +
> +	/*
> +	 * 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_present_cpu(cpu) {
> +		if (cpu_logical_map(cpu) == mpidr) {
> +			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
> +			       mpidr);
> +			return -EINVAL;
> +		}
> +	}
> +
> +skip_mpidr_check:
> +	enabled_cpus++;
> +
> +	/* allocate a logical cpu id for the new comer */
> +	if (cpu_logical_map(0) == mpidr) {
> +		/*
> +		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
> +		 * for BSP, no need to allocate again.
> +		 */
> +		cpu = 0;
> +	} else {
> +		cpu = cpumask_next_zero(-1, cpu_present_mask);
> +	}
> +
> +	/* map the logical cpu id to cpu MPIDR */
> +	cpu_logical_map(cpu) = mpidr;
> +
> +	set_cpu_possible(cpu, true);
> +	set_cpu_present(cpu, true);
> +
> +	return cpu;
> +}

Why not only set the cpu possible here (with the additional mpidr
validity checks changed to for_each_possible_cpu)...

> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 40f38f4..8f1d37c 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -36,6 +36,7 @@
>  #include <linux/completion.h>
>  #include <linux/of.h>
>  #include <linux/irq_work.h>
> +#include <linux/acpi.h>
>  
>  #include <asm/atomic.h>
>  #include <asm/cacheflush.h>
> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>  		if (err)
>  			continue;
>  
> -		set_cpu_present(cpu, true);
> +		/*
> +		 * In ACPI mode, cpu_present_map was initialised when
> +		 * MADT table was parsed which before this function
> +		 * is called.
> +		 */
> +		if (acpi_disabled)
> +			set_cpu_present(cpu, true);
> +
>  		max_cpus--;

... and don't touch this at all.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-18 14:27     ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6e04868..e877967 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>  extern int (*acpi_suspend_lowlevel)(void);
>  #define acpi_wakeup_address 0
>  
> +#define MAX_GIC_CPU_INTERFACE 65535

Does this need to be more than NR_CPUS?

> +/**
> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
> + * generates a logical cpu number
> + * @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 the gic cpu interface
> + */
> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
> +{
> +	int cpu;
> +
> +	if (mpidr == INVALID_HWID) {
> +		pr_info("Skip invalid cpu hardware ID\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;
> +	}
> +
> +	/* If it is the first CPU, no need to check duplicate MPIDRs */
> +	if (!enabled_cpus)
> +		goto skip_mpidr_check;
> +
> +	/*
> +	 * 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_present_cpu(cpu) {
> +		if (cpu_logical_map(cpu) == mpidr) {
> +			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
> +			       mpidr);
> +			return -EINVAL;
> +		}
> +	}
> +
> +skip_mpidr_check:
> +	enabled_cpus++;
> +
> +	/* allocate a logical cpu id for the new comer */
> +	if (cpu_logical_map(0) == mpidr) {
> +		/*
> +		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
> +		 * for BSP, no need to allocate again.
> +		 */
> +		cpu = 0;
> +	} else {
> +		cpu = cpumask_next_zero(-1, cpu_present_mask);
> +	}
> +
> +	/* map the logical cpu id to cpu MPIDR */
> +	cpu_logical_map(cpu) = mpidr;
> +
> +	set_cpu_possible(cpu, true);
> +	set_cpu_present(cpu, true);
> +
> +	return cpu;
> +}

Why not only set the cpu possible here (with the additional mpidr
validity checks changed to for_each_possible_cpu)...

> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 40f38f4..8f1d37c 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -36,6 +36,7 @@
>  #include <linux/completion.h>
>  #include <linux/of.h>
>  #include <linux/irq_work.h>
> +#include <linux/acpi.h>
>  
>  #include <asm/atomic.h>
>  #include <asm/cacheflush.h>
> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>  		if (err)
>  			continue;
>  
> -		set_cpu_present(cpu, true);
> +		/*
> +		 * In ACPI mode, cpu_present_map was initialised when
> +		 * MADT table was parsed which before this function
> +		 * is called.
> +		 */
> +		if (acpi_disabled)
> +			set_cpu_present(cpu, true);
> +
>  		max_cpus--;

... and don't touch this at all.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-04 15:28   ` Hanjun Guo
@ 2014-08-18 14:27     ` Catalin Marinas
  -1 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Mark Rutland, linaro-acpi, Will Deacon, Lv Zheng, Rob Herring,
	Lorenzo Pieralisi, Daniel Lezcano, Robert Moore, linux-acpi,
	grant.likely, Charles Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Liviu Dudau, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, graeme.gregory

On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index e877967..022f4ad 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -14,6 +14,27 @@
>  
>  /* Basic configuration for ACPI */
>  #ifdef	CONFIG_ACPI
> +/*
> + * ACPI 5.1 only has two explicit methods to
> + * boot up SMP, PSCI and Parking protocol,
> + * but the Parking protocol is only defined
> + * 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.
> + *
> + * This enum is intend to make the boot method
> + * scalable when above updates are happended,
> + * which NOT means to support all of them.
> + */
> +enum acpi_smp_boot_protocol {
> +	ACPI_SMP_BOOT_PSCI,
> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
> +	ACPI_SMP_BOOT_PROTOCOL_MAX
> +};
> +
> +enum acpi_smp_boot_protocol smp_boot_protocol(void);

Since this is not a static function and ACPI-specific, could you prefix
it with something like acpi (or arm64_acpi_ unless it gets too long)?

> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
> index d62d12f..05bc314 100644
> --- a/arch/arm64/kernel/cpu_ops.c
> +++ b/arch/arm64/kernel/cpu_ops.c
> @@ -16,11 +16,13 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> -#include <asm/cpu_ops.h>
> -#include <asm/smp_plat.h>
>  #include <linux/errno.h>
>  #include <linux/of.h>
>  #include <linux/string.h>
> +#include <linux/acpi.h>
> +
> +#include <asm/cpu_ops.h>
> +#include <asm/smp_plat.h>
>  
>  extern const struct cpu_operations smp_spin_table_ops;
>  extern const struct cpu_operations cpu_psci_ops;
> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>  	return NULL;
>  }
>  
> +#ifdef CONFIG_ACPI
> +/*
> + * Get a cpu's boot method in the ACPI way.
> + */
> +static char * __init acpi_get_cpu_boot_method(void)
> +{
> +	/*
> +	 * For ACPI 5.1, only two kind of methods are provided,
> +	 * Parking protocol and PSCI, but Parking protocol is
> +	 * specified for ARMv7 only, so make PSCI as the only method
> +	 * for SMP initialization before the ACPI spec or Parking
> +	 * protocol spec is updated.
> +	 */
> +	switch (smp_boot_protocol()) {
> +	case ACPI_SMP_BOOT_PSCI:
> +		return "psci";
> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> +	default:
> +		return NULL;
> +	}
> +}

Actually, do we even need to define smp_boot_protocol()? Is it used
anywhere else apart from this patch (I still haven't gone through all
patches)?

> +#else
> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
> +#endif
> +
>  /*
> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
> + * Read a cpu's enable method and record it in cpu_ops.
>   */
>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>  {
> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
> +	const char *enable_method;
> +
> +	if (!acpi_disabled) {
> +		enable_method = acpi_get_cpu_boot_method();
> +		goto get_ops;

Are we always guaranteed an enable_method here? You should have an
if/else of ACPI vs DT and keep the if (!enable_method) check for both
cases.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-18 14:27     ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index e877967..022f4ad 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -14,6 +14,27 @@
>  
>  /* Basic configuration for ACPI */
>  #ifdef	CONFIG_ACPI
> +/*
> + * ACPI 5.1 only has two explicit methods to
> + * boot up SMP, PSCI and Parking protocol,
> + * but the Parking protocol is only defined
> + * 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.
> + *
> + * This enum is intend to make the boot method
> + * scalable when above updates are happended,
> + * which NOT means to support all of them.
> + */
> +enum acpi_smp_boot_protocol {
> +	ACPI_SMP_BOOT_PSCI,
> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
> +	ACPI_SMP_BOOT_PROTOCOL_MAX
> +};
> +
> +enum acpi_smp_boot_protocol smp_boot_protocol(void);

Since this is not a static function and ACPI-specific, could you prefix
it with something like acpi (or arm64_acpi_ unless it gets too long)?

> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
> index d62d12f..05bc314 100644
> --- a/arch/arm64/kernel/cpu_ops.c
> +++ b/arch/arm64/kernel/cpu_ops.c
> @@ -16,11 +16,13 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> -#include <asm/cpu_ops.h>
> -#include <asm/smp_plat.h>
>  #include <linux/errno.h>
>  #include <linux/of.h>
>  #include <linux/string.h>
> +#include <linux/acpi.h>
> +
> +#include <asm/cpu_ops.h>
> +#include <asm/smp_plat.h>
>  
>  extern const struct cpu_operations smp_spin_table_ops;
>  extern const struct cpu_operations cpu_psci_ops;
> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>  	return NULL;
>  }
>  
> +#ifdef CONFIG_ACPI
> +/*
> + * Get a cpu's boot method in the ACPI way.
> + */
> +static char * __init acpi_get_cpu_boot_method(void)
> +{
> +	/*
> +	 * For ACPI 5.1, only two kind of methods are provided,
> +	 * Parking protocol and PSCI, but Parking protocol is
> +	 * specified for ARMv7 only, so make PSCI as the only method
> +	 * for SMP initialization before the ACPI spec or Parking
> +	 * protocol spec is updated.
> +	 */
> +	switch (smp_boot_protocol()) {
> +	case ACPI_SMP_BOOT_PSCI:
> +		return "psci";
> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> +	default:
> +		return NULL;
> +	}
> +}

Actually, do we even need to define smp_boot_protocol()? Is it used
anywhere else apart from this patch (I still haven't gone through all
patches)?

> +#else
> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
> +#endif
> +
>  /*
> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
> + * Read a cpu's enable method and record it in cpu_ops.
>   */
>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>  {
> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
> +	const char *enable_method;
> +
> +	if (!acpi_disabled) {
> +		enable_method = acpi_get_cpu_boot_method();
> +		goto get_ops;

Are we always guaranteed an enable_method here? You should have an
if/else of ACPI vs DT and keep the if (!enable_method) check for both
cases.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
  2014-08-04 15:28   ` Hanjun Guo
@ 2014-08-18 14:27     ` Catalin Marinas
  -1 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Mark Rutland, linaro-acpi, Will Deacon, Lv Zheng, Rob Herring,
	Lorenzo Pieralisi, Daniel Lezcano, Robert Moore, linux-acpi,
	grant.likely, Charles Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Liviu Dudau, Mark Brown,
	Bjorn Helgaas, linux-arm-kernel, graeme.gregory, Randy

On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 022f4ad..a81898d 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -12,6 +12,8 @@
>  #ifndef _ASM_ACPI_H
>  #define _ASM_ACPI_H
>  
> +#include <asm/smp_plat.h>
> +
>  /* Basic configuration for ACPI */
>  #ifdef	CONFIG_ACPI
>  /*
> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>  	acpi_noirq = 1;
>  }
>  
> +u32 pack_mpidr_into_32_bits(u64 mpidr);

I would define this as a static inline function here.

> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
> index e32321c..4007313 100644
> --- a/drivers/acpi/processor_core.c
> +++ b/drivers/acpi/processor_core.c
> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>  	return 0;
>  }
>  
> +/*
> + * On ARM platform, MPIDR value is the hardware ID as apic ID
> + * on Intel platforms
> + */
> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
> +		int device_declaration, u32 acpi_id, int *mpidr)
> +{
> +	struct acpi_madt_generic_interrupt *gicc =
> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
> +
> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
> +		return -ENODEV;
> +
> +	/* In the GIC interrupt model, logical processors are
> +	 * required to have a Processor Device object in the DSDT,
> +	 * so we should check device_declaration here
> +	 */
> +	if (device_declaration && (gicc->uid == acpi_id)) {
> +		/*
> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
> +		 * fields into a single 32 bit identifier to accommodate the
> +		 * acpi processor drivers.
> +		 */
> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
> +			 | gicc->arm_mpidr;

You can use pack_mpidr_into_32_bits().

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-18 14:27     ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 022f4ad..a81898d 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -12,6 +12,8 @@
>  #ifndef _ASM_ACPI_H
>  #define _ASM_ACPI_H
>  
> +#include <asm/smp_plat.h>
> +
>  /* Basic configuration for ACPI */
>  #ifdef	CONFIG_ACPI
>  /*
> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>  	acpi_noirq = 1;
>  }
>  
> +u32 pack_mpidr_into_32_bits(u64 mpidr);

I would define this as a static inline function here.

> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
> index e32321c..4007313 100644
> --- a/drivers/acpi/processor_core.c
> +++ b/drivers/acpi/processor_core.c
> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>  	return 0;
>  }
>  
> +/*
> + * On ARM platform, MPIDR value is the hardware ID as apic ID
> + * on Intel platforms
> + */
> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
> +		int device_declaration, u32 acpi_id, int *mpidr)
> +{
> +	struct acpi_madt_generic_interrupt *gicc =
> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
> +
> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
> +		return -ENODEV;
> +
> +	/* In the GIC interrupt model, logical processors are
> +	 * required to have a Processor Device object in the DSDT,
> +	 * so we should check device_declaration here
> +	 */
> +	if (device_declaration && (gicc->uid == acpi_id)) {
> +		/*
> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
> +		 * fields into a single 32 bit identifier to accommodate the
> +		 * acpi processor drivers.
> +		 */
> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
> +			 | gicc->arm_mpidr;

You can use pack_mpidr_into_32_bits().

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 17/18] ARM64 / ACPI: Enable ARM64 in Kconfig
  2014-08-04 15:28   ` Hanjun Guo
@ 2014-08-18 14:27     ` Catalin Marinas
  -1 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Mark Rutland, linaro-acpi, Will Deacon, Lv Zheng, Rob Herring,
	Lorenzo Pieralisi, Al Stone, Daniel Lezcano, Robert Moore,
	linux-acpi, grant.likely, Charles Garcia-Tobin, Robert Richter,
	Jason Cooper, Arnd Bergmann, Marc Zyngier, Liviu Dudau,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel,
	graeme.gregory@linaro.org

On Mon, Aug 04, 2014 at 04:28:24PM +0100, Hanjun Guo wrote:
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 3f5f745..f6b6791 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -5,8 +5,7 @@
>  menuconfig ACPI
>  	bool "ACPI (Advanced Configuration and Power Interface) Support"
>  	depends on !IA64_HP_SIM
> -	depends on IA64 || X86
> -	depends on PCI
> +	depends on ((IA64 || X86) && PCI) || ARM64

depends on (ARM64 && EXPERT)? (together with default on if CONFIG_ACPI
is enabled).

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 17/18] ARM64 / ACPI: Enable ARM64 in Kconfig
@ 2014-08-18 14:27     ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-18 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 04, 2014 at 04:28:24PM +0100, Hanjun Guo wrote:
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 3f5f745..f6b6791 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -5,8 +5,7 @@
>  menuconfig ACPI
>  	bool "ACPI (Advanced Configuration and Power Interface) Support"
>  	depends on !IA64_HP_SIM
> -	depends on IA64 || X86
> -	depends on PCI
> +	depends on ((IA64 || X86) && PCI) || ARM64

depends on (ARM64 && EXPERT)? (together with default on if CONFIG_ACPI
is enabled).

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
  2014-08-05  3:34     ` Hanjun Guo
  (?)
@ 2014-08-18 17:08       ` Alexander Spyridakis
  -1 siblings, 0 replies; 180+ messages in thread
From: Alexander Spyridakis @ 2014-08-18 17:08 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Alexander Spyridakis, Catalin Marinas, Rafael J. Wysocki,
	Mark Rutland, linaro-acpi, Liviu Dudau, Lv Zheng, Rob Herring,
	Daniel Lezcano, Robert Moore, linux-acpi, Robert Richter,
	Jason Cooper, Arnd Bergmann, Marc Zyngier, Will Deacon,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Randy Dunlap,
	linux-kernel, Olof Johansson

> Yes, I think so. If you meet any problem , please let us know, and we will
> update the wiki.
>
>>
>> Should I assume that UEFI is mandatory (alternative being the aarch64
>> bootwrapper), as described in Documentation/arm64/arm-acpi.txt?
>
> Yes, UEFI is mandatory if you want to use ACPI.

Hello Hanjun,

What tables do you use for the foundation model (or AEMv8)?

The ones found in this repository:
git://git.linaro.org/leg/acpi/acpi-asl.git are ACPIv5.0, and when the
kernel gets pointed to them acpi is disabled because it expects an
FADT v5.1 or later. Of course building these tables with latest ACPICA
also fails.

Regards.

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
@ 2014-08-18 17:08       ` Alexander Spyridakis
  0 siblings, 0 replies; 180+ messages in thread
From: Alexander Spyridakis @ 2014-08-18 17:08 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Alexander Spyridakis, Catalin Marinas, Rafael J. Wysocki,
	Mark Rutland, linaro-acpi, Liviu Dudau, Lv Zheng, Rob Herring,
	Daniel Lezcano, Robert Moore, linux-acpi, Robert Richter,
	Jason Cooper, Arnd Bergmann, Marc Zyngier, Will Deacon,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Randy Dunlap,
	linux-kernel, Olof Johansson

> Yes, I think so. If you meet any problem , please let us know, and we will
> update the wiki.
>
>>
>> Should I assume that UEFI is mandatory (alternative being the aarch64
>> bootwrapper), as described in Documentation/arm64/arm-acpi.txt?
>
> Yes, UEFI is mandatory if you want to use ACPI.

Hello Hanjun,

What tables do you use for the foundation model (or AEMv8)?

The ones found in this repository:
git://git.linaro.org/leg/acpi/acpi-asl.git are ACPIv5.0, and when the
kernel gets pointed to them acpi is disabled because it expects an
FADT v5.1 or later. Of course building these tables with latest ACPICA
also fails.

Regards.

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
@ 2014-08-18 17:08       ` Alexander Spyridakis
  0 siblings, 0 replies; 180+ messages in thread
From: Alexander Spyridakis @ 2014-08-18 17:08 UTC (permalink / raw)
  To: linux-arm-kernel

> Yes, I think so. If you meet any problem , please let us know, and we will
> update the wiki.
>
>>
>> Should I assume that UEFI is mandatory (alternative being the aarch64
>> bootwrapper), as described in Documentation/arm64/arm-acpi.txt?
>
> Yes, UEFI is mandatory if you want to use ACPI.

Hello Hanjun,

What tables do you use for the foundation model (or AEMv8)?

The ones found in this repository:
git://git.linaro.org/leg/acpi/acpi-asl.git are ACPIv5.0, and when the
kernel gets pointed to them acpi is disabled because it expects an
FADT v5.1 or later. Of course building these tables with latest ACPICA
also fails.

Regards.

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
  2014-08-18 17:08       ` Alexander Spyridakis
  (?)
@ 2014-08-18 18:11         ` Graeme Gregory
  -1 siblings, 0 replies; 180+ messages in thread
From: Graeme Gregory @ 2014-08-18 18:11 UTC (permalink / raw)
  To: Alexander Spyridakis
  Cc: Hanjun Guo, linaro-acpi, Liviu Dudau, Lv Zheng, Rob Herring,
	Daniel Lezcano, Robert Moore, linux-acpi, Catalin Marinas,
	Robert Richter, Jason Cooper, Arnd Bergmann, Marc Zyngier,
	Will Deacon, Mark Brown, Bjorn Helgaas, linux-arm-kernel,
	Randy Dunlap, Rafael J. Wysocki, linux-kernel, Olof Johansson

On Mon, Aug 18, 2014 at 07:08:59PM +0200, Alexander Spyridakis wrote:
> > Yes, I think so. If you meet any problem , please let us know, and we will
> > update the wiki.
> >
> >>
> >> Should I assume that UEFI is mandatory (alternative being the aarch64
> >> bootwrapper), as described in Documentation/arm64/arm-acpi.txt?
> >
> > Yes, UEFI is mandatory if you want to use ACPI.
> 
> Hello Hanjun,
> 
> What tables do you use for the foundation model (or AEMv8)?
> 
> The ones found in this repository:
> git://git.linaro.org/leg/acpi/acpi-asl.git are ACPIv5.0, and when the
> kernel gets pointed to them acpi is disabled because it expects an
> FADT v5.1 or later. Of course building these tables with latest ACPICA
> also fails.
> 
I updated that repository to ACPI 5.1 approximately 4 hours ago.

If you re-fetch you should see 5.1 tables for foundation model.

Graeme


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
@ 2014-08-18 18:11         ` Graeme Gregory
  0 siblings, 0 replies; 180+ messages in thread
From: Graeme Gregory @ 2014-08-18 18:11 UTC (permalink / raw)
  To: Alexander Spyridakis
  Cc: Hanjun Guo, linaro-acpi, Liviu Dudau, Lv Zheng, Rob Herring,
	Daniel Lezcano, Robert Moore, linux-acpi, Catalin Marinas,
	Robert Richter, Jason Cooper, Arnd Bergmann, Marc Zyngier,
	Will Deacon, Mark Brown, Bjorn Helgaas, linux-arm-kernel,
	Randy Dunlap, Rafael J. Wysocki, linux-kernel, Olof Johansson

On Mon, Aug 18, 2014 at 07:08:59PM +0200, Alexander Spyridakis wrote:
> > Yes, I think so. If you meet any problem , please let us know, and we will
> > update the wiki.
> >
> >>
> >> Should I assume that UEFI is mandatory (alternative being the aarch64
> >> bootwrapper), as described in Documentation/arm64/arm-acpi.txt?
> >
> > Yes, UEFI is mandatory if you want to use ACPI.
> 
> Hello Hanjun,
> 
> What tables do you use for the foundation model (or AEMv8)?
> 
> The ones found in this repository:
> git://git.linaro.org/leg/acpi/acpi-asl.git are ACPIv5.0, and when the
> kernel gets pointed to them acpi is disabled because it expects an
> FADT v5.1 or later. Of course building these tables with latest ACPICA
> also fails.
> 
I updated that repository to ACPI 5.1 approximately 4 hours ago.

If you re-fetch you should see 5.1 tables for foundation model.

Graeme


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1
@ 2014-08-18 18:11         ` Graeme Gregory
  0 siblings, 0 replies; 180+ messages in thread
From: Graeme Gregory @ 2014-08-18 18:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 18, 2014 at 07:08:59PM +0200, Alexander Spyridakis wrote:
> > Yes, I think so. If you meet any problem , please let us know, and we will
> > update the wiki.
> >
> >>
> >> Should I assume that UEFI is mandatory (alternative being the aarch64
> >> bootwrapper), as described in Documentation/arm64/arm-acpi.txt?
> >
> > Yes, UEFI is mandatory if you want to use ACPI.
> 
> Hello Hanjun,
> 
> What tables do you use for the foundation model (or AEMv8)?
> 
> The ones found in this repository:
> git://git.linaro.org/leg/acpi/acpi-asl.git are ACPIv5.0, and when the
> kernel gets pointed to them acpi is disabled because it expects an
> FADT v5.1 or later. Of course building these tables with latest ACPICA
> also fails.
> 
I updated that repository to ACPI 5.1 approximately 4 hours ago.

If you re-fetch you should see 5.1 tables for foundation model.

Graeme

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
  2014-08-04 15:28   ` Hanjun Guo
  (?)
@ 2014-08-18 18:30     ` Sudeep Holla
  -1 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:30 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel@lists.infradead.org



On 04/08/14 16:28, Hanjun Guo wrote:
> From: Al Stone <al.stone@linaro.org>
>
> As we want to get ACPI tables to parse and then use the information
> for system initialization, we should get the RSDP (Root System
> Description Pointer) first, it then locates Extended Root Description
> Table (XSDT) which contains all the 64-bit physical address that
> pointer to other boot-time tables.
>
> Introduce acpi.c and its related head file in this patch to provide
> fundamental needs of extern variables and functions for ACPI core,
> and then get boot-time tables as needed.
>    - asm/cpu.h need for ACPI core and will be updated in the future to
>      add definitions for arch_(un)register_cpu which are required for
>      ACPI based physical CPU hotplug;

This can go away now, as it's already present in v3.17-rc1

>    - asm/acenv.h for arch specific ACPICA environments and
>      implementation;
>    - asm/acpi.h for arch specific variables and functions needed by
>      ACPI driver core;
>    - acpi.c for ARM64 related ACPI implementation for ACPI driver
>      core;
>
> acpi_boot_table_init() is introduced to get RSDP and boot-time tables,
> it will be called in setup_arch() before paging_init(), so we should
> use eary_memremap() mechanism here to get the RSDP and all the table
> pointers.
>
> Signed-off-by: Al Stone <al.stone@linaro.org>
> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   arch/arm64/include/asm/acenv.h |   18 +++++++++++
>   arch/arm64/include/asm/acpi.h  |   45 ++++++++++++++++++++++++++
>   arch/arm64/include/asm/cpu.h   |   11 +++++++
>   arch/arm64/kernel/Makefile     |    1 +
>   arch/arm64/kernel/acpi.c       |   69 ++++++++++++++++++++++++++++++++++++++++
>   arch/arm64/kernel/setup.c      |    4 +++
>   6 files changed, 148 insertions(+)
>   create mode 100644 arch/arm64/include/asm/acenv.h
>   create mode 100644 arch/arm64/include/asm/acpi.h
>   create mode 100644 arch/arm64/include/asm/cpu.h
>   create mode 100644 arch/arm64/kernel/acpi.c
>

[...]

> +
> +/*
> + * Checking for the posibility that the CPU can be initialized from the MADT.
> + * It's used from ACPI core in crash kernel case where boot CPU is not
> + * necessarily CPU0 like spec demands. Since MADT must provide at least one

Do you mean ACPI spec demands CPU0 to be boot cpu ?

IIUC it's basically to handle UP system with SMP kernel. IWO if all the
ACPI resources are reused from SMP system to boot UP system with SMP
kernel, with this check the ACPI core won't override the CPU index
obtained from GIC/APIC mapping to zero.

> + * GICC structure for GIC initialization, CPU will be always available in
> + * MADT on ARM64.
> + */
> +static inline bool acpi_has_cpu_in_madt(void)
> +{
> +	return 1;

probably true instead of 1

> +}
> +
> +static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> +
> +#endif /* CONFIG_ACPI */
> +
> +#endif /*_ASM_ACPI_H*/
> diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
> new file mode 100644
> index 0000000..cee7d3f
> --- /dev/null
> +++ b/arch/arm64/include/asm/cpu.h
> @@ -0,0 +1,11 @@
> +/*
> + *  Copyright (C) 2013-2014 ARM Ltd.
> + *
> + * 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.
> + */
> +#ifndef __ASM_CPU_H
> +#define __ASM_CPU_H
> +
> +#endif
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index cdaedad..b568c26 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
>   arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
>   arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
>   arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
> +arm64-obj-$(CONFIG_ACPI)		+= acpi.o
>
>   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
> new file mode 100644
> index 0000000..395778c
> --- /dev/null
> +++ b/arch/arm64/kernel/acpi.c
> @@ -0,0 +1,69 @@
> +/*
> + *  ARM64 Specific Low-Level ACPI Boot Support
> + *
> + *  Copyright (C) 2013-2014, Linaro Ltd.
> + *	Author: Al Stone <al.stone@linaro.org>
> + *	Author: Graeme Gregory <graeme.gregory@linaro.org>
> + *	Author: Hanjun Guo <hanjun.guo@linaro.org>
> + *
> + *  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.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/acpi.h>
> +#include <linux/cpumask.h>
> +#include <linux/memblock.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/bootmem.h>
> +#include <linux/smp.h>
> +
> +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);
> +
> +/*
> + * __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_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
> + *
> + * We can parse ACPI boot-time tables such as FADT, 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()) {

Can't we call acpi_table_init directly in setup ?
IIUC x86 has acpi_boot_table_init as it parses Boot Flags
table(ACPI_SIG_BOOT)

> +		disable_acpi();
> +		return;
> +	}
> +}
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index fc50461..85c6326 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -43,6 +43,7 @@
>   #include <linux/of_fdt.h>
>   #include <linux/of_platform.h>
>   #include <linux/efi.h>
> +#include <linux/acpi.h>
>
>   #include <asm/fixmap.h>
>   #include <asm/cputype.h>
> @@ -385,6 +386,9 @@ void __init setup_arch(char **cmdline_p)
>   	efi_init();
>   	arm64_memblock_init();
>
> +	/* Parse the ACPI tables for possible boot-time configuration */
> +	acpi_boot_table_init();
> +
>   	paging_init();
>   	request_standard_resources();
>
>


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
@ 2014-08-18 18:30     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:30 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Tomasz Nowicki



On 04/08/14 16:28, Hanjun Guo wrote:
> From: Al Stone <al.stone@linaro.org>
>
> As we want to get ACPI tables to parse and then use the information
> for system initialization, we should get the RSDP (Root System
> Description Pointer) first, it then locates Extended Root Description
> Table (XSDT) which contains all the 64-bit physical address that
> pointer to other boot-time tables.
>
> Introduce acpi.c and its related head file in this patch to provide
> fundamental needs of extern variables and functions for ACPI core,
> and then get boot-time tables as needed.
>    - asm/cpu.h need for ACPI core and will be updated in the future to
>      add definitions for arch_(un)register_cpu which are required for
>      ACPI based physical CPU hotplug;

This can go away now, as it's already present in v3.17-rc1

>    - asm/acenv.h for arch specific ACPICA environments and
>      implementation;
>    - asm/acpi.h for arch specific variables and functions needed by
>      ACPI driver core;
>    - acpi.c for ARM64 related ACPI implementation for ACPI driver
>      core;
>
> acpi_boot_table_init() is introduced to get RSDP and boot-time tables,
> it will be called in setup_arch() before paging_init(), so we should
> use eary_memremap() mechanism here to get the RSDP and all the table
> pointers.
>
> Signed-off-by: Al Stone <al.stone@linaro.org>
> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   arch/arm64/include/asm/acenv.h |   18 +++++++++++
>   arch/arm64/include/asm/acpi.h  |   45 ++++++++++++++++++++++++++
>   arch/arm64/include/asm/cpu.h   |   11 +++++++
>   arch/arm64/kernel/Makefile     |    1 +
>   arch/arm64/kernel/acpi.c       |   69 ++++++++++++++++++++++++++++++++++++++++
>   arch/arm64/kernel/setup.c      |    4 +++
>   6 files changed, 148 insertions(+)
>   create mode 100644 arch/arm64/include/asm/acenv.h
>   create mode 100644 arch/arm64/include/asm/acpi.h
>   create mode 100644 arch/arm64/include/asm/cpu.h
>   create mode 100644 arch/arm64/kernel/acpi.c
>

[...]

> +
> +/*
> + * Checking for the posibility that the CPU can be initialized from the MADT.
> + * It's used from ACPI core in crash kernel case where boot CPU is not
> + * necessarily CPU0 like spec demands. Since MADT must provide at least one

Do you mean ACPI spec demands CPU0 to be boot cpu ?

IIUC it's basically to handle UP system with SMP kernel. IWO if all the
ACPI resources are reused from SMP system to boot UP system with SMP
kernel, with this check the ACPI core won't override the CPU index
obtained from GIC/APIC mapping to zero.

> + * GICC structure for GIC initialization, CPU will be always available in
> + * MADT on ARM64.
> + */
> +static inline bool acpi_has_cpu_in_madt(void)
> +{
> +	return 1;

probably true instead of 1

> +}
> +
> +static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> +
> +#endif /* CONFIG_ACPI */
> +
> +#endif /*_ASM_ACPI_H*/
> diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
> new file mode 100644
> index 0000000..cee7d3f
> --- /dev/null
> +++ b/arch/arm64/include/asm/cpu.h
> @@ -0,0 +1,11 @@
> +/*
> + *  Copyright (C) 2013-2014 ARM Ltd.
> + *
> + * 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.
> + */
> +#ifndef __ASM_CPU_H
> +#define __ASM_CPU_H
> +
> +#endif
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index cdaedad..b568c26 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
>   arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
>   arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
>   arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
> +arm64-obj-$(CONFIG_ACPI)		+= acpi.o
>
>   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
> new file mode 100644
> index 0000000..395778c
> --- /dev/null
> +++ b/arch/arm64/kernel/acpi.c
> @@ -0,0 +1,69 @@
> +/*
> + *  ARM64 Specific Low-Level ACPI Boot Support
> + *
> + *  Copyright (C) 2013-2014, Linaro Ltd.
> + *	Author: Al Stone <al.stone@linaro.org>
> + *	Author: Graeme Gregory <graeme.gregory@linaro.org>
> + *	Author: Hanjun Guo <hanjun.guo@linaro.org>
> + *
> + *  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.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/acpi.h>
> +#include <linux/cpumask.h>
> +#include <linux/memblock.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/bootmem.h>
> +#include <linux/smp.h>
> +
> +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);
> +
> +/*
> + * __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_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
> + *
> + * We can parse ACPI boot-time tables such as FADT, 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()) {

Can't we call acpi_table_init directly in setup ?
IIUC x86 has acpi_boot_table_init as it parses Boot Flags
table(ACPI_SIG_BOOT)

> +		disable_acpi();
> +		return;
> +	}
> +}
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index fc50461..85c6326 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -43,6 +43,7 @@
>   #include <linux/of_fdt.h>
>   #include <linux/of_platform.h>
>   #include <linux/efi.h>
> +#include <linux/acpi.h>
>
>   #include <asm/fixmap.h>
>   #include <asm/cputype.h>
> @@ -385,6 +386,9 @@ void __init setup_arch(char **cmdline_p)
>   	efi_init();
>   	arm64_memblock_init();
>
> +	/* Parse the ACPI tables for possible boot-time configuration */
> +	acpi_boot_table_init();
> +
>   	paging_init();
>   	request_standard_resources();
>
>


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
@ 2014-08-18 18:30     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:30 UTC (permalink / raw)
  To: linux-arm-kernel



On 04/08/14 16:28, Hanjun Guo wrote:
> From: Al Stone <al.stone@linaro.org>
>
> As we want to get ACPI tables to parse and then use the information
> for system initialization, we should get the RSDP (Root System
> Description Pointer) first, it then locates Extended Root Description
> Table (XSDT) which contains all the 64-bit physical address that
> pointer to other boot-time tables.
>
> Introduce acpi.c and its related head file in this patch to provide
> fundamental needs of extern variables and functions for ACPI core,
> and then get boot-time tables as needed.
>    - asm/cpu.h need for ACPI core and will be updated in the future to
>      add definitions for arch_(un)register_cpu which are required for
>      ACPI based physical CPU hotplug;

This can go away now, as it's already present in v3.17-rc1

>    - asm/acenv.h for arch specific ACPICA environments and
>      implementation;
>    - asm/acpi.h for arch specific variables and functions needed by
>      ACPI driver core;
>    - acpi.c for ARM64 related ACPI implementation for ACPI driver
>      core;
>
> acpi_boot_table_init() is introduced to get RSDP and boot-time tables,
> it will be called in setup_arch() before paging_init(), so we should
> use eary_memremap() mechanism here to get the RSDP and all the table
> pointers.
>
> Signed-off-by: Al Stone <al.stone@linaro.org>
> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   arch/arm64/include/asm/acenv.h |   18 +++++++++++
>   arch/arm64/include/asm/acpi.h  |   45 ++++++++++++++++++++++++++
>   arch/arm64/include/asm/cpu.h   |   11 +++++++
>   arch/arm64/kernel/Makefile     |    1 +
>   arch/arm64/kernel/acpi.c       |   69 ++++++++++++++++++++++++++++++++++++++++
>   arch/arm64/kernel/setup.c      |    4 +++
>   6 files changed, 148 insertions(+)
>   create mode 100644 arch/arm64/include/asm/acenv.h
>   create mode 100644 arch/arm64/include/asm/acpi.h
>   create mode 100644 arch/arm64/include/asm/cpu.h
>   create mode 100644 arch/arm64/kernel/acpi.c
>

[...]

> +
> +/*
> + * Checking for the posibility that the CPU can be initialized from the MADT.
> + * It's used from ACPI core in crash kernel case where boot CPU is not
> + * necessarily CPU0 like spec demands. Since MADT must provide at least one

Do you mean ACPI spec demands CPU0 to be boot cpu ?

IIUC it's basically to handle UP system with SMP kernel. IWO if all the
ACPI resources are reused from SMP system to boot UP system with SMP
kernel, with this check the ACPI core won't override the CPU index
obtained from GIC/APIC mapping to zero.

> + * GICC structure for GIC initialization, CPU will be always available in
> + * MADT on ARM64.
> + */
> +static inline bool acpi_has_cpu_in_madt(void)
> +{
> +	return 1;

probably true instead of 1

> +}
> +
> +static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> +
> +#endif /* CONFIG_ACPI */
> +
> +#endif /*_ASM_ACPI_H*/
> diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
> new file mode 100644
> index 0000000..cee7d3f
> --- /dev/null
> +++ b/arch/arm64/include/asm/cpu.h
> @@ -0,0 +1,11 @@
> +/*
> + *  Copyright (C) 2013-2014 ARM Ltd.
> + *
> + * 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.
> + */
> +#ifndef __ASM_CPU_H
> +#define __ASM_CPU_H
> +
> +#endif
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index cdaedad..b568c26 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
>   arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
>   arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
>   arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
> +arm64-obj-$(CONFIG_ACPI)		+= acpi.o
>
>   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
> new file mode 100644
> index 0000000..395778c
> --- /dev/null
> +++ b/arch/arm64/kernel/acpi.c
> @@ -0,0 +1,69 @@
> +/*
> + *  ARM64 Specific Low-Level ACPI Boot Support
> + *
> + *  Copyright (C) 2013-2014, Linaro Ltd.
> + *	Author: Al Stone <al.stone@linaro.org>
> + *	Author: Graeme Gregory <graeme.gregory@linaro.org>
> + *	Author: Hanjun Guo <hanjun.guo@linaro.org>
> + *
> + *  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.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/acpi.h>
> +#include <linux/cpumask.h>
> +#include <linux/memblock.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/bootmem.h>
> +#include <linux/smp.h>
> +
> +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);
> +
> +/*
> + * __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_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
> + *
> + * We can parse ACPI boot-time tables such as FADT, 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()) {

Can't we call acpi_table_init directly in setup ?
IIUC x86 has acpi_boot_table_init as it parses Boot Flags
table(ACPI_SIG_BOOT)

> +		disable_acpi();
> +		return;
> +	}
> +}
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index fc50461..85c6326 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -43,6 +43,7 @@
>   #include <linux/of_fdt.h>
>   #include <linux/of_platform.h>
>   #include <linux/efi.h>
> +#include <linux/acpi.h>
>
>   #include <asm/fixmap.h>
>   #include <asm/cputype.h>
> @@ -385,6 +386,9 @@ void __init setup_arch(char **cmdline_p)
>   	efi_init();
>   	arm64_memblock_init();
>
> +	/* Parse the ACPI tables for possible boot-time configuration */
> +	acpi_boot_table_init();
> +
>   	paging_init();
>   	request_standard_resources();
>
>

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-04 15:28   ` Hanjun Guo
  (?)
@ 2014-08-18 18:32     ` Sudeep Holla
  -1 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:32 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel@lists.infradead.org



On 04/08/14 16:28, Hanjun Guo wrote:
> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
> the former signals to the OS that the hardware is PSCI compliant.
> The latter selects the appropriate conduit for PSCI calls by
> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
> (SMC).
>
> FADT table contains such information, parse FADT to get the flags
> for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
> function IDs, which means that only PSCI 0.2+ is supported in ACPI.
>
> At the same time, only ACPI 5.1 or higher verison supports PSCI,
> and FADT Major.Minor version was introduced in ACPI 5.1, so we
> will check the version and only parse FADT table with version >= 5.1.
>
> If firmware provides ACPI tables with ACPI version less than 5.1,
> OS will be messed up with those information and have no way to
> bring up secondery CPUs, so disable ACPI if we get an FADT table
> with version less that 5.1.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |   12 ++++++
>   arch/arm64/kernel/acpi.c      |   37 +++++++++++++++++
>   arch/arm64/kernel/psci.c      |   89 ++++++++++++++++++++++++++++++-----------
>   arch/arm64/kernel/setup.c     |    2 +
>   4 files changed, 117 insertions(+), 23 deletions(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6400312..6e04868 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -19,6 +19,18 @@ extern int acpi_disabled;
>   extern int acpi_noirq;
>   extern int acpi_pci_disabled;
>
> +/* 1 to indicate PSCI 0.2+ is implemented */
> +static inline bool acpi_psci_present(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
> +}
> +
> +/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
> +static inline bool acpi_psci_use_hvc(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
> +}
> +
>   static inline void disable_acpi(void)
>   {
>   	acpi_disabled = 1;
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 9cf9127..69a315d 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -11,6 +11,8 @@
>    *  published by the Free Software Foundation.
>    */
>
> +#define pr_fmt(fmt) "ACPI: " fmt
> +
>   #include <linux/init.h>
>   #include <linux/acpi.h>
>   #include <linux/cpumask.h>
> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>   	early_memunmap(map, size);
>   }
>
> +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 version,
> +	 * and there is a minor version of FADT which was introduced
> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> +	 * to get arm boot flags, or we will disable ACPI.
> +	 */
> +	if (table->revision < 5 || fadt->minor_revision < 1) {

				&&

> +		pr_info("FADT version is %d.%d, no PSCI support, should be 5.1 or higher\n",
> +			table->revision, fadt->minor_revision);
> +		disable_acpi();

Instead of disabling ACPI at multiple places in the boot sequence, can't
it be done once if acpi_boot_init failed ?

> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>   /*
>    * acpi_boot_table_init() called from setup_arch(), always.
>    *	1. find RSDP and get its address, and then find XSDT
> @@ -68,6 +90,21 @@ void __init acpi_boot_table_init(void)
>   	}
>   }
>
> +int __init acpi_boot_init(void)
> +{
> +	int err = 0;
> +
> +	/* If acpi_disabled, bail out */
> +	if (acpi_disabled)
> +		return -ENODEV;
> +
> +	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
> +	if (err)
> +		pr_err("Can't find FADT\n");
> +
> +	return err;
> +}
> +
>   /*
>    * acpi_suspend_lowlevel() - save kernel state and suspend.
>    *
> diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
> index 9e9798f..2ad2084 100644
> --- a/arch/arm64/kernel/psci.c
> +++ b/arch/arm64/kernel/psci.c
> @@ -15,6 +15,7 @@
>
>   #define pr_fmt(fmt) "psci: " fmt
>
> +#include <linux/acpi.h>
>   #include <linux/init.h>
>   #include <linux/of.h>
>   #include <linux/smp.h>
> @@ -231,6 +232,33 @@ static void psci_sys_poweroff(void)
>   	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
>   }
>
> +static void psci_0_2_set_functions(void)
> +{
> +	pr_info("Using standard PSCI v0.2 function IDs\n");
> +	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
> +	psci_ops.cpu_suspend = psci_cpu_suspend;
> +
> +	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
> +	psci_ops.cpu_off = psci_cpu_off;
> +
> +	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
> +	psci_ops.cpu_on = psci_cpu_on;
> +
> +	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
> +	psci_ops.migrate = psci_migrate;
> +
> +	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
> +	psci_ops.affinity_info = psci_affinity_info;
> +
> +	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
> +		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
> +	psci_ops.migrate_info_type = psci_migrate_info_type;
> +
> +	arm_pm_restart = psci_sys_reset;
> +
> +	pm_power_off = psci_sys_poweroff;
> +}
> +

Nit: IMO may be you can move these refactoring as separate patch before
ACPI related changes ?

>   /*
>    * PSCI Function IDs for v0.2+ are well defined so use
>    * standard values.
> @@ -264,29 +292,7 @@ static int psci_0_2_init(struct device_node *np)
>   		}
>   	}
>
> -	pr_info("Using standard PSCI v0.2 function IDs\n");
> -	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
> -	psci_ops.cpu_suspend = psci_cpu_suspend;
> -
> -	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
> -	psci_ops.cpu_off = psci_cpu_off;
> -
> -	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
> -	psci_ops.cpu_on = psci_cpu_on;
> -
> -	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
> -	psci_ops.migrate = psci_migrate;
> -
> -	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
> -	psci_ops.affinity_info = psci_affinity_info;
> -
> -	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
> -		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
> -	psci_ops.migrate_info_type = psci_migrate_info_type;
> -
> -	arm_pm_restart = psci_sys_reset;
> -
> -	pm_power_off = psci_sys_poweroff;
> +	psci_0_2_set_functions();
>
>   out_put_node:
>   	of_node_put(np);
> @@ -333,6 +339,40 @@ out_put_node:
>   	return err;
>   }
>
> +#ifdef CONFIG_ACPI
> +static int get_set_conduit_method_acpi(void)
> +{
> +	pr_info("probing for conduit method from ACPI.\n");
> +
> +	if (acpi_psci_use_hvc())
> +		invoke_psci_fn = __invoke_psci_fn_hvc;
> +	else
> +		invoke_psci_fn = __invoke_psci_fn_smc;
> +
> +	return 0;
> +}
> +
> +/* We use PSCI 0.2+ when ACPI is deployed */
> +static int psci_0_2_init_acpi(void)

May be this can be renamed psci_acpi_init and called from setup directly
instead of calling from DT function with acpi_disabled check.

> +{
> +	if (!acpi_psci_present()) {
> +		pr_info("is not implemented in ACPI.\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	get_set_conduit_method_acpi();
> +
> +	psci_0_2_set_functions();
> +
> +	return 0;
> +}
> +#else
> +static inline int psci_0_2_init_acpi(void)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
>   static const struct of_device_id psci_of_match[] __initconst = {
>   	{ .compatible = "arm,psci",	.data = psci_0_1_init},
>   	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
> @@ -345,6 +385,9 @@ int __init psci_init(void)
>   	const struct of_device_id *matched_np;
>   	psci_initcall_t init_fn;
>
> +	if (!acpi_disabled)
> +		return psci_0_2_init_acpi();
> +

As mentioned above you need not modify this.

>   	np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
>
>   	if (!np)
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 85c6326..dfc4e4f3 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>   	efi_idmap_init();
>
>   	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
> +	acpi_boot_init();
> +

Check for the return error here and disable ACPI once rather than at
multiple places all over.

>   	unflatten_device_tree();
>
>   	psci_init();
>


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-18 18:32     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:32 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi



On 04/08/14 16:28, Hanjun Guo wrote:
> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
> the former signals to the OS that the hardware is PSCI compliant.
> The latter selects the appropriate conduit for PSCI calls by
> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
> (SMC).
>
> FADT table contains such information, parse FADT to get the flags
> for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
> function IDs, which means that only PSCI 0.2+ is supported in ACPI.
>
> At the same time, only ACPI 5.1 or higher verison supports PSCI,
> and FADT Major.Minor version was introduced in ACPI 5.1, so we
> will check the version and only parse FADT table with version >= 5.1.
>
> If firmware provides ACPI tables with ACPI version less than 5.1,
> OS will be messed up with those information and have no way to
> bring up secondery CPUs, so disable ACPI if we get an FADT table
> with version less that 5.1.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |   12 ++++++
>   arch/arm64/kernel/acpi.c      |   37 +++++++++++++++++
>   arch/arm64/kernel/psci.c      |   89 ++++++++++++++++++++++++++++++-----------
>   arch/arm64/kernel/setup.c     |    2 +
>   4 files changed, 117 insertions(+), 23 deletions(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6400312..6e04868 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -19,6 +19,18 @@ extern int acpi_disabled;
>   extern int acpi_noirq;
>   extern int acpi_pci_disabled;
>
> +/* 1 to indicate PSCI 0.2+ is implemented */
> +static inline bool acpi_psci_present(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
> +}
> +
> +/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
> +static inline bool acpi_psci_use_hvc(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
> +}
> +
>   static inline void disable_acpi(void)
>   {
>   	acpi_disabled = 1;
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 9cf9127..69a315d 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -11,6 +11,8 @@
>    *  published by the Free Software Foundation.
>    */
>
> +#define pr_fmt(fmt) "ACPI: " fmt
> +
>   #include <linux/init.h>
>   #include <linux/acpi.h>
>   #include <linux/cpumask.h>
> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>   	early_memunmap(map, size);
>   }
>
> +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 version,
> +	 * and there is a minor version of FADT which was introduced
> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> +	 * to get arm boot flags, or we will disable ACPI.
> +	 */
> +	if (table->revision < 5 || fadt->minor_revision < 1) {

				&&

> +		pr_info("FADT version is %d.%d, no PSCI support, should be 5.1 or higher\n",
> +			table->revision, fadt->minor_revision);
> +		disable_acpi();

Instead of disabling ACPI at multiple places in the boot sequence, can't
it be done once if acpi_boot_init failed ?

> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>   /*
>    * acpi_boot_table_init() called from setup_arch(), always.
>    *	1. find RSDP and get its address, and then find XSDT
> @@ -68,6 +90,21 @@ void __init acpi_boot_table_init(void)
>   	}
>   }
>
> +int __init acpi_boot_init(void)
> +{
> +	int err = 0;
> +
> +	/* If acpi_disabled, bail out */
> +	if (acpi_disabled)
> +		return -ENODEV;
> +
> +	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
> +	if (err)
> +		pr_err("Can't find FADT\n");
> +
> +	return err;
> +}
> +
>   /*
>    * acpi_suspend_lowlevel() - save kernel state and suspend.
>    *
> diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
> index 9e9798f..2ad2084 100644
> --- a/arch/arm64/kernel/psci.c
> +++ b/arch/arm64/kernel/psci.c
> @@ -15,6 +15,7 @@
>
>   #define pr_fmt(fmt) "psci: " fmt
>
> +#include <linux/acpi.h>
>   #include <linux/init.h>
>   #include <linux/of.h>
>   #include <linux/smp.h>
> @@ -231,6 +232,33 @@ static void psci_sys_poweroff(void)
>   	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
>   }
>
> +static void psci_0_2_set_functions(void)
> +{
> +	pr_info("Using standard PSCI v0.2 function IDs\n");
> +	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
> +	psci_ops.cpu_suspend = psci_cpu_suspend;
> +
> +	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
> +	psci_ops.cpu_off = psci_cpu_off;
> +
> +	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
> +	psci_ops.cpu_on = psci_cpu_on;
> +
> +	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
> +	psci_ops.migrate = psci_migrate;
> +
> +	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
> +	psci_ops.affinity_info = psci_affinity_info;
> +
> +	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
> +		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
> +	psci_ops.migrate_info_type = psci_migrate_info_type;
> +
> +	arm_pm_restart = psci_sys_reset;
> +
> +	pm_power_off = psci_sys_poweroff;
> +}
> +

Nit: IMO may be you can move these refactoring as separate patch before
ACPI related changes ?

>   /*
>    * PSCI Function IDs for v0.2+ are well defined so use
>    * standard values.
> @@ -264,29 +292,7 @@ static int psci_0_2_init(struct device_node *np)
>   		}
>   	}
>
> -	pr_info("Using standard PSCI v0.2 function IDs\n");
> -	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
> -	psci_ops.cpu_suspend = psci_cpu_suspend;
> -
> -	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
> -	psci_ops.cpu_off = psci_cpu_off;
> -
> -	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
> -	psci_ops.cpu_on = psci_cpu_on;
> -
> -	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
> -	psci_ops.migrate = psci_migrate;
> -
> -	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
> -	psci_ops.affinity_info = psci_affinity_info;
> -
> -	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
> -		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
> -	psci_ops.migrate_info_type = psci_migrate_info_type;
> -
> -	arm_pm_restart = psci_sys_reset;
> -
> -	pm_power_off = psci_sys_poweroff;
> +	psci_0_2_set_functions();
>
>   out_put_node:
>   	of_node_put(np);
> @@ -333,6 +339,40 @@ out_put_node:
>   	return err;
>   }
>
> +#ifdef CONFIG_ACPI
> +static int get_set_conduit_method_acpi(void)
> +{
> +	pr_info("probing for conduit method from ACPI.\n");
> +
> +	if (acpi_psci_use_hvc())
> +		invoke_psci_fn = __invoke_psci_fn_hvc;
> +	else
> +		invoke_psci_fn = __invoke_psci_fn_smc;
> +
> +	return 0;
> +}
> +
> +/* We use PSCI 0.2+ when ACPI is deployed */
> +static int psci_0_2_init_acpi(void)

May be this can be renamed psci_acpi_init and called from setup directly
instead of calling from DT function with acpi_disabled check.

> +{
> +	if (!acpi_psci_present()) {
> +		pr_info("is not implemented in ACPI.\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	get_set_conduit_method_acpi();
> +
> +	psci_0_2_set_functions();
> +
> +	return 0;
> +}
> +#else
> +static inline int psci_0_2_init_acpi(void)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
>   static const struct of_device_id psci_of_match[] __initconst = {
>   	{ .compatible = "arm,psci",	.data = psci_0_1_init},
>   	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
> @@ -345,6 +385,9 @@ int __init psci_init(void)
>   	const struct of_device_id *matched_np;
>   	psci_initcall_t init_fn;
>
> +	if (!acpi_disabled)
> +		return psci_0_2_init_acpi();
> +

As mentioned above you need not modify this.

>   	np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
>
>   	if (!np)
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 85c6326..dfc4e4f3 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>   	efi_idmap_init();
>
>   	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
> +	acpi_boot_init();
> +

Check for the return error here and disable ACPI once rather than at
multiple places all over.

>   	unflatten_device_tree();
>
>   	psci_init();
>


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-18 18:32     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:32 UTC (permalink / raw)
  To: linux-arm-kernel



On 04/08/14 16:28, Hanjun Guo wrote:
> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
> the former signals to the OS that the hardware is PSCI compliant.
> The latter selects the appropriate conduit for PSCI calls by
> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
> (SMC).
>
> FADT table contains such information, parse FADT to get the flags
> for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
> function IDs, which means that only PSCI 0.2+ is supported in ACPI.
>
> At the same time, only ACPI 5.1 or higher verison supports PSCI,
> and FADT Major.Minor version was introduced in ACPI 5.1, so we
> will check the version and only parse FADT table with version >= 5.1.
>
> If firmware provides ACPI tables with ACPI version less than 5.1,
> OS will be messed up with those information and have no way to
> bring up secondery CPUs, so disable ACPI if we get an FADT table
> with version less that 5.1.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |   12 ++++++
>   arch/arm64/kernel/acpi.c      |   37 +++++++++++++++++
>   arch/arm64/kernel/psci.c      |   89 ++++++++++++++++++++++++++++++-----------
>   arch/arm64/kernel/setup.c     |    2 +
>   4 files changed, 117 insertions(+), 23 deletions(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6400312..6e04868 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -19,6 +19,18 @@ extern int acpi_disabled;
>   extern int acpi_noirq;
>   extern int acpi_pci_disabled;
>
> +/* 1 to indicate PSCI 0.2+ is implemented */
> +static inline bool acpi_psci_present(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
> +}
> +
> +/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
> +static inline bool acpi_psci_use_hvc(void)
> +{
> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
> +}
> +
>   static inline void disable_acpi(void)
>   {
>   	acpi_disabled = 1;
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 9cf9127..69a315d 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -11,6 +11,8 @@
>    *  published by the Free Software Foundation.
>    */
>
> +#define pr_fmt(fmt) "ACPI: " fmt
> +
>   #include <linux/init.h>
>   #include <linux/acpi.h>
>   #include <linux/cpumask.h>
> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>   	early_memunmap(map, size);
>   }
>
> +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 version,
> +	 * and there is a minor version of FADT which was introduced
> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> +	 * to get arm boot flags, or we will disable ACPI.
> +	 */
> +	if (table->revision < 5 || fadt->minor_revision < 1) {

				&&

> +		pr_info("FADT version is %d.%d, no PSCI support, should be 5.1 or higher\n",
> +			table->revision, fadt->minor_revision);
> +		disable_acpi();

Instead of disabling ACPI at multiple places in the boot sequence, can't
it be done once if acpi_boot_init failed ?

> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>   /*
>    * acpi_boot_table_init() called from setup_arch(), always.
>    *	1. find RSDP and get its address, and then find XSDT
> @@ -68,6 +90,21 @@ void __init acpi_boot_table_init(void)
>   	}
>   }
>
> +int __init acpi_boot_init(void)
> +{
> +	int err = 0;
> +
> +	/* If acpi_disabled, bail out */
> +	if (acpi_disabled)
> +		return -ENODEV;
> +
> +	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
> +	if (err)
> +		pr_err("Can't find FADT\n");
> +
> +	return err;
> +}
> +
>   /*
>    * acpi_suspend_lowlevel() - save kernel state and suspend.
>    *
> diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
> index 9e9798f..2ad2084 100644
> --- a/arch/arm64/kernel/psci.c
> +++ b/arch/arm64/kernel/psci.c
> @@ -15,6 +15,7 @@
>
>   #define pr_fmt(fmt) "psci: " fmt
>
> +#include <linux/acpi.h>
>   #include <linux/init.h>
>   #include <linux/of.h>
>   #include <linux/smp.h>
> @@ -231,6 +232,33 @@ static void psci_sys_poweroff(void)
>   	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
>   }
>
> +static void psci_0_2_set_functions(void)
> +{
> +	pr_info("Using standard PSCI v0.2 function IDs\n");
> +	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
> +	psci_ops.cpu_suspend = psci_cpu_suspend;
> +
> +	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
> +	psci_ops.cpu_off = psci_cpu_off;
> +
> +	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
> +	psci_ops.cpu_on = psci_cpu_on;
> +
> +	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
> +	psci_ops.migrate = psci_migrate;
> +
> +	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
> +	psci_ops.affinity_info = psci_affinity_info;
> +
> +	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
> +		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
> +	psci_ops.migrate_info_type = psci_migrate_info_type;
> +
> +	arm_pm_restart = psci_sys_reset;
> +
> +	pm_power_off = psci_sys_poweroff;
> +}
> +

Nit: IMO may be you can move these refactoring as separate patch before
ACPI related changes ?

>   /*
>    * PSCI Function IDs for v0.2+ are well defined so use
>    * standard values.
> @@ -264,29 +292,7 @@ static int psci_0_2_init(struct device_node *np)
>   		}
>   	}
>
> -	pr_info("Using standard PSCI v0.2 function IDs\n");
> -	psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
> -	psci_ops.cpu_suspend = psci_cpu_suspend;
> -
> -	psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
> -	psci_ops.cpu_off = psci_cpu_off;
> -
> -	psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
> -	psci_ops.cpu_on = psci_cpu_on;
> -
> -	psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
> -	psci_ops.migrate = psci_migrate;
> -
> -	psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
> -	psci_ops.affinity_info = psci_affinity_info;
> -
> -	psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
> -		PSCI_0_2_FN_MIGRATE_INFO_TYPE;
> -	psci_ops.migrate_info_type = psci_migrate_info_type;
> -
> -	arm_pm_restart = psci_sys_reset;
> -
> -	pm_power_off = psci_sys_poweroff;
> +	psci_0_2_set_functions();
>
>   out_put_node:
>   	of_node_put(np);
> @@ -333,6 +339,40 @@ out_put_node:
>   	return err;
>   }
>
> +#ifdef CONFIG_ACPI
> +static int get_set_conduit_method_acpi(void)
> +{
> +	pr_info("probing for conduit method from ACPI.\n");
> +
> +	if (acpi_psci_use_hvc())
> +		invoke_psci_fn = __invoke_psci_fn_hvc;
> +	else
> +		invoke_psci_fn = __invoke_psci_fn_smc;
> +
> +	return 0;
> +}
> +
> +/* We use PSCI 0.2+ when ACPI is deployed */
> +static int psci_0_2_init_acpi(void)

May be this can be renamed psci_acpi_init and called from setup directly
instead of calling from DT function with acpi_disabled check.

> +{
> +	if (!acpi_psci_present()) {
> +		pr_info("is not implemented in ACPI.\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	get_set_conduit_method_acpi();
> +
> +	psci_0_2_set_functions();
> +
> +	return 0;
> +}
> +#else
> +static inline int psci_0_2_init_acpi(void)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
>   static const struct of_device_id psci_of_match[] __initconst = {
>   	{ .compatible = "arm,psci",	.data = psci_0_1_init},
>   	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
> @@ -345,6 +385,9 @@ int __init psci_init(void)
>   	const struct of_device_id *matched_np;
>   	psci_initcall_t init_fn;
>
> +	if (!acpi_disabled)
> +		return psci_0_2_init_acpi();
> +

As mentioned above you need not modify this.

>   	np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
>
>   	if (!np)
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 85c6326..dfc4e4f3 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>   	efi_idmap_init();
>
>   	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
> +	acpi_boot_init();
> +

Check for the return error here and disable ACPI once rather than at
multiple places all over.

>   	unflatten_device_tree();
>
>   	psci_init();
>

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
  2014-08-04 15:28   ` Hanjun Guo
  (?)
@ 2014-08-18 18:33     ` Sudeep Holla
  -1 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:33 UTC (permalink / raw)
  To: hanjun.guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel@lists.infradead.org



On 04/08/14 16:28, Hanjun Guo wrote:
> MADT contains the information for MPIDR which is essential for
> SMP initialization, parse the GIC cpu interface structures to
> get the MPIDR value and map it to cpu_logical_map(), and add
> enabled cpu with valid MPIDR into cpu_possible_map and
> cpu_present_map.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |    2 +
>   arch/arm64/kernel/acpi.c      |  129 ++++++++++++++++++++++++++++++++++++++++-
>   arch/arm64/kernel/smp.c       |   10 +++-
>   3 files changed, 138 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6e04868..e877967 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>   extern int (*acpi_suspend_lowlevel)(void);
>   #define acpi_wakeup_address 0
>
> +#define MAX_GIC_CPU_INTERFACE 65535
> +

Did you get this information from GIC specification ?

IIUC you are trying to represent max number of interrupt controller
entries MADT can possibly have. So, I had suggested to change the name
like MAX_MADT_INTERRUPT_CONTROLLER_ENTRIES so that it is not GIC specific.

>   #endif /* CONFIG_ACPI */
>
>   #endif /*_ASM_ACPI_H*/
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 69a315d..9e07d99 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -22,6 +22,9 @@
>   #include <linux/bootmem.h>
>   #include <linux/smp.h>
>
> +#include <asm/smp_plat.h>
> +#include <asm/cputype.h>
> +
>   int acpi_noirq;			/* skip ACPI IRQ initialization */
>   int acpi_disabled;
>   EXPORT_SYMBOL(acpi_disabled);
> @@ -29,6 +32,8 @@ 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 */
> +
>   /*
>    * __acpi_map_table() will be called before page_init(), so early_ioremap()
>    * or early_memremap() should be called here to for ACPI table mapping.
> @@ -49,6 +54,122 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>   	early_memunmap(map, size);
>   }
>
> +/**
> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
> + * generates a logical cpu number
> + * @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 the gic cpu interface
> + */
> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
> +{

IMO the function name gives me a wrong idea that you are registering
something with GIC. How about acpi_map_gic_cpu_interface ?

> +	int cpu;
> +
> +	if (mpidr == INVALID_HWID) {
> +		pr_info("Skip invalid cpu hardware ID\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;
> +	}
> +
> +	/* If it is the first CPU, no need to check duplicate MPIDRs */
> +	if (!enabled_cpus)
> +		goto skip_mpidr_check;
> +
> +	/*
> +	 * 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_present_cpu(cpu) {
> +		if (cpu_logical_map(cpu) == mpidr) {
> +			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
> +			       mpidr);
> +			return -EINVAL;
> +		}
> +	}
> +
> +skip_mpidr_check:
> +	enabled_cpus++;
> +
> +	/* allocate a logical cpu id for the new comer */
> +	if (cpu_logical_map(0) == mpidr) {
> +		/*
> +		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
> +		 * for BSP, no need to allocate again.
> +		 */
> +		cpu = 0;
> +	} else {
> +		cpu = cpumask_next_zero(-1, cpu_present_mask);
> +	}
> +
> +	/* map the logical cpu id to cpu MPIDR */
> +	cpu_logical_map(cpu) = mpidr;
> +
> +	set_cpu_possible(cpu, true);

IMO it better to keep all these updates to cpumasks contained in the
smp.c as I had mentioned before. I think you can refactor smp_init_cpus
to achieve that.

> +	set_cpu_present(cpu, true);

This is totally wrong ? What would you do if the cpu failed to
initialize ? I don't see that handled.

> +
> +	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_register_gic_cpu_interface(processor->arm_mpidr,
> +		processor->flags & ACPI_MADT_ENABLED);
> +
> +	return 0;
> +}
> +
> +/*
> + * Parse GIC cpu interface related entries in MADT
> + * returns 0 on success, < 0 on error
> + */
> +static int __init acpi_parse_madt_gic_cpu_interface_entries(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, MAX_GIC_CPU_INTERFACE);
> +
> +	if (!count) {
> +		pr_err("No GIC CPU interface entries present\n");
> +		return -ENODEV;
> +	} else if (count < 0) {
> +		pr_err("Error parsing GIC CPU interface entry\n");
> +		return count;
> +	}
> +
> +	/* Make boot-up look pretty */
> +	pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);

Ideally just setup cpu_logical_map in acpi_parse_gic_cpu_interface and
setup cpumasks in smp_init_cpus.

> +
> +	return 0;
> +}
> +
>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>   {
>   	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
> @@ -99,8 +220,12 @@ int __init acpi_boot_init(void)
>   		return -ENODEV;
>
>   	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
> -	if (err)
> -		pr_err("Can't find FADT\n");
> +	if (err) {
> +		pr_err("Can't find FADT or error happened during parsing FADT\n");
> +		return err;
> +	}
> +
> +	err = acpi_parse_madt_gic_cpu_interface_entries();
>
>   	return err;
>   }
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 40f38f4..8f1d37c 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -36,6 +36,7 @@
>   #include <linux/completion.h>
>   #include <linux/of.h>
>   #include <linux/irq_work.h>
> +#include <linux/acpi.h>
>
>   #include <asm/atomic.h>
>   #include <asm/cacheflush.h>
> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>   		if (err)
>   			continue;
>
> -		set_cpu_present(cpu, true);
> +		/*
> +		 * In ACPI mode, cpu_present_map was initialised when
> +		 * MADT table was parsed which before this function
> +		 * is called.
> +		 */
> +		if (acpi_disabled)
> +			set_cpu_present(cpu, true);
> +

This is the right place to set the cpu present based on the return value
of cpu_prepare.

>   		max_cpus--;
>   	}
>   }
>

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-18 18:33     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:33 UTC (permalink / raw)
  To: hanjun.guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Tomasz Nowicki



On 04/08/14 16:28, Hanjun Guo wrote:
> MADT contains the information for MPIDR which is essential for
> SMP initialization, parse the GIC cpu interface structures to
> get the MPIDR value and map it to cpu_logical_map(), and add
> enabled cpu with valid MPIDR into cpu_possible_map and
> cpu_present_map.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |    2 +
>   arch/arm64/kernel/acpi.c      |  129 ++++++++++++++++++++++++++++++++++++++++-
>   arch/arm64/kernel/smp.c       |   10 +++-
>   3 files changed, 138 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6e04868..e877967 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>   extern int (*acpi_suspend_lowlevel)(void);
>   #define acpi_wakeup_address 0
>
> +#define MAX_GIC_CPU_INTERFACE 65535
> +

Did you get this information from GIC specification ?

IIUC you are trying to represent max number of interrupt controller
entries MADT can possibly have. So, I had suggested to change the name
like MAX_MADT_INTERRUPT_CONTROLLER_ENTRIES so that it is not GIC specific.

>   #endif /* CONFIG_ACPI */
>
>   #endif /*_ASM_ACPI_H*/
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 69a315d..9e07d99 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -22,6 +22,9 @@
>   #include <linux/bootmem.h>
>   #include <linux/smp.h>
>
> +#include <asm/smp_plat.h>
> +#include <asm/cputype.h>
> +
>   int acpi_noirq;			/* skip ACPI IRQ initialization */
>   int acpi_disabled;
>   EXPORT_SYMBOL(acpi_disabled);
> @@ -29,6 +32,8 @@ 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 */
> +
>   /*
>    * __acpi_map_table() will be called before page_init(), so early_ioremap()
>    * or early_memremap() should be called here to for ACPI table mapping.
> @@ -49,6 +54,122 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>   	early_memunmap(map, size);
>   }
>
> +/**
> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
> + * generates a logical cpu number
> + * @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 the gic cpu interface
> + */
> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
> +{

IMO the function name gives me a wrong idea that you are registering
something with GIC. How about acpi_map_gic_cpu_interface ?

> +	int cpu;
> +
> +	if (mpidr == INVALID_HWID) {
> +		pr_info("Skip invalid cpu hardware ID\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;
> +	}
> +
> +	/* If it is the first CPU, no need to check duplicate MPIDRs */
> +	if (!enabled_cpus)
> +		goto skip_mpidr_check;
> +
> +	/*
> +	 * 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_present_cpu(cpu) {
> +		if (cpu_logical_map(cpu) == mpidr) {
> +			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
> +			       mpidr);
> +			return -EINVAL;
> +		}
> +	}
> +
> +skip_mpidr_check:
> +	enabled_cpus++;
> +
> +	/* allocate a logical cpu id for the new comer */
> +	if (cpu_logical_map(0) == mpidr) {
> +		/*
> +		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
> +		 * for BSP, no need to allocate again.
> +		 */
> +		cpu = 0;
> +	} else {
> +		cpu = cpumask_next_zero(-1, cpu_present_mask);
> +	}
> +
> +	/* map the logical cpu id to cpu MPIDR */
> +	cpu_logical_map(cpu) = mpidr;
> +
> +	set_cpu_possible(cpu, true);

IMO it better to keep all these updates to cpumasks contained in the
smp.c as I had mentioned before. I think you can refactor smp_init_cpus
to achieve that.

> +	set_cpu_present(cpu, true);

This is totally wrong ? What would you do if the cpu failed to
initialize ? I don't see that handled.

> +
> +	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_register_gic_cpu_interface(processor->arm_mpidr,
> +		processor->flags & ACPI_MADT_ENABLED);
> +
> +	return 0;
> +}
> +
> +/*
> + * Parse GIC cpu interface related entries in MADT
> + * returns 0 on success, < 0 on error
> + */
> +static int __init acpi_parse_madt_gic_cpu_interface_entries(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, MAX_GIC_CPU_INTERFACE);
> +
> +	if (!count) {
> +		pr_err("No GIC CPU interface entries present\n");
> +		return -ENODEV;
> +	} else if (count < 0) {
> +		pr_err("Error parsing GIC CPU interface entry\n");
> +		return count;
> +	}
> +
> +	/* Make boot-up look pretty */
> +	pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);

Ideally just setup cpu_logical_map in acpi_parse_gic_cpu_interface and
setup cpumasks in smp_init_cpus.

> +
> +	return 0;
> +}
> +
>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>   {
>   	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
> @@ -99,8 +220,12 @@ int __init acpi_boot_init(void)
>   		return -ENODEV;
>
>   	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
> -	if (err)
> -		pr_err("Can't find FADT\n");
> +	if (err) {
> +		pr_err("Can't find FADT or error happened during parsing FADT\n");
> +		return err;
> +	}
> +
> +	err = acpi_parse_madt_gic_cpu_interface_entries();
>
>   	return err;
>   }
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 40f38f4..8f1d37c 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -36,6 +36,7 @@
>   #include <linux/completion.h>
>   #include <linux/of.h>
>   #include <linux/irq_work.h>
> +#include <linux/acpi.h>
>
>   #include <asm/atomic.h>
>   #include <asm/cacheflush.h>
> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>   		if (err)
>   			continue;
>
> -		set_cpu_present(cpu, true);
> +		/*
> +		 * In ACPI mode, cpu_present_map was initialised when
> +		 * MADT table was parsed which before this function
> +		 * is called.
> +		 */
> +		if (acpi_disabled)
> +			set_cpu_present(cpu, true);
> +

This is the right place to set the cpu present based on the return value
of cpu_prepare.

>   		max_cpus--;
>   	}
>   }
>


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-18 18:33     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:33 UTC (permalink / raw)
  To: linux-arm-kernel



On 04/08/14 16:28, Hanjun Guo wrote:
> MADT contains the information for MPIDR which is essential for
> SMP initialization, parse the GIC cpu interface structures to
> get the MPIDR value and map it to cpu_logical_map(), and add
> enabled cpu with valid MPIDR into cpu_possible_map and
> cpu_present_map.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |    2 +
>   arch/arm64/kernel/acpi.c      |  129 ++++++++++++++++++++++++++++++++++++++++-
>   arch/arm64/kernel/smp.c       |   10 +++-
>   3 files changed, 138 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 6e04868..e877967 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>   extern int (*acpi_suspend_lowlevel)(void);
>   #define acpi_wakeup_address 0
>
> +#define MAX_GIC_CPU_INTERFACE 65535
> +

Did you get this information from GIC specification ?

IIUC you are trying to represent max number of interrupt controller
entries MADT can possibly have. So, I had suggested to change the name
like MAX_MADT_INTERRUPT_CONTROLLER_ENTRIES so that it is not GIC specific.

>   #endif /* CONFIG_ACPI */
>
>   #endif /*_ASM_ACPI_H*/
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 69a315d..9e07d99 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -22,6 +22,9 @@
>   #include <linux/bootmem.h>
>   #include <linux/smp.h>
>
> +#include <asm/smp_plat.h>
> +#include <asm/cputype.h>
> +
>   int acpi_noirq;			/* skip ACPI IRQ initialization */
>   int acpi_disabled;
>   EXPORT_SYMBOL(acpi_disabled);
> @@ -29,6 +32,8 @@ 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 */
> +
>   /*
>    * __acpi_map_table() will be called before page_init(), so early_ioremap()
>    * or early_memremap() should be called here to for ACPI table mapping.
> @@ -49,6 +54,122 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>   	early_memunmap(map, size);
>   }
>
> +/**
> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
> + * generates a logical cpu number
> + * @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 the gic cpu interface
> + */
> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
> +{

IMO the function name gives me a wrong idea that you are registering
something with GIC. How about acpi_map_gic_cpu_interface ?

> +	int cpu;
> +
> +	if (mpidr == INVALID_HWID) {
> +		pr_info("Skip invalid cpu hardware ID\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;
> +	}
> +
> +	/* If it is the first CPU, no need to check duplicate MPIDRs */
> +	if (!enabled_cpus)
> +		goto skip_mpidr_check;
> +
> +	/*
> +	 * 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_present_cpu(cpu) {
> +		if (cpu_logical_map(cpu) == mpidr) {
> +			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
> +			       mpidr);
> +			return -EINVAL;
> +		}
> +	}
> +
> +skip_mpidr_check:
> +	enabled_cpus++;
> +
> +	/* allocate a logical cpu id for the new comer */
> +	if (cpu_logical_map(0) == mpidr) {
> +		/*
> +		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
> +		 * for BSP, no need to allocate again.
> +		 */
> +		cpu = 0;
> +	} else {
> +		cpu = cpumask_next_zero(-1, cpu_present_mask);
> +	}
> +
> +	/* map the logical cpu id to cpu MPIDR */
> +	cpu_logical_map(cpu) = mpidr;
> +
> +	set_cpu_possible(cpu, true);

IMO it better to keep all these updates to cpumasks contained in the
smp.c as I had mentioned before. I think you can refactor smp_init_cpus
to achieve that.

> +	set_cpu_present(cpu, true);

This is totally wrong ? What would you do if the cpu failed to
initialize ? I don't see that handled.

> +
> +	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_register_gic_cpu_interface(processor->arm_mpidr,
> +		processor->flags & ACPI_MADT_ENABLED);
> +
> +	return 0;
> +}
> +
> +/*
> + * Parse GIC cpu interface related entries in MADT
> + * returns 0 on success, < 0 on error
> + */
> +static int __init acpi_parse_madt_gic_cpu_interface_entries(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, MAX_GIC_CPU_INTERFACE);
> +
> +	if (!count) {
> +		pr_err("No GIC CPU interface entries present\n");
> +		return -ENODEV;
> +	} else if (count < 0) {
> +		pr_err("Error parsing GIC CPU interface entry\n");
> +		return count;
> +	}
> +
> +	/* Make boot-up look pretty */
> +	pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);

Ideally just setup cpu_logical_map in acpi_parse_gic_cpu_interface and
setup cpumasks in smp_init_cpus.

> +
> +	return 0;
> +}
> +
>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>   {
>   	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
> @@ -99,8 +220,12 @@ int __init acpi_boot_init(void)
>   		return -ENODEV;
>
>   	err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
> -	if (err)
> -		pr_err("Can't find FADT\n");
> +	if (err) {
> +		pr_err("Can't find FADT or error happened during parsing FADT\n");
> +		return err;
> +	}
> +
> +	err = acpi_parse_madt_gic_cpu_interface_entries();
>
>   	return err;
>   }
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 40f38f4..8f1d37c 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -36,6 +36,7 @@
>   #include <linux/completion.h>
>   #include <linux/of.h>
>   #include <linux/irq_work.h>
> +#include <linux/acpi.h>
>
>   #include <asm/atomic.h>
>   #include <asm/cacheflush.h>
> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>   		if (err)
>   			continue;
>
> -		set_cpu_present(cpu, true);
> +		/*
> +		 * In ACPI mode, cpu_present_map was initialised when
> +		 * MADT table was parsed which before this function
> +		 * is called.
> +		 */
> +		if (acpi_disabled)
> +			set_cpu_present(cpu, true);
> +

This is the right place to set the cpu present based on the return value
of cpu_prepare.

>   		max_cpus--;
>   	}
>   }
>

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-04 15:28   ` Hanjun Guo
  (?)
@ 2014-08-18 18:34     ` Sudeep Holla
  -1 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:34 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel@lists.infradead.org



On 04/08/14 16:28, Hanjun Guo wrote:
> ACPI 5.1 only has two explicit methods to boot up SMP,
> PSCI and Parking protocol, but the Parking protocol is
> only suitable 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.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |   21 ++++++++++++++
>   arch/arm64/include/asm/smp.h  |    3 +-
>   arch/arm64/kernel/acpi.c      |    9 ++++++
>   arch/arm64/kernel/cpu_ops.c   |   62 ++++++++++++++++++++++++++++++++++++-----
>   arch/arm64/kernel/smp.c       |   27 +++++++++++++++++-
>   5 files changed, 113 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index e877967..022f4ad 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -14,6 +14,27 @@
>
>   /* Basic configuration for ACPI */
>   #ifdef	CONFIG_ACPI
> +/*
> + * ACPI 5.1 only has two explicit methods to
> + * boot up SMP, PSCI and Parking protocol,
> + * but the Parking protocol is only defined
> + * 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.
> + *
> + * This enum is intend to make the boot method
> + * scalable when above updates are happended,
> + * which NOT means to support all of them.
> + */
> +enum acpi_smp_boot_protocol {
> +	ACPI_SMP_BOOT_PSCI,
> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
> +	ACPI_SMP_BOOT_PROTOCOL_MAX
> +};
> +
> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
> +
>   #define acpi_strict 1	/* No out-of-spec workarounds on ARM64 */
>   extern int acpi_disabled;
>   extern int acpi_noirq;
> diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
> index a498f2c..282932c2 100644
> --- a/arch/arm64/include/asm/smp.h
> +++ b/arch/arm64/include/asm/smp.h
> @@ -39,7 +39,8 @@ extern void show_ipi_list(struct seq_file *p, int prec);
>   extern void handle_IPI(int ipinr, struct pt_regs *regs);
>
>   /*
> - * Setup the set of possible CPUs (via set_cpu_possible)
> + * Discover the set of possible CPUs and determine their
> + * SMP operations.
>    */
>   extern void smp_init_cpus(void);
>
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 9e07d99..8a54b4e 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -170,6 +170,15 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
>   	return 0;
>   }
>
> +/* Protocol to bring up secondary CPUs */
> +enum acpi_smp_boot_protocol smp_boot_protocol(void)
> +{
> +	if (acpi_psci_present())
> +		return ACPI_SMP_BOOT_PSCI;
> +	else
> +		return ACPI_SMP_BOOT_PARKING_PROTOCOL;
> +}
> +

Which do you need this here ? Can't you use acpi_psci_present directly
in acpi_get_cpu_boot_method ?

>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>   {
>   	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
> index d62d12f..05bc314 100644
> --- a/arch/arm64/kernel/cpu_ops.c
> +++ b/arch/arm64/kernel/cpu_ops.c
> @@ -16,11 +16,13 @@
>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>    */
>
> -#include <asm/cpu_ops.h>
> -#include <asm/smp_plat.h>
>   #include <linux/errno.h>
>   #include <linux/of.h>
>   #include <linux/string.h>
> +#include <linux/acpi.h>
> +
> +#include <asm/cpu_ops.h>
> +#include <asm/smp_plat.h>
>
>   extern const struct cpu_operations smp_spin_table_ops;
>   extern const struct cpu_operations cpu_psci_ops;
> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>   	return NULL;
>   }
>
> +#ifdef CONFIG_ACPI
> +/*
> + * Get a cpu's boot method in the ACPI way.
> + */
> +static char * __init acpi_get_cpu_boot_method(void)
> +{
> +	/*
> +	 * For ACPI 5.1, only two kind of methods are provided,
> +	 * Parking protocol and PSCI, but Parking protocol is
> +	 * specified for ARMv7 only, so make PSCI as the only method
> +	 * for SMP initialization before the ACPI spec or Parking
> +	 * protocol spec is updated.
> +	 */
> +	switch (smp_boot_protocol()) {
> +	case ACPI_SMP_BOOT_PSCI:
> +		return "psci";
> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> +	default:
> +		return NULL;
> +	}

Use acpi_psci_present as mentioned above.

> +}
> +#else
> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
> +#endif
> +
>   /*
> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
> + * Read a cpu's enable method and record it in cpu_ops.
>    */
>   int __init cpu_read_ops(struct device_node *dn, int cpu)
>   {
> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
> +	const char *enable_method;
> +
> +	if (!acpi_disabled) {
> +		enable_method = acpi_get_cpu_boot_method();
> +		goto get_ops;
> +	}
> +
> +	enable_method = of_get_property(dn, "enable-method", NULL);
>   	if (!enable_method) {
>   		/*
>   		 * The boot CPU may not have an enable method (e.g. when
> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>   		return -ENOENT;
>   	}
>
> +get_ops:
>   	cpu_ops[cpu] = cpu_get_ops(enable_method);
>   	if (!cpu_ops[cpu]) {
> -		pr_warn("%s: unsupported enable-method property: %s\n",
> -			dn->full_name, enable_method);
> +		if (acpi_disabled) {
> +			pr_warn("%s: unsupported enable-method property: %s\n",
> +				dn->full_name, enable_method);
> +		} else {
> +			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
> +				cpu);
> +		}
> +
>   		return -EOPNOTSUPP;
>   	}
>
> @@ -78,7 +119,14 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>
>   void __init cpu_read_bootcpu_ops(void)
>   {
> -	struct device_node *dn = of_get_cpu_node(0, NULL);
> +	struct device_node *dn;
> +
> +	if (!acpi_disabled) {
> +		cpu_read_ops(NULL, 0);
> +		return;
> +	}
> +

Again not good to mix ACPI in DT functions forcing you to pass
device_node ptr as NULL, better to separate this. Once you gather all
this !acpi_disabled case, you can create appropriate abstractions to be
used in setup.c

E.g. here you check !acpi_disabled and pass NULL for DT node to
cpu_read_ops and hence again you check for !acpi_disabled in
cpu_read_ops. So you need first identify all these checks and put in one
place to understand well how you can refactor existing code to avoid
these multiple checks.


> +	dn = of_get_cpu_node(0, NULL);
>   	if (!dn) {
>   		pr_err("Failed to find device node for boot cpu\n");
>   		return;
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 8f1d37c..e21bbc9 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -315,7 +315,7 @@ static void (*smp_cross_call)(const struct cpumask *, unsigned int);
>    * cpu logical map array containing MPIDR values related to logical
>    * cpus. Assumes that cpu_logical_map(0) has already been initialized.
>    */
> -void __init smp_init_cpus(void)
> +static void __init of_smp_init_cpus(void)
>   {
>   	struct device_node *dn = NULL;
>   	unsigned int i, cpu = 1;
> @@ -418,6 +418,31 @@ next:
>   			set_cpu_possible(i, true);
>   }
>
> +/*
> + * In ACPI mode, the cpu possible map was enumerated before SMP
> + * initialization when MADT table was parsed, so we can get the
> + * possible map here to initialize CPUs.
> + */
> +static void __init acpi_smp_init_cpus(void)
> +{
> +	int cpu;
> +
> +	for_each_possible_cpu(cpu) {
> +		if (cpu_read_ops(NULL, cpu) != 0)
> +			continue;
> +
> +		cpu_ops[cpu]->cpu_init(NULL, cpu);
> +	}
> +}
> +
> +void __init smp_init_cpus(void)
> +{
> +	if (acpi_disabled)
> +		of_smp_init_cpus();
> +	else
> +		acpi_smp_init_cpus();
> +}
> +
>   void __init smp_prepare_cpus(unsigned int max_cpus)
>   {
>   	int err;
>


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-18 18:34     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:34 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Tomasz Nowicki



On 04/08/14 16:28, Hanjun Guo wrote:
> ACPI 5.1 only has two explicit methods to boot up SMP,
> PSCI and Parking protocol, but the Parking protocol is
> only suitable 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.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |   21 ++++++++++++++
>   arch/arm64/include/asm/smp.h  |    3 +-
>   arch/arm64/kernel/acpi.c      |    9 ++++++
>   arch/arm64/kernel/cpu_ops.c   |   62 ++++++++++++++++++++++++++++++++++++-----
>   arch/arm64/kernel/smp.c       |   27 +++++++++++++++++-
>   5 files changed, 113 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index e877967..022f4ad 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -14,6 +14,27 @@
>
>   /* Basic configuration for ACPI */
>   #ifdef	CONFIG_ACPI
> +/*
> + * ACPI 5.1 only has two explicit methods to
> + * boot up SMP, PSCI and Parking protocol,
> + * but the Parking protocol is only defined
> + * 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.
> + *
> + * This enum is intend to make the boot method
> + * scalable when above updates are happended,
> + * which NOT means to support all of them.
> + */
> +enum acpi_smp_boot_protocol {
> +	ACPI_SMP_BOOT_PSCI,
> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
> +	ACPI_SMP_BOOT_PROTOCOL_MAX
> +};
> +
> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
> +
>   #define acpi_strict 1	/* No out-of-spec workarounds on ARM64 */
>   extern int acpi_disabled;
>   extern int acpi_noirq;
> diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
> index a498f2c..282932c2 100644
> --- a/arch/arm64/include/asm/smp.h
> +++ b/arch/arm64/include/asm/smp.h
> @@ -39,7 +39,8 @@ extern void show_ipi_list(struct seq_file *p, int prec);
>   extern void handle_IPI(int ipinr, struct pt_regs *regs);
>
>   /*
> - * Setup the set of possible CPUs (via set_cpu_possible)
> + * Discover the set of possible CPUs and determine their
> + * SMP operations.
>    */
>   extern void smp_init_cpus(void);
>
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 9e07d99..8a54b4e 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -170,6 +170,15 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
>   	return 0;
>   }
>
> +/* Protocol to bring up secondary CPUs */
> +enum acpi_smp_boot_protocol smp_boot_protocol(void)
> +{
> +	if (acpi_psci_present())
> +		return ACPI_SMP_BOOT_PSCI;
> +	else
> +		return ACPI_SMP_BOOT_PARKING_PROTOCOL;
> +}
> +

Which do you need this here ? Can't you use acpi_psci_present directly
in acpi_get_cpu_boot_method ?

>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>   {
>   	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
> index d62d12f..05bc314 100644
> --- a/arch/arm64/kernel/cpu_ops.c
> +++ b/arch/arm64/kernel/cpu_ops.c
> @@ -16,11 +16,13 @@
>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>    */
>
> -#include <asm/cpu_ops.h>
> -#include <asm/smp_plat.h>
>   #include <linux/errno.h>
>   #include <linux/of.h>
>   #include <linux/string.h>
> +#include <linux/acpi.h>
> +
> +#include <asm/cpu_ops.h>
> +#include <asm/smp_plat.h>
>
>   extern const struct cpu_operations smp_spin_table_ops;
>   extern const struct cpu_operations cpu_psci_ops;
> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>   	return NULL;
>   }
>
> +#ifdef CONFIG_ACPI
> +/*
> + * Get a cpu's boot method in the ACPI way.
> + */
> +static char * __init acpi_get_cpu_boot_method(void)
> +{
> +	/*
> +	 * For ACPI 5.1, only two kind of methods are provided,
> +	 * Parking protocol and PSCI, but Parking protocol is
> +	 * specified for ARMv7 only, so make PSCI as the only method
> +	 * for SMP initialization before the ACPI spec or Parking
> +	 * protocol spec is updated.
> +	 */
> +	switch (smp_boot_protocol()) {
> +	case ACPI_SMP_BOOT_PSCI:
> +		return "psci";
> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> +	default:
> +		return NULL;
> +	}

Use acpi_psci_present as mentioned above.

> +}
> +#else
> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
> +#endif
> +
>   /*
> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
> + * Read a cpu's enable method and record it in cpu_ops.
>    */
>   int __init cpu_read_ops(struct device_node *dn, int cpu)
>   {
> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
> +	const char *enable_method;
> +
> +	if (!acpi_disabled) {
> +		enable_method = acpi_get_cpu_boot_method();
> +		goto get_ops;
> +	}
> +
> +	enable_method = of_get_property(dn, "enable-method", NULL);
>   	if (!enable_method) {
>   		/*
>   		 * The boot CPU may not have an enable method (e.g. when
> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>   		return -ENOENT;
>   	}
>
> +get_ops:
>   	cpu_ops[cpu] = cpu_get_ops(enable_method);
>   	if (!cpu_ops[cpu]) {
> -		pr_warn("%s: unsupported enable-method property: %s\n",
> -			dn->full_name, enable_method);
> +		if (acpi_disabled) {
> +			pr_warn("%s: unsupported enable-method property: %s\n",
> +				dn->full_name, enable_method);
> +		} else {
> +			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
> +				cpu);
> +		}
> +
>   		return -EOPNOTSUPP;
>   	}
>
> @@ -78,7 +119,14 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>
>   void __init cpu_read_bootcpu_ops(void)
>   {
> -	struct device_node *dn = of_get_cpu_node(0, NULL);
> +	struct device_node *dn;
> +
> +	if (!acpi_disabled) {
> +		cpu_read_ops(NULL, 0);
> +		return;
> +	}
> +

Again not good to mix ACPI in DT functions forcing you to pass
device_node ptr as NULL, better to separate this. Once you gather all
this !acpi_disabled case, you can create appropriate abstractions to be
used in setup.c

E.g. here you check !acpi_disabled and pass NULL for DT node to
cpu_read_ops and hence again you check for !acpi_disabled in
cpu_read_ops. So you need first identify all these checks and put in one
place to understand well how you can refactor existing code to avoid
these multiple checks.


> +	dn = of_get_cpu_node(0, NULL);
>   	if (!dn) {
>   		pr_err("Failed to find device node for boot cpu\n");
>   		return;
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 8f1d37c..e21bbc9 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -315,7 +315,7 @@ static void (*smp_cross_call)(const struct cpumask *, unsigned int);
>    * cpu logical map array containing MPIDR values related to logical
>    * cpus. Assumes that cpu_logical_map(0) has already been initialized.
>    */
> -void __init smp_init_cpus(void)
> +static void __init of_smp_init_cpus(void)
>   {
>   	struct device_node *dn = NULL;
>   	unsigned int i, cpu = 1;
> @@ -418,6 +418,31 @@ next:
>   			set_cpu_possible(i, true);
>   }
>
> +/*
> + * In ACPI mode, the cpu possible map was enumerated before SMP
> + * initialization when MADT table was parsed, so we can get the
> + * possible map here to initialize CPUs.
> + */
> +static void __init acpi_smp_init_cpus(void)
> +{
> +	int cpu;
> +
> +	for_each_possible_cpu(cpu) {
> +		if (cpu_read_ops(NULL, cpu) != 0)
> +			continue;
> +
> +		cpu_ops[cpu]->cpu_init(NULL, cpu);
> +	}
> +}
> +
> +void __init smp_init_cpus(void)
> +{
> +	if (acpi_disabled)
> +		of_smp_init_cpus();
> +	else
> +		acpi_smp_init_cpus();
> +}
> +
>   void __init smp_prepare_cpus(unsigned int max_cpus)
>   {
>   	int err;
>


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-18 18:34     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:34 UTC (permalink / raw)
  To: linux-arm-kernel



On 04/08/14 16:28, Hanjun Guo wrote:
> ACPI 5.1 only has two explicit methods to boot up SMP,
> PSCI and Parking protocol, but the Parking protocol is
> only suitable 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.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |   21 ++++++++++++++
>   arch/arm64/include/asm/smp.h  |    3 +-
>   arch/arm64/kernel/acpi.c      |    9 ++++++
>   arch/arm64/kernel/cpu_ops.c   |   62 ++++++++++++++++++++++++++++++++++++-----
>   arch/arm64/kernel/smp.c       |   27 +++++++++++++++++-
>   5 files changed, 113 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index e877967..022f4ad 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -14,6 +14,27 @@
>
>   /* Basic configuration for ACPI */
>   #ifdef	CONFIG_ACPI
> +/*
> + * ACPI 5.1 only has two explicit methods to
> + * boot up SMP, PSCI and Parking protocol,
> + * but the Parking protocol is only defined
> + * 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.
> + *
> + * This enum is intend to make the boot method
> + * scalable when above updates are happended,
> + * which NOT means to support all of them.
> + */
> +enum acpi_smp_boot_protocol {
> +	ACPI_SMP_BOOT_PSCI,
> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
> +	ACPI_SMP_BOOT_PROTOCOL_MAX
> +};
> +
> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
> +
>   #define acpi_strict 1	/* No out-of-spec workarounds on ARM64 */
>   extern int acpi_disabled;
>   extern int acpi_noirq;
> diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
> index a498f2c..282932c2 100644
> --- a/arch/arm64/include/asm/smp.h
> +++ b/arch/arm64/include/asm/smp.h
> @@ -39,7 +39,8 @@ extern void show_ipi_list(struct seq_file *p, int prec);
>   extern void handle_IPI(int ipinr, struct pt_regs *regs);
>
>   /*
> - * Setup the set of possible CPUs (via set_cpu_possible)
> + * Discover the set of possible CPUs and determine their
> + * SMP operations.
>    */
>   extern void smp_init_cpus(void);
>
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 9e07d99..8a54b4e 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -170,6 +170,15 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
>   	return 0;
>   }
>
> +/* Protocol to bring up secondary CPUs */
> +enum acpi_smp_boot_protocol smp_boot_protocol(void)
> +{
> +	if (acpi_psci_present())
> +		return ACPI_SMP_BOOT_PSCI;
> +	else
> +		return ACPI_SMP_BOOT_PARKING_PROTOCOL;
> +}
> +

Which do you need this here ? Can't you use acpi_psci_present directly
in acpi_get_cpu_boot_method ?

>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>   {
>   	struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
> index d62d12f..05bc314 100644
> --- a/arch/arm64/kernel/cpu_ops.c
> +++ b/arch/arm64/kernel/cpu_ops.c
> @@ -16,11 +16,13 @@
>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>    */
>
> -#include <asm/cpu_ops.h>
> -#include <asm/smp_plat.h>
>   #include <linux/errno.h>
>   #include <linux/of.h>
>   #include <linux/string.h>
> +#include <linux/acpi.h>
> +
> +#include <asm/cpu_ops.h>
> +#include <asm/smp_plat.h>
>
>   extern const struct cpu_operations smp_spin_table_ops;
>   extern const struct cpu_operations cpu_psci_ops;
> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>   	return NULL;
>   }
>
> +#ifdef CONFIG_ACPI
> +/*
> + * Get a cpu's boot method in the ACPI way.
> + */
> +static char * __init acpi_get_cpu_boot_method(void)
> +{
> +	/*
> +	 * For ACPI 5.1, only two kind of methods are provided,
> +	 * Parking protocol and PSCI, but Parking protocol is
> +	 * specified for ARMv7 only, so make PSCI as the only method
> +	 * for SMP initialization before the ACPI spec or Parking
> +	 * protocol spec is updated.
> +	 */
> +	switch (smp_boot_protocol()) {
> +	case ACPI_SMP_BOOT_PSCI:
> +		return "psci";
> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> +	default:
> +		return NULL;
> +	}

Use acpi_psci_present as mentioned above.

> +}
> +#else
> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
> +#endif
> +
>   /*
> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
> + * Read a cpu's enable method and record it in cpu_ops.
>    */
>   int __init cpu_read_ops(struct device_node *dn, int cpu)
>   {
> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
> +	const char *enable_method;
> +
> +	if (!acpi_disabled) {
> +		enable_method = acpi_get_cpu_boot_method();
> +		goto get_ops;
> +	}
> +
> +	enable_method = of_get_property(dn, "enable-method", NULL);
>   	if (!enable_method) {
>   		/*
>   		 * The boot CPU may not have an enable method (e.g. when
> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>   		return -ENOENT;
>   	}
>
> +get_ops:
>   	cpu_ops[cpu] = cpu_get_ops(enable_method);
>   	if (!cpu_ops[cpu]) {
> -		pr_warn("%s: unsupported enable-method property: %s\n",
> -			dn->full_name, enable_method);
> +		if (acpi_disabled) {
> +			pr_warn("%s: unsupported enable-method property: %s\n",
> +				dn->full_name, enable_method);
> +		} else {
> +			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
> +				cpu);
> +		}
> +
>   		return -EOPNOTSUPP;
>   	}
>
> @@ -78,7 +119,14 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>
>   void __init cpu_read_bootcpu_ops(void)
>   {
> -	struct device_node *dn = of_get_cpu_node(0, NULL);
> +	struct device_node *dn;
> +
> +	if (!acpi_disabled) {
> +		cpu_read_ops(NULL, 0);
> +		return;
> +	}
> +

Again not good to mix ACPI in DT functions forcing you to pass
device_node ptr as NULL, better to separate this. Once you gather all
this !acpi_disabled case, you can create appropriate abstractions to be
used in setup.c

E.g. here you check !acpi_disabled and pass NULL for DT node to
cpu_read_ops and hence again you check for !acpi_disabled in
cpu_read_ops. So you need first identify all these checks and put in one
place to understand well how you can refactor existing code to avoid
these multiple checks.


> +	dn = of_get_cpu_node(0, NULL);
>   	if (!dn) {
>   		pr_err("Failed to find device node for boot cpu\n");
>   		return;
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 8f1d37c..e21bbc9 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -315,7 +315,7 @@ static void (*smp_cross_call)(const struct cpumask *, unsigned int);
>    * cpu logical map array containing MPIDR values related to logical
>    * cpus. Assumes that cpu_logical_map(0) has already been initialized.
>    */
> -void __init smp_init_cpus(void)
> +static void __init of_smp_init_cpus(void)
>   {
>   	struct device_node *dn = NULL;
>   	unsigned int i, cpu = 1;
> @@ -418,6 +418,31 @@ next:
>   			set_cpu_possible(i, true);
>   }
>
> +/*
> + * In ACPI mode, the cpu possible map was enumerated before SMP
> + * initialization when MADT table was parsed, so we can get the
> + * possible map here to initialize CPUs.
> + */
> +static void __init acpi_smp_init_cpus(void)
> +{
> +	int cpu;
> +
> +	for_each_possible_cpu(cpu) {
> +		if (cpu_read_ops(NULL, cpu) != 0)
> +			continue;
> +
> +		cpu_ops[cpu]->cpu_init(NULL, cpu);
> +	}
> +}
> +
> +void __init smp_init_cpus(void)
> +{
> +	if (acpi_disabled)
> +		of_smp_init_cpus();
> +	else
> +		acpi_smp_init_cpus();
> +}
> +
>   void __init smp_prepare_cpus(unsigned int max_cpus)
>   {
>   	int err;
>

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
  2014-08-04 15:28   ` Hanjun Guo
  (?)
@ 2014-08-18 18:34     ` Sudeep Holla
  -1 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:34 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel@lists.infradead.org



On 04/08/14 16:28, Hanjun Guo wrote:
> Introduce a new function map_gicc_mpidr() to allow MPIDRs to be obtained
> from the GICC Structure introduced by ACPI 5.1.
>
> MPIDR is the CPU hardware ID as local APIC ID on x86 platform, so we use
> MPIDR not the GIC CPU interface ID to identify CPUs.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |   14 ++++++++++++++
>   arch/arm64/kernel/acpi.c      |   21 ++++++++++++++++++++-
>   drivers/acpi/processor_core.c |   37 +++++++++++++++++++++++++++++++++++++
>   3 files changed, 71 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 022f4ad..a81898d 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -12,6 +12,8 @@
>   #ifndef _ASM_ACPI_H
>   #define _ASM_ACPI_H
>
> +#include <asm/smp_plat.h>
> +
>   /* Basic configuration for ACPI */
>   #ifdef	CONFIG_ACPI
>   /*
> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>   	acpi_noirq = 1;
>   }
>
> +u32 pack_mpidr_into_32_bits(u64 mpidr);
> +
> +/*
> + * The ACPI processor driver for ACPI core code needs this macro
> + * to find out this cpu was already mapped (mapping from CPU hardware
> + * ID to CPU logical ID) or not.
> + *
> + * cpu_logical_map(cpu) is the mapping of MPIDR and the logical cpu,
> + * and MPIDR is the cpu hardware ID we needed.

You need to specify this is packed version of cpu_logical_map or
better is to move pack_mpidr_into_32_bits here along with the
description you have so that it's easy to understand.

> + */
> +#define cpu_physical_id(cpu) pack_mpidr_into_32_bits(cpu_logical_map(cpu))
> +
>   /*
>    * Checking for the posibility that the CPU can be initialized from the MADT.
>    * It's used from ACPI core in crash kernel case where boot CPU is not
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 8a54b4e..ac7ab34 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -22,7 +22,6 @@
>   #include <linux/bootmem.h>
>   #include <linux/smp.h>
>
> -#include <asm/smp_plat.h>
>   #include <asm/cputype.h>
>
>   int acpi_noirq;			/* skip ACPI IRQ initialization */
> @@ -239,6 +238,26 @@ int __init acpi_boot_init(void)
>   	return err;
>   }
>
> +/* MPIDR value provided in GICC structure is 64 bits, but
> + * the acpi processor driver use the 32 bits cpu hardware
> + * ID (apic_id on intel platform) everywhere, it is pretty
> + * hard to modify the acpi processor driver to accept the
> + * 64 bits MPIDR value, at the same time, only 32 bits of
> + * the MPIDR is used in the 64 bits MPIDR, just pack the
> + * Affx fields into a single 32 bit identifier to accommodate
> + * the acpi processor drivers.
> + */
> +u32 pack_mpidr_into_32_bits(u64 mpidr)
> +{
> +	/*
> +	 * Bits [0:7] Aff0;
> +	 * Bits [8:15] Aff1;
> +	 * Bits [16:23] Aff2;
> +	 * Bits [32:39] Aff3;
> +	 */
> +	return (u32) ((mpidr & 0xff00000000) >> 8) | mpidr;
> +}
> +
>   /*
>    * acpi_suspend_lowlevel() - save kernel state and suspend.
>    *
> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
> index e32321c..4007313 100644
> --- a/drivers/acpi/processor_core.c
> +++ b/drivers/acpi/processor_core.c
> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>   	return 0;
>   }
>
> +/*
> + * On ARM platform, MPIDR value is the hardware ID as apic ID
> + * on Intel platforms
> + */
> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
> +		int device_declaration, u32 acpi_id, int *mpidr)
> +{
> +	struct acpi_madt_generic_interrupt *gicc =
> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
> +
> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
> +		return -ENODEV;
> +
> +	/* In the GIC interrupt model, logical processors are
> +	 * required to have a Processor Device object in the DSDT,
> +	 * so we should check device_declaration here
> +	 */
> +	if (device_declaration && (gicc->uid == acpi_id)) {
> +		/*
> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
> +		 * fields into a single 32 bit identifier to accommodate the
> +		 * acpi processor drivers.
> +		 */
> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
> +			 | gicc->arm_mpidr;

Reuse pack_mpidr_into_32_bits

> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>   static int map_madt_entry(int type, u32 acpi_id)
>   {
>   	unsigned long madt_end, entry;
> @@ -99,6 +131,9 @@ static int map_madt_entry(int type, u32 acpi_id)
>   		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
>   			if (!map_lsapic_id(header, type, acpi_id, &apic_id))
>   				break;
> +		} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
> +			if (!map_gicc_mpidr(header, type, acpi_id, &apic_id))
> +				break;
>   		}
>   		entry += header->length;
>   	}
> @@ -131,6 +166,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
>   		map_lsapic_id(header, type, acpi_id, &apic_id);
>   	} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
>   		map_x2apic_id(header, type, acpi_id, &apic_id);
> +	} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
> +		map_gicc_mpidr(header, type, acpi_id, &apic_id);
>   	}
>
>   exit:
>


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-18 18:34     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:34 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi



On 04/08/14 16:28, Hanjun Guo wrote:
> Introduce a new function map_gicc_mpidr() to allow MPIDRs to be obtained
> from the GICC Structure introduced by ACPI 5.1.
>
> MPIDR is the CPU hardware ID as local APIC ID on x86 platform, so we use
> MPIDR not the GIC CPU interface ID to identify CPUs.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |   14 ++++++++++++++
>   arch/arm64/kernel/acpi.c      |   21 ++++++++++++++++++++-
>   drivers/acpi/processor_core.c |   37 +++++++++++++++++++++++++++++++++++++
>   3 files changed, 71 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 022f4ad..a81898d 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -12,6 +12,8 @@
>   #ifndef _ASM_ACPI_H
>   #define _ASM_ACPI_H
>
> +#include <asm/smp_plat.h>
> +
>   /* Basic configuration for ACPI */
>   #ifdef	CONFIG_ACPI
>   /*
> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>   	acpi_noirq = 1;
>   }
>
> +u32 pack_mpidr_into_32_bits(u64 mpidr);
> +
> +/*
> + * The ACPI processor driver for ACPI core code needs this macro
> + * to find out this cpu was already mapped (mapping from CPU hardware
> + * ID to CPU logical ID) or not.
> + *
> + * cpu_logical_map(cpu) is the mapping of MPIDR and the logical cpu,
> + * and MPIDR is the cpu hardware ID we needed.

You need to specify this is packed version of cpu_logical_map or
better is to move pack_mpidr_into_32_bits here along with the
description you have so that it's easy to understand.

> + */
> +#define cpu_physical_id(cpu) pack_mpidr_into_32_bits(cpu_logical_map(cpu))
> +
>   /*
>    * Checking for the posibility that the CPU can be initialized from the MADT.
>    * It's used from ACPI core in crash kernel case where boot CPU is not
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 8a54b4e..ac7ab34 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -22,7 +22,6 @@
>   #include <linux/bootmem.h>
>   #include <linux/smp.h>
>
> -#include <asm/smp_plat.h>
>   #include <asm/cputype.h>
>
>   int acpi_noirq;			/* skip ACPI IRQ initialization */
> @@ -239,6 +238,26 @@ int __init acpi_boot_init(void)
>   	return err;
>   }
>
> +/* MPIDR value provided in GICC structure is 64 bits, but
> + * the acpi processor driver use the 32 bits cpu hardware
> + * ID (apic_id on intel platform) everywhere, it is pretty
> + * hard to modify the acpi processor driver to accept the
> + * 64 bits MPIDR value, at the same time, only 32 bits of
> + * the MPIDR is used in the 64 bits MPIDR, just pack the
> + * Affx fields into a single 32 bit identifier to accommodate
> + * the acpi processor drivers.
> + */
> +u32 pack_mpidr_into_32_bits(u64 mpidr)
> +{
> +	/*
> +	 * Bits [0:7] Aff0;
> +	 * Bits [8:15] Aff1;
> +	 * Bits [16:23] Aff2;
> +	 * Bits [32:39] Aff3;
> +	 */
> +	return (u32) ((mpidr & 0xff00000000) >> 8) | mpidr;
> +}
> +
>   /*
>    * acpi_suspend_lowlevel() - save kernel state and suspend.
>    *
> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
> index e32321c..4007313 100644
> --- a/drivers/acpi/processor_core.c
> +++ b/drivers/acpi/processor_core.c
> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>   	return 0;
>   }
>
> +/*
> + * On ARM platform, MPIDR value is the hardware ID as apic ID
> + * on Intel platforms
> + */
> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
> +		int device_declaration, u32 acpi_id, int *mpidr)
> +{
> +	struct acpi_madt_generic_interrupt *gicc =
> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
> +
> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
> +		return -ENODEV;
> +
> +	/* In the GIC interrupt model, logical processors are
> +	 * required to have a Processor Device object in the DSDT,
> +	 * so we should check device_declaration here
> +	 */
> +	if (device_declaration && (gicc->uid == acpi_id)) {
> +		/*
> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
> +		 * fields into a single 32 bit identifier to accommodate the
> +		 * acpi processor drivers.
> +		 */
> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
> +			 | gicc->arm_mpidr;

Reuse pack_mpidr_into_32_bits

> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>   static int map_madt_entry(int type, u32 acpi_id)
>   {
>   	unsigned long madt_end, entry;
> @@ -99,6 +131,9 @@ static int map_madt_entry(int type, u32 acpi_id)
>   		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
>   			if (!map_lsapic_id(header, type, acpi_id, &apic_id))
>   				break;
> +		} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
> +			if (!map_gicc_mpidr(header, type, acpi_id, &apic_id))
> +				break;
>   		}
>   		entry += header->length;
>   	}
> @@ -131,6 +166,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
>   		map_lsapic_id(header, type, acpi_id, &apic_id);
>   	} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
>   		map_x2apic_id(header, type, acpi_id, &apic_id);
> +	} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
> +		map_gicc_mpidr(header, type, acpi_id, &apic_id);
>   	}
>
>   exit:
>


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-18 18:34     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:34 UTC (permalink / raw)
  To: linux-arm-kernel



On 04/08/14 16:28, Hanjun Guo wrote:
> Introduce a new function map_gicc_mpidr() to allow MPIDRs to be obtained
> from the GICC Structure introduced by ACPI 5.1.
>
> MPIDR is the CPU hardware ID as local APIC ID on x86 platform, so we use
> MPIDR not the GIC CPU interface ID to identify CPUs.
>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   arch/arm64/include/asm/acpi.h |   14 ++++++++++++++
>   arch/arm64/kernel/acpi.c      |   21 ++++++++++++++++++++-
>   drivers/acpi/processor_core.c |   37 +++++++++++++++++++++++++++++++++++++
>   3 files changed, 71 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 022f4ad..a81898d 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -12,6 +12,8 @@
>   #ifndef _ASM_ACPI_H
>   #define _ASM_ACPI_H
>
> +#include <asm/smp_plat.h>
> +
>   /* Basic configuration for ACPI */
>   #ifdef	CONFIG_ACPI
>   /*
> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>   	acpi_noirq = 1;
>   }
>
> +u32 pack_mpidr_into_32_bits(u64 mpidr);
> +
> +/*
> + * The ACPI processor driver for ACPI core code needs this macro
> + * to find out this cpu was already mapped (mapping from CPU hardware
> + * ID to CPU logical ID) or not.
> + *
> + * cpu_logical_map(cpu) is the mapping of MPIDR and the logical cpu,
> + * and MPIDR is the cpu hardware ID we needed.

You need to specify this is packed version of cpu_logical_map or
better is to move pack_mpidr_into_32_bits here along with the
description you have so that it's easy to understand.

> + */
> +#define cpu_physical_id(cpu) pack_mpidr_into_32_bits(cpu_logical_map(cpu))
> +
>   /*
>    * Checking for the posibility that the CPU can be initialized from the MADT.
>    * It's used from ACPI core in crash kernel case where boot CPU is not
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 8a54b4e..ac7ab34 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -22,7 +22,6 @@
>   #include <linux/bootmem.h>
>   #include <linux/smp.h>
>
> -#include <asm/smp_plat.h>
>   #include <asm/cputype.h>
>
>   int acpi_noirq;			/* skip ACPI IRQ initialization */
> @@ -239,6 +238,26 @@ int __init acpi_boot_init(void)
>   	return err;
>   }
>
> +/* MPIDR value provided in GICC structure is 64 bits, but
> + * the acpi processor driver use the 32 bits cpu hardware
> + * ID (apic_id on intel platform) everywhere, it is pretty
> + * hard to modify the acpi processor driver to accept the
> + * 64 bits MPIDR value, at the same time, only 32 bits of
> + * the MPIDR is used in the 64 bits MPIDR, just pack the
> + * Affx fields into a single 32 bit identifier to accommodate
> + * the acpi processor drivers.
> + */
> +u32 pack_mpidr_into_32_bits(u64 mpidr)
> +{
> +	/*
> +	 * Bits [0:7] Aff0;
> +	 * Bits [8:15] Aff1;
> +	 * Bits [16:23] Aff2;
> +	 * Bits [32:39] Aff3;
> +	 */
> +	return (u32) ((mpidr & 0xff00000000) >> 8) | mpidr;
> +}
> +
>   /*
>    * acpi_suspend_lowlevel() - save kernel state and suspend.
>    *
> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
> index e32321c..4007313 100644
> --- a/drivers/acpi/processor_core.c
> +++ b/drivers/acpi/processor_core.c
> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>   	return 0;
>   }
>
> +/*
> + * On ARM platform, MPIDR value is the hardware ID as apic ID
> + * on Intel platforms
> + */
> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
> +		int device_declaration, u32 acpi_id, int *mpidr)
> +{
> +	struct acpi_madt_generic_interrupt *gicc =
> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
> +
> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
> +		return -ENODEV;
> +
> +	/* In the GIC interrupt model, logical processors are
> +	 * required to have a Processor Device object in the DSDT,
> +	 * so we should check device_declaration here
> +	 */
> +	if (device_declaration && (gicc->uid == acpi_id)) {
> +		/*
> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
> +		 * fields into a single 32 bit identifier to accommodate the
> +		 * acpi processor drivers.
> +		 */
> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
> +			 | gicc->arm_mpidr;

Reuse pack_mpidr_into_32_bits

> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>   static int map_madt_entry(int type, u32 acpi_id)
>   {
>   	unsigned long madt_end, entry;
> @@ -99,6 +131,9 @@ static int map_madt_entry(int type, u32 acpi_id)
>   		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
>   			if (!map_lsapic_id(header, type, acpi_id, &apic_id))
>   				break;
> +		} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
> +			if (!map_gicc_mpidr(header, type, acpi_id, &apic_id))
> +				break;
>   		}
>   		entry += header->length;
>   	}
> @@ -131,6 +166,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
>   		map_lsapic_id(header, type, acpi_id, &apic_id);
>   	} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
>   		map_x2apic_id(header, type, acpi_id, &apic_id);
> +	} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
> +		map_gicc_mpidr(header, type, acpi_id, &apic_id);
>   	}
>
>   exit:
>

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 10/18] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
  2014-08-04 15:28   ` Hanjun Guo
  (?)
@ 2014-08-18 18:34     ` Sudeep Holla
  -1 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:34 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel@lists.infradead.org



On 04/08/14 16:28, Hanjun Guo wrote:
> Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
> used, and then register device's gsi with the core IRQ subsystem.
>
> acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
> since gsi is unique in the system, so use hwirq number directly
> for the mapping.
>
> Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   arch/arm64/kernel/acpi.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++
>   drivers/acpi/bus.c       |    3 ++
>   include/linux/acpi.h     |    1 +
>   3 files changed, 77 insertions(+)
>
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index ac7ab34..621ced8 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -34,6 +34,12 @@ 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.
>    */
> @@ -169,6 +175,73 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
>   	return 0;
>   }
>
> +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);
> +

Not sure if acpi_gsi_to_irq and acpi_{,un}register_gsi belong here.
These are GIC specific and should belong to GIC driver IMO.

Regards,
Sudeep


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 10/18] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
@ 2014-08-18 18:34     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:34 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi



On 04/08/14 16:28, Hanjun Guo wrote:
> Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
> used, and then register device's gsi with the core IRQ subsystem.
>
> acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
> since gsi is unique in the system, so use hwirq number directly
> for the mapping.
>
> Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   arch/arm64/kernel/acpi.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++
>   drivers/acpi/bus.c       |    3 ++
>   include/linux/acpi.h     |    1 +
>   3 files changed, 77 insertions(+)
>
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index ac7ab34..621ced8 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -34,6 +34,12 @@ 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.
>    */
> @@ -169,6 +175,73 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
>   	return 0;
>   }
>
> +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);
> +

Not sure if acpi_gsi_to_irq and acpi_{,un}register_gsi belong here.
These are GIC specific and should belong to GIC driver IMO.

Regards,
Sudeep


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 10/18] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
@ 2014-08-18 18:34     ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-18 18:34 UTC (permalink / raw)
  To: linux-arm-kernel



On 04/08/14 16:28, Hanjun Guo wrote:
> Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
> used, and then register device's gsi with the core IRQ subsystem.
>
> acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
> since gsi is unique in the system, so use hwirq number directly
> for the mapping.
>
> Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>   arch/arm64/kernel/acpi.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++
>   drivers/acpi/bus.c       |    3 ++
>   include/linux/acpi.h     |    1 +
>   3 files changed, 77 insertions(+)
>
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index ac7ab34..621ced8 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -34,6 +34,12 @@ 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.
>    */
> @@ -169,6 +175,73 @@ static int __init acpi_parse_madt_gic_cpu_interface_entries(void)
>   	return 0;
>   }
>
> +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);
> +

Not sure if acpi_gsi_to_irq and acpi_{,un}register_gsi belong here.
These are GIC specific and should belong to GIC driver IMO.

Regards,
Sudeep

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-04 15:28   ` Hanjun Guo
  (?)
@ 2014-08-18 18:56     ` Geoff Levand
  -1 siblings, 0 replies; 180+ messages in thread
From: Geoff Levand @ 2014-08-18 18:56 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Catalin Marinas, Rafael J. Wysocki, Mark Rutland, linaro-acpi,
	Liviu Dudau, Lv Zheng, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Robert Moore, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap

Hi Hanjun,

On Mon, 2014-08-04 at 23:28 +0800, Hanjun Guo wrote:
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -14,6 +14,27 @@
>  
>  /* Basic configuration for ACPI */
>  #ifdef	CONFIG_ACPI

By having this preprocessor conditional in the header leads
to a proliferation of preprocessor conditionals since any
code that includes this header will also need to have
preprocessor conditionals.  Another down side of having
this is that this code will not get a build test for
builds with CONFIG_ACPI=n.

> +/*
> + * ACPI 5.1 only has two explicit methods to
> + * boot up SMP, PSCI and Parking protocol,
> + * but the Parking protocol is only defined
> + * 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.
> + *
> + * This enum is intend to make the boot method
> + * scalable when above updates are happended,
> + * which NOT means to support all of them.
> + */
> +enum acpi_smp_boot_protocol {
> +	ACPI_SMP_BOOT_PSCI,
> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
> +	ACPI_SMP_BOOT_PROTOCOL_MAX
> +};
> +
> +enum acpi_smp_boot_protocol smp_boot_protocol(void);

The name smp_boot_protocol() seems like it would be a generic
routine, but it is acpi specific.  Maybe:

enum acpi_boot_protocol_type {...};

enum acpi_boot_protocol_type acpi_boot_protocol(void);

> --- a/arch/arm64/kernel/cpu_ops.c
> +++ b/arch/arm64/kernel/cpu_ops.c
> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>  	return NULL;
>  }
>  
> +#ifdef CONFIG_ACPI
> +/*
> + * Get a cpu's boot method in the ACPI way.
> + */
> +static char * __init acpi_get_cpu_boot_method(void)
> +{
> +	/*
> +	 * For ACPI 5.1, only two kind of methods are provided,
> +	 * Parking protocol and PSCI, but Parking protocol is
> +	 * specified for ARMv7 only, so make PSCI as the only method
> +	 * for SMP initialization before the ACPI spec or Parking
> +	 * protocol spec is updated.
> +	 */
> +	switch (smp_boot_protocol()) {
> +	case ACPI_SMP_BOOT_PSCI:
> +		return "psci";
> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> +	default:
> +		return NULL;
> +	}
> +}
> +#else
> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
> +#endif

Since this is inside a C source file, the inline keyword
isn't needed since the optimizer will inline regardless.

With that said, I think it would be cleaner to have this
as:

static char * __init acpi_get_cpu_boot_method(void)
{
#ifdef CONFIG_ACPI
	return NULL;
#else
 ...
#endif
}

Or better to make smp_boot_protocol() callable regardless
of CONFIG_ACPI and then no preprocessor conditionals at all
would be needed.

> +
>  /*
> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
> + * Read a cpu's enable method and record it in cpu_ops.
>   */
>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>  {
> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
> +	const char *enable_method;
> +
> +	if (!acpi_disabled) {
> +		enable_method = acpi_get_cpu_boot_method();
> +		goto get_ops;
> +	}
> +
> +	enable_method = of_get_property(dn, "enable-method", NULL);
>  	if (!enable_method) {
>  		/*
>  		 * The boot CPU may not have an enable method (e.g. when
> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>  		return -ENOENT;
>  	}
>  
> +get_ops:
>  	cpu_ops[cpu] = cpu_get_ops(enable_method);
>  	if (!cpu_ops[cpu]) {
> -		pr_warn("%s: unsupported enable-method property: %s\n",
> -			dn->full_name, enable_method);
> +		if (acpi_disabled) {
> +			pr_warn("%s: unsupported enable-method property: %s\n",
> +				dn->full_name, enable_method);
> +		} else {
> +			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
> +				cpu);
> +		}
> +

Can't we have this more integrated, maybe something like this?

	enable_method = acpi_disabled ? of_get_property(dn, "enable-method", NULL)
		: acpi_get_cpu_boot_method();
	message = acpi_disabled ? dn->full_name : "";

	...
	
	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
				cpu, message, enable_method)

-Geoff


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-18 18:56     ` Geoff Levand
  0 siblings, 0 replies; 180+ messages in thread
From: Geoff Levand @ 2014-08-18 18:56 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Catalin Marinas, Rafael J. Wysocki, Mark Rutland, linaro-acpi,
	Liviu Dudau, Lv Zheng, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Robert Moore, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap, linux-kernel, Sudeep Holla, Olof Johansson

Hi Hanjun,

On Mon, 2014-08-04 at 23:28 +0800, Hanjun Guo wrote:
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -14,6 +14,27 @@
>  
>  /* Basic configuration for ACPI */
>  #ifdef	CONFIG_ACPI

By having this preprocessor conditional in the header leads
to a proliferation of preprocessor conditionals since any
code that includes this header will also need to have
preprocessor conditionals.  Another down side of having
this is that this code will not get a build test for
builds with CONFIG_ACPI=n.

> +/*
> + * ACPI 5.1 only has two explicit methods to
> + * boot up SMP, PSCI and Parking protocol,
> + * but the Parking protocol is only defined
> + * 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.
> + *
> + * This enum is intend to make the boot method
> + * scalable when above updates are happended,
> + * which NOT means to support all of them.
> + */
> +enum acpi_smp_boot_protocol {
> +	ACPI_SMP_BOOT_PSCI,
> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
> +	ACPI_SMP_BOOT_PROTOCOL_MAX
> +};
> +
> +enum acpi_smp_boot_protocol smp_boot_protocol(void);

The name smp_boot_protocol() seems like it would be a generic
routine, but it is acpi specific.  Maybe:

enum acpi_boot_protocol_type {...};

enum acpi_boot_protocol_type acpi_boot_protocol(void);

> --- a/arch/arm64/kernel/cpu_ops.c
> +++ b/arch/arm64/kernel/cpu_ops.c
> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>  	return NULL;
>  }
>  
> +#ifdef CONFIG_ACPI
> +/*
> + * Get a cpu's boot method in the ACPI way.
> + */
> +static char * __init acpi_get_cpu_boot_method(void)
> +{
> +	/*
> +	 * For ACPI 5.1, only two kind of methods are provided,
> +	 * Parking protocol and PSCI, but Parking protocol is
> +	 * specified for ARMv7 only, so make PSCI as the only method
> +	 * for SMP initialization before the ACPI spec or Parking
> +	 * protocol spec is updated.
> +	 */
> +	switch (smp_boot_protocol()) {
> +	case ACPI_SMP_BOOT_PSCI:
> +		return "psci";
> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> +	default:
> +		return NULL;
> +	}
> +}
> +#else
> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
> +#endif

Since this is inside a C source file, the inline keyword
isn't needed since the optimizer will inline regardless.

With that said, I think it would be cleaner to have this
as:

static char * __init acpi_get_cpu_boot_method(void)
{
#ifdef CONFIG_ACPI
	return NULL;
#else
 ...
#endif
}

Or better to make smp_boot_protocol() callable regardless
of CONFIG_ACPI and then no preprocessor conditionals at all
would be needed.

> +
>  /*
> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
> + * Read a cpu's enable method and record it in cpu_ops.
>   */
>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>  {
> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
> +	const char *enable_method;
> +
> +	if (!acpi_disabled) {
> +		enable_method = acpi_get_cpu_boot_method();
> +		goto get_ops;
> +	}
> +
> +	enable_method = of_get_property(dn, "enable-method", NULL);
>  	if (!enable_method) {
>  		/*
>  		 * The boot CPU may not have an enable method (e.g. when
> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>  		return -ENOENT;
>  	}
>  
> +get_ops:
>  	cpu_ops[cpu] = cpu_get_ops(enable_method);
>  	if (!cpu_ops[cpu]) {
> -		pr_warn("%s: unsupported enable-method property: %s\n",
> -			dn->full_name, enable_method);
> +		if (acpi_disabled) {
> +			pr_warn("%s: unsupported enable-method property: %s\n",
> +				dn->full_name, enable_method);
> +		} else {
> +			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
> +				cpu);
> +		}
> +

Can't we have this more integrated, maybe something like this?

	enable_method = acpi_disabled ? of_get_property(dn, "enable-method", NULL)
		: acpi_get_cpu_boot_method();
	message = acpi_disabled ? dn->full_name : "";

	...
	
	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
				cpu, message, enable_method)

-Geoff


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-18 18:56     ` Geoff Levand
  0 siblings, 0 replies; 180+ messages in thread
From: Geoff Levand @ 2014-08-18 18:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Hanjun,

On Mon, 2014-08-04 at 23:28 +0800, Hanjun Guo wrote:
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -14,6 +14,27 @@
>  
>  /* Basic configuration for ACPI */
>  #ifdef	CONFIG_ACPI

By having this preprocessor conditional in the header leads
to a proliferation of preprocessor conditionals since any
code that includes this header will also need to have
preprocessor conditionals.  Another down side of having
this is that this code will not get a build test for
builds with CONFIG_ACPI=n.

> +/*
> + * ACPI 5.1 only has two explicit methods to
> + * boot up SMP, PSCI and Parking protocol,
> + * but the Parking protocol is only defined
> + * 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.
> + *
> + * This enum is intend to make the boot method
> + * scalable when above updates are happended,
> + * which NOT means to support all of them.
> + */
> +enum acpi_smp_boot_protocol {
> +	ACPI_SMP_BOOT_PSCI,
> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
> +	ACPI_SMP_BOOT_PROTOCOL_MAX
> +};
> +
> +enum acpi_smp_boot_protocol smp_boot_protocol(void);

The name smp_boot_protocol() seems like it would be a generic
routine, but it is acpi specific.  Maybe:

enum acpi_boot_protocol_type {...};

enum acpi_boot_protocol_type acpi_boot_protocol(void);

> --- a/arch/arm64/kernel/cpu_ops.c
> +++ b/arch/arm64/kernel/cpu_ops.c
> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>  	return NULL;
>  }
>  
> +#ifdef CONFIG_ACPI
> +/*
> + * Get a cpu's boot method in the ACPI way.
> + */
> +static char * __init acpi_get_cpu_boot_method(void)
> +{
> +	/*
> +	 * For ACPI 5.1, only two kind of methods are provided,
> +	 * Parking protocol and PSCI, but Parking protocol is
> +	 * specified for ARMv7 only, so make PSCI as the only method
> +	 * for SMP initialization before the ACPI spec or Parking
> +	 * protocol spec is updated.
> +	 */
> +	switch (smp_boot_protocol()) {
> +	case ACPI_SMP_BOOT_PSCI:
> +		return "psci";
> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> +	default:
> +		return NULL;
> +	}
> +}
> +#else
> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
> +#endif

Since this is inside a C source file, the inline keyword
isn't needed since the optimizer will inline regardless.

With that said, I think it would be cleaner to have this
as:

static char * __init acpi_get_cpu_boot_method(void)
{
#ifdef CONFIG_ACPI
	return NULL;
#else
 ...
#endif
}

Or better to make smp_boot_protocol() callable regardless
of CONFIG_ACPI and then no preprocessor conditionals at all
would be needed.

> +
>  /*
> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
> + * Read a cpu's enable method and record it in cpu_ops.
>   */
>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>  {
> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
> +	const char *enable_method;
> +
> +	if (!acpi_disabled) {
> +		enable_method = acpi_get_cpu_boot_method();
> +		goto get_ops;
> +	}
> +
> +	enable_method = of_get_property(dn, "enable-method", NULL);
>  	if (!enable_method) {
>  		/*
>  		 * The boot CPU may not have an enable method (e.g. when
> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>  		return -ENOENT;
>  	}
>  
> +get_ops:
>  	cpu_ops[cpu] = cpu_get_ops(enable_method);
>  	if (!cpu_ops[cpu]) {
> -		pr_warn("%s: unsupported enable-method property: %s\n",
> -			dn->full_name, enable_method);
> +		if (acpi_disabled) {
> +			pr_warn("%s: unsupported enable-method property: %s\n",
> +				dn->full_name, enable_method);
> +		} else {
> +			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
> +				cpu);
> +		}
> +

Can't we have this more integrated, maybe something like this?

	enable_method = acpi_disabled ? of_get_property(dn, "enable-method", NULL)
		: acpi_get_cpu_boot_method();
	message = acpi_disabled ? dn->full_name : "";

	...
	
	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
				cpu, message, enable_method)

-Geoff

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-18 14:27     ` Catalin Marinas
  (?)
@ 2014-08-19  3:50       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  3:50 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:12PM +0100, Hanjun Guo wrote:
>> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
>> the former signals to the OS that the hardware is PSCI compliant.
> 
> Actually it signals that the firmware is PSCI compliant. The hardware
> doesn't care much.

Right, I will update it.

> 
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 6400312..6e04868 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -19,6 +19,18 @@ extern int acpi_disabled;
>>  extern int acpi_noirq;
>>  extern int acpi_pci_disabled;
>>  
>> +/* 1 to indicate PSCI 0.2+ is implemented */
>> +static inline bool acpi_psci_present(void)
>> +{
>> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
>> +}
>> +
>> +/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
>> +static inline bool acpi_psci_use_hvc(void)
>> +{
>> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
>> +}
> 
> Do we actually need !! here? Shouldn't the compiler figure out
> conversion to bool automatically?

I thought !! will explicitly show that it's a bool value and
improve the readability of the code, but I'm ok to remove !!
here.

> 
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index 9cf9127..69a315d 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -11,6 +11,8 @@
>>   *  published by the Free Software Foundation.
>>   */
>>  
>> +#define pr_fmt(fmt) "ACPI: " fmt
>> +
>>  #include <linux/init.h>
>>  #include <linux/acpi.h>
>>  #include <linux/cpumask.h>
>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>>  	early_memunmap(map, size);
>>  }
>>  
>> +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 version,
>> +	 * and there is a minor version of FADT which was introduced
>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>> +	 * to get arm boot flags, or we will disable ACPI.
>> +	 */
>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
> 
> If we ever get revision 6.0, this would trigger.

Yes, good catch, actually I already fixed that in my local git repo,

+       if (table->revision > 5 ||
+           (table->revision == 5 && fadt->minor_revision >= 1)) {
+               return 0;
+       } else {
+               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
or higher\n",
+                       table->revision, fadt->minor_revision);
+               disable_acpi();
+               return -EINVAL;
+       }

> 
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index 85c6326..dfc4e4f3 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>>  	efi_idmap_init();
>>  
>>  	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
>> +	acpi_boot_init();
>> +
>>  	unflatten_device_tree();
> 
> Unless that's changed in a subsequent patch, do we still need to call
> unflatten_device_tree() if ACPI was successful?

No, we don't. in [PATCH v2 16/18], we will not call unflatten_device_tree()
if ACPI is successful. Since the CONFIG_ACPI is not enabled for ARM64 (will
enable it in the last patch), so acpi_boot_init() is a stub empty function
here.

> 
>>  	psci_init();
> 
> I would also rename this to something like psci_dt_init() and move the
> acpi_disabled check here rather than in the callee.

thanks for the suggestion, I will update my patch :)

Thanks
Hanjun



^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19  3:50       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  3:50 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:12PM +0100, Hanjun Guo wrote:
>> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
>> the former signals to the OS that the hardware is PSCI compliant.
> 
> Actually it signals that the firmware is PSCI compliant. The hardware
> doesn't care much.

Right, I will update it.

> 
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 6400312..6e04868 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -19,6 +19,18 @@ extern int acpi_disabled;
>>  extern int acpi_noirq;
>>  extern int acpi_pci_disabled;
>>  
>> +/* 1 to indicate PSCI 0.2+ is implemented */
>> +static inline bool acpi_psci_present(void)
>> +{
>> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
>> +}
>> +
>> +/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
>> +static inline bool acpi_psci_use_hvc(void)
>> +{
>> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
>> +}
> 
> Do we actually need !! here? Shouldn't the compiler figure out
> conversion to bool automatically?

I thought !! will explicitly show that it's a bool value and
improve the readability of the code, but I'm ok to remove !!
here.

> 
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index 9cf9127..69a315d 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -11,6 +11,8 @@
>>   *  published by the Free Software Foundation.
>>   */
>>  
>> +#define pr_fmt(fmt) "ACPI: " fmt
>> +
>>  #include <linux/init.h>
>>  #include <linux/acpi.h>
>>  #include <linux/cpumask.h>
>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>>  	early_memunmap(map, size);
>>  }
>>  
>> +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 version,
>> +	 * and there is a minor version of FADT which was introduced
>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>> +	 * to get arm boot flags, or we will disable ACPI.
>> +	 */
>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
> 
> If we ever get revision 6.0, this would trigger.

Yes, good catch, actually I already fixed that in my local git repo,

+       if (table->revision > 5 ||
+           (table->revision == 5 && fadt->minor_revision >= 1)) {
+               return 0;
+       } else {
+               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
or higher\n",
+                       table->revision, fadt->minor_revision);
+               disable_acpi();
+               return -EINVAL;
+       }

> 
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index 85c6326..dfc4e4f3 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>>  	efi_idmap_init();
>>  
>>  	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
>> +	acpi_boot_init();
>> +
>>  	unflatten_device_tree();
> 
> Unless that's changed in a subsequent patch, do we still need to call
> unflatten_device_tree() if ACPI was successful?

No, we don't. in [PATCH v2 16/18], we will not call unflatten_device_tree()
if ACPI is successful. Since the CONFIG_ACPI is not enabled for ARM64 (will
enable it in the last patch), so acpi_boot_init() is a stub empty function
here.

> 
>>  	psci_init();
> 
> I would also rename this to something like psci_dt_init() and move the
> acpi_disabled check here rather than in the callee.

thanks for the suggestion, I will update my patch :)

Thanks
Hanjun



^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19  3:50       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:12PM +0100, Hanjun Guo wrote:
>> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
>> the former signals to the OS that the hardware is PSCI compliant.
> 
> Actually it signals that the firmware is PSCI compliant. The hardware
> doesn't care much.

Right, I will update it.

> 
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 6400312..6e04868 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -19,6 +19,18 @@ extern int acpi_disabled;
>>  extern int acpi_noirq;
>>  extern int acpi_pci_disabled;
>>  
>> +/* 1 to indicate PSCI 0.2+ is implemented */
>> +static inline bool acpi_psci_present(void)
>> +{
>> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT);
>> +}
>> +
>> +/* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */
>> +static inline bool acpi_psci_use_hvc(void)
>> +{
>> +	return !!(acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC);
>> +}
> 
> Do we actually need !! here? Shouldn't the compiler figure out
> conversion to bool automatically?

I thought !! will explicitly show that it's a bool value and
improve the readability of the code, but I'm ok to remove !!
here.

> 
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index 9cf9127..69a315d 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -11,6 +11,8 @@
>>   *  published by the Free Software Foundation.
>>   */
>>  
>> +#define pr_fmt(fmt) "ACPI: " fmt
>> +
>>  #include <linux/init.h>
>>  #include <linux/acpi.h>
>>  #include <linux/cpumask.h>
>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>>  	early_memunmap(map, size);
>>  }
>>  
>> +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 version,
>> +	 * and there is a minor version of FADT which was introduced
>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>> +	 * to get arm boot flags, or we will disable ACPI.
>> +	 */
>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
> 
> If we ever get revision 6.0, this would trigger.

Yes, good catch, actually I already fixed that in my local git repo,

+       if (table->revision > 5 ||
+           (table->revision == 5 && fadt->minor_revision >= 1)) {
+               return 0;
+       } else {
+               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
or higher\n",
+                       table->revision, fadt->minor_revision);
+               disable_acpi();
+               return -EINVAL;
+       }

> 
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index 85c6326..dfc4e4f3 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>>  	efi_idmap_init();
>>  
>>  	cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
>> +	acpi_boot_init();
>> +
>>  	unflatten_device_tree();
> 
> Unless that's changed in a subsequent patch, do we still need to call
> unflatten_device_tree() if ACPI was successful?

No, we don't. in [PATCH v2 16/18], we will not call unflatten_device_tree()
if ACPI is successful. Since the CONFIG_ACPI is not enabled for ARM64 (will
enable it in the last patch), so acpi_boot_init() is a stub empty function
here.

> 
>>  	psci_init();
> 
> I would also rename this to something like psci_dt_init() and move the
> acpi_disabled check here rather than in the callee.

thanks for the suggestion, I will update my patch :)

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
  2014-08-18 14:27     ` Catalin Marinas
  (?)
@ 2014-08-19  7:36       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  7:36 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 6e04868..e877967 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>>  extern int (*acpi_suspend_lowlevel)(void);
>>  #define acpi_wakeup_address 0
>>  
>> +#define MAX_GIC_CPU_INTERFACE 65535
> 
> Does this need to be more than NR_CPUS?

Sometimes yes, CPU structure entries in MADT just like CPU nodes in
device tree, the number of them may more than NR_CPUS.

> 
>> +/**
>> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
>> + * generates a logical cpu number
>> + * @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 the gic cpu interface
>> + */
>> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
>> +{
>> +	int cpu;
>> +
>> +	if (mpidr == INVALID_HWID) {
>> +		pr_info("Skip invalid cpu hardware ID\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;
>> +	}
>> +
>> +	/* If it is the first CPU, no need to check duplicate MPIDRs */
>> +	if (!enabled_cpus)
>> +		goto skip_mpidr_check;
>> +
>> +	/*
>> +	 * 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_present_cpu(cpu) {
>> +		if (cpu_logical_map(cpu) == mpidr) {
>> +			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
>> +			       mpidr);
>> +			return -EINVAL;
>> +		}
>> +	}
>> +
>> +skip_mpidr_check:
>> +	enabled_cpus++;
>> +
>> +	/* allocate a logical cpu id for the new comer */
>> +	if (cpu_logical_map(0) == mpidr) {
>> +		/*
>> +		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
>> +		 * for BSP, no need to allocate again.
>> +		 */
>> +		cpu = 0;
>> +	} else {
>> +		cpu = cpumask_next_zero(-1, cpu_present_mask);
>> +	}
>> +
>> +	/* map the logical cpu id to cpu MPIDR */
>> +	cpu_logical_map(cpu) = mpidr;
>> +
>> +	set_cpu_possible(cpu, true);
>> +	set_cpu_present(cpu, true);
>> +
>> +	return cpu;
>> +}
> 
> Why not only set the cpu possible here (with the additional mpidr
> validity checks changed to for_each_possible_cpu)...
> 
>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>> index 40f38f4..8f1d37c 100644
>> --- a/arch/arm64/kernel/smp.c
>> +++ b/arch/arm64/kernel/smp.c
>> @@ -36,6 +36,7 @@
>>  #include <linux/completion.h>
>>  #include <linux/of.h>
>>  #include <linux/irq_work.h>
>> +#include <linux/acpi.h>
>>  
>>  #include <asm/atomic.h>
>>  #include <asm/cacheflush.h>
>> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>>  		if (err)
>>  			continue;
>>  
>> -		set_cpu_present(cpu, true);
>> +		/*
>> +		 * In ACPI mode, cpu_present_map was initialised when
>> +		 * MADT table was parsed which before this function
>> +		 * is called.
>> +		 */
>> +		if (acpi_disabled)
>> +			set_cpu_present(cpu, true);
>> +
>>  		max_cpus--;
> 
> ... and don't touch this at all.

the original intent was to support CPU hotplug, I will update the patch
as you suggested and introduce the change when CPU hotplug patch is upstreamed,
then it will make the patch less confusing.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-19  7:36       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  7:36 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi, Tomasz Nowicki

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 6e04868..e877967 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>>  extern int (*acpi_suspend_lowlevel)(void);
>>  #define acpi_wakeup_address 0
>>  
>> +#define MAX_GIC_CPU_INTERFACE 65535
> 
> Does this need to be more than NR_CPUS?

Sometimes yes, CPU structure entries in MADT just like CPU nodes in
device tree, the number of them may more than NR_CPUS.

> 
>> +/**
>> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
>> + * generates a logical cpu number
>> + * @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 the gic cpu interface
>> + */
>> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
>> +{
>> +	int cpu;
>> +
>> +	if (mpidr == INVALID_HWID) {
>> +		pr_info("Skip invalid cpu hardware ID\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;
>> +	}
>> +
>> +	/* If it is the first CPU, no need to check duplicate MPIDRs */
>> +	if (!enabled_cpus)
>> +		goto skip_mpidr_check;
>> +
>> +	/*
>> +	 * 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_present_cpu(cpu) {
>> +		if (cpu_logical_map(cpu) == mpidr) {
>> +			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
>> +			       mpidr);
>> +			return -EINVAL;
>> +		}
>> +	}
>> +
>> +skip_mpidr_check:
>> +	enabled_cpus++;
>> +
>> +	/* allocate a logical cpu id for the new comer */
>> +	if (cpu_logical_map(0) == mpidr) {
>> +		/*
>> +		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
>> +		 * for BSP, no need to allocate again.
>> +		 */
>> +		cpu = 0;
>> +	} else {
>> +		cpu = cpumask_next_zero(-1, cpu_present_mask);
>> +	}
>> +
>> +	/* map the logical cpu id to cpu MPIDR */
>> +	cpu_logical_map(cpu) = mpidr;
>> +
>> +	set_cpu_possible(cpu, true);
>> +	set_cpu_present(cpu, true);
>> +
>> +	return cpu;
>> +}
> 
> Why not only set the cpu possible here (with the additional mpidr
> validity checks changed to for_each_possible_cpu)...
> 
>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>> index 40f38f4..8f1d37c 100644
>> --- a/arch/arm64/kernel/smp.c
>> +++ b/arch/arm64/kernel/smp.c
>> @@ -36,6 +36,7 @@
>>  #include <linux/completion.h>
>>  #include <linux/of.h>
>>  #include <linux/irq_work.h>
>> +#include <linux/acpi.h>
>>  
>>  #include <asm/atomic.h>
>>  #include <asm/cacheflush.h>
>> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>>  		if (err)
>>  			continue;
>>  
>> -		set_cpu_present(cpu, true);
>> +		/*
>> +		 * In ACPI mode, cpu_present_map was initialised when
>> +		 * MADT table was parsed which before this function
>> +		 * is called.
>> +		 */
>> +		if (acpi_disabled)
>> +			set_cpu_present(cpu, true);
>> +
>>  		max_cpus--;
> 
> ... and don't touch this at all.

the original intent was to support CPU hotplug, I will update the patch
as you suggested and introduce the change when CPU hotplug patch is upstreamed,
then it will make the patch less confusing.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-19  7:36       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  7:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 6e04868..e877967 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>>  extern int (*acpi_suspend_lowlevel)(void);
>>  #define acpi_wakeup_address 0
>>  
>> +#define MAX_GIC_CPU_INTERFACE 65535
> 
> Does this need to be more than NR_CPUS?

Sometimes yes, CPU structure entries in MADT just like CPU nodes in
device tree, the number of them may more than NR_CPUS.

> 
>> +/**
>> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
>> + * generates a logical cpu number
>> + * @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 the gic cpu interface
>> + */
>> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
>> +{
>> +	int cpu;
>> +
>> +	if (mpidr == INVALID_HWID) {
>> +		pr_info("Skip invalid cpu hardware ID\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;
>> +	}
>> +
>> +	/* If it is the first CPU, no need to check duplicate MPIDRs */
>> +	if (!enabled_cpus)
>> +		goto skip_mpidr_check;
>> +
>> +	/*
>> +	 * 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_present_cpu(cpu) {
>> +		if (cpu_logical_map(cpu) == mpidr) {
>> +			pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
>> +			       mpidr);
>> +			return -EINVAL;
>> +		}
>> +	}
>> +
>> +skip_mpidr_check:
>> +	enabled_cpus++;
>> +
>> +	/* allocate a logical cpu id for the new comer */
>> +	if (cpu_logical_map(0) == mpidr) {
>> +		/*
>> +		 * boot_cpu_init() already hold bit 0 in cpu_present_mask
>> +		 * for BSP, no need to allocate again.
>> +		 */
>> +		cpu = 0;
>> +	} else {
>> +		cpu = cpumask_next_zero(-1, cpu_present_mask);
>> +	}
>> +
>> +	/* map the logical cpu id to cpu MPIDR */
>> +	cpu_logical_map(cpu) = mpidr;
>> +
>> +	set_cpu_possible(cpu, true);
>> +	set_cpu_present(cpu, true);
>> +
>> +	return cpu;
>> +}
> 
> Why not only set the cpu possible here (with the additional mpidr
> validity checks changed to for_each_possible_cpu)...
> 
>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>> index 40f38f4..8f1d37c 100644
>> --- a/arch/arm64/kernel/smp.c
>> +++ b/arch/arm64/kernel/smp.c
>> @@ -36,6 +36,7 @@
>>  #include <linux/completion.h>
>>  #include <linux/of.h>
>>  #include <linux/irq_work.h>
>> +#include <linux/acpi.h>
>>  
>>  #include <asm/atomic.h>
>>  #include <asm/cacheflush.h>
>> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>>  		if (err)
>>  			continue;
>>  
>> -		set_cpu_present(cpu, true);
>> +		/*
>> +		 * In ACPI mode, cpu_present_map was initialised when
>> +		 * MADT table was parsed which before this function
>> +		 * is called.
>> +		 */
>> +		if (acpi_disabled)
>> +			set_cpu_present(cpu, true);
>> +
>>  		max_cpus--;
> 
> ... and don't touch this at all.

the original intent was to support CPU hotplug, I will update the patch
as you suggested and introduce the change when CPU hotplug patch is upstreamed,
then it will make the patch less confusing.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-18 14:27     ` Catalin Marinas
  (?)
@ 2014-08-19  8:32       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  8:32 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index e877967..022f4ad 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -14,6 +14,27 @@
>>  
>>  /* Basic configuration for ACPI */
>>  #ifdef	CONFIG_ACPI
>> +/*
>> + * ACPI 5.1 only has two explicit methods to
>> + * boot up SMP, PSCI and Parking protocol,
>> + * but the Parking protocol is only defined
>> + * 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.
>> + *
>> + * This enum is intend to make the boot method
>> + * scalable when above updates are happended,
>> + * which NOT means to support all of them.
>> + */
>> +enum acpi_smp_boot_protocol {
>> +	ACPI_SMP_BOOT_PSCI,
>> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
>> +	ACPI_SMP_BOOT_PROTOCOL_MAX
>> +};
>> +
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
> 
> Since this is not a static function and ACPI-specific, could you prefix
> it with something like acpi (or arm64_acpi_ unless it gets too long)?
> 
>> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
>> index d62d12f..05bc314 100644
>> --- a/arch/arm64/kernel/cpu_ops.c
>> +++ b/arch/arm64/kernel/cpu_ops.c
>> @@ -16,11 +16,13 @@
>>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>   */
>>  
>> -#include <asm/cpu_ops.h>
>> -#include <asm/smp_plat.h>
>>  #include <linux/errno.h>
>>  #include <linux/of.h>
>>  #include <linux/string.h>
>> +#include <linux/acpi.h>
>> +
>> +#include <asm/cpu_ops.h>
>> +#include <asm/smp_plat.h>
>>  
>>  extern const struct cpu_operations smp_spin_table_ops;
>>  extern const struct cpu_operations cpu_psci_ops;
>> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>>  	return NULL;
>>  }
>>  
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Get a cpu's boot method in the ACPI way.
>> + */
>> +static char * __init acpi_get_cpu_boot_method(void)
>> +{
>> +	/*
>> +	 * For ACPI 5.1, only two kind of methods are provided,
>> +	 * Parking protocol and PSCI, but Parking protocol is
>> +	 * specified for ARMv7 only, so make PSCI as the only method
>> +	 * for SMP initialization before the ACPI spec or Parking
>> +	 * protocol spec is updated.
>> +	 */
>> +	switch (smp_boot_protocol()) {
>> +	case ACPI_SMP_BOOT_PSCI:
>> +		return "psci";
>> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>> +	default:
>> +		return NULL;
>> +	}
>> +}
> 
> Actually, do we even need to define smp_boot_protocol()? Is it used
> anywhere else apart from this patch (I still haven't gone through all
> patches)?

It is just used in this patch. I think we can make the ACPI boot protocol
scalable in this way, if we support another boot protocol in ACPI in the
future, we can easily update the function to support it, does it make sense?

> 
>> +#else
>> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
>> +#endif
>> +
>>  /*
>> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
>> + * Read a cpu's enable method and record it in cpu_ops.
>>   */
>>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>>  {
>> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
>> +	const char *enable_method;
>> +
>> +	if (!acpi_disabled) {
>> +		enable_method = acpi_get_cpu_boot_method();
>> +		goto get_ops;
> 
> Are we always guaranteed an enable_method here? You should have an
> if/else of ACPI vs DT and keep the if (!enable_method) check for both
> cases.

ok, I will fix it.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-19  8:32       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  8:32 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi, Tomasz Nowicki

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index e877967..022f4ad 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -14,6 +14,27 @@
>>  
>>  /* Basic configuration for ACPI */
>>  #ifdef	CONFIG_ACPI
>> +/*
>> + * ACPI 5.1 only has two explicit methods to
>> + * boot up SMP, PSCI and Parking protocol,
>> + * but the Parking protocol is only defined
>> + * 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.
>> + *
>> + * This enum is intend to make the boot method
>> + * scalable when above updates are happended,
>> + * which NOT means to support all of them.
>> + */
>> +enum acpi_smp_boot_protocol {
>> +	ACPI_SMP_BOOT_PSCI,
>> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
>> +	ACPI_SMP_BOOT_PROTOCOL_MAX
>> +};
>> +
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
> 
> Since this is not a static function and ACPI-specific, could you prefix
> it with something like acpi (or arm64_acpi_ unless it gets too long)?
> 
>> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
>> index d62d12f..05bc314 100644
>> --- a/arch/arm64/kernel/cpu_ops.c
>> +++ b/arch/arm64/kernel/cpu_ops.c
>> @@ -16,11 +16,13 @@
>>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>   */
>>  
>> -#include <asm/cpu_ops.h>
>> -#include <asm/smp_plat.h>
>>  #include <linux/errno.h>
>>  #include <linux/of.h>
>>  #include <linux/string.h>
>> +#include <linux/acpi.h>
>> +
>> +#include <asm/cpu_ops.h>
>> +#include <asm/smp_plat.h>
>>  
>>  extern const struct cpu_operations smp_spin_table_ops;
>>  extern const struct cpu_operations cpu_psci_ops;
>> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>>  	return NULL;
>>  }
>>  
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Get a cpu's boot method in the ACPI way.
>> + */
>> +static char * __init acpi_get_cpu_boot_method(void)
>> +{
>> +	/*
>> +	 * For ACPI 5.1, only two kind of methods are provided,
>> +	 * Parking protocol and PSCI, but Parking protocol is
>> +	 * specified for ARMv7 only, so make PSCI as the only method
>> +	 * for SMP initialization before the ACPI spec or Parking
>> +	 * protocol spec is updated.
>> +	 */
>> +	switch (smp_boot_protocol()) {
>> +	case ACPI_SMP_BOOT_PSCI:
>> +		return "psci";
>> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>> +	default:
>> +		return NULL;
>> +	}
>> +}
> 
> Actually, do we even need to define smp_boot_protocol()? Is it used
> anywhere else apart from this patch (I still haven't gone through all
> patches)?

It is just used in this patch. I think we can make the ACPI boot protocol
scalable in this way, if we support another boot protocol in ACPI in the
future, we can easily update the function to support it, does it make sense?

> 
>> +#else
>> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
>> +#endif
>> +
>>  /*
>> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
>> + * Read a cpu's enable method and record it in cpu_ops.
>>   */
>>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>>  {
>> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
>> +	const char *enable_method;
>> +
>> +	if (!acpi_disabled) {
>> +		enable_method = acpi_get_cpu_boot_method();
>> +		goto get_ops;
> 
> Are we always guaranteed an enable_method here? You should have an
> if/else of ACPI vs DT and keep the if (!enable_method) check for both
> cases.

ok, I will fix it.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-19  8:32       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  8:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index e877967..022f4ad 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -14,6 +14,27 @@
>>  
>>  /* Basic configuration for ACPI */
>>  #ifdef	CONFIG_ACPI
>> +/*
>> + * ACPI 5.1 only has two explicit methods to
>> + * boot up SMP, PSCI and Parking protocol,
>> + * but the Parking protocol is only defined
>> + * 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.
>> + *
>> + * This enum is intend to make the boot method
>> + * scalable when above updates are happended,
>> + * which NOT means to support all of them.
>> + */
>> +enum acpi_smp_boot_protocol {
>> +	ACPI_SMP_BOOT_PSCI,
>> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
>> +	ACPI_SMP_BOOT_PROTOCOL_MAX
>> +};
>> +
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
> 
> Since this is not a static function and ACPI-specific, could you prefix
> it with something like acpi (or arm64_acpi_ unless it gets too long)?
> 
>> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
>> index d62d12f..05bc314 100644
>> --- a/arch/arm64/kernel/cpu_ops.c
>> +++ b/arch/arm64/kernel/cpu_ops.c
>> @@ -16,11 +16,13 @@
>>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>   */
>>  
>> -#include <asm/cpu_ops.h>
>> -#include <asm/smp_plat.h>
>>  #include <linux/errno.h>
>>  #include <linux/of.h>
>>  #include <linux/string.h>
>> +#include <linux/acpi.h>
>> +
>> +#include <asm/cpu_ops.h>
>> +#include <asm/smp_plat.h>
>>  
>>  extern const struct cpu_operations smp_spin_table_ops;
>>  extern const struct cpu_operations cpu_psci_ops;
>> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>>  	return NULL;
>>  }
>>  
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Get a cpu's boot method in the ACPI way.
>> + */
>> +static char * __init acpi_get_cpu_boot_method(void)
>> +{
>> +	/*
>> +	 * For ACPI 5.1, only two kind of methods are provided,
>> +	 * Parking protocol and PSCI, but Parking protocol is
>> +	 * specified for ARMv7 only, so make PSCI as the only method
>> +	 * for SMP initialization before the ACPI spec or Parking
>> +	 * protocol spec is updated.
>> +	 */
>> +	switch (smp_boot_protocol()) {
>> +	case ACPI_SMP_BOOT_PSCI:
>> +		return "psci";
>> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>> +	default:
>> +		return NULL;
>> +	}
>> +}
> 
> Actually, do we even need to define smp_boot_protocol()? Is it used
> anywhere else apart from this patch (I still haven't gone through all
> patches)?

It is just used in this patch. I think we can make the ACPI boot protocol
scalable in this way, if we support another boot protocol in ACPI in the
future, we can easily update the function to support it, does it make sense?

> 
>> +#else
>> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
>> +#endif
>> +
>>  /*
>> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
>> + * Read a cpu's enable method and record it in cpu_ops.
>>   */
>>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>>  {
>> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
>> +	const char *enable_method;
>> +
>> +	if (!acpi_disabled) {
>> +		enable_method = acpi_get_cpu_boot_method();
>> +		goto get_ops;
> 
> Are we always guaranteed an enable_method here? You should have an
> if/else of ACPI vs DT and keep the if (!enable_method) check for both
> cases.

ok, I will fix it.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
  2014-08-18 14:27     ` Catalin Marinas
  (?)
@ 2014-08-19  8:37       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  8:37 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 022f4ad..a81898d 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -12,6 +12,8 @@
>>  #ifndef _ASM_ACPI_H
>>  #define _ASM_ACPI_H
>>  
>> +#include <asm/smp_plat.h>
>> +
>>  /* Basic configuration for ACPI */
>>  #ifdef	CONFIG_ACPI
>>  /*
>> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>>  	acpi_noirq = 1;
>>  }
>>  
>> +u32 pack_mpidr_into_32_bits(u64 mpidr);
> 
> I would define this as a static inline function here.

ok, will update it.

> 
>> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
>> index e32321c..4007313 100644
>> --- a/drivers/acpi/processor_core.c
>> +++ b/drivers/acpi/processor_core.c
>> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>>  	return 0;
>>  }
>>  
>> +/*
>> + * On ARM platform, MPIDR value is the hardware ID as apic ID
>> + * on Intel platforms
>> + */
>> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
>> +		int device_declaration, u32 acpi_id, int *mpidr)
>> +{
>> +	struct acpi_madt_generic_interrupt *gicc =
>> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
>> +
>> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
>> +		return -ENODEV;
>> +
>> +	/* In the GIC interrupt model, logical processors are
>> +	 * required to have a Processor Device object in the DSDT,
>> +	 * so we should check device_declaration here
>> +	 */
>> +	if (device_declaration && (gicc->uid == acpi_id)) {
>> +		/*
>> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
>> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
>> +		 * fields into a single 32 bit identifier to accommodate the
>> +		 * acpi processor drivers.
>> +		 */
>> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
>> +			 | gicc->arm_mpidr;
> 
> You can use pack_mpidr_into_32_bits().

processor_core.c will be used by x86 and ia64 too, it will cause
compile error on !ARM64 platforms.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-19  8:37       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  8:37 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 022f4ad..a81898d 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -12,6 +12,8 @@
>>  #ifndef _ASM_ACPI_H
>>  #define _ASM_ACPI_H
>>  
>> +#include <asm/smp_plat.h>
>> +
>>  /* Basic configuration for ACPI */
>>  #ifdef	CONFIG_ACPI
>>  /*
>> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>>  	acpi_noirq = 1;
>>  }
>>  
>> +u32 pack_mpidr_into_32_bits(u64 mpidr);
> 
> I would define this as a static inline function here.

ok, will update it.

> 
>> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
>> index e32321c..4007313 100644
>> --- a/drivers/acpi/processor_core.c
>> +++ b/drivers/acpi/processor_core.c
>> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>>  	return 0;
>>  }
>>  
>> +/*
>> + * On ARM platform, MPIDR value is the hardware ID as apic ID
>> + * on Intel platforms
>> + */
>> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
>> +		int device_declaration, u32 acpi_id, int *mpidr)
>> +{
>> +	struct acpi_madt_generic_interrupt *gicc =
>> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
>> +
>> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
>> +		return -ENODEV;
>> +
>> +	/* In the GIC interrupt model, logical processors are
>> +	 * required to have a Processor Device object in the DSDT,
>> +	 * so we should check device_declaration here
>> +	 */
>> +	if (device_declaration && (gicc->uid == acpi_id)) {
>> +		/*
>> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
>> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
>> +		 * fields into a single 32 bit identifier to accommodate the
>> +		 * acpi processor drivers.
>> +		 */
>> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
>> +			 | gicc->arm_mpidr;
> 
> You can use pack_mpidr_into_32_bits().

processor_core.c will be used by x86 and ia64 too, it will cause
compile error on !ARM64 platforms.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-19  8:37       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  8:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 022f4ad..a81898d 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -12,6 +12,8 @@
>>  #ifndef _ASM_ACPI_H
>>  #define _ASM_ACPI_H
>>  
>> +#include <asm/smp_plat.h>
>> +
>>  /* Basic configuration for ACPI */
>>  #ifdef	CONFIG_ACPI
>>  /*
>> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>>  	acpi_noirq = 1;
>>  }
>>  
>> +u32 pack_mpidr_into_32_bits(u64 mpidr);
> 
> I would define this as a static inline function here.

ok, will update it.

> 
>> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
>> index e32321c..4007313 100644
>> --- a/drivers/acpi/processor_core.c
>> +++ b/drivers/acpi/processor_core.c
>> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>>  	return 0;
>>  }
>>  
>> +/*
>> + * On ARM platform, MPIDR value is the hardware ID as apic ID
>> + * on Intel platforms
>> + */
>> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
>> +		int device_declaration, u32 acpi_id, int *mpidr)
>> +{
>> +	struct acpi_madt_generic_interrupt *gicc =
>> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
>> +
>> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
>> +		return -ENODEV;
>> +
>> +	/* In the GIC interrupt model, logical processors are
>> +	 * required to have a Processor Device object in the DSDT,
>> +	 * so we should check device_declaration here
>> +	 */
>> +	if (device_declaration && (gicc->uid == acpi_id)) {
>> +		/*
>> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
>> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
>> +		 * fields into a single 32 bit identifier to accommodate the
>> +		 * acpi processor drivers.
>> +		 */
>> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
>> +			 | gicc->arm_mpidr;
> 
> You can use pack_mpidr_into_32_bits().

processor_core.c will be used by x86 and ia64 too, it will cause
compile error on !ARM64 platforms.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 17/18] ARM64 / ACPI: Enable ARM64 in Kconfig
  2014-08-18 14:27     ` Catalin Marinas
  (?)
@ 2014-08-19  8:38       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  8:38 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:24PM +0100, Hanjun Guo wrote:
>> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
>> index 3f5f745..f6b6791 100644
>> --- a/drivers/acpi/Kconfig
>> +++ b/drivers/acpi/Kconfig
>> @@ -5,8 +5,7 @@
>>  menuconfig ACPI
>>  	bool "ACPI (Advanced Configuration and Power Interface) Support"
>>  	depends on !IA64_HP_SIM
>> -	depends on IA64 || X86
>> -	depends on PCI
>> +	depends on ((IA64 || X86) && PCI) || ARM64
> 
> depends on (ARM64 && EXPERT)? (together with default on if CONFIG_ACPI
> is enabled).

I will update that in next version.

Thanks for all your comments!

Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 17/18] ARM64 / ACPI: Enable ARM64 in Kconfig
@ 2014-08-19  8:38       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  8:38 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi, Al Stone

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:24PM +0100, Hanjun Guo wrote:
>> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
>> index 3f5f745..f6b6791 100644
>> --- a/drivers/acpi/Kconfig
>> +++ b/drivers/acpi/Kconfig
>> @@ -5,8 +5,7 @@
>>  menuconfig ACPI
>>  	bool "ACPI (Advanced Configuration and Power Interface) Support"
>>  	depends on !IA64_HP_SIM
>> -	depends on IA64 || X86
>> -	depends on PCI
>> +	depends on ((IA64 || X86) && PCI) || ARM64
> 
> depends on (ARM64 && EXPERT)? (together with default on if CONFIG_ACPI
> is enabled).

I will update that in next version.

Thanks for all your comments!

Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 17/18] ARM64 / ACPI: Enable ARM64 in Kconfig
@ 2014-08-19  8:38       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  8:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-18 22:27, Catalin Marinas wrote:
> On Mon, Aug 04, 2014 at 04:28:24PM +0100, Hanjun Guo wrote:
>> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
>> index 3f5f745..f6b6791 100644
>> --- a/drivers/acpi/Kconfig
>> +++ b/drivers/acpi/Kconfig
>> @@ -5,8 +5,7 @@
>>  menuconfig ACPI
>>  	bool "ACPI (Advanced Configuration and Power Interface) Support"
>>  	depends on !IA64_HP_SIM
>> -	depends on IA64 || X86
>> -	depends on PCI
>> +	depends on ((IA64 || X86) && PCI) || ARM64
> 
> depends on (ARM64 && EXPERT)? (together with default on if CONFIG_ACPI
> is enabled).

I will update that in next version.

Thanks for all your comments!

Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
  2014-08-18 18:30     ` Sudeep Holla
  (?)
@ 2014-08-19  9:35       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  9:35 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel

On 2014-8-19 2:30, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
>> From: Al Stone <al.stone@linaro.org>
>>
>> As we want to get ACPI tables to parse and then use the information
>> for system initialization, we should get the RSDP (Root System
>> Description Pointer) first, it then locates Extended Root Description
>> Table (XSDT) which contains all the 64-bit physical address that
>> pointer to other boot-time tables.
>>
>> Introduce acpi.c and its related head file in this patch to provide
>> fundamental needs of extern variables and functions for ACPI core,
>> and then get boot-time tables as needed.
>>    - asm/cpu.h need for ACPI core and will be updated in the future to
>>      add definitions for arch_(un)register_cpu which are required for
>>      ACPI based physical CPU hotplug;
> 
> This can go away now, as it's already present in v3.17-rc1

Thanks for the reminding, I will rebase this patch set on top of
3.17-rc1 and remove the outdated description.

> 
>>    - asm/acenv.h for arch specific ACPICA environments and
>>      implementation;
>>    - asm/acpi.h for arch specific variables and functions needed by
>>      ACPI driver core;
>>    - acpi.c for ARM64 related ACPI implementation for ACPI driver
>>      core;
>>
>> acpi_boot_table_init() is introduced to get RSDP and boot-time tables,
>> it will be called in setup_arch() before paging_init(), so we should
>> use eary_memremap() mechanism here to get the RSDP and all the table
>> pointers.
[...]
>> +
>> +/*
>> + * Checking for the posibility that the CPU can be initialized from the MADT.
>> + * It's used from ACPI core in crash kernel case where boot CPU is not
>> + * necessarily CPU0 like spec demands. Since MADT must provide at least one
> 
> Do you mean ACPI spec demands CPU0 to be boot cpu ?

ACPI spec demands CPU0 (BSP) should be the first entry in MADT.

> 
> IIUC it's basically to handle UP system with SMP kernel. IWO if all the
> ACPI resources are reused from SMP system to boot UP system with SMP
> kernel, with this check the ACPI core won't override the CPU index
> obtained from GIC/APIC mapping to zero.

Yes, you are right, I will update the comments.

> 
>> + * GICC structure for GIC initialization, CPU will be always available in
>> + * MADT on ARM64.
>> + */
>> +static inline bool acpi_has_cpu_in_madt(void)
>> +{
>> +    return 1;
> 
> probably true instead of 1

ok.

> 
>> +}
>> +
>> +static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>> +
>> +#endif /* CONFIG_ACPI */
>> +
>> +#endif /*_ASM_ACPI_H*/
>> diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
>> new file mode 100644
>> index 0000000..cee7d3f
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/cpu.h
>> @@ -0,0 +1,11 @@
>> +/*
>> + *  Copyright (C) 2013-2014 ARM Ltd.
>> + *
>> + * 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.
>> + */
>> +#ifndef __ASM_CPU_H
>> +#define __ASM_CPU_H
>> +
>> +#endif
>> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>> index cdaedad..b568c26 100644
>> --- a/arch/arm64/kernel/Makefile
>> +++ b/arch/arm64/kernel/Makefile
>> @@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)    += sleep.o suspend.o
>>   arm64-obj-$(CONFIG_JUMP_LABEL)        += jump_label.o
>>   arm64-obj-$(CONFIG_KGDB)        += kgdb.o
>>   arm64-obj-$(CONFIG_EFI)            += efi.o efi-stub.o efi-entry.o
>> +arm64-obj-$(CONFIG_ACPI)        += acpi.o
>>
>>   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
>> new file mode 100644
>> index 0000000..395778c
>> --- /dev/null
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -0,0 +1,69 @@
>> +/*
>> + *  ARM64 Specific Low-Level ACPI Boot Support
>> + *
>> + *  Copyright (C) 2013-2014, Linaro Ltd.
>> + *    Author: Al Stone <al.stone@linaro.org>
>> + *    Author: Graeme Gregory <graeme.gregory@linaro.org>
>> + *    Author: Hanjun Guo <hanjun.guo@linaro.org>
>> + *
>> + *  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.
>> + */
>> +
>> +#include <linux/init.h>
>> +#include <linux/acpi.h>
>> +#include <linux/cpumask.h>
>> +#include <linux/memblock.h>
>> +#include <linux/irq.h>
>> +#include <linux/irqdomain.h>
>> +#include <linux/bootmem.h>
>> +#include <linux/smp.h>
>> +
>> +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);
>> +
>> +/*
>> + * __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_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
>> + *
>> + * We can parse ACPI boot-time tables such as FADT, 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()) {
> 
> Can't we call acpi_table_init directly in setup ?
> IIUC x86 has acpi_boot_table_init as it parses Boot Flags
> table(ACPI_SIG_BOOT)

Yes, we can. But I think it not a big deal to dot that, if that
makes the code more readable, I will update it.

> 
>> +        disable_acpi();
>> +        return;
>> +    }
>> +}
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index fc50461..85c6326 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -43,6 +43,7 @@
>>   #include <linux/of_fdt.h>
>>   #include <linux/of_platform.h>
>>   #include <linux/efi.h>
>> +#include <linux/acpi.h>
>>
>>   #include <asm/fixmap.h>
>>   #include <asm/cputype.h>
>> @@ -385,6 +386,9 @@ void __init setup_arch(char **cmdline_p)
>>       efi_init();
>>       arm64_memblock_init();
>>
>> +    /* Parse the ACPI tables for possible boot-time configuration */
>> +    acpi_boot_table_init();
>> +
>>       paging_init();
>>       request_standard_resources();

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
@ 2014-08-19  9:35       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  9:35 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel,
	linux-kernel, linaro-acpi, Al Stone, Tomasz Nowicki

On 2014-8-19 2:30, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
>> From: Al Stone <al.stone@linaro.org>
>>
>> As we want to get ACPI tables to parse and then use the information
>> for system initialization, we should get the RSDP (Root System
>> Description Pointer) first, it then locates Extended Root Description
>> Table (XSDT) which contains all the 64-bit physical address that
>> pointer to other boot-time tables.
>>
>> Introduce acpi.c and its related head file in this patch to provide
>> fundamental needs of extern variables and functions for ACPI core,
>> and then get boot-time tables as needed.
>>    - asm/cpu.h need for ACPI core and will be updated in the future to
>>      add definitions for arch_(un)register_cpu which are required for
>>      ACPI based physical CPU hotplug;
> 
> This can go away now, as it's already present in v3.17-rc1

Thanks for the reminding, I will rebase this patch set on top of
3.17-rc1 and remove the outdated description.

> 
>>    - asm/acenv.h for arch specific ACPICA environments and
>>      implementation;
>>    - asm/acpi.h for arch specific variables and functions needed by
>>      ACPI driver core;
>>    - acpi.c for ARM64 related ACPI implementation for ACPI driver
>>      core;
>>
>> acpi_boot_table_init() is introduced to get RSDP and boot-time tables,
>> it will be called in setup_arch() before paging_init(), so we should
>> use eary_memremap() mechanism here to get the RSDP and all the table
>> pointers.
[...]
>> +
>> +/*
>> + * Checking for the posibility that the CPU can be initialized from the MADT.
>> + * It's used from ACPI core in crash kernel case where boot CPU is not
>> + * necessarily CPU0 like spec demands. Since MADT must provide at least one
> 
> Do you mean ACPI spec demands CPU0 to be boot cpu ?

ACPI spec demands CPU0 (BSP) should be the first entry in MADT.

> 
> IIUC it's basically to handle UP system with SMP kernel. IWO if all the
> ACPI resources are reused from SMP system to boot UP system with SMP
> kernel, with this check the ACPI core won't override the CPU index
> obtained from GIC/APIC mapping to zero.

Yes, you are right, I will update the comments.

> 
>> + * GICC structure for GIC initialization, CPU will be always available in
>> + * MADT on ARM64.
>> + */
>> +static inline bool acpi_has_cpu_in_madt(void)
>> +{
>> +    return 1;
> 
> probably true instead of 1

ok.

> 
>> +}
>> +
>> +static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>> +
>> +#endif /* CONFIG_ACPI */
>> +
>> +#endif /*_ASM_ACPI_H*/
>> diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
>> new file mode 100644
>> index 0000000..cee7d3f
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/cpu.h
>> @@ -0,0 +1,11 @@
>> +/*
>> + *  Copyright (C) 2013-2014 ARM Ltd.
>> + *
>> + * 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.
>> + */
>> +#ifndef __ASM_CPU_H
>> +#define __ASM_CPU_H
>> +
>> +#endif
>> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>> index cdaedad..b568c26 100644
>> --- a/arch/arm64/kernel/Makefile
>> +++ b/arch/arm64/kernel/Makefile
>> @@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)    += sleep.o suspend.o
>>   arm64-obj-$(CONFIG_JUMP_LABEL)        += jump_label.o
>>   arm64-obj-$(CONFIG_KGDB)        += kgdb.o
>>   arm64-obj-$(CONFIG_EFI)            += efi.o efi-stub.o efi-entry.o
>> +arm64-obj-$(CONFIG_ACPI)        += acpi.o
>>
>>   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
>> new file mode 100644
>> index 0000000..395778c
>> --- /dev/null
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -0,0 +1,69 @@
>> +/*
>> + *  ARM64 Specific Low-Level ACPI Boot Support
>> + *
>> + *  Copyright (C) 2013-2014, Linaro Ltd.
>> + *    Author: Al Stone <al.stone@linaro.org>
>> + *    Author: Graeme Gregory <graeme.gregory@linaro.org>
>> + *    Author: Hanjun Guo <hanjun.guo@linaro.org>
>> + *
>> + *  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.
>> + */
>> +
>> +#include <linux/init.h>
>> +#include <linux/acpi.h>
>> +#include <linux/cpumask.h>
>> +#include <linux/memblock.h>
>> +#include <linux/irq.h>
>> +#include <linux/irqdomain.h>
>> +#include <linux/bootmem.h>
>> +#include <linux/smp.h>
>> +
>> +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);
>> +
>> +/*
>> + * __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_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
>> + *
>> + * We can parse ACPI boot-time tables such as FADT, 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()) {
> 
> Can't we call acpi_table_init directly in setup ?
> IIUC x86 has acpi_boot_table_init as it parses Boot Flags
> table(ACPI_SIG_BOOT)

Yes, we can. But I think it not a big deal to dot that, if that
makes the code more readable, I will update it.

> 
>> +        disable_acpi();
>> +        return;
>> +    }
>> +}
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index fc50461..85c6326 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -43,6 +43,7 @@
>>   #include <linux/of_fdt.h>
>>   #include <linux/of_platform.h>
>>   #include <linux/efi.h>
>> +#include <linux/acpi.h>
>>
>>   #include <asm/fixmap.h>
>>   #include <asm/cputype.h>
>> @@ -385,6 +386,9 @@ void __init setup_arch(char **cmdline_p)
>>       efi_init();
>>       arm64_memblock_init();
>>
>> +    /* Parse the ACPI tables for possible boot-time configuration */
>> +    acpi_boot_table_init();
>> +
>>       paging_init();
>>       request_standard_resources();

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
@ 2014-08-19  9:35       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19  9:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-19 2:30, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
>> From: Al Stone <al.stone@linaro.org>
>>
>> As we want to get ACPI tables to parse and then use the information
>> for system initialization, we should get the RSDP (Root System
>> Description Pointer) first, it then locates Extended Root Description
>> Table (XSDT) which contains all the 64-bit physical address that
>> pointer to other boot-time tables.
>>
>> Introduce acpi.c and its related head file in this patch to provide
>> fundamental needs of extern variables and functions for ACPI core,
>> and then get boot-time tables as needed.
>>    - asm/cpu.h need for ACPI core and will be updated in the future to
>>      add definitions for arch_(un)register_cpu which are required for
>>      ACPI based physical CPU hotplug;
> 
> This can go away now, as it's already present in v3.17-rc1

Thanks for the reminding, I will rebase this patch set on top of
3.17-rc1 and remove the outdated description.

> 
>>    - asm/acenv.h for arch specific ACPICA environments and
>>      implementation;
>>    - asm/acpi.h for arch specific variables and functions needed by
>>      ACPI driver core;
>>    - acpi.c for ARM64 related ACPI implementation for ACPI driver
>>      core;
>>
>> acpi_boot_table_init() is introduced to get RSDP and boot-time tables,
>> it will be called in setup_arch() before paging_init(), so we should
>> use eary_memremap() mechanism here to get the RSDP and all the table
>> pointers.
[...]
>> +
>> +/*
>> + * Checking for the posibility that the CPU can be initialized from the MADT.
>> + * It's used from ACPI core in crash kernel case where boot CPU is not
>> + * necessarily CPU0 like spec demands. Since MADT must provide at least one
> 
> Do you mean ACPI spec demands CPU0 to be boot cpu ?

ACPI spec demands CPU0 (BSP) should be the first entry in MADT.

> 
> IIUC it's basically to handle UP system with SMP kernel. IWO if all the
> ACPI resources are reused from SMP system to boot UP system with SMP
> kernel, with this check the ACPI core won't override the CPU index
> obtained from GIC/APIC mapping to zero.

Yes, you are right, I will update the comments.

> 
>> + * GICC structure for GIC initialization, CPU will be always available in
>> + * MADT on ARM64.
>> + */
>> +static inline bool acpi_has_cpu_in_madt(void)
>> +{
>> +    return 1;
> 
> probably true instead of 1

ok.

> 
>> +}
>> +
>> +static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>> +
>> +#endif /* CONFIG_ACPI */
>> +
>> +#endif /*_ASM_ACPI_H*/
>> diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
>> new file mode 100644
>> index 0000000..cee7d3f
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/cpu.h
>> @@ -0,0 +1,11 @@
>> +/*
>> + *  Copyright (C) 2013-2014 ARM Ltd.
>> + *
>> + * 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.
>> + */
>> +#ifndef __ASM_CPU_H
>> +#define __ASM_CPU_H
>> +
>> +#endif
>> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>> index cdaedad..b568c26 100644
>> --- a/arch/arm64/kernel/Makefile
>> +++ b/arch/arm64/kernel/Makefile
>> @@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)    += sleep.o suspend.o
>>   arm64-obj-$(CONFIG_JUMP_LABEL)        += jump_label.o
>>   arm64-obj-$(CONFIG_KGDB)        += kgdb.o
>>   arm64-obj-$(CONFIG_EFI)            += efi.o efi-stub.o efi-entry.o
>> +arm64-obj-$(CONFIG_ACPI)        += acpi.o
>>
>>   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
>> new file mode 100644
>> index 0000000..395778c
>> --- /dev/null
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -0,0 +1,69 @@
>> +/*
>> + *  ARM64 Specific Low-Level ACPI Boot Support
>> + *
>> + *  Copyright (C) 2013-2014, Linaro Ltd.
>> + *    Author: Al Stone <al.stone@linaro.org>
>> + *    Author: Graeme Gregory <graeme.gregory@linaro.org>
>> + *    Author: Hanjun Guo <hanjun.guo@linaro.org>
>> + *
>> + *  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.
>> + */
>> +
>> +#include <linux/init.h>
>> +#include <linux/acpi.h>
>> +#include <linux/cpumask.h>
>> +#include <linux/memblock.h>
>> +#include <linux/irq.h>
>> +#include <linux/irqdomain.h>
>> +#include <linux/bootmem.h>
>> +#include <linux/smp.h>
>> +
>> +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);
>> +
>> +/*
>> + * __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_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
>> + *
>> + * We can parse ACPI boot-time tables such as FADT, 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()) {
> 
> Can't we call acpi_table_init directly in setup ?
> IIUC x86 has acpi_boot_table_init as it parses Boot Flags
> table(ACPI_SIG_BOOT)

Yes, we can. But I think it not a big deal to dot that, if that
makes the code more readable, I will update it.

> 
>> +        disable_acpi();
>> +        return;
>> +    }
>> +}
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index fc50461..85c6326 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -43,6 +43,7 @@
>>   #include <linux/of_fdt.h>
>>   #include <linux/of_platform.h>
>>   #include <linux/efi.h>
>> +#include <linux/acpi.h>
>>
>>   #include <asm/fixmap.h>
>>   #include <asm/cputype.h>
>> @@ -385,6 +386,9 @@ void __init setup_arch(char **cmdline_p)
>>       efi_init();
>>       arm64_memblock_init();
>>
>> +    /* Parse the ACPI tables for possible boot-time configuration */
>> +    acpi_boot_table_init();
>> +
>>       paging_init();
>>       request_standard_resources();

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
  2014-08-19  9:35       ` Hanjun Guo
  (?)
@ 2014-08-19  9:47         ` Sudeep Holla
  -1 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-19  9:47 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel@lists.infradead.org



On 19/08/14 10:35, Hanjun Guo wrote:
> On 2014-8-19 2:30, Sudeep Holla wrote:
>> On 04/08/14 16:28, Hanjun Guo wrote:
>>> From: Al Stone <al.stone@linaro.org>
>>>
>>> As we want to get ACPI tables to parse and then use the information
>>> for system initialization, we should get the RSDP (Root System
>>> Description Pointer) first, it then locates Extended Root Description
>>> Table (XSDT) which contains all the 64-bit physical address that
>>> pointer to other boot-time tables.
>>>
>>> Introduce acpi.c and its related head file in this patch to provide
>>> fundamental needs of extern variables and functions for ACPI core,
>>> and then get boot-time tables as needed.
>>>     - asm/cpu.h need for ACPI core and will be updated in the future to
>>>       add definitions for arch_(un)register_cpu which are required for
>>>       ACPI based physical CPU hotplug;
>>

[...]

>>> +/*
>>> + * 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
>>> + *
>>> + * We can parse ACPI boot-time tables such as FADT, 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()) {
>>
>> Can't we call acpi_table_init directly in setup ?
>> IIUC x86 has acpi_boot_table_init as it parses Boot Flags
>> table(ACPI_SIG_BOOT)
>
> Yes, we can. But I think it not a big deal to dot that, if that
> makes the code more readable, I will update it.
>

I agree, but I actually wanted to check if we ever have to use/parse
Simple Boot Flag Table on ARM64 which is reserved but not part of ACPI
spec. I assume x86 use either for Legacy reason or firmware expects it.

Regards,
Sudeep


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
@ 2014-08-19  9:47         ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-19  9:47 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi, Al Stone,
	Tomasz Nowicki



On 19/08/14 10:35, Hanjun Guo wrote:
> On 2014-8-19 2:30, Sudeep Holla wrote:
>> On 04/08/14 16:28, Hanjun Guo wrote:
>>> From: Al Stone <al.stone@linaro.org>
>>>
>>> As we want to get ACPI tables to parse and then use the information
>>> for system initialization, we should get the RSDP (Root System
>>> Description Pointer) first, it then locates Extended Root Description
>>> Table (XSDT) which contains all the 64-bit physical address that
>>> pointer to other boot-time tables.
>>>
>>> Introduce acpi.c and its related head file in this patch to provide
>>> fundamental needs of extern variables and functions for ACPI core,
>>> and then get boot-time tables as needed.
>>>     - asm/cpu.h need for ACPI core and will be updated in the future to
>>>       add definitions for arch_(un)register_cpu which are required for
>>>       ACPI based physical CPU hotplug;
>>

[...]

>>> +/*
>>> + * 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
>>> + *
>>> + * We can parse ACPI boot-time tables such as FADT, 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()) {
>>
>> Can't we call acpi_table_init directly in setup ?
>> IIUC x86 has acpi_boot_table_init as it parses Boot Flags
>> table(ACPI_SIG_BOOT)
>
> Yes, we can. But I think it not a big deal to dot that, if that
> makes the code more readable, I will update it.
>

I agree, but I actually wanted to check if we ever have to use/parse
Simple Boot Flag Table on ARM64 which is reserved but not part of ACPI
spec. I assume x86 use either for Legacy reason or firmware expects it.

Regards,
Sudeep


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables
@ 2014-08-19  9:47         ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-19  9:47 UTC (permalink / raw)
  To: linux-arm-kernel



On 19/08/14 10:35, Hanjun Guo wrote:
> On 2014-8-19 2:30, Sudeep Holla wrote:
>> On 04/08/14 16:28, Hanjun Guo wrote:
>>> From: Al Stone <al.stone@linaro.org>
>>>
>>> As we want to get ACPI tables to parse and then use the information
>>> for system initialization, we should get the RSDP (Root System
>>> Description Pointer) first, it then locates Extended Root Description
>>> Table (XSDT) which contains all the 64-bit physical address that
>>> pointer to other boot-time tables.
>>>
>>> Introduce acpi.c and its related head file in this patch to provide
>>> fundamental needs of extern variables and functions for ACPI core,
>>> and then get boot-time tables as needed.
>>>     - asm/cpu.h need for ACPI core and will be updated in the future to
>>>       add definitions for arch_(un)register_cpu which are required for
>>>       ACPI based physical CPU hotplug;
>>

[...]

>>> +/*
>>> + * 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
>>> + *
>>> + * We can parse ACPI boot-time tables such as FADT, 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()) {
>>
>> Can't we call acpi_table_init directly in setup ?
>> IIUC x86 has acpi_boot_table_init as it parses Boot Flags
>> table(ACPI_SIG_BOOT)
>
> Yes, we can. But I think it not a big deal to dot that, if that
> makes the code more readable, I will update it.
>

I agree, but I actually wanted to check if we ever have to use/parse
Simple Boot Flag Table on ARM64 which is reserved but not part of ACPI
spec. I assume x86 use either for Legacy reason or firmware expects it.

Regards,
Sudeep

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-18 18:32     ` Sudeep Holla
  (?)
@ 2014-08-19 10:39       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 10:39 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel

On 2014-8-19 2:32, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
>> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
>> the former signals to the OS that the hardware is PSCI compliant.
>> The latter selects the appropriate conduit for PSCI calls by
>> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
>> (SMC).
>>
>> FADT table contains such information, parse FADT to get the flags
>> for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
>> function IDs, which means that only PSCI 0.2+ is supported in ACPI.
>>
>> At the same time, only ACPI 5.1 or higher verison supports PSCI,
>> and FADT Major.Minor version was introduced in ACPI 5.1, so we
>> will check the version and only parse FADT table with version >= 5.1.
>>
>> If firmware provides ACPI tables with ACPI version less than 5.1,
>> OS will be messed up with those information and have no way to
>> bring up secondery CPUs, so disable ACPI if we get an FADT table
>> with version less that 5.1.
>>
[...]
>>
>> +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 version,
>> +     * and there is a minor version of FADT which was introduced
>> +     * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>> +     * to get arm boot flags, or we will disable ACPI.
>> +     */
>> +    if (table->revision < 5 || fadt->minor_revision < 1) {
> 
>                 &&

Catalin also pointed out this bug :), but && is not enough, for example,
this would not trigger of revision 4.1, although 4.1 is not exist, but
the code will still confusing people, so I updated the code as:

+       if (table->revision > 5 ||
+           (table->revision == 5 && fadt->minor_revision >= 1)) {
+               return 0;
+       } else {
+               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
or higher\n",
+                       table->revision, fadt->minor_revision);
+               disable_acpi();
+               return -EINVAL;
+       }

> 
>> +        pr_info("FADT version is %d.%d, no PSCI support, should be 5.1 or
>> higher\n",
>> +            table->revision, fadt->minor_revision);
>> +        disable_acpi();
> 
> Instead of disabling ACPI at multiple places in the boot sequence, can't
> it be done once if acpi_boot_init failed ?
> 
>> +        return -EINVAL;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   /*
>>    * acpi_boot_table_init() called from setup_arch(), always.
>>    *    1. find RSDP and get its address, and then find XSDT
>> @@ -68,6 +90,21 @@ void __init acpi_boot_table_init(void)
>>       }
>>   }
>>
>> +int __init acpi_boot_init(void)
>> +{
>> +    int err = 0;
>> +
>> +    /* If acpi_disabled, bail out */
>> +    if (acpi_disabled)
>> +        return -ENODEV;
>> +
>> +    err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
>> +    if (err)
>> +        pr_err("Can't find FADT\n");
>> +
>> +    return err;
>> +}
>> +
>>   /*
>>    * acpi_suspend_lowlevel() - save kernel state and suspend.
>>    *
>> diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
>> index 9e9798f..2ad2084 100644
>> --- a/arch/arm64/kernel/psci.c
>> +++ b/arch/arm64/kernel/psci.c
>> @@ -15,6 +15,7 @@
>>
>>   #define pr_fmt(fmt) "psci: " fmt
>>
>> +#include <linux/acpi.h>
>>   #include <linux/init.h>
>>   #include <linux/of.h>
>>   #include <linux/smp.h>
>> @@ -231,6 +232,33 @@ static void psci_sys_poweroff(void)
>>       invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
>>   }
>>
>> +static void psci_0_2_set_functions(void)
>> +{
>> +    pr_info("Using standard PSCI v0.2 function IDs\n");
>> +    psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
>> +    psci_ops.cpu_suspend = psci_cpu_suspend;
>> +
>> +    psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
>> +    psci_ops.cpu_off = psci_cpu_off;
>> +
>> +    psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
>> +    psci_ops.cpu_on = psci_cpu_on;
>> +
>> +    psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
>> +    psci_ops.migrate = psci_migrate;
>> +
>> +    psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
>> +    psci_ops.affinity_info = psci_affinity_info;
>> +
>> +    psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
>> +        PSCI_0_2_FN_MIGRATE_INFO_TYPE;
>> +    psci_ops.migrate_info_type = psci_migrate_info_type;
>> +
>> +    arm_pm_restart = psci_sys_reset;
>> +
>> +    pm_power_off = psci_sys_poweroff;
>> +}
>> +
> 
> Nit: IMO may be you can move these refactoring as separate patch before
> ACPI related changes ?

I'm ok with it, will format another patch and place it in the
beginning of this patch set.

> 
>>   /*
>>    * PSCI Function IDs for v0.2+ are well defined so use
>>    * standard values.
>> @@ -264,29 +292,7 @@ static int psci_0_2_init(struct device_node *np)
>>           }
>>       }
>>
>> -    pr_info("Using standard PSCI v0.2 function IDs\n");
>> -    psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
>> -    psci_ops.cpu_suspend = psci_cpu_suspend;
>> -
>> -    psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
>> -    psci_ops.cpu_off = psci_cpu_off;
>> -
>> -    psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
>> -    psci_ops.cpu_on = psci_cpu_on;
>> -
>> -    psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
>> -    psci_ops.migrate = psci_migrate;
>> -
>> -    psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
>> -    psci_ops.affinity_info = psci_affinity_info;
>> -
>> -    psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
>> -        PSCI_0_2_FN_MIGRATE_INFO_TYPE;
>> -    psci_ops.migrate_info_type = psci_migrate_info_type;
>> -
>> -    arm_pm_restart = psci_sys_reset;
>> -
>> -    pm_power_off = psci_sys_poweroff;
>> +    psci_0_2_set_functions();
>>
>>   out_put_node:
>>       of_node_put(np);
>> @@ -333,6 +339,40 @@ out_put_node:
>>       return err;
>>   }
>>
>> +#ifdef CONFIG_ACPI
>> +static int get_set_conduit_method_acpi(void)
>> +{
>> +    pr_info("probing for conduit method from ACPI.\n");
>> +
>> +    if (acpi_psci_use_hvc())
>> +        invoke_psci_fn = __invoke_psci_fn_hvc;
>> +    else
>> +        invoke_psci_fn = __invoke_psci_fn_smc;
>> +
>> +    return 0;
>> +}
>> +
>> +/* We use PSCI 0.2+ when ACPI is deployed */
>> +static int psci_0_2_init_acpi(void)
> 
> May be this can be renamed psci_acpi_init and called from setup directly
> instead of calling from DT function with acpi_disabled check.

Also suggested by Catalin, will do it :)

> 
>> +{
>> +    if (!acpi_psci_present()) {
>> +        pr_info("is not implemented in ACPI.\n");
>> +        return -EOPNOTSUPP;
>> +    }
>> +
>> +    get_set_conduit_method_acpi();
>> +
>> +    psci_0_2_set_functions();
>> +
>> +    return 0;
>> +}
>> +#else
>> +static inline int psci_0_2_init_acpi(void)
>> +{
>> +    return -ENODEV;
>> +}
>> +#endif
>> +
>>   static const struct of_device_id psci_of_match[] __initconst = {
>>       { .compatible = "arm,psci",    .data = psci_0_1_init},
>>       { .compatible = "arm,psci-0.2",    .data = psci_0_2_init},
>> @@ -345,6 +385,9 @@ int __init psci_init(void)
>>       const struct of_device_id *matched_np;
>>       psci_initcall_t init_fn;
>>
>> +    if (!acpi_disabled)
>> +        return psci_0_2_init_acpi();
>> +
> 
> As mentioned above you need not modify this.
> 
>>       np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
>>
>>       if (!np)
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index 85c6326..dfc4e4f3 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>>       efi_idmap_init();
>>
>>       cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
>> +    acpi_boot_init();
>> +
> 
> Check for the return error here and disable ACPI once rather than at
> multiple places all over.

ok.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 10:39       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 10:39 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel,
	linux-kernel, linaro-acpi

On 2014-8-19 2:32, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
>> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
>> the former signals to the OS that the hardware is PSCI compliant.
>> The latter selects the appropriate conduit for PSCI calls by
>> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
>> (SMC).
>>
>> FADT table contains such information, parse FADT to get the flags
>> for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
>> function IDs, which means that only PSCI 0.2+ is supported in ACPI.
>>
>> At the same time, only ACPI 5.1 or higher verison supports PSCI,
>> and FADT Major.Minor version was introduced in ACPI 5.1, so we
>> will check the version and only parse FADT table with version >= 5.1.
>>
>> If firmware provides ACPI tables with ACPI version less than 5.1,
>> OS will be messed up with those information and have no way to
>> bring up secondery CPUs, so disable ACPI if we get an FADT table
>> with version less that 5.1.
>>
[...]
>>
>> +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 version,
>> +     * and there is a minor version of FADT which was introduced
>> +     * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>> +     * to get arm boot flags, or we will disable ACPI.
>> +     */
>> +    if (table->revision < 5 || fadt->minor_revision < 1) {
> 
>                 &&

Catalin also pointed out this bug :), but && is not enough, for example,
this would not trigger of revision 4.1, although 4.1 is not exist, but
the code will still confusing people, so I updated the code as:

+       if (table->revision > 5 ||
+           (table->revision == 5 && fadt->minor_revision >= 1)) {
+               return 0;
+       } else {
+               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
or higher\n",
+                       table->revision, fadt->minor_revision);
+               disable_acpi();
+               return -EINVAL;
+       }

> 
>> +        pr_info("FADT version is %d.%d, no PSCI support, should be 5.1 or
>> higher\n",
>> +            table->revision, fadt->minor_revision);
>> +        disable_acpi();
> 
> Instead of disabling ACPI at multiple places in the boot sequence, can't
> it be done once if acpi_boot_init failed ?
> 
>> +        return -EINVAL;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   /*
>>    * acpi_boot_table_init() called from setup_arch(), always.
>>    *    1. find RSDP and get its address, and then find XSDT
>> @@ -68,6 +90,21 @@ void __init acpi_boot_table_init(void)
>>       }
>>   }
>>
>> +int __init acpi_boot_init(void)
>> +{
>> +    int err = 0;
>> +
>> +    /* If acpi_disabled, bail out */
>> +    if (acpi_disabled)
>> +        return -ENODEV;
>> +
>> +    err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
>> +    if (err)
>> +        pr_err("Can't find FADT\n");
>> +
>> +    return err;
>> +}
>> +
>>   /*
>>    * acpi_suspend_lowlevel() - save kernel state and suspend.
>>    *
>> diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
>> index 9e9798f..2ad2084 100644
>> --- a/arch/arm64/kernel/psci.c
>> +++ b/arch/arm64/kernel/psci.c
>> @@ -15,6 +15,7 @@
>>
>>   #define pr_fmt(fmt) "psci: " fmt
>>
>> +#include <linux/acpi.h>
>>   #include <linux/init.h>
>>   #include <linux/of.h>
>>   #include <linux/smp.h>
>> @@ -231,6 +232,33 @@ static void psci_sys_poweroff(void)
>>       invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
>>   }
>>
>> +static void psci_0_2_set_functions(void)
>> +{
>> +    pr_info("Using standard PSCI v0.2 function IDs\n");
>> +    psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
>> +    psci_ops.cpu_suspend = psci_cpu_suspend;
>> +
>> +    psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
>> +    psci_ops.cpu_off = psci_cpu_off;
>> +
>> +    psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
>> +    psci_ops.cpu_on = psci_cpu_on;
>> +
>> +    psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
>> +    psci_ops.migrate = psci_migrate;
>> +
>> +    psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
>> +    psci_ops.affinity_info = psci_affinity_info;
>> +
>> +    psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
>> +        PSCI_0_2_FN_MIGRATE_INFO_TYPE;
>> +    psci_ops.migrate_info_type = psci_migrate_info_type;
>> +
>> +    arm_pm_restart = psci_sys_reset;
>> +
>> +    pm_power_off = psci_sys_poweroff;
>> +}
>> +
> 
> Nit: IMO may be you can move these refactoring as separate patch before
> ACPI related changes ?

I'm ok with it, will format another patch and place it in the
beginning of this patch set.

> 
>>   /*
>>    * PSCI Function IDs for v0.2+ are well defined so use
>>    * standard values.
>> @@ -264,29 +292,7 @@ static int psci_0_2_init(struct device_node *np)
>>           }
>>       }
>>
>> -    pr_info("Using standard PSCI v0.2 function IDs\n");
>> -    psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
>> -    psci_ops.cpu_suspend = psci_cpu_suspend;
>> -
>> -    psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
>> -    psci_ops.cpu_off = psci_cpu_off;
>> -
>> -    psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
>> -    psci_ops.cpu_on = psci_cpu_on;
>> -
>> -    psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
>> -    psci_ops.migrate = psci_migrate;
>> -
>> -    psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
>> -    psci_ops.affinity_info = psci_affinity_info;
>> -
>> -    psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
>> -        PSCI_0_2_FN_MIGRATE_INFO_TYPE;
>> -    psci_ops.migrate_info_type = psci_migrate_info_type;
>> -
>> -    arm_pm_restart = psci_sys_reset;
>> -
>> -    pm_power_off = psci_sys_poweroff;
>> +    psci_0_2_set_functions();
>>
>>   out_put_node:
>>       of_node_put(np);
>> @@ -333,6 +339,40 @@ out_put_node:
>>       return err;
>>   }
>>
>> +#ifdef CONFIG_ACPI
>> +static int get_set_conduit_method_acpi(void)
>> +{
>> +    pr_info("probing for conduit method from ACPI.\n");
>> +
>> +    if (acpi_psci_use_hvc())
>> +        invoke_psci_fn = __invoke_psci_fn_hvc;
>> +    else
>> +        invoke_psci_fn = __invoke_psci_fn_smc;
>> +
>> +    return 0;
>> +}
>> +
>> +/* We use PSCI 0.2+ when ACPI is deployed */
>> +static int psci_0_2_init_acpi(void)
> 
> May be this can be renamed psci_acpi_init and called from setup directly
> instead of calling from DT function with acpi_disabled check.

Also suggested by Catalin, will do it :)

> 
>> +{
>> +    if (!acpi_psci_present()) {
>> +        pr_info("is not implemented in ACPI.\n");
>> +        return -EOPNOTSUPP;
>> +    }
>> +
>> +    get_set_conduit_method_acpi();
>> +
>> +    psci_0_2_set_functions();
>> +
>> +    return 0;
>> +}
>> +#else
>> +static inline int psci_0_2_init_acpi(void)
>> +{
>> +    return -ENODEV;
>> +}
>> +#endif
>> +
>>   static const struct of_device_id psci_of_match[] __initconst = {
>>       { .compatible = "arm,psci",    .data = psci_0_1_init},
>>       { .compatible = "arm,psci-0.2",    .data = psci_0_2_init},
>> @@ -345,6 +385,9 @@ int __init psci_init(void)
>>       const struct of_device_id *matched_np;
>>       psci_initcall_t init_fn;
>>
>> +    if (!acpi_disabled)
>> +        return psci_0_2_init_acpi();
>> +
> 
> As mentioned above you need not modify this.
> 
>>       np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
>>
>>       if (!np)
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index 85c6326..dfc4e4f3 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>>       efi_idmap_init();
>>
>>       cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
>> +    acpi_boot_init();
>> +
> 
> Check for the return error here and disable ACPI once rather than at
> multiple places all over.

ok.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 10:39       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-19 2:32, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
>> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
>> the former signals to the OS that the hardware is PSCI compliant.
>> The latter selects the appropriate conduit for PSCI calls by
>> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
>> (SMC).
>>
>> FADT table contains such information, parse FADT to get the flags
>> for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
>> function IDs, which means that only PSCI 0.2+ is supported in ACPI.
>>
>> At the same time, only ACPI 5.1 or higher verison supports PSCI,
>> and FADT Major.Minor version was introduced in ACPI 5.1, so we
>> will check the version and only parse FADT table with version >= 5.1.
>>
>> If firmware provides ACPI tables with ACPI version less than 5.1,
>> OS will be messed up with those information and have no way to
>> bring up secondery CPUs, so disable ACPI if we get an FADT table
>> with version less that 5.1.
>>
[...]
>>
>> +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 version,
>> +     * and there is a minor version of FADT which was introduced
>> +     * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>> +     * to get arm boot flags, or we will disable ACPI.
>> +     */
>> +    if (table->revision < 5 || fadt->minor_revision < 1) {
> 
>                 &&

Catalin also pointed out this bug :), but && is not enough, for example,
this would not trigger of revision 4.1, although 4.1 is not exist, but
the code will still confusing people, so I updated the code as:

+       if (table->revision > 5 ||
+           (table->revision == 5 && fadt->minor_revision >= 1)) {
+               return 0;
+       } else {
+               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
or higher\n",
+                       table->revision, fadt->minor_revision);
+               disable_acpi();
+               return -EINVAL;
+       }

> 
>> +        pr_info("FADT version is %d.%d, no PSCI support, should be 5.1 or
>> higher\n",
>> +            table->revision, fadt->minor_revision);
>> +        disable_acpi();
> 
> Instead of disabling ACPI at multiple places in the boot sequence, can't
> it be done once if acpi_boot_init failed ?
> 
>> +        return -EINVAL;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   /*
>>    * acpi_boot_table_init() called from setup_arch(), always.
>>    *    1. find RSDP and get its address, and then find XSDT
>> @@ -68,6 +90,21 @@ void __init acpi_boot_table_init(void)
>>       }
>>   }
>>
>> +int __init acpi_boot_init(void)
>> +{
>> +    int err = 0;
>> +
>> +    /* If acpi_disabled, bail out */
>> +    if (acpi_disabled)
>> +        return -ENODEV;
>> +
>> +    err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
>> +    if (err)
>> +        pr_err("Can't find FADT\n");
>> +
>> +    return err;
>> +}
>> +
>>   /*
>>    * acpi_suspend_lowlevel() - save kernel state and suspend.
>>    *
>> diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
>> index 9e9798f..2ad2084 100644
>> --- a/arch/arm64/kernel/psci.c
>> +++ b/arch/arm64/kernel/psci.c
>> @@ -15,6 +15,7 @@
>>
>>   #define pr_fmt(fmt) "psci: " fmt
>>
>> +#include <linux/acpi.h>
>>   #include <linux/init.h>
>>   #include <linux/of.h>
>>   #include <linux/smp.h>
>> @@ -231,6 +232,33 @@ static void psci_sys_poweroff(void)
>>       invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
>>   }
>>
>> +static void psci_0_2_set_functions(void)
>> +{
>> +    pr_info("Using standard PSCI v0.2 function IDs\n");
>> +    psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
>> +    psci_ops.cpu_suspend = psci_cpu_suspend;
>> +
>> +    psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
>> +    psci_ops.cpu_off = psci_cpu_off;
>> +
>> +    psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
>> +    psci_ops.cpu_on = psci_cpu_on;
>> +
>> +    psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
>> +    psci_ops.migrate = psci_migrate;
>> +
>> +    psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
>> +    psci_ops.affinity_info = psci_affinity_info;
>> +
>> +    psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
>> +        PSCI_0_2_FN_MIGRATE_INFO_TYPE;
>> +    psci_ops.migrate_info_type = psci_migrate_info_type;
>> +
>> +    arm_pm_restart = psci_sys_reset;
>> +
>> +    pm_power_off = psci_sys_poweroff;
>> +}
>> +
> 
> Nit: IMO may be you can move these refactoring as separate patch before
> ACPI related changes ?

I'm ok with it, will format another patch and place it in the
beginning of this patch set.

> 
>>   /*
>>    * PSCI Function IDs for v0.2+ are well defined so use
>>    * standard values.
>> @@ -264,29 +292,7 @@ static int psci_0_2_init(struct device_node *np)
>>           }
>>       }
>>
>> -    pr_info("Using standard PSCI v0.2 function IDs\n");
>> -    psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
>> -    psci_ops.cpu_suspend = psci_cpu_suspend;
>> -
>> -    psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
>> -    psci_ops.cpu_off = psci_cpu_off;
>> -
>> -    psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
>> -    psci_ops.cpu_on = psci_cpu_on;
>> -
>> -    psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
>> -    psci_ops.migrate = psci_migrate;
>> -
>> -    psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
>> -    psci_ops.affinity_info = psci_affinity_info;
>> -
>> -    psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
>> -        PSCI_0_2_FN_MIGRATE_INFO_TYPE;
>> -    psci_ops.migrate_info_type = psci_migrate_info_type;
>> -
>> -    arm_pm_restart = psci_sys_reset;
>> -
>> -    pm_power_off = psci_sys_poweroff;
>> +    psci_0_2_set_functions();
>>
>>   out_put_node:
>>       of_node_put(np);
>> @@ -333,6 +339,40 @@ out_put_node:
>>       return err;
>>   }
>>
>> +#ifdef CONFIG_ACPI
>> +static int get_set_conduit_method_acpi(void)
>> +{
>> +    pr_info("probing for conduit method from ACPI.\n");
>> +
>> +    if (acpi_psci_use_hvc())
>> +        invoke_psci_fn = __invoke_psci_fn_hvc;
>> +    else
>> +        invoke_psci_fn = __invoke_psci_fn_smc;
>> +
>> +    return 0;
>> +}
>> +
>> +/* We use PSCI 0.2+ when ACPI is deployed */
>> +static int psci_0_2_init_acpi(void)
> 
> May be this can be renamed psci_acpi_init and called from setup directly
> instead of calling from DT function with acpi_disabled check.

Also suggested by Catalin, will do it :)

> 
>> +{
>> +    if (!acpi_psci_present()) {
>> +        pr_info("is not implemented in ACPI.\n");
>> +        return -EOPNOTSUPP;
>> +    }
>> +
>> +    get_set_conduit_method_acpi();
>> +
>> +    psci_0_2_set_functions();
>> +
>> +    return 0;
>> +}
>> +#else
>> +static inline int psci_0_2_init_acpi(void)
>> +{
>> +    return -ENODEV;
>> +}
>> +#endif
>> +
>>   static const struct of_device_id psci_of_match[] __initconst = {
>>       { .compatible = "arm,psci",    .data = psci_0_1_init},
>>       { .compatible = "arm,psci-0.2",    .data = psci_0_2_init},
>> @@ -345,6 +385,9 @@ int __init psci_init(void)
>>       const struct of_device_id *matched_np;
>>       psci_initcall_t init_fn;
>>
>> +    if (!acpi_disabled)
>> +        return psci_0_2_init_acpi();
>> +
> 
> As mentioned above you need not modify this.
> 
>>       np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
>>
>>       if (!np)
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index 85c6326..dfc4e4f3 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -395,6 +395,8 @@ void __init setup_arch(char **cmdline_p)
>>       efi_idmap_init();
>>
>>       cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
>> +    acpi_boot_init();
>> +
> 
> Check for the return error here and disable ACPI once rather than at
> multiple places all over.

ok.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
  2014-08-18 18:33     ` Sudeep Holla
  (?)
@ 2014-08-19 11:00       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:00 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel

Hi Sudeep,

On 2014-8-19 2:33, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
>> MADT contains the information for MPIDR which is essential for
>> SMP initialization, parse the GIC cpu interface structures to
>> get the MPIDR value and map it to cpu_logical_map(), and add
>> enabled cpu with valid MPIDR into cpu_possible_map and
>> cpu_present_map.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>> ---
>>   arch/arm64/include/asm/acpi.h |    2 +
>>   arch/arm64/kernel/acpi.c      |  129 ++++++++++++++++++++++++++++++++++++++++-
>>   arch/arm64/kernel/smp.c       |   10 +++-
>>   3 files changed, 138 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 6e04868..e877967 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32
>> slot) { }
>>   extern int (*acpi_suspend_lowlevel)(void);
>>   #define acpi_wakeup_address 0
>>
>> +#define MAX_GIC_CPU_INTERFACE 65535
>> +
> 
> Did you get this information from GIC specification ?

Actually not. since MAX_GIC_CPU_INTERFACE represents the maximum GIC CPU
interfaces (CPUs) entries in MADT, so I use a number big enough to represent max
CPUs in the system.

> 
> IIUC you are trying to represent max number of interrupt controller
> entries MADT can possibly have. So, I had suggested to change the name
> like MAX_MADT_INTERRUPT_CONTROLLER_ENTRIES so that it is not GIC specific.

Will INTERRUPT_CONTROLLER confuse people? There is only one GIC redistributor
(some people regard it as interrupt controller) in ARM system, if we use
INTERRUPT_CONTROLLER people will regard it as multi-redistributors in the
system, I think GIC_CPU_INTERFACE would be better, what do you think?

> 
>>   #endif /* CONFIG_ACPI */
>>
>>   #endif /*_ASM_ACPI_H*/
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index 69a315d..9e07d99 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -22,6 +22,9 @@
>>   #include <linux/bootmem.h>
>>   #include <linux/smp.h>
>>
>> +#include <asm/smp_plat.h>
>> +#include <asm/cputype.h>
>> +
>>   int acpi_noirq;            /* skip ACPI IRQ initialization */
>>   int acpi_disabled;
>>   EXPORT_SYMBOL(acpi_disabled);
>> @@ -29,6 +32,8 @@ 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 */
>> +
>>   /*
>>    * __acpi_map_table() will be called before page_init(), so early_ioremap()
>>    * or early_memremap() should be called here to for ACPI table mapping.
>> @@ -49,6 +54,122 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>>       early_memunmap(map, size);
>>   }
>>
>> +/**
>> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
>> + * generates a logical cpu number
>> + * @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 the gic cpu interface
>> + */
>> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
>> +{
> 
> IMO the function name gives me a wrong idea that you are registering
> something with GIC. How about acpi_map_gic_cpu_interface ?

Great, acpi_map_gic_cpu_interface is better.

> 
>> +    int cpu;
>> +
>> +    if (mpidr == INVALID_HWID) {
>> +        pr_info("Skip invalid cpu hardware ID\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;
>> +    }
>> +
>> +    /* If it is the first CPU, no need to check duplicate MPIDRs */
>> +    if (!enabled_cpus)
>> +        goto skip_mpidr_check;
>> +
>> +    /*
>> +     * 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_present_cpu(cpu) {
>> +        if (cpu_logical_map(cpu) == mpidr) {
>> +            pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
>> +                   mpidr);
>> +            return -EINVAL;
>> +        }
>> +    }
>> +
>> +skip_mpidr_check:
>> +    enabled_cpus++;
>> +
>> +    /* allocate a logical cpu id for the new comer */
>> +    if (cpu_logical_map(0) == mpidr) {
>> +        /*
>> +         * boot_cpu_init() already hold bit 0 in cpu_present_mask
>> +         * for BSP, no need to allocate again.
>> +         */
>> +        cpu = 0;
>> +    } else {
>> +        cpu = cpumask_next_zero(-1, cpu_present_mask);
>> +    }
>> +
>> +    /* map the logical cpu id to cpu MPIDR */
>> +    cpu_logical_map(cpu) = mpidr;
>> +
>> +    set_cpu_possible(cpu, true);
> 
> IMO it better to keep all these updates to cpumasks contained in the
> smp.c as I had mentioned before. I think you can refactor smp_init_cpus
> to achieve that.

Could you give me more hints? smp_init_cpus() use the CPU node in device
tree to map cpu, but in ACPI, they are table entries, if you can give me
more hints about how to refactor it, I will appreciate a lot.

> 
>> +    set_cpu_present(cpu, true);
> 
> This is totally wrong ? What would you do if the cpu failed to
> initialize ? I don't see that handled.
> 
>> +
>> +    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_register_gic_cpu_interface(processor->arm_mpidr,
>> +        processor->flags & ACPI_MADT_ENABLED);
>> +
>> +    return 0;
>> +}
>> +
>> +/*
>> + * Parse GIC cpu interface related entries in MADT
>> + * returns 0 on success, < 0 on error
>> + */
>> +static int __init acpi_parse_madt_gic_cpu_interface_entries(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, MAX_GIC_CPU_INTERFACE);
>> +
>> +    if (!count) {
>> +        pr_err("No GIC CPU interface entries present\n");
>> +        return -ENODEV;
>> +    } else if (count < 0) {
>> +        pr_err("Error parsing GIC CPU interface entry\n");
>> +        return count;
>> +    }
>> +
>> +    /* Make boot-up look pretty */
>> +    pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);
> 
> Ideally just setup cpu_logical_map in acpi_parse_gic_cpu_interface and
> setup cpumasks in smp_init_cpus.
> 
>> +
>> +    return 0;
>> +}
>> +
>>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>>   {
>>       struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
>> @@ -99,8 +220,12 @@ int __init acpi_boot_init(void)
>>           return -ENODEV;
>>
>>       err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
>> -    if (err)
>> -        pr_err("Can't find FADT\n");
>> +    if (err) {
>> +        pr_err("Can't find FADT or error happened during parsing FADT\n");
>> +        return err;
>> +    }
>> +
>> +    err = acpi_parse_madt_gic_cpu_interface_entries();
>>
>>       return err;
>>   }
>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>> index 40f38f4..8f1d37c 100644
>> --- a/arch/arm64/kernel/smp.c
>> +++ b/arch/arm64/kernel/smp.c
>> @@ -36,6 +36,7 @@
>>   #include <linux/completion.h>
>>   #include <linux/of.h>
>>   #include <linux/irq_work.h>
>> +#include <linux/acpi.h>
>>
>>   #include <asm/atomic.h>
>>   #include <asm/cacheflush.h>
>> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>>           if (err)
>>               continue;
>>
>> -        set_cpu_present(cpu, true);
>> +        /*
>> +         * In ACPI mode, cpu_present_map was initialised when
>> +         * MADT table was parsed which before this function
>> +         * is called.
>> +         */
>> +        if (acpi_disabled)
>> +            set_cpu_present(cpu, true);
>> +
> 
> This is the right place to set the cpu present based on the return value
> of cpu_prepare.

Yes, as I replied in previous email, I will update the patch and consider
CPU hotplug in the future.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-19 11:00       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:00 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel,
	linux-kernel, linaro-acpi, Tomasz Nowicki

Hi Sudeep,

On 2014-8-19 2:33, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
>> MADT contains the information for MPIDR which is essential for
>> SMP initialization, parse the GIC cpu interface structures to
>> get the MPIDR value and map it to cpu_logical_map(), and add
>> enabled cpu with valid MPIDR into cpu_possible_map and
>> cpu_present_map.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>> ---
>>   arch/arm64/include/asm/acpi.h |    2 +
>>   arch/arm64/kernel/acpi.c      |  129 ++++++++++++++++++++++++++++++++++++++++-
>>   arch/arm64/kernel/smp.c       |   10 +++-
>>   3 files changed, 138 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 6e04868..e877967 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32
>> slot) { }
>>   extern int (*acpi_suspend_lowlevel)(void);
>>   #define acpi_wakeup_address 0
>>
>> +#define MAX_GIC_CPU_INTERFACE 65535
>> +
> 
> Did you get this information from GIC specification ?

Actually not. since MAX_GIC_CPU_INTERFACE represents the maximum GIC CPU
interfaces (CPUs) entries in MADT, so I use a number big enough to represent max
CPUs in the system.

> 
> IIUC you are trying to represent max number of interrupt controller
> entries MADT can possibly have. So, I had suggested to change the name
> like MAX_MADT_INTERRUPT_CONTROLLER_ENTRIES so that it is not GIC specific.

Will INTERRUPT_CONTROLLER confuse people? There is only one GIC redistributor
(some people regard it as interrupt controller) in ARM system, if we use
INTERRUPT_CONTROLLER people will regard it as multi-redistributors in the
system, I think GIC_CPU_INTERFACE would be better, what do you think?

> 
>>   #endif /* CONFIG_ACPI */
>>
>>   #endif /*_ASM_ACPI_H*/
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index 69a315d..9e07d99 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -22,6 +22,9 @@
>>   #include <linux/bootmem.h>
>>   #include <linux/smp.h>
>>
>> +#include <asm/smp_plat.h>
>> +#include <asm/cputype.h>
>> +
>>   int acpi_noirq;            /* skip ACPI IRQ initialization */
>>   int acpi_disabled;
>>   EXPORT_SYMBOL(acpi_disabled);
>> @@ -29,6 +32,8 @@ 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 */
>> +
>>   /*
>>    * __acpi_map_table() will be called before page_init(), so early_ioremap()
>>    * or early_memremap() should be called here to for ACPI table mapping.
>> @@ -49,6 +54,122 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>>       early_memunmap(map, size);
>>   }
>>
>> +/**
>> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
>> + * generates a logical cpu number
>> + * @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 the gic cpu interface
>> + */
>> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
>> +{
> 
> IMO the function name gives me a wrong idea that you are registering
> something with GIC. How about acpi_map_gic_cpu_interface ?

Great, acpi_map_gic_cpu_interface is better.

> 
>> +    int cpu;
>> +
>> +    if (mpidr == INVALID_HWID) {
>> +        pr_info("Skip invalid cpu hardware ID\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;
>> +    }
>> +
>> +    /* If it is the first CPU, no need to check duplicate MPIDRs */
>> +    if (!enabled_cpus)
>> +        goto skip_mpidr_check;
>> +
>> +    /*
>> +     * 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_present_cpu(cpu) {
>> +        if (cpu_logical_map(cpu) == mpidr) {
>> +            pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
>> +                   mpidr);
>> +            return -EINVAL;
>> +        }
>> +    }
>> +
>> +skip_mpidr_check:
>> +    enabled_cpus++;
>> +
>> +    /* allocate a logical cpu id for the new comer */
>> +    if (cpu_logical_map(0) == mpidr) {
>> +        /*
>> +         * boot_cpu_init() already hold bit 0 in cpu_present_mask
>> +         * for BSP, no need to allocate again.
>> +         */
>> +        cpu = 0;
>> +    } else {
>> +        cpu = cpumask_next_zero(-1, cpu_present_mask);
>> +    }
>> +
>> +    /* map the logical cpu id to cpu MPIDR */
>> +    cpu_logical_map(cpu) = mpidr;
>> +
>> +    set_cpu_possible(cpu, true);
> 
> IMO it better to keep all these updates to cpumasks contained in the
> smp.c as I had mentioned before. I think you can refactor smp_init_cpus
> to achieve that.

Could you give me more hints? smp_init_cpus() use the CPU node in device
tree to map cpu, but in ACPI, they are table entries, if you can give me
more hints about how to refactor it, I will appreciate a lot.

> 
>> +    set_cpu_present(cpu, true);
> 
> This is totally wrong ? What would you do if the cpu failed to
> initialize ? I don't see that handled.
> 
>> +
>> +    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_register_gic_cpu_interface(processor->arm_mpidr,
>> +        processor->flags & ACPI_MADT_ENABLED);
>> +
>> +    return 0;
>> +}
>> +
>> +/*
>> + * Parse GIC cpu interface related entries in MADT
>> + * returns 0 on success, < 0 on error
>> + */
>> +static int __init acpi_parse_madt_gic_cpu_interface_entries(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, MAX_GIC_CPU_INTERFACE);
>> +
>> +    if (!count) {
>> +        pr_err("No GIC CPU interface entries present\n");
>> +        return -ENODEV;
>> +    } else if (count < 0) {
>> +        pr_err("Error parsing GIC CPU interface entry\n");
>> +        return count;
>> +    }
>> +
>> +    /* Make boot-up look pretty */
>> +    pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);
> 
> Ideally just setup cpu_logical_map in acpi_parse_gic_cpu_interface and
> setup cpumasks in smp_init_cpus.
> 
>> +
>> +    return 0;
>> +}
>> +
>>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>>   {
>>       struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
>> @@ -99,8 +220,12 @@ int __init acpi_boot_init(void)
>>           return -ENODEV;
>>
>>       err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
>> -    if (err)
>> -        pr_err("Can't find FADT\n");
>> +    if (err) {
>> +        pr_err("Can't find FADT or error happened during parsing FADT\n");
>> +        return err;
>> +    }
>> +
>> +    err = acpi_parse_madt_gic_cpu_interface_entries();
>>
>>       return err;
>>   }
>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>> index 40f38f4..8f1d37c 100644
>> --- a/arch/arm64/kernel/smp.c
>> +++ b/arch/arm64/kernel/smp.c
>> @@ -36,6 +36,7 @@
>>   #include <linux/completion.h>
>>   #include <linux/of.h>
>>   #include <linux/irq_work.h>
>> +#include <linux/acpi.h>
>>
>>   #include <asm/atomic.h>
>>   #include <asm/cacheflush.h>
>> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>>           if (err)
>>               continue;
>>
>> -        set_cpu_present(cpu, true);
>> +        /*
>> +         * In ACPI mode, cpu_present_map was initialised when
>> +         * MADT table was parsed which before this function
>> +         * is called.
>> +         */
>> +        if (acpi_disabled)
>> +            set_cpu_present(cpu, true);
>> +
> 
> This is the right place to set the cpu present based on the return value
> of cpu_prepare.

Yes, as I replied in previous email, I will update the patch and consider
CPU hotplug in the future.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-19 11:00       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sudeep,

On 2014-8-19 2:33, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
>> MADT contains the information for MPIDR which is essential for
>> SMP initialization, parse the GIC cpu interface structures to
>> get the MPIDR value and map it to cpu_logical_map(), and add
>> enabled cpu with valid MPIDR into cpu_possible_map and
>> cpu_present_map.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
>> ---
>>   arch/arm64/include/asm/acpi.h |    2 +
>>   arch/arm64/kernel/acpi.c      |  129 ++++++++++++++++++++++++++++++++++++++++-
>>   arch/arm64/kernel/smp.c       |   10 +++-
>>   3 files changed, 138 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>> index 6e04868..e877967 100644
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32
>> slot) { }
>>   extern int (*acpi_suspend_lowlevel)(void);
>>   #define acpi_wakeup_address 0
>>
>> +#define MAX_GIC_CPU_INTERFACE 65535
>> +
> 
> Did you get this information from GIC specification ?

Actually not. since MAX_GIC_CPU_INTERFACE represents the maximum GIC CPU
interfaces (CPUs) entries in MADT, so I use a number big enough to represent max
CPUs in the system.

> 
> IIUC you are trying to represent max number of interrupt controller
> entries MADT can possibly have. So, I had suggested to change the name
> like MAX_MADT_INTERRUPT_CONTROLLER_ENTRIES so that it is not GIC specific.

Will INTERRUPT_CONTROLLER confuse people? There is only one GIC redistributor
(some people regard it as interrupt controller) in ARM system, if we use
INTERRUPT_CONTROLLER people will regard it as multi-redistributors in the
system, I think GIC_CPU_INTERFACE would be better, what do you think?

> 
>>   #endif /* CONFIG_ACPI */
>>
>>   #endif /*_ASM_ACPI_H*/
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index 69a315d..9e07d99 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -22,6 +22,9 @@
>>   #include <linux/bootmem.h>
>>   #include <linux/smp.h>
>>
>> +#include <asm/smp_plat.h>
>> +#include <asm/cputype.h>
>> +
>>   int acpi_noirq;            /* skip ACPI IRQ initialization */
>>   int acpi_disabled;
>>   EXPORT_SYMBOL(acpi_disabled);
>> @@ -29,6 +32,8 @@ 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 */
>> +
>>   /*
>>    * __acpi_map_table() will be called before page_init(), so early_ioremap()
>>    * or early_memremap() should be called here to for ACPI table mapping.
>> @@ -49,6 +54,122 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>>       early_memunmap(map, size);
>>   }
>>
>> +/**
>> + * acpi_register_gic_cpu_interface - register a gic cpu interface and
>> + * generates a logical cpu number
>> + * @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 the gic cpu interface
>> + */
>> +static int acpi_register_gic_cpu_interface(u64 mpidr, u8 enabled)
>> +{
> 
> IMO the function name gives me a wrong idea that you are registering
> something with GIC. How about acpi_map_gic_cpu_interface ?

Great, acpi_map_gic_cpu_interface is better.

> 
>> +    int cpu;
>> +
>> +    if (mpidr == INVALID_HWID) {
>> +        pr_info("Skip invalid cpu hardware ID\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;
>> +    }
>> +
>> +    /* If it is the first CPU, no need to check duplicate MPIDRs */
>> +    if (!enabled_cpus)
>> +        goto skip_mpidr_check;
>> +
>> +    /*
>> +     * 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_present_cpu(cpu) {
>> +        if (cpu_logical_map(cpu) == mpidr) {
>> +            pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
>> +                   mpidr);
>> +            return -EINVAL;
>> +        }
>> +    }
>> +
>> +skip_mpidr_check:
>> +    enabled_cpus++;
>> +
>> +    /* allocate a logical cpu id for the new comer */
>> +    if (cpu_logical_map(0) == mpidr) {
>> +        /*
>> +         * boot_cpu_init() already hold bit 0 in cpu_present_mask
>> +         * for BSP, no need to allocate again.
>> +         */
>> +        cpu = 0;
>> +    } else {
>> +        cpu = cpumask_next_zero(-1, cpu_present_mask);
>> +    }
>> +
>> +    /* map the logical cpu id to cpu MPIDR */
>> +    cpu_logical_map(cpu) = mpidr;
>> +
>> +    set_cpu_possible(cpu, true);
> 
> IMO it better to keep all these updates to cpumasks contained in the
> smp.c as I had mentioned before. I think you can refactor smp_init_cpus
> to achieve that.

Could you give me more hints? smp_init_cpus() use the CPU node in device
tree to map cpu, but in ACPI, they are table entries, if you can give me
more hints about how to refactor it, I will appreciate a lot.

> 
>> +    set_cpu_present(cpu, true);
> 
> This is totally wrong ? What would you do if the cpu failed to
> initialize ? I don't see that handled.
> 
>> +
>> +    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_register_gic_cpu_interface(processor->arm_mpidr,
>> +        processor->flags & ACPI_MADT_ENABLED);
>> +
>> +    return 0;
>> +}
>> +
>> +/*
>> + * Parse GIC cpu interface related entries in MADT
>> + * returns 0 on success, < 0 on error
>> + */
>> +static int __init acpi_parse_madt_gic_cpu_interface_entries(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, MAX_GIC_CPU_INTERFACE);
>> +
>> +    if (!count) {
>> +        pr_err("No GIC CPU interface entries present\n");
>> +        return -ENODEV;
>> +    } else if (count < 0) {
>> +        pr_err("Error parsing GIC CPU interface entry\n");
>> +        return count;
>> +    }
>> +
>> +    /* Make boot-up look pretty */
>> +    pr_info("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);
> 
> Ideally just setup cpu_logical_map in acpi_parse_gic_cpu_interface and
> setup cpumasks in smp_init_cpus.
> 
>> +
>> +    return 0;
>> +}
>> +
>>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>>   {
>>       struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
>> @@ -99,8 +220,12 @@ int __init acpi_boot_init(void)
>>           return -ENODEV;
>>
>>       err = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
>> -    if (err)
>> -        pr_err("Can't find FADT\n");
>> +    if (err) {
>> +        pr_err("Can't find FADT or error happened during parsing FADT\n");
>> +        return err;
>> +    }
>> +
>> +    err = acpi_parse_madt_gic_cpu_interface_entries();
>>
>>       return err;
>>   }
>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>> index 40f38f4..8f1d37c 100644
>> --- a/arch/arm64/kernel/smp.c
>> +++ b/arch/arm64/kernel/smp.c
>> @@ -36,6 +36,7 @@
>>   #include <linux/completion.h>
>>   #include <linux/of.h>
>>   #include <linux/irq_work.h>
>> +#include <linux/acpi.h>
>>
>>   #include <asm/atomic.h>
>>   #include <asm/cacheflush.h>
>> @@ -458,7 +459,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>>           if (err)
>>               continue;
>>
>> -        set_cpu_present(cpu, true);
>> +        /*
>> +         * In ACPI mode, cpu_present_map was initialised when
>> +         * MADT table was parsed which before this function
>> +         * is called.
>> +         */
>> +        if (acpi_disabled)
>> +            set_cpu_present(cpu, true);
>> +
> 
> This is the right place to set the cpu present based on the return value
> of cpu_prepare.

Yes, as I replied in previous email, I will update the patch and consider
CPU hotplug in the future.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-19 10:39       ` Hanjun Guo
  (?)
@ 2014-08-19 11:07         ` Sudeep Holla
  -1 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-19 11:07 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel@lists.infradead.org



On 19/08/14 11:39, Hanjun Guo wrote:
> On 2014-8-19 2:32, Sudeep Holla wrote:
>> On 04/08/14 16:28, Hanjun Guo wrote:
>>> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
>>> the former signals to the OS that the hardware is PSCI compliant.
>>> The latter selects the appropriate conduit for PSCI calls by
>>> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
>>> (SMC).
>>>
>>> FADT table contains such information, parse FADT to get the flags
>>> for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
>>> function IDs, which means that only PSCI 0.2+ is supported in ACPI.
>>>
>>> At the same time, only ACPI 5.1 or higher verison supports PSCI,
>>> and FADT Major.Minor version was introduced in ACPI 5.1, so we
>>> will check the version and only parse FADT table with version >= 5.1.
>>>
>>> If firmware provides ACPI tables with ACPI version less than 5.1,
>>> OS will be messed up with those information and have no way to
>>> bring up secondery CPUs, so disable ACPI if we get an FADT table
>>> with version less that 5.1.
>>>
> [...]
>>>
>>> +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 version,
>>> +     * and there is a minor version of FADT which was introduced
>>> +     * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>>> +     * to get arm boot flags, or we will disable ACPI.
>>> +     */
>>> +    if (table->revision < 5 || fadt->minor_revision < 1) {
>>
>>                  &&
>
> Catalin also pointed out this bug :), but && is not enough, for example,
> this would not trigger of revision 4.1, although 4.1 is not exist, but
> the code will still confusing people, so I updated the code as:
>

Right I missed it :), the below code looks fine.

> +       if (table->revision > 5 ||
> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
> +               return 0;
> +       } else {
> +               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
> or higher\n",
> +                       table->revision, fadt->minor_revision);
> +               disable_acpi();

As suggested elsewhere try to eliminate this and have it once if
acpi_boot_init failed for any reasons.

Regards,
Sudeep


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 11:07         ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-19 11:07 UTC (permalink / raw)
  To: Hanjun Guo, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: Sudeep Holla, graeme.gregory, Arnd Bergmann, Olof Johansson,
	grant.likely, Will Deacon, Jason Cooper, Marc Zyngier,
	Bjorn Helgaas, Daniel Lezcano, Mark Brown, Rob Herring,
	Robert Richter, Lv Zheng, Robert Moore, Lorenzo Pieralisi,
	Liviu Dudau, Randy Dunlap, Charles Garcia-Tobin, linux-acpi,
	linux-arm-kernel, linux-kernel, linaro-acpi



On 19/08/14 11:39, Hanjun Guo wrote:
> On 2014-8-19 2:32, Sudeep Holla wrote:
>> On 04/08/14 16:28, Hanjun Guo wrote:
>>> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
>>> the former signals to the OS that the hardware is PSCI compliant.
>>> The latter selects the appropriate conduit for PSCI calls by
>>> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
>>> (SMC).
>>>
>>> FADT table contains such information, parse FADT to get the flags
>>> for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
>>> function IDs, which means that only PSCI 0.2+ is supported in ACPI.
>>>
>>> At the same time, only ACPI 5.1 or higher verison supports PSCI,
>>> and FADT Major.Minor version was introduced in ACPI 5.1, so we
>>> will check the version and only parse FADT table with version >= 5.1.
>>>
>>> If firmware provides ACPI tables with ACPI version less than 5.1,
>>> OS will be messed up with those information and have no way to
>>> bring up secondery CPUs, so disable ACPI if we get an FADT table
>>> with version less that 5.1.
>>>
> [...]
>>>
>>> +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 version,
>>> +     * and there is a minor version of FADT which was introduced
>>> +     * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>>> +     * to get arm boot flags, or we will disable ACPI.
>>> +     */
>>> +    if (table->revision < 5 || fadt->minor_revision < 1) {
>>
>>                  &&
>
> Catalin also pointed out this bug :), but && is not enough, for example,
> this would not trigger of revision 4.1, although 4.1 is not exist, but
> the code will still confusing people, so I updated the code as:
>

Right I missed it :), the below code looks fine.

> +       if (table->revision > 5 ||
> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
> +               return 0;
> +       } else {
> +               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
> or higher\n",
> +                       table->revision, fadt->minor_revision);
> +               disable_acpi();

As suggested elsewhere try to eliminate this and have it once if
acpi_boot_init failed for any reasons.

Regards,
Sudeep


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 11:07         ` Sudeep Holla
  0 siblings, 0 replies; 180+ messages in thread
From: Sudeep Holla @ 2014-08-19 11:07 UTC (permalink / raw)
  To: linux-arm-kernel



On 19/08/14 11:39, Hanjun Guo wrote:
> On 2014-8-19 2:32, Sudeep Holla wrote:
>> On 04/08/14 16:28, Hanjun Guo wrote:
>>> There are two flags: PSCI_COMPLIANT and PSCI_USE_HVC. When set,
>>> the former signals to the OS that the hardware is PSCI compliant.
>>> The latter selects the appropriate conduit for PSCI calls by
>>> toggling between Hypervisor Calls (HVC) and Secure Monitor Calls
>>> (SMC).
>>>
>>> FADT table contains such information, parse FADT to get the flags
>>> for PSCI init. Since ACPI 5.1 doesn't support self defined PSCI
>>> function IDs, which means that only PSCI 0.2+ is supported in ACPI.
>>>
>>> At the same time, only ACPI 5.1 or higher verison supports PSCI,
>>> and FADT Major.Minor version was introduced in ACPI 5.1, so we
>>> will check the version and only parse FADT table with version >= 5.1.
>>>
>>> If firmware provides ACPI tables with ACPI version less than 5.1,
>>> OS will be messed up with those information and have no way to
>>> bring up secondery CPUs, so disable ACPI if we get an FADT table
>>> with version less that 5.1.
>>>
> [...]
>>>
>>> +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 version,
>>> +     * and there is a minor version of FADT which was introduced
>>> +     * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>>> +     * to get arm boot flags, or we will disable ACPI.
>>> +     */
>>> +    if (table->revision < 5 || fadt->minor_revision < 1) {
>>
>>                  &&
>
> Catalin also pointed out this bug :), but && is not enough, for example,
> this would not trigger of revision 4.1, although 4.1 is not exist, but
> the code will still confusing people, so I updated the code as:
>

Right I missed it :), the below code looks fine.

> +       if (table->revision > 5 ||
> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
> +               return 0;
> +       } else {
> +               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
> or higher\n",
> +                       table->revision, fadt->minor_revision);
> +               disable_acpi();

As suggested elsewhere try to eliminate this and have it once if
acpi_boot_init failed for any reasons.

Regards,
Sudeep

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-19  3:50       ` Hanjun Guo
  (?)
@ 2014-08-19 11:10         ` Mark Rutland
  -1 siblings, 0 replies; 180+ messages in thread
From: Mark Rutland @ 2014-08-19 11:10 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Sudeep Holla,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi@vger.kernel.org

> >> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
> >>  	early_memunmap(map, size);
> >>  }
> >>  
> >> +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 version,
> >> +	 * and there is a minor version of FADT which was introduced
> >> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> >> +	 * to get arm boot flags, or we will disable ACPI.
> >> +	 */
> >> +	if (table->revision < 5 || fadt->minor_revision < 1) {
> > 
> > If we ever get revision 6.0, this would trigger.
> 
> Yes, good catch, actually I already fixed that in my local git repo,
> 
> +       if (table->revision > 5 ||
> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
> +               return 0;
> +       } else {
> +               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
> or higher\n",
> +                       table->revision, fadt->minor_revision);
> +               disable_acpi();
> +               return -EINVAL;
> +       }

Given you return in the first path, you don't need the remaining code to
live in an else block.

Mark.

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 11:10         ` Mark Rutland
  0 siblings, 0 replies; 180+ messages in thread
From: Mark Rutland @ 2014-08-19 11:10 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Sudeep Holla,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel,
	linux-kernel, linaro-acpi

> >> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
> >>  	early_memunmap(map, size);
> >>  }
> >>  
> >> +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 version,
> >> +	 * and there is a minor version of FADT which was introduced
> >> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> >> +	 * to get arm boot flags, or we will disable ACPI.
> >> +	 */
> >> +	if (table->revision < 5 || fadt->minor_revision < 1) {
> > 
> > If we ever get revision 6.0, this would trigger.
> 
> Yes, good catch, actually I already fixed that in my local git repo,
> 
> +       if (table->revision > 5 ||
> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
> +               return 0;
> +       } else {
> +               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
> or higher\n",
> +                       table->revision, fadt->minor_revision);
> +               disable_acpi();
> +               return -EINVAL;
> +       }

Given you return in the first path, you don't need the remaining code to
live in an else block.

Mark.

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 11:10         ` Mark Rutland
  0 siblings, 0 replies; 180+ messages in thread
From: Mark Rutland @ 2014-08-19 11:10 UTC (permalink / raw)
  To: linux-arm-kernel

> >> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
> >>  	early_memunmap(map, size);
> >>  }
> >>  
> >> +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 version,
> >> +	 * and there is a minor version of FADT which was introduced
> >> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> >> +	 * to get arm boot flags, or we will disable ACPI.
> >> +	 */
> >> +	if (table->revision < 5 || fadt->minor_revision < 1) {
> > 
> > If we ever get revision 6.0, this would trigger.
> 
> Yes, good catch, actually I already fixed that in my local git repo,
> 
> +       if (table->revision > 5 ||
> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
> +               return 0;
> +       } else {
> +               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
> or higher\n",
> +                       table->revision, fadt->minor_revision);
> +               disable_acpi();
> +               return -EINVAL;
> +       }

Given you return in the first path, you don't need the remaining code to
live in an else block.

Mark.

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-18 18:34     ` Sudeep Holla
  (?)
@ 2014-08-19 11:26       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:26 UTC (permalink / raw)
  To: Sudeep Holla, Mark Rutland
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel

On 2014-8-19 2:34, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
[...]
>>   /* Basic configuration for ACPI */
>>   #ifdef    CONFIG_ACPI
>> +/*
>> + * ACPI 5.1 only has two explicit methods to
>> + * boot up SMP, PSCI and Parking protocol,
>> + * but the Parking protocol is only defined
>> + * 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.
>> + *
>> + * This enum is intend to make the boot method
>> + * scalable when above updates are happended,
>> + * which NOT means to support all of them.
>> + */
>> +enum acpi_smp_boot_protocol {
>> +    ACPI_SMP_BOOT_PSCI,
>> +    ACPI_SMP_BOOT_PARKING_PROTOCOL,
>> +    ACPI_SMP_BOOT_PROTOCOL_MAX
>> +};
>> +
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
>> +
[...]
>> +/* Protocol to bring up secondary CPUs */
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void)
>> +{
>> +    if (acpi_psci_present())
>> +        return ACPI_SMP_BOOT_PSCI;
>> +    else
>> +        return ACPI_SMP_BOOT_PARKING_PROTOCOL;
>> +}
>> +
> 
> Which do you need this here ? Can't you use acpi_psci_present directly
> in acpi_get_cpu_boot_method ?

My intent was to make the code scalable if we introduce another (or more)
boot protocol in ACPI, does it make sense to you?

> 
>>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>>   {
>>       struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
>> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
>> index d62d12f..05bc314 100644
>> --- a/arch/arm64/kernel/cpu_ops.c
>> +++ b/arch/arm64/kernel/cpu_ops.c
>> @@ -16,11 +16,13 @@
>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>    */
>>
>> -#include <asm/cpu_ops.h>
>> -#include <asm/smp_plat.h>
>>   #include <linux/errno.h>
>>   #include <linux/of.h>
>>   #include <linux/string.h>
>> +#include <linux/acpi.h>
>> +
>> +#include <asm/cpu_ops.h>
>> +#include <asm/smp_plat.h>
>>
>>   extern const struct cpu_operations smp_spin_table_ops;
>>   extern const struct cpu_operations cpu_psci_ops;
>> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init
>> cpu_get_ops(const char *name)
>>       return NULL;
>>   }
>>
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Get a cpu's boot method in the ACPI way.
>> + */
>> +static char * __init acpi_get_cpu_boot_method(void)
>> +{
>> +    /*
>> +     * For ACPI 5.1, only two kind of methods are provided,
>> +     * Parking protocol and PSCI, but Parking protocol is
>> +     * specified for ARMv7 only, so make PSCI as the only method
>> +     * for SMP initialization before the ACPI spec or Parking
>> +     * protocol spec is updated.
>> +     */
>> +    switch (smp_boot_protocol()) {
>> +    case ACPI_SMP_BOOT_PSCI:
>> +        return "psci";
>> +    case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>> +    default:
>> +        return NULL;
>> +    }
> 
> Use acpi_psci_present as mentioned above.
> 
>> +}
>> +#else
>> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
>> +#endif
>> +
>>   /*
>> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
>> + * Read a cpu's enable method and record it in cpu_ops.
>>    */
>>   int __init cpu_read_ops(struct device_node *dn, int cpu)
>>   {
>> -    const char *enable_method = of_get_property(dn, "enable-method", NULL);
>> +    const char *enable_method;
>> +
>> +    if (!acpi_disabled) {
>> +        enable_method = acpi_get_cpu_boot_method();
>> +        goto get_ops;
>> +    }
>> +
>> +    enable_method = of_get_property(dn, "enable-method", NULL);
>>       if (!enable_method) {
>>           /*
>>            * The boot CPU may not have an enable method (e.g. when
>> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>>           return -ENOENT;
>>       }
>>
>> +get_ops:
>>       cpu_ops[cpu] = cpu_get_ops(enable_method);
>>       if (!cpu_ops[cpu]) {
>> -        pr_warn("%s: unsupported enable-method property: %s\n",
>> -            dn->full_name, enable_method);
>> +        if (acpi_disabled) {
>> +            pr_warn("%s: unsupported enable-method property: %s\n",
>> +                dn->full_name, enable_method);
>> +        } else {
>> +            pr_warn("CPU %d: boot protocol unsupported or unknown\n",
>> +                cpu);
>> +        }
>> +
>>           return -EOPNOTSUPP;
>>       }
>>
>> @@ -78,7 +119,14 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>>
>>   void __init cpu_read_bootcpu_ops(void)
>>   {
>> -    struct device_node *dn = of_get_cpu_node(0, NULL);
>> +    struct device_node *dn;
>> +
>> +    if (!acpi_disabled) {
>> +        cpu_read_ops(NULL, 0);
>> +        return;
>> +    }
>> +
> 
> Again not good to mix ACPI in DT functions forcing you to pass
> device_node ptr as NULL, better to separate this. 

I separate them in the first version, and combine tham as Geoff suggested
for scalable reasons.

> Once you gather all
> this !acpi_disabled case, you can create appropriate abstractions to be
> used in setup.c
> 
> E.g. here you check !acpi_disabled and pass NULL for DT node to
> cpu_read_ops and hence again you check for !acpi_disabled in
> cpu_read_ops. So you need first identify all these checks and put in one
> place to understand well how you can refactor existing code to avoid
> these multiple checks.

I will remove the multiple acpi_disabled checks and refactor the code.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-19 11:26       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:26 UTC (permalink / raw)
  To: Sudeep Holla, Mark Rutland
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi, Tomasz Nowicki

On 2014-8-19 2:34, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
[...]
>>   /* Basic configuration for ACPI */
>>   #ifdef    CONFIG_ACPI
>> +/*
>> + * ACPI 5.1 only has two explicit methods to
>> + * boot up SMP, PSCI and Parking protocol,
>> + * but the Parking protocol is only defined
>> + * 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.
>> + *
>> + * This enum is intend to make the boot method
>> + * scalable when above updates are happended,
>> + * which NOT means to support all of them.
>> + */
>> +enum acpi_smp_boot_protocol {
>> +    ACPI_SMP_BOOT_PSCI,
>> +    ACPI_SMP_BOOT_PARKING_PROTOCOL,
>> +    ACPI_SMP_BOOT_PROTOCOL_MAX
>> +};
>> +
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
>> +
[...]
>> +/* Protocol to bring up secondary CPUs */
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void)
>> +{
>> +    if (acpi_psci_present())
>> +        return ACPI_SMP_BOOT_PSCI;
>> +    else
>> +        return ACPI_SMP_BOOT_PARKING_PROTOCOL;
>> +}
>> +
> 
> Which do you need this here ? Can't you use acpi_psci_present directly
> in acpi_get_cpu_boot_method ?

My intent was to make the code scalable if we introduce another (or more)
boot protocol in ACPI, does it make sense to you?

> 
>>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>>   {
>>       struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
>> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
>> index d62d12f..05bc314 100644
>> --- a/arch/arm64/kernel/cpu_ops.c
>> +++ b/arch/arm64/kernel/cpu_ops.c
>> @@ -16,11 +16,13 @@
>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>    */
>>
>> -#include <asm/cpu_ops.h>
>> -#include <asm/smp_plat.h>
>>   #include <linux/errno.h>
>>   #include <linux/of.h>
>>   #include <linux/string.h>
>> +#include <linux/acpi.h>
>> +
>> +#include <asm/cpu_ops.h>
>> +#include <asm/smp_plat.h>
>>
>>   extern const struct cpu_operations smp_spin_table_ops;
>>   extern const struct cpu_operations cpu_psci_ops;
>> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init
>> cpu_get_ops(const char *name)
>>       return NULL;
>>   }
>>
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Get a cpu's boot method in the ACPI way.
>> + */
>> +static char * __init acpi_get_cpu_boot_method(void)
>> +{
>> +    /*
>> +     * For ACPI 5.1, only two kind of methods are provided,
>> +     * Parking protocol and PSCI, but Parking protocol is
>> +     * specified for ARMv7 only, so make PSCI as the only method
>> +     * for SMP initialization before the ACPI spec or Parking
>> +     * protocol spec is updated.
>> +     */
>> +    switch (smp_boot_protocol()) {
>> +    case ACPI_SMP_BOOT_PSCI:
>> +        return "psci";
>> +    case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>> +    default:
>> +        return NULL;
>> +    }
> 
> Use acpi_psci_present as mentioned above.
> 
>> +}
>> +#else
>> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
>> +#endif
>> +
>>   /*
>> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
>> + * Read a cpu's enable method and record it in cpu_ops.
>>    */
>>   int __init cpu_read_ops(struct device_node *dn, int cpu)
>>   {
>> -    const char *enable_method = of_get_property(dn, "enable-method", NULL);
>> +    const char *enable_method;
>> +
>> +    if (!acpi_disabled) {
>> +        enable_method = acpi_get_cpu_boot_method();
>> +        goto get_ops;
>> +    }
>> +
>> +    enable_method = of_get_property(dn, "enable-method", NULL);
>>       if (!enable_method) {
>>           /*
>>            * The boot CPU may not have an enable method (e.g. when
>> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>>           return -ENOENT;
>>       }
>>
>> +get_ops:
>>       cpu_ops[cpu] = cpu_get_ops(enable_method);
>>       if (!cpu_ops[cpu]) {
>> -        pr_warn("%s: unsupported enable-method property: %s\n",
>> -            dn->full_name, enable_method);
>> +        if (acpi_disabled) {
>> +            pr_warn("%s: unsupported enable-method property: %s\n",
>> +                dn->full_name, enable_method);
>> +        } else {
>> +            pr_warn("CPU %d: boot protocol unsupported or unknown\n",
>> +                cpu);
>> +        }
>> +
>>           return -EOPNOTSUPP;
>>       }
>>
>> @@ -78,7 +119,14 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>>
>>   void __init cpu_read_bootcpu_ops(void)
>>   {
>> -    struct device_node *dn = of_get_cpu_node(0, NULL);
>> +    struct device_node *dn;
>> +
>> +    if (!acpi_disabled) {
>> +        cpu_read_ops(NULL, 0);
>> +        return;
>> +    }
>> +
> 
> Again not good to mix ACPI in DT functions forcing you to pass
> device_node ptr as NULL, better to separate this. 

I separate them in the first version, and combine tham as Geoff suggested
for scalable reasons.

> Once you gather all
> this !acpi_disabled case, you can create appropriate abstractions to be
> used in setup.c
> 
> E.g. here you check !acpi_disabled and pass NULL for DT node to
> cpu_read_ops and hence again you check for !acpi_disabled in
> cpu_read_ops. So you need first identify all these checks and put in one
> place to understand well how you can refactor existing code to avoid
> these multiple checks.

I will remove the multiple acpi_disabled checks and refactor the code.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-19 11:26       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-19 2:34, Sudeep Holla wrote:
> On 04/08/14 16:28, Hanjun Guo wrote:
[...]
>>   /* Basic configuration for ACPI */
>>   #ifdef    CONFIG_ACPI
>> +/*
>> + * ACPI 5.1 only has two explicit methods to
>> + * boot up SMP, PSCI and Parking protocol,
>> + * but the Parking protocol is only defined
>> + * 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.
>> + *
>> + * This enum is intend to make the boot method
>> + * scalable when above updates are happended,
>> + * which NOT means to support all of them.
>> + */
>> +enum acpi_smp_boot_protocol {
>> +    ACPI_SMP_BOOT_PSCI,
>> +    ACPI_SMP_BOOT_PARKING_PROTOCOL,
>> +    ACPI_SMP_BOOT_PROTOCOL_MAX
>> +};
>> +
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
>> +
[...]
>> +/* Protocol to bring up secondary CPUs */
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void)
>> +{
>> +    if (acpi_psci_present())
>> +        return ACPI_SMP_BOOT_PSCI;
>> +    else
>> +        return ACPI_SMP_BOOT_PARKING_PROTOCOL;
>> +}
>> +
> 
> Which do you need this here ? Can't you use acpi_psci_present directly
> in acpi_get_cpu_boot_method ?

My intent was to make the code scalable if we introduce another (or more)
boot protocol in ACPI, does it make sense to you?

> 
>>   static int __init acpi_parse_fadt(struct acpi_table_header *table)
>>   {
>>       struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
>> diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
>> index d62d12f..05bc314 100644
>> --- a/arch/arm64/kernel/cpu_ops.c
>> +++ b/arch/arm64/kernel/cpu_ops.c
>> @@ -16,11 +16,13 @@
>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>    */
>>
>> -#include <asm/cpu_ops.h>
>> -#include <asm/smp_plat.h>
>>   #include <linux/errno.h>
>>   #include <linux/of.h>
>>   #include <linux/string.h>
>> +#include <linux/acpi.h>
>> +
>> +#include <asm/cpu_ops.h>
>> +#include <asm/smp_plat.h>
>>
>>   extern const struct cpu_operations smp_spin_table_ops;
>>   extern const struct cpu_operations cpu_psci_ops;
>> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init
>> cpu_get_ops(const char *name)
>>       return NULL;
>>   }
>>
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Get a cpu's boot method in the ACPI way.
>> + */
>> +static char * __init acpi_get_cpu_boot_method(void)
>> +{
>> +    /*
>> +     * For ACPI 5.1, only two kind of methods are provided,
>> +     * Parking protocol and PSCI, but Parking protocol is
>> +     * specified for ARMv7 only, so make PSCI as the only method
>> +     * for SMP initialization before the ACPI spec or Parking
>> +     * protocol spec is updated.
>> +     */
>> +    switch (smp_boot_protocol()) {
>> +    case ACPI_SMP_BOOT_PSCI:
>> +        return "psci";
>> +    case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>> +    default:
>> +        return NULL;
>> +    }
> 
> Use acpi_psci_present as mentioned above.
> 
>> +}
>> +#else
>> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
>> +#endif
>> +
>>   /*
>> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
>> + * Read a cpu's enable method and record it in cpu_ops.
>>    */
>>   int __init cpu_read_ops(struct device_node *dn, int cpu)
>>   {
>> -    const char *enable_method = of_get_property(dn, "enable-method", NULL);
>> +    const char *enable_method;
>> +
>> +    if (!acpi_disabled) {
>> +        enable_method = acpi_get_cpu_boot_method();
>> +        goto get_ops;
>> +    }
>> +
>> +    enable_method = of_get_property(dn, "enable-method", NULL);
>>       if (!enable_method) {
>>           /*
>>            * The boot CPU may not have an enable method (e.g. when
>> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>>           return -ENOENT;
>>       }
>>
>> +get_ops:
>>       cpu_ops[cpu] = cpu_get_ops(enable_method);
>>       if (!cpu_ops[cpu]) {
>> -        pr_warn("%s: unsupported enable-method property: %s\n",
>> -            dn->full_name, enable_method);
>> +        if (acpi_disabled) {
>> +            pr_warn("%s: unsupported enable-method property: %s\n",
>> +                dn->full_name, enable_method);
>> +        } else {
>> +            pr_warn("CPU %d: boot protocol unsupported or unknown\n",
>> +                cpu);
>> +        }
>> +
>>           return -EOPNOTSUPP;
>>       }
>>
>> @@ -78,7 +119,14 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>>
>>   void __init cpu_read_bootcpu_ops(void)
>>   {
>> -    struct device_node *dn = of_get_cpu_node(0, NULL);
>> +    struct device_node *dn;
>> +
>> +    if (!acpi_disabled) {
>> +        cpu_read_ops(NULL, 0);
>> +        return;
>> +    }
>> +
> 
> Again not good to mix ACPI in DT functions forcing you to pass
> device_node ptr as NULL, better to separate this. 

I separate them in the first version, and combine tham as Geoff suggested
for scalable reasons.

> Once you gather all
> this !acpi_disabled case, you can create appropriate abstractions to be
> used in setup.c
> 
> E.g. here you check !acpi_disabled and pass NULL for DT node to
> cpu_read_ops and hence again you check for !acpi_disabled in
> cpu_read_ops. So you need first identify all these checks and put in one
> place to understand well how you can refactor existing code to avoid
> these multiple checks.

I will remove the multiple acpi_disabled checks and refactor the code.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
  2014-08-18 18:34     ` Sudeep Holla
  (?)
@ 2014-08-19 11:29       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:29 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel

On 2014-8-19 2:34, Sudeep Holla wrote:
[...]
>>
>> +#include <asm/smp_plat.h>
>> +
>>   /* Basic configuration for ACPI */
>>   #ifdef    CONFIG_ACPI
>>   /*
>> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>>       acpi_noirq = 1;
>>   }
>>
>> +u32 pack_mpidr_into_32_bits(u64 mpidr);
>> +
>> +/*
>> + * The ACPI processor driver for ACPI core code needs this macro
>> + * to find out this cpu was already mapped (mapping from CPU hardware
>> + * ID to CPU logical ID) or not.
>> + *
>> + * cpu_logical_map(cpu) is the mapping of MPIDR and the logical cpu,
>> + * and MPIDR is the cpu hardware ID we needed.
> 
> You need to specify this is packed version of cpu_logical_map or
> better is to move pack_mpidr_into_32_bits here along with the
> description you have so that it's easy to understand.

Agreed, I will make pack_mpidr_into_32_bits() as inline function here and
specify that it is the packed version we needed.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-19 11:29       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:29 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel,
	linux-kernel, linaro-acpi

On 2014-8-19 2:34, Sudeep Holla wrote:
[...]
>>
>> +#include <asm/smp_plat.h>
>> +
>>   /* Basic configuration for ACPI */
>>   #ifdef    CONFIG_ACPI
>>   /*
>> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>>       acpi_noirq = 1;
>>   }
>>
>> +u32 pack_mpidr_into_32_bits(u64 mpidr);
>> +
>> +/*
>> + * The ACPI processor driver for ACPI core code needs this macro
>> + * to find out this cpu was already mapped (mapping from CPU hardware
>> + * ID to CPU logical ID) or not.
>> + *
>> + * cpu_logical_map(cpu) is the mapping of MPIDR and the logical cpu,
>> + * and MPIDR is the cpu hardware ID we needed.
> 
> You need to specify this is packed version of cpu_logical_map or
> better is to move pack_mpidr_into_32_bits here along with the
> description you have so that it's easy to understand.

Agreed, I will make pack_mpidr_into_32_bits() as inline function here and
specify that it is the packed version we needed.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-19 11:29       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-19 2:34, Sudeep Holla wrote:
[...]
>>
>> +#include <asm/smp_plat.h>
>> +
>>   /* Basic configuration for ACPI */
>>   #ifdef    CONFIG_ACPI
>>   /*
>> @@ -59,6 +61,18 @@ static inline void disable_acpi(void)
>>       acpi_noirq = 1;
>>   }
>>
>> +u32 pack_mpidr_into_32_bits(u64 mpidr);
>> +
>> +/*
>> + * The ACPI processor driver for ACPI core code needs this macro
>> + * to find out this cpu was already mapped (mapping from CPU hardware
>> + * ID to CPU logical ID) or not.
>> + *
>> + * cpu_logical_map(cpu) is the mapping of MPIDR and the logical cpu,
>> + * and MPIDR is the cpu hardware ID we needed.
> 
> You need to specify this is packed version of cpu_logical_map or
> better is to move pack_mpidr_into_32_bits here along with the
> description you have so that it's easy to understand.

Agreed, I will make pack_mpidr_into_32_bits() as inline function here and
specify that it is the packed version we needed.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 10/18] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
  2014-08-18 18:34     ` Sudeep Holla
  (?)
@ 2014-08-19 11:36       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:36 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel

On 2014-8-19 2:34, Sudeep Holla wrote:
> 
> 
> On 04/08/14 16:28, Hanjun Guo wrote:
>> Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
>> used, and then register device's gsi with the core IRQ subsystem.
>>
>> acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
>> since gsi is unique in the system, so use hwirq number directly
>> for the mapping.
>>
>> Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   arch/arm64/kernel/acpi.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++
>>   drivers/acpi/bus.c       |    3 ++
>>   include/linux/acpi.h     |    1 +
>>   3 files changed, 77 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index ac7ab34..621ced8 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -34,6 +34,12 @@ 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.
>>    */
>> @@ -169,6 +175,73 @@ static int __init
>> acpi_parse_madt_gic_cpu_interface_entries(void)
>>       return 0;
>>   }
>>
>> +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);
>> +
> 
> Not sure if acpi_gsi_to_irq and acpi_{,un}register_gsi belong here.
> These are GIC specific and should belong to GIC driver IMO.

I think we can keep them here as GSI is ACPI specific and they are
not GIC init related.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 10/18] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
@ 2014-08-19 11:36       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:36 UTC (permalink / raw)
  To: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland
  Cc: graeme.gregory, Arnd Bergmann, Olof Johansson, grant.likely,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel,
	linux-kernel, linaro-acpi

On 2014-8-19 2:34, Sudeep Holla wrote:
> 
> 
> On 04/08/14 16:28, Hanjun Guo wrote:
>> Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
>> used, and then register device's gsi with the core IRQ subsystem.
>>
>> acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
>> since gsi is unique in the system, so use hwirq number directly
>> for the mapping.
>>
>> Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   arch/arm64/kernel/acpi.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++
>>   drivers/acpi/bus.c       |    3 ++
>>   include/linux/acpi.h     |    1 +
>>   3 files changed, 77 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index ac7ab34..621ced8 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -34,6 +34,12 @@ 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.
>>    */
>> @@ -169,6 +175,73 @@ static int __init
>> acpi_parse_madt_gic_cpu_interface_entries(void)
>>       return 0;
>>   }
>>
>> +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);
>> +
> 
> Not sure if acpi_gsi_to_irq and acpi_{,un}register_gsi belong here.
> These are GIC specific and should belong to GIC driver IMO.

I think we can keep them here as GSI is ACPI specific and they are
not GIC init related.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 10/18] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
@ 2014-08-19 11:36       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-19 2:34, Sudeep Holla wrote:
> 
> 
> On 04/08/14 16:28, Hanjun Guo wrote:
>> Introduce ACPI_IRQ_MODEL_GIC which is needed for ARM64 as GIC is
>> used, and then register device's gsi with the core IRQ subsystem.
>>
>> acpi_register_gsi() is similar to DT based irq_of_parse_and_map(),
>> since gsi is unique in the system, so use hwirq number directly
>> for the mapping.
>>
>> Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   arch/arm64/kernel/acpi.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++
>>   drivers/acpi/bus.c       |    3 ++
>>   include/linux/acpi.h     |    1 +
>>   3 files changed, 77 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
>> index ac7ab34..621ced8 100644
>> --- a/arch/arm64/kernel/acpi.c
>> +++ b/arch/arm64/kernel/acpi.c
>> @@ -34,6 +34,12 @@ 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.
>>    */
>> @@ -169,6 +175,73 @@ static int __init
>> acpi_parse_madt_gic_cpu_interface_entries(void)
>>       return 0;
>>   }
>>
>> +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);
>> +
> 
> Not sure if acpi_gsi_to_irq and acpi_{,un}register_gsi belong here.
> These are GIC specific and should belong to GIC driver IMO.

I think we can keep them here as GSI is ACPI specific and they are
not GIC init related.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-18 18:56     ` Geoff Levand
  (?)
@ 2014-08-19 12:11       ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 12:11 UTC (permalink / raw)
  To: Geoff Levand
  Cc: Catalin Marinas, Rafael J. Wysocki, Mark Rutland, linaro-acpi,
	Liviu Dudau, Lv Zheng, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Robert Moore, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap

On 2014-8-19 2:56, Geoff Levand wrote:
> Hi Hanjun,

Hi Geoff,

> 
> On Mon, 2014-08-04 at 23:28 +0800, Hanjun Guo wrote:
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -14,6 +14,27 @@
>>  
>>  /* Basic configuration for ACPI */
>>  #ifdef	CONFIG_ACPI
> 
> By having this preprocessor conditional in the header leads
> to a proliferation of preprocessor conditionals since any
> code that includes this header will also need to have
> preprocessor conditionals.  Another down side of having
> this is that this code will not get a build test for
> builds with CONFIG_ACPI=n.

I will move some definitions out of preprocessor conditional and
introduce some stub function when CONFIG_ACPI is disabled, then
I think I can remove all the preprocessor conditionals in .c file.

> 
>> +/*
>> + * ACPI 5.1 only has two explicit methods to
>> + * boot up SMP, PSCI and Parking protocol,
>> + * but the Parking protocol is only defined
>> + * 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.
>> + *
>> + * This enum is intend to make the boot method
>> + * scalable when above updates are happended,
>> + * which NOT means to support all of them.
>> + */
>> +enum acpi_smp_boot_protocol {
>> +	ACPI_SMP_BOOT_PSCI,
>> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
>> +	ACPI_SMP_BOOT_PROTOCOL_MAX
>> +};
>> +
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
> 
> The name smp_boot_protocol() seems like it would be a generic
> routine, but it is acpi specific.  Maybe:
> 
> enum acpi_boot_protocol_type {...};
> 
> enum acpi_boot_protocol_type acpi_boot_protocol(void);

Agreed.

> 
>> --- a/arch/arm64/kernel/cpu_ops.c
>> +++ b/arch/arm64/kernel/cpu_ops.c
>> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>>  	return NULL;
>>  }
>>  
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Get a cpu's boot method in the ACPI way.
>> + */
>> +static char * __init acpi_get_cpu_boot_method(void)
>> +{
>> +	/*
>> +	 * For ACPI 5.1, only two kind of methods are provided,
>> +	 * Parking protocol and PSCI, but Parking protocol is
>> +	 * specified for ARMv7 only, so make PSCI as the only method
>> +	 * for SMP initialization before the ACPI spec or Parking
>> +	 * protocol spec is updated.
>> +	 */
>> +	switch (smp_boot_protocol()) {
>> +	case ACPI_SMP_BOOT_PSCI:
>> +		return "psci";
>> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>> +	default:
>> +		return NULL;
>> +	}
>> +}
>> +#else
>> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
>> +#endif
> 
> Since this is inside a C source file, the inline keyword
> isn't needed since the optimizer will inline regardless.
> 
> With that said, I think it would be cleaner to have this
> as:
> 
> static char * __init acpi_get_cpu_boot_method(void)
> {
> #ifdef CONFIG_ACPI
> 	return NULL;
> #else
>  ...
> #endif
> }
> 
> Or better to make smp_boot_protocol() callable regardless
> of CONFIG_ACPI and then no preprocessor conditionals at all
> would be needed.
> 
>> +
>>  /*
>> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
>> + * Read a cpu's enable method and record it in cpu_ops.
>>   */
>>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>>  {
>> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
>> +	const char *enable_method;
>> +
>> +	if (!acpi_disabled) {
>> +		enable_method = acpi_get_cpu_boot_method();
>> +		goto get_ops;
>> +	}
>> +
>> +	enable_method = of_get_property(dn, "enable-method", NULL);
>>  	if (!enable_method) {
>>  		/*
>>  		 * The boot CPU may not have an enable method (e.g. when
>> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>>  		return -ENOENT;
>>  	}
>>  
>> +get_ops:
>>  	cpu_ops[cpu] = cpu_get_ops(enable_method);
>>  	if (!cpu_ops[cpu]) {
>> -		pr_warn("%s: unsupported enable-method property: %s\n",
>> -			dn->full_name, enable_method);
>> +		if (acpi_disabled) {
>> +			pr_warn("%s: unsupported enable-method property: %s\n",
>> +				dn->full_name, enable_method);
>> +		} else {
>> +			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
>> +				cpu);
>> +		}
>> +
> 
> Can't we have this more integrated, maybe something like this?
> 
> 	enable_method = acpi_disabled ? of_get_property(dn, "enable-method", NULL)
> 		: acpi_get_cpu_boot_method();

I like this :)

> 	message = acpi_disabled ? dn->full_name : "";
> 
> 	...
> 	
> 	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
> 				cpu, message, enable_method)

In ACPI, there is no enable-method property, it is a term from, so I think the
message printed can be separated.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-19 12:11       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 12:11 UTC (permalink / raw)
  To: Geoff Levand
  Cc: Catalin Marinas, Rafael J. Wysocki, Mark Rutland, linaro-acpi,
	Liviu Dudau, Lv Zheng, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Robert Moore, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap, linux-kernel, Sudeep Holla, Olof Johansson

On 2014-8-19 2:56, Geoff Levand wrote:
> Hi Hanjun,

Hi Geoff,

> 
> On Mon, 2014-08-04 at 23:28 +0800, Hanjun Guo wrote:
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -14,6 +14,27 @@
>>  
>>  /* Basic configuration for ACPI */
>>  #ifdef	CONFIG_ACPI
> 
> By having this preprocessor conditional in the header leads
> to a proliferation of preprocessor conditionals since any
> code that includes this header will also need to have
> preprocessor conditionals.  Another down side of having
> this is that this code will not get a build test for
> builds with CONFIG_ACPI=n.

I will move some definitions out of preprocessor conditional and
introduce some stub function when CONFIG_ACPI is disabled, then
I think I can remove all the preprocessor conditionals in .c file.

> 
>> +/*
>> + * ACPI 5.1 only has two explicit methods to
>> + * boot up SMP, PSCI and Parking protocol,
>> + * but the Parking protocol is only defined
>> + * 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.
>> + *
>> + * This enum is intend to make the boot method
>> + * scalable when above updates are happended,
>> + * which NOT means to support all of them.
>> + */
>> +enum acpi_smp_boot_protocol {
>> +	ACPI_SMP_BOOT_PSCI,
>> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
>> +	ACPI_SMP_BOOT_PROTOCOL_MAX
>> +};
>> +
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
> 
> The name smp_boot_protocol() seems like it would be a generic
> routine, but it is acpi specific.  Maybe:
> 
> enum acpi_boot_protocol_type {...};
> 
> enum acpi_boot_protocol_type acpi_boot_protocol(void);

Agreed.

> 
>> --- a/arch/arm64/kernel/cpu_ops.c
>> +++ b/arch/arm64/kernel/cpu_ops.c
>> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>>  	return NULL;
>>  }
>>  
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Get a cpu's boot method in the ACPI way.
>> + */
>> +static char * __init acpi_get_cpu_boot_method(void)
>> +{
>> +	/*
>> +	 * For ACPI 5.1, only two kind of methods are provided,
>> +	 * Parking protocol and PSCI, but Parking protocol is
>> +	 * specified for ARMv7 only, so make PSCI as the only method
>> +	 * for SMP initialization before the ACPI spec or Parking
>> +	 * protocol spec is updated.
>> +	 */
>> +	switch (smp_boot_protocol()) {
>> +	case ACPI_SMP_BOOT_PSCI:
>> +		return "psci";
>> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>> +	default:
>> +		return NULL;
>> +	}
>> +}
>> +#else
>> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
>> +#endif
> 
> Since this is inside a C source file, the inline keyword
> isn't needed since the optimizer will inline regardless.
> 
> With that said, I think it would be cleaner to have this
> as:
> 
> static char * __init acpi_get_cpu_boot_method(void)
> {
> #ifdef CONFIG_ACPI
> 	return NULL;
> #else
>  ...
> #endif
> }
> 
> Or better to make smp_boot_protocol() callable regardless
> of CONFIG_ACPI and then no preprocessor conditionals at all
> would be needed.
> 
>> +
>>  /*
>> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
>> + * Read a cpu's enable method and record it in cpu_ops.
>>   */
>>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>>  {
>> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
>> +	const char *enable_method;
>> +
>> +	if (!acpi_disabled) {
>> +		enable_method = acpi_get_cpu_boot_method();
>> +		goto get_ops;
>> +	}
>> +
>> +	enable_method = of_get_property(dn, "enable-method", NULL);
>>  	if (!enable_method) {
>>  		/*
>>  		 * The boot CPU may not have an enable method (e.g. when
>> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>>  		return -ENOENT;
>>  	}
>>  
>> +get_ops:
>>  	cpu_ops[cpu] = cpu_get_ops(enable_method);
>>  	if (!cpu_ops[cpu]) {
>> -		pr_warn("%s: unsupported enable-method property: %s\n",
>> -			dn->full_name, enable_method);
>> +		if (acpi_disabled) {
>> +			pr_warn("%s: unsupported enable-method property: %s\n",
>> +				dn->full_name, enable_method);
>> +		} else {
>> +			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
>> +				cpu);
>> +		}
>> +
> 
> Can't we have this more integrated, maybe something like this?
> 
> 	enable_method = acpi_disabled ? of_get_property(dn, "enable-method", NULL)
> 		: acpi_get_cpu_boot_method();

I like this :)

> 	message = acpi_disabled ? dn->full_name : "";
> 
> 	...
> 	
> 	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
> 				cpu, message, enable_method)

In ACPI, there is no enable-method property, it is a term from, so I think the
message printed can be separated.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-19 12:11       ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-19 2:56, Geoff Levand wrote:
> Hi Hanjun,

Hi Geoff,

> 
> On Mon, 2014-08-04 at 23:28 +0800, Hanjun Guo wrote:
>> --- a/arch/arm64/include/asm/acpi.h
>> +++ b/arch/arm64/include/asm/acpi.h
>> @@ -14,6 +14,27 @@
>>  
>>  /* Basic configuration for ACPI */
>>  #ifdef	CONFIG_ACPI
> 
> By having this preprocessor conditional in the header leads
> to a proliferation of preprocessor conditionals since any
> code that includes this header will also need to have
> preprocessor conditionals.  Another down side of having
> this is that this code will not get a build test for
> builds with CONFIG_ACPI=n.

I will move some definitions out of preprocessor conditional and
introduce some stub function when CONFIG_ACPI is disabled, then
I think I can remove all the preprocessor conditionals in .c file.

> 
>> +/*
>> + * ACPI 5.1 only has two explicit methods to
>> + * boot up SMP, PSCI and Parking protocol,
>> + * but the Parking protocol is only defined
>> + * 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.
>> + *
>> + * This enum is intend to make the boot method
>> + * scalable when above updates are happended,
>> + * which NOT means to support all of them.
>> + */
>> +enum acpi_smp_boot_protocol {
>> +	ACPI_SMP_BOOT_PSCI,
>> +	ACPI_SMP_BOOT_PARKING_PROTOCOL,
>> +	ACPI_SMP_BOOT_PROTOCOL_MAX
>> +};
>> +
>> +enum acpi_smp_boot_protocol smp_boot_protocol(void);
> 
> The name smp_boot_protocol() seems like it would be a generic
> routine, but it is acpi specific.  Maybe:
> 
> enum acpi_boot_protocol_type {...};
> 
> enum acpi_boot_protocol_type acpi_boot_protocol(void);

Agreed.

> 
>> --- a/arch/arm64/kernel/cpu_ops.c
>> +++ b/arch/arm64/kernel/cpu_ops.c
>> @@ -49,12 +51,44 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)
>>  	return NULL;
>>  }
>>  
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Get a cpu's boot method in the ACPI way.
>> + */
>> +static char * __init acpi_get_cpu_boot_method(void)
>> +{
>> +	/*
>> +	 * For ACPI 5.1, only two kind of methods are provided,
>> +	 * Parking protocol and PSCI, but Parking protocol is
>> +	 * specified for ARMv7 only, so make PSCI as the only method
>> +	 * for SMP initialization before the ACPI spec or Parking
>> +	 * protocol spec is updated.
>> +	 */
>> +	switch (smp_boot_protocol()) {
>> +	case ACPI_SMP_BOOT_PSCI:
>> +		return "psci";
>> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>> +	default:
>> +		return NULL;
>> +	}
>> +}
>> +#else
>> +static inline char * __init acpi_get_cpu_boot_method(void) { return NULL; }
>> +#endif
> 
> Since this is inside a C source file, the inline keyword
> isn't needed since the optimizer will inline regardless.
> 
> With that said, I think it would be cleaner to have this
> as:
> 
> static char * __init acpi_get_cpu_boot_method(void)
> {
> #ifdef CONFIG_ACPI
> 	return NULL;
> #else
>  ...
> #endif
> }
> 
> Or better to make smp_boot_protocol() callable regardless
> of CONFIG_ACPI and then no preprocessor conditionals at all
> would be needed.
> 
>> +
>>  /*
>> - * Read a cpu's enable method from the device tree and record it in cpu_ops.
>> + * Read a cpu's enable method and record it in cpu_ops.
>>   */
>>  int __init cpu_read_ops(struct device_node *dn, int cpu)
>>  {
>> -	const char *enable_method = of_get_property(dn, "enable-method", NULL);
>> +	const char *enable_method;
>> +
>> +	if (!acpi_disabled) {
>> +		enable_method = acpi_get_cpu_boot_method();
>> +		goto get_ops;
>> +	}
>> +
>> +	enable_method = of_get_property(dn, "enable-method", NULL);
>>  	if (!enable_method) {
>>  		/*
>>  		 * The boot CPU may not have an enable method (e.g. when
>> @@ -66,10 +100,17 @@ int __init cpu_read_ops(struct device_node *dn, int cpu)
>>  		return -ENOENT;
>>  	}
>>  
>> +get_ops:
>>  	cpu_ops[cpu] = cpu_get_ops(enable_method);
>>  	if (!cpu_ops[cpu]) {
>> -		pr_warn("%s: unsupported enable-method property: %s\n",
>> -			dn->full_name, enable_method);
>> +		if (acpi_disabled) {
>> +			pr_warn("%s: unsupported enable-method property: %s\n",
>> +				dn->full_name, enable_method);
>> +		} else {
>> +			pr_warn("CPU %d: boot protocol unsupported or unknown\n",
>> +				cpu);
>> +		}
>> +
> 
> Can't we have this more integrated, maybe something like this?
> 
> 	enable_method = acpi_disabled ? of_get_property(dn, "enable-method", NULL)
> 		: acpi_get_cpu_boot_method();

I like this :)

> 	message = acpi_disabled ? dn->full_name : "";
> 
> 	...
> 	
> 	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
> 				cpu, message, enable_method)

In ACPI, there is no enable-method property, it is a term from, so I think the
message printed can be separated.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-19 11:10         ` Mark Rutland
  (?)
@ 2014-08-19 12:13           ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 12:13 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Sudeep Holla,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi@vger.kernel.org

On 2014-8-19 19:10, Mark Rutland wrote:
>>>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>>>>  	early_memunmap(map, size);
>>>>  }
>>>>  
>>>> +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 version,
>>>> +	 * and there is a minor version of FADT which was introduced
>>>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>>>> +	 * to get arm boot flags, or we will disable ACPI.
>>>> +	 */
>>>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
>>>
>>> If we ever get revision 6.0, this would trigger.
>>
>> Yes, good catch, actually I already fixed that in my local git repo,
>>
>> +       if (table->revision > 5 ||
>> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
>> +               return 0;
>> +       } else {
>> +               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
>> or higher\n",
>> +                       table->revision, fadt->minor_revision);
>> +               disable_acpi();
>> +               return -EINVAL;
>> +       }
> 
> Given you return in the first path, you don't need the remaining code to
> live in an else block.

Agreed, I will update it, and move disable_acpi() outside this function and keep
it in one place as Sudeep suggested.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 12:13           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 12:13 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Sudeep Holla,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter,
	Lv Zheng, Robert Moore, Lorenzo Pieralisi, Liviu Dudau,
	Randy Dunlap, Charles Garcia-Tobin, linux-acpi, linux-arm-kernel,
	linux-kernel, linaro-acpi

On 2014-8-19 19:10, Mark Rutland wrote:
>>>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>>>>  	early_memunmap(map, size);
>>>>  }
>>>>  
>>>> +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 version,
>>>> +	 * and there is a minor version of FADT which was introduced
>>>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>>>> +	 * to get arm boot flags, or we will disable ACPI.
>>>> +	 */
>>>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
>>>
>>> If we ever get revision 6.0, this would trigger.
>>
>> Yes, good catch, actually I already fixed that in my local git repo,
>>
>> +       if (table->revision > 5 ||
>> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
>> +               return 0;
>> +       } else {
>> +               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
>> or higher\n",
>> +                       table->revision, fadt->minor_revision);
>> +               disable_acpi();
>> +               return -EINVAL;
>> +       }
> 
> Given you return in the first path, you don't need the remaining code to
> live in an else block.

Agreed, I will update it, and move disable_acpi() outside this function and keep
it in one place as Sudeep suggested.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 12:13           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-19 12:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-19 19:10, Mark Rutland wrote:
>>>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned long size)
>>>>  	early_memunmap(map, size);
>>>>  }
>>>>  
>>>> +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 version,
>>>> +	 * and there is a minor version of FADT which was introduced
>>>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>>>> +	 * to get arm boot flags, or we will disable ACPI.
>>>> +	 */
>>>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
>>>
>>> If we ever get revision 6.0, this would trigger.
>>
>> Yes, good catch, actually I already fixed that in my local git repo,
>>
>> +       if (table->revision > 5 ||
>> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
>> +               return 0;
>> +       } else {
>> +               pr_info("FADT revision is %d.%d, no PSCI support, should be 5.1
>> or higher\n",
>> +                       table->revision, fadt->minor_revision);
>> +               disable_acpi();
>> +               return -EINVAL;
>> +       }
> 
> Given you return in the first path, you don't need the remaining code to
> live in an else block.

Agreed, I will update it, and move disable_acpi() outside this function and keep
it in one place as Sudeep suggested.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
  2014-08-19 11:00       ` Hanjun Guo
  (?)
@ 2014-08-19 16:46         ` Zi Shen Lim
  -1 siblings, 0 replies; 180+ messages in thread
From: Zi Shen Lim @ 2014-08-19 16:46 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland,
	linaro-acpi, Liviu Dudau, Lv Zheng, Rob Herring, Daniel Lezcano,
	Robert Moore, linux-acpi, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Mark Brown,
	Bjorn Helgaas, linux-arm-kernel, Randy Dunlap,
	linux-kernel@vger.kernel.org

Hanjun,

On Tue, Aug 19, 2014 at 6:00 AM, Hanjun Guo <hanjun.guo@linaro.org> wrote:
> Will INTERRUPT_CONTROLLER confuse people? There is only one GIC redistributor
> (some people regard it as interrupt controller) in ARM system, if we use
> INTERRUPT_CONTROLLER people will regard it as multi-redistributors in the
> system, I think GIC_CPU_INTERFACE would be better, what do you think?

I think you meant to say "one GIC _distributor_" (GICD) instead of
redistributor (GICR).
ACPI5.1 only describes one GICD per system, but we can most certainly
describe multiple GICRs.
For multi-cpu systems, you'll definitely see multiple GIC redistributors.

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-19 16:46         ` Zi Shen Lim
  0 siblings, 0 replies; 180+ messages in thread
From: Zi Shen Lim @ 2014-08-19 16:46 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland,
	linaro-acpi, Liviu Dudau, Lv Zheng, Rob Herring, Daniel Lezcano,
	Robert Moore, linux-acpi, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Mark Brown,
	Bjorn Helgaas, linux-arm-kernel, Randy Dunlap, linux-kernel,
	Olof Johansson

Hanjun,

On Tue, Aug 19, 2014 at 6:00 AM, Hanjun Guo <hanjun.guo@linaro.org> wrote:
> Will INTERRUPT_CONTROLLER confuse people? There is only one GIC redistributor
> (some people regard it as interrupt controller) in ARM system, if we use
> INTERRUPT_CONTROLLER people will regard it as multi-redistributors in the
> system, I think GIC_CPU_INTERFACE would be better, what do you think?

I think you meant to say "one GIC _distributor_" (GICD) instead of
redistributor (GICR).
ACPI5.1 only describes one GICD per system, but we can most certainly
describe multiple GICRs.
For multi-cpu systems, you'll definitely see multiple GIC redistributors.

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [Linaro-acpi] [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-19 16:46         ` Zi Shen Lim
  0 siblings, 0 replies; 180+ messages in thread
From: Zi Shen Lim @ 2014-08-19 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hanjun,

On Tue, Aug 19, 2014 at 6:00 AM, Hanjun Guo <hanjun.guo@linaro.org> wrote:
> Will INTERRUPT_CONTROLLER confuse people? There is only one GIC redistributor
> (some people regard it as interrupt controller) in ARM system, if we use
> INTERRUPT_CONTROLLER people will regard it as multi-redistributors in the
> system, I think GIC_CPU_INTERFACE would be better, what do you think?

I think you meant to say "one GIC _distributor_" (GICD) instead of
redistributor (GICR).
ACPI5.1 only describes one GICD per system, but we can most certainly
describe multiple GICRs.
For multi-cpu systems, you'll definitely see multiple GIC redistributors.

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-19 12:11       ` Hanjun Guo
  (?)
@ 2014-08-19 19:25         ` Geoff Levand
  -1 siblings, 0 replies; 180+ messages in thread
From: Geoff Levand @ 2014-08-19 19:25 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Catalin Marinas, Rafael J. Wysocki, Mark Rutland, linaro-acpi,
	Liviu Dudau, Lv Zheng, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Robert Moore, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap

Hi Hanjun,

On Tue, 2014-08-19 at 20:11 +0800, Hanjun Guo wrote:
> On 2014-8-19 2:56, Geoff Levand wrote:

> > 	message = acpi_disabled ? dn->full_name : "";
> > 
> > 	...
> > 	
> > 	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
> > 				cpu, message, enable_method)
> 
> In ACPI, there is no enable-method property, it is a term from, so I think the
> message printed can be separated.

I think it better to have a single message that can cover all
than to have separate messages.  Wouldn't the enable method be
"acpi-parking" or "acpi-psci"?  Then something like this would
work:

	pr_warn("CPU %d: %s Unsupported enable method: %s\n", cpu, message, enable_method);

-Geoff



^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-19 19:25         ` Geoff Levand
  0 siblings, 0 replies; 180+ messages in thread
From: Geoff Levand @ 2014-08-19 19:25 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Catalin Marinas, Rafael J. Wysocki, Mark Rutland, linaro-acpi,
	Liviu Dudau, Lv Zheng, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Robert Moore, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap, linux-kernel, Sudeep Holla, Olof Johansson

Hi Hanjun,

On Tue, 2014-08-19 at 20:11 +0800, Hanjun Guo wrote:
> On 2014-8-19 2:56, Geoff Levand wrote:

> > 	message = acpi_disabled ? dn->full_name : "";
> > 
> > 	...
> > 	
> > 	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
> > 				cpu, message, enable_method)
> 
> In ACPI, there is no enable-method property, it is a term from, so I think the
> message printed can be separated.

I think it better to have a single message that can cover all
than to have separate messages.  Wouldn't the enable method be
"acpi-parking" or "acpi-psci"?  Then something like this would
work:

	pr_warn("CPU %d: %s Unsupported enable method: %s\n", cpu, message, enable_method);

-Geoff



^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-19 19:25         ` Geoff Levand
  0 siblings, 0 replies; 180+ messages in thread
From: Geoff Levand @ 2014-08-19 19:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Hanjun,

On Tue, 2014-08-19 at 20:11 +0800, Hanjun Guo wrote:
> On 2014-8-19 2:56, Geoff Levand wrote:

> > 	message = acpi_disabled ? dn->full_name : "";
> > 
> > 	...
> > 	
> > 	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
> > 				cpu, message, enable_method)
> 
> In ACPI, there is no enable-method property, it is a term from, so I think the
> message printed can be separated.

I think it better to have a single message that can cover all
than to have separate messages.  Wouldn't the enable method be
"acpi-parking" or "acpi-psci"?  Then something like this would
work:

	pr_warn("CPU %d: %s Unsupported enable method: %s\n", cpu, message, enable_method);

-Geoff

^ permalink raw reply	[flat|nested] 180+ messages in thread

* RE: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-19 12:13           ` Hanjun Guo
  (?)
@ 2014-08-19 22:55             ` Moore, Robert
  -1 siblings, 0 replies; 180+ messages in thread
From: Moore, Robert @ 2014-08-19 22:55 UTC (permalink / raw)
  To: Hanjun Guo, Mark Rutland
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Sudeep Holla,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter, Zheng,
	Lv, Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel

I should warn you that FADT version numbers are notoriously unreliable; In fact, in ACPICA we were eventually forced to abandon them entirely. We use the actual size of the FADT instead.

Bob



> -----Original Message-----
> From: Hanjun Guo [mailto:hanjun.guo@linaro.org]
> Sent: Tuesday, August 19, 2014 5:14 AM
> To: Mark Rutland
> Cc: Catalin Marinas; Rafael J. Wysocki; graeme.gregory@linaro.org; Arnd
> Bergmann; Olof Johansson; grant.likely@linaro.org; Sudeep Holla; Will
> Deacon; Jason Cooper; Marc Zyngier; Bjorn Helgaas; Daniel Lezcano; Mark
> Brown; Rob Herring; Robert Richter; Zheng, Lv; Moore, Robert; Lorenzo
> Pieralisi; Liviu Dudau; Randy Dunlap; Charles Garcia-Tobin; linux-
> acpi@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; linaro-acpi@lists.linaro.org
> Subject: Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI
> flags for PSCI init
> 
> On 2014-8-19 19:10, Mark Rutland wrote:
> >>>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned
> long size)
> >>>>  	early_memunmap(map, size);
> >>>>  }
> >>>>
> >>>> +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 version,
> >>>> +	 * and there is a minor version of FADT which was introduced
> >>>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> >>>> +	 * to get arm boot flags, or we will disable ACPI.
> >>>> +	 */
> >>>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
> >>>
> >>> If we ever get revision 6.0, this would trigger.
> >>
> >> Yes, good catch, actually I already fixed that in my local git repo,
> >>
> >> +       if (table->revision > 5 ||
> >> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
> >> +               return 0;
> >> +       } else {
> >> +               pr_info("FADT revision is %d.%d, no PSCI support,
> >> + should be 5.1
> >> or higher\n",
> >> +                       table->revision, fadt->minor_revision);
> >> +               disable_acpi();
> >> +               return -EINVAL;
> >> +       }
> >
> > Given you return in the first path, you don't need the remaining code
> > to live in an else block.
> 
> Agreed, I will update it, and move disable_acpi() outside this function
> and keep it in one place as Sudeep suggested.
> 
> Thanks
> Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* RE: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 22:55             ` Moore, Robert
  0 siblings, 0 replies; 180+ messages in thread
From: Moore, Robert @ 2014-08-19 22:55 UTC (permalink / raw)
  To: Hanjun Guo, Mark Rutland
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Sudeep Holla,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter, Zheng,
	Lv, Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi

I should warn you that FADT version numbers are notoriously unreliable; In fact, in ACPICA we were eventually forced to abandon them entirely. We use the actual size of the FADT instead.

Bob



> -----Original Message-----
> From: Hanjun Guo [mailto:hanjun.guo@linaro.org]
> Sent: Tuesday, August 19, 2014 5:14 AM
> To: Mark Rutland
> Cc: Catalin Marinas; Rafael J. Wysocki; graeme.gregory@linaro.org; Arnd
> Bergmann; Olof Johansson; grant.likely@linaro.org; Sudeep Holla; Will
> Deacon; Jason Cooper; Marc Zyngier; Bjorn Helgaas; Daniel Lezcano; Mark
> Brown; Rob Herring; Robert Richter; Zheng, Lv; Moore, Robert; Lorenzo
> Pieralisi; Liviu Dudau; Randy Dunlap; Charles Garcia-Tobin; linux-
> acpi@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; linaro-acpi@lists.linaro.org
> Subject: Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI
> flags for PSCI init
> 
> On 2014-8-19 19:10, Mark Rutland wrote:
> >>>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned
> long size)
> >>>>  	early_memunmap(map, size);
> >>>>  }
> >>>>
> >>>> +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 version,
> >>>> +	 * and there is a minor version of FADT which was introduced
> >>>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> >>>> +	 * to get arm boot flags, or we will disable ACPI.
> >>>> +	 */
> >>>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
> >>>
> >>> If we ever get revision 6.0, this would trigger.
> >>
> >> Yes, good catch, actually I already fixed that in my local git repo,
> >>
> >> +       if (table->revision > 5 ||
> >> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
> >> +               return 0;
> >> +       } else {
> >> +               pr_info("FADT revision is %d.%d, no PSCI support,
> >> + should be 5.1
> >> or higher\n",
> >> +                       table->revision, fadt->minor_revision);
> >> +               disable_acpi();
> >> +               return -EINVAL;
> >> +       }
> >
> > Given you return in the first path, you don't need the remaining code
> > to live in an else block.
> 
> Agreed, I will update it, and move disable_acpi() outside this function
> and keep it in one place as Sudeep suggested.
> 
> Thanks
> Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-19 22:55             ` Moore, Robert
  0 siblings, 0 replies; 180+ messages in thread
From: Moore, Robert @ 2014-08-19 22:55 UTC (permalink / raw)
  To: linux-arm-kernel

I should warn you that FADT version numbers are notoriously unreliable; In fact, in ACPICA we were eventually forced to abandon them entirely. We use the actual size of the FADT instead.

Bob



> -----Original Message-----
> From: Hanjun Guo [mailto:hanjun.guo at linaro.org]
> Sent: Tuesday, August 19, 2014 5:14 AM
> To: Mark Rutland
> Cc: Catalin Marinas; Rafael J. Wysocki; graeme.gregory at linaro.org; Arnd
> Bergmann; Olof Johansson; grant.likely at linaro.org; Sudeep Holla; Will
> Deacon; Jason Cooper; Marc Zyngier; Bjorn Helgaas; Daniel Lezcano; Mark
> Brown; Rob Herring; Robert Richter; Zheng, Lv; Moore, Robert; Lorenzo
> Pieralisi; Liviu Dudau; Randy Dunlap; Charles Garcia-Tobin; linux-
> acpi at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; linaro-acpi at lists.linaro.org
> Subject: Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI
> flags for PSCI init
> 
> On 2014-8-19 19:10, Mark Rutland wrote:
> >>>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned
> long size)
> >>>>  	early_memunmap(map, size);
> >>>>  }
> >>>>
> >>>> +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 version,
> >>>> +	 * and there is a minor version of FADT which was introduced
> >>>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
> >>>> +	 * to get arm boot flags, or we will disable ACPI.
> >>>> +	 */
> >>>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
> >>>
> >>> If we ever get revision 6.0, this would trigger.
> >>
> >> Yes, good catch, actually I already fixed that in my local git repo,
> >>
> >> +       if (table->revision > 5 ||
> >> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
> >> +               return 0;
> >> +       } else {
> >> +               pr_info("FADT revision is %d.%d, no PSCI support,
> >> + should be 5.1
> >> or higher\n",
> >> +                       table->revision, fadt->minor_revision);
> >> +               disable_acpi();
> >> +               return -EINVAL;
> >> +       }
> >
> > Given you return in the first path, you don't need the remaining code
> > to live in an else block.
> 
> Agreed, I will update it, and move disable_acpi() outside this function
> and keep it in one place as Sudeep suggested.
> 
> Thanks
> Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
  2014-08-19 16:46         ` Zi Shen Lim
  (?)
@ 2014-08-20  3:24           ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-20  3:24 UTC (permalink / raw)
  To: Zi Shen Lim
  Cc: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland,
	linaro-acpi, Liviu Dudau, Lv Zheng, Rob Herring, Daniel Lezcano,
	Robert Moore, linux-acpi, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Mark Brown,
	Bjorn Helgaas, linux-arm-kernel, Randy Dunlap,
	linux-kernel@vger.kernel.org

On 2014-8-20 0:46, Zi Shen Lim wrote:
> Hanjun,

Hi Lim,

> 
> On Tue, Aug 19, 2014 at 6:00 AM, Hanjun Guo <hanjun.guo@linaro.org> wrote:
>> Will INTERRUPT_CONTROLLER confuse people? There is only one GIC redistributor
>> (some people regard it as interrupt controller) in ARM system, if we use
>> INTERRUPT_CONTROLLER people will regard it as multi-redistributors in the
>> system, I think GIC_CPU_INTERFACE would be better, what do you think?
> 
> I think you meant to say "one GIC _distributor_" (GICD) instead of
> redistributor (GICR).
> ACPI5.1 only describes one GICD per system, but we can most certainly
> describe multiple GICRs.
> For multi-cpu systems, you'll definitely see multiple GIC redistributors.

Yes, you are right, thanks for pointing it out, I think I need more coffee :)

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [Linaro-acpi] [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-20  3:24           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-20  3:24 UTC (permalink / raw)
  To: Zi Shen Lim
  Cc: Sudeep Holla, Catalin Marinas, Rafael J. Wysocki, Mark Rutland,
	linaro-acpi, Liviu Dudau, Lv Zheng, Rob Herring, Daniel Lezcano,
	Robert Moore, linux-acpi, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Mark Brown,
	Bjorn Helgaas, linux-arm-kernel, Randy Dunlap, linux-kernel,
	Olof Johansson

On 2014-8-20 0:46, Zi Shen Lim wrote:
> Hanjun,

Hi Lim,

> 
> On Tue, Aug 19, 2014 at 6:00 AM, Hanjun Guo <hanjun.guo@linaro.org> wrote:
>> Will INTERRUPT_CONTROLLER confuse people? There is only one GIC redistributor
>> (some people regard it as interrupt controller) in ARM system, if we use
>> INTERRUPT_CONTROLLER people will regard it as multi-redistributors in the
>> system, I think GIC_CPU_INTERFACE would be better, what do you think?
> 
> I think you meant to say "one GIC _distributor_" (GICD) instead of
> redistributor (GICR).
> ACPI5.1 only describes one GICD per system, but we can most certainly
> describe multiple GICRs.
> For multi-cpu systems, you'll definitely see multiple GIC redistributors.

Yes, you are right, thanks for pointing it out, I think I need more coffee :)

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [Linaro-acpi] [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-20  3:24           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-20  3:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-20 0:46, Zi Shen Lim wrote:
> Hanjun,

Hi Lim,

> 
> On Tue, Aug 19, 2014 at 6:00 AM, Hanjun Guo <hanjun.guo@linaro.org> wrote:
>> Will INTERRUPT_CONTROLLER confuse people? There is only one GIC redistributor
>> (some people regard it as interrupt controller) in ARM system, if we use
>> INTERRUPT_CONTROLLER people will regard it as multi-redistributors in the
>> system, I think GIC_CPU_INTERFACE would be better, what do you think?
> 
> I think you meant to say "one GIC _distributor_" (GICD) instead of
> redistributor (GICR).
> ACPI5.1 only describes one GICD per system, but we can most certainly
> describe multiple GICRs.
> For multi-cpu systems, you'll definitely see multiple GIC redistributors.

Yes, you are right, thanks for pointing it out, I think I need more coffee :)

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-19 19:25         ` Geoff Levand
  (?)
@ 2014-08-20  3:25           ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-20  3:25 UTC (permalink / raw)
  To: Geoff Levand
  Cc: Catalin Marinas, Rafael J. Wysocki, Mark Rutland, linaro-acpi,
	Liviu Dudau, Lv Zheng, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Robert Moore, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap

On 2014-8-20 3:25, Geoff Levand wrote:
> Hi Hanjun,
> 
> On Tue, 2014-08-19 at 20:11 +0800, Hanjun Guo wrote:
>> On 2014-8-19 2:56, Geoff Levand wrote:
> 
>>> 	message = acpi_disabled ? dn->full_name : "";
>>>
>>> 	...
>>> 	
>>> 	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
>>> 				cpu, message, enable_method)
>>
>> In ACPI, there is no enable-method property, it is a term from, so I think the
>> message printed can be separated.
> 
> I think it better to have a single message that can cover all
> than to have separate messages.  Wouldn't the enable method be
> "acpi-parking" or "acpi-psci"?  Then something like this would
> work:
> 
> 	pr_warn("CPU %d: %s Unsupported enable method: %s\n", cpu, message, enable_method);

Thanks for the suggestion, I will update it in next version.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-20  3:25           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-20  3:25 UTC (permalink / raw)
  To: Geoff Levand
  Cc: Catalin Marinas, Rafael J. Wysocki, Mark Rutland, linaro-acpi,
	Liviu Dudau, Lv Zheng, Rob Herring, Lorenzo Pieralisi,
	Daniel Lezcano, Robert Moore, linux-acpi, Grant Likely,
	Charles.Garcia-Tobin, Robert Richter, Jason Cooper,
	Arnd Bergmann, Marc Zyngier, Will Deacon, Tomasz Nowicki,
	Mark Brown, Bjorn Helgaas, linux-arm-kernel, Graeme Gregory,
	Randy Dunlap, linux-kernel, Sudeep Holla, Olof Johansson

On 2014-8-20 3:25, Geoff Levand wrote:
> Hi Hanjun,
> 
> On Tue, 2014-08-19 at 20:11 +0800, Hanjun Guo wrote:
>> On 2014-8-19 2:56, Geoff Levand wrote:
> 
>>> 	message = acpi_disabled ? dn->full_name : "";
>>>
>>> 	...
>>> 	
>>> 	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
>>> 				cpu, message, enable_method)
>>
>> In ACPI, there is no enable-method property, it is a term from, so I think the
>> message printed can be separated.
> 
> I think it better to have a single message that can cover all
> than to have separate messages.  Wouldn't the enable method be
> "acpi-parking" or "acpi-psci"?  Then something like this would
> work:
> 
> 	pr_warn("CPU %d: %s Unsupported enable method: %s\n", cpu, message, enable_method);

Thanks for the suggestion, I will update it in next version.

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-20  3:25           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-20  3:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-20 3:25, Geoff Levand wrote:
> Hi Hanjun,
> 
> On Tue, 2014-08-19 at 20:11 +0800, Hanjun Guo wrote:
>> On 2014-8-19 2:56, Geoff Levand wrote:
> 
>>> 	message = acpi_disabled ? dn->full_name : "";
>>>
>>> 	...
>>> 	
>>> 	pr_warn("CPU %d: %s unsupported enable-method property: %s\n",
>>> 				cpu, message, enable_method)
>>
>> In ACPI, there is no enable-method property, it is a term from, so I think the
>> message printed can be separated.
> 
> I think it better to have a single message that can cover all
> than to have separate messages.  Wouldn't the enable method be
> "acpi-parking" or "acpi-psci"?  Then something like this would
> work:
> 
> 	pr_warn("CPU %d: %s Unsupported enable method: %s\n", cpu, message, enable_method);

Thanks for the suggestion, I will update it in next version.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
  2014-08-19 22:55             ` Moore, Robert
  (?)
@ 2014-08-20  4:12               ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-20  4:12 UTC (permalink / raw)
  To: Moore, Robert, Mark Rutland
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Sudeep Holla,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter, Zheng,
	Lv, Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel

Hi Bob,

On 2014-8-20 6:55, Moore, Robert wrote:
> I should warn you that FADT version numbers are notoriously unreliable;
> In fact, in ACPICA we were eventually forced to abandon them entirely. 
> We use the actual size of the FADT instead.

Yes, I heard that story, thanks for the reminding. But I also see that the
revision number is used on x86 and ia64 now in parsing FADT, it is a firmware
bug not to comply with the spec, and on ARM, only ACPI 5.1 or higher can be
used in Linux, Major.Minor revision was introduced in ACPI 5.1 and it was a
major change for it, so I think firmware should comply with that, if firmware
just copy some code from somewhere else and leave the revision number
unchanged, we will not boot (disable ACPI).

The size of FADT for 5.0 and 5.1 is no difference, it is pretty hard to use
that to identify the version of FADT, did I  miss something?

Thanks
Hanjun

> 
> Bob
> 
> 
> 
>> -----Original Message-----
>> From: Hanjun Guo [mailto:hanjun.guo@linaro.org]
>> Sent: Tuesday, August 19, 2014 5:14 AM
>> To: Mark Rutland
>> Cc: Catalin Marinas; Rafael J. Wysocki; graeme.gregory@linaro.org; Arnd
>> Bergmann; Olof Johansson; grant.likely@linaro.org; Sudeep Holla; Will
>> Deacon; Jason Cooper; Marc Zyngier; Bjorn Helgaas; Daniel Lezcano; Mark
>> Brown; Rob Herring; Robert Richter; Zheng, Lv; Moore, Robert; Lorenzo
>> Pieralisi; Liviu Dudau; Randy Dunlap; Charles Garcia-Tobin; linux-
>> acpi@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
>> kernel@vger.kernel.org; linaro-acpi@lists.linaro.org
>> Subject: Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI
>> flags for PSCI init
>>
>> On 2014-8-19 19:10, Mark Rutland wrote:
>>>>>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned
>> long size)
>>>>>>  	early_memunmap(map, size);
>>>>>>  }
>>>>>>
>>>>>> +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 version,
>>>>>> +	 * and there is a minor version of FADT which was introduced
>>>>>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>>>>>> +	 * to get arm boot flags, or we will disable ACPI.
>>>>>> +	 */
>>>>>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
>>>>>
>>>>> If we ever get revision 6.0, this would trigger.
>>>>
>>>> Yes, good catch, actually I already fixed that in my local git repo,
>>>>
>>>> +       if (table->revision > 5 ||
>>>> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
>>>> +               return 0;
>>>> +       } else {
>>>> +               pr_info("FADT revision is %d.%d, no PSCI support,
>>>> + should be 5.1
>>>> or higher\n",
>>>> +                       table->revision, fadt->minor_revision);
>>>> +               disable_acpi();
>>>> +               return -EINVAL;
>>>> +       }
>>>
>>> Given you return in the first path, you don't need the remaining code
>>> to live in an else block.
>>
>> Agreed, I will update it, and move disable_acpi() outside this function
>> and keep it in one place as Sudeep suggested.
>>
>> Thanks
>> Hanjun
> 


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-20  4:12               ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-20  4:12 UTC (permalink / raw)
  To: Moore, Robert, Mark Rutland
  Cc: Catalin Marinas, Rafael J. Wysocki, graeme.gregory,
	Arnd Bergmann, Olof Johansson, grant.likely, Sudeep Holla,
	Will Deacon, Jason Cooper, Marc Zyngier, Bjorn Helgaas,
	Daniel Lezcano, Mark Brown, Rob Herring, Robert Richter, Zheng,
	Lv, Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi

Hi Bob,

On 2014-8-20 6:55, Moore, Robert wrote:
> I should warn you that FADT version numbers are notoriously unreliable;
> In fact, in ACPICA we were eventually forced to abandon them entirely. 
> We use the actual size of the FADT instead.

Yes, I heard that story, thanks for the reminding. But I also see that the
revision number is used on x86 and ia64 now in parsing FADT, it is a firmware
bug not to comply with the spec, and on ARM, only ACPI 5.1 or higher can be
used in Linux, Major.Minor revision was introduced in ACPI 5.1 and it was a
major change for it, so I think firmware should comply with that, if firmware
just copy some code from somewhere else and leave the revision number
unchanged, we will not boot (disable ACPI).

The size of FADT for 5.0 and 5.1 is no difference, it is pretty hard to use
that to identify the version of FADT, did I  miss something?

Thanks
Hanjun

> 
> Bob
> 
> 
> 
>> -----Original Message-----
>> From: Hanjun Guo [mailto:hanjun.guo@linaro.org]
>> Sent: Tuesday, August 19, 2014 5:14 AM
>> To: Mark Rutland
>> Cc: Catalin Marinas; Rafael J. Wysocki; graeme.gregory@linaro.org; Arnd
>> Bergmann; Olof Johansson; grant.likely@linaro.org; Sudeep Holla; Will
>> Deacon; Jason Cooper; Marc Zyngier; Bjorn Helgaas; Daniel Lezcano; Mark
>> Brown; Rob Herring; Robert Richter; Zheng, Lv; Moore, Robert; Lorenzo
>> Pieralisi; Liviu Dudau; Randy Dunlap; Charles Garcia-Tobin; linux-
>> acpi@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
>> kernel@vger.kernel.org; linaro-acpi@lists.linaro.org
>> Subject: Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI
>> flags for PSCI init
>>
>> On 2014-8-19 19:10, Mark Rutland wrote:
>>>>>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned
>> long size)
>>>>>>  	early_memunmap(map, size);
>>>>>>  }
>>>>>>
>>>>>> +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 version,
>>>>>> +	 * and there is a minor version of FADT which was introduced
>>>>>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>>>>>> +	 * to get arm boot flags, or we will disable ACPI.
>>>>>> +	 */
>>>>>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
>>>>>
>>>>> If we ever get revision 6.0, this would trigger.
>>>>
>>>> Yes, good catch, actually I already fixed that in my local git repo,
>>>>
>>>> +       if (table->revision > 5 ||
>>>> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
>>>> +               return 0;
>>>> +       } else {
>>>> +               pr_info("FADT revision is %d.%d, no PSCI support,
>>>> + should be 5.1
>>>> or higher\n",
>>>> +                       table->revision, fadt->minor_revision);
>>>> +               disable_acpi();
>>>> +               return -EINVAL;
>>>> +       }
>>>
>>> Given you return in the first path, you don't need the remaining code
>>> to live in an else block.
>>
>> Agreed, I will update it, and move disable_acpi() outside this function
>> and keep it in one place as Sudeep suggested.
>>
>> Thanks
>> Hanjun
> 


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@ 2014-08-20  4:12               ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-20  4:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bob,

On 2014-8-20 6:55, Moore, Robert wrote:
> I should warn you that FADT version numbers are notoriously unreliable;
> In fact, in ACPICA we were eventually forced to abandon them entirely. 
> We use the actual size of the FADT instead.

Yes, I heard that story, thanks for the reminding. But I also see that the
revision number is used on x86 and ia64 now in parsing FADT, it is a firmware
bug not to comply with the spec, and on ARM, only ACPI 5.1 or higher can be
used in Linux, Major.Minor revision was introduced in ACPI 5.1 and it was a
major change for it, so I think firmware should comply with that, if firmware
just copy some code from somewhere else and leave the revision number
unchanged, we will not boot (disable ACPI).

The size of FADT for 5.0 and 5.1 is no difference, it is pretty hard to use
that to identify the version of FADT, did I  miss something?

Thanks
Hanjun

> 
> Bob
> 
> 
> 
>> -----Original Message-----
>> From: Hanjun Guo [mailto:hanjun.guo at linaro.org]
>> Sent: Tuesday, August 19, 2014 5:14 AM
>> To: Mark Rutland
>> Cc: Catalin Marinas; Rafael J. Wysocki; graeme.gregory at linaro.org; Arnd
>> Bergmann; Olof Johansson; grant.likely at linaro.org; Sudeep Holla; Will
>> Deacon; Jason Cooper; Marc Zyngier; Bjorn Helgaas; Daniel Lezcano; Mark
>> Brown; Rob Herring; Robert Richter; Zheng, Lv; Moore, Robert; Lorenzo
>> Pieralisi; Liviu Dudau; Randy Dunlap; Charles Garcia-Tobin; linux-
>> acpi at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
>> kernel at vger.kernel.org; linaro-acpi at lists.linaro.org
>> Subject: Re: [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI
>> flags for PSCI init
>>
>> On 2014-8-19 19:10, Mark Rutland wrote:
>>>>>> @@ -47,6 +49,26 @@ void __init __acpi_unmap_table(char *map, unsigned
>> long size)
>>>>>>  	early_memunmap(map, size);
>>>>>>  }
>>>>>>
>>>>>> +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 version,
>>>>>> +	 * and there is a minor version of FADT which was introduced
>>>>>> +	 * by ACPI 5.1, we only deal with ACPI 5.1 or higher version
>>>>>> +	 * to get arm boot flags, or we will disable ACPI.
>>>>>> +	 */
>>>>>> +	if (table->revision < 5 || fadt->minor_revision < 1) {
>>>>>
>>>>> If we ever get revision 6.0, this would trigger.
>>>>
>>>> Yes, good catch, actually I already fixed that in my local git repo,
>>>>
>>>> +       if (table->revision > 5 ||
>>>> +           (table->revision == 5 && fadt->minor_revision >= 1)) {
>>>> +               return 0;
>>>> +       } else {
>>>> +               pr_info("FADT revision is %d.%d, no PSCI support,
>>>> + should be 5.1
>>>> or higher\n",
>>>> +                       table->revision, fadt->minor_revision);
>>>> +               disable_acpi();
>>>> +               return -EINVAL;
>>>> +       }
>>>
>>> Given you return in the first path, you don't need the remaining code
>>> to live in an else block.
>>
>> Agreed, I will update it, and move disable_acpi() outside this function
>> and keep it in one place as Sudeep suggested.
>>
>> Thanks
>> Hanjun
> 

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
  2014-08-19  7:36       ` Hanjun Guo
  (?)
@ 2014-08-20 14:38         ` Catalin Marinas
  -1 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-20 14:38 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On Tue, Aug 19, 2014 at 08:36:46AM +0100, Hanjun Guo wrote:
> On 2014-8-18 22:27, Catalin Marinas wrote:
> > On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
> >> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> >> index 6e04868..e877967 100644
> >> --- a/arch/arm64/include/asm/acpi.h
> >> +++ b/arch/arm64/include/asm/acpi.h
> >> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> >>  extern int (*acpi_suspend_lowlevel)(void);
> >>  #define acpi_wakeup_address 0
> >>  
> >> +#define MAX_GIC_CPU_INTERFACE 65535
> > 
> > Does this need to be more than NR_CPUS?
> 
> Sometimes yes, CPU structure entries in MADT just like CPU nodes in
> device tree, the number of them may more than NR_CPUS.

I have a more general question here. In ACPI, is MADT the only way to
build a CPU topology? It looks weird that we use GIC properties to
create the cpu_logical_map(). A side-effect is that the GIC-related
functions are now scattered all over the kernel rather than being
contained in the GIC driver itself.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-20 14:38         ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-20 14:38 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi, Tomasz Nowicki

On Tue, Aug 19, 2014 at 08:36:46AM +0100, Hanjun Guo wrote:
> On 2014-8-18 22:27, Catalin Marinas wrote:
> > On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
> >> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> >> index 6e04868..e877967 100644
> >> --- a/arch/arm64/include/asm/acpi.h
> >> +++ b/arch/arm64/include/asm/acpi.h
> >> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> >>  extern int (*acpi_suspend_lowlevel)(void);
> >>  #define acpi_wakeup_address 0
> >>  
> >> +#define MAX_GIC_CPU_INTERFACE 65535
> > 
> > Does this need to be more than NR_CPUS?
> 
> Sometimes yes, CPU structure entries in MADT just like CPU nodes in
> device tree, the number of them may more than NR_CPUS.

I have a more general question here. In ACPI, is MADT the only way to
build a CPU topology? It looks weird that we use GIC properties to
create the cpu_logical_map(). A side-effect is that the GIC-related
functions are now scattered all over the kernel rather than being
contained in the GIC driver itself.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-20 14:38         ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-20 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 19, 2014 at 08:36:46AM +0100, Hanjun Guo wrote:
> On 2014-8-18 22:27, Catalin Marinas wrote:
> > On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
> >> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> >> index 6e04868..e877967 100644
> >> --- a/arch/arm64/include/asm/acpi.h
> >> +++ b/arch/arm64/include/asm/acpi.h
> >> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
> >>  extern int (*acpi_suspend_lowlevel)(void);
> >>  #define acpi_wakeup_address 0
> >>  
> >> +#define MAX_GIC_CPU_INTERFACE 65535
> > 
> > Does this need to be more than NR_CPUS?
> 
> Sometimes yes, CPU structure entries in MADT just like CPU nodes in
> device tree, the number of them may more than NR_CPUS.

I have a more general question here. In ACPI, is MADT the only way to
build a CPU topology? It looks weird that we use GIC properties to
create the cpu_logical_map(). A side-effect is that the GIC-related
functions are now scattered all over the kernel rather than being
contained in the GIC driver itself.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-19  8:32       ` Hanjun Guo
  (?)
@ 2014-08-20 14:52         ` Catalin Marinas
  -1 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-20 14:52 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On Tue, Aug 19, 2014 at 09:32:25AM +0100, Hanjun Guo wrote:
> On 2014-8-18 22:27, Catalin Marinas wrote:
> > On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
> >> +#ifdef CONFIG_ACPI
> >> +/*
> >> + * Get a cpu's boot method in the ACPI way.
> >> + */
> >> +static char * __init acpi_get_cpu_boot_method(void)
> >> +{
> >> +	/*
> >> +	 * For ACPI 5.1, only two kind of methods are provided,
> >> +	 * Parking protocol and PSCI, but Parking protocol is
> >> +	 * specified for ARMv7 only, so make PSCI as the only method
> >> +	 * for SMP initialization before the ACPI spec or Parking
> >> +	 * protocol spec is updated.
> >> +	 */
> >> +	switch (smp_boot_protocol()) {
> >> +	case ACPI_SMP_BOOT_PSCI:
> >> +		return "psci";
> >> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> >> +	default:
> >> +		return NULL;
> >> +	}
> >> +}
> > 
> > Actually, do we even need to define smp_boot_protocol()? Is it used
> > anywhere else apart from this patch (I still haven't gone through all
> > patches)?
> 
> It is just used in this patch. I think we can make the ACPI boot protocol
> scalable in this way, if we support another boot protocol in ACPI in the
> future, we can easily update the function to support it, does it make sense?

Not really. You just add additional code, enums, functions when all you
do is check for acpi_psci_present() (or whatever new protocol you would
get). If the enum is never going to be used outside this file, don't
bother with additional functions.

BTW, it would be nicer if the acpi related functions are contained in as
fewer files as possible. So here you could keep
acpi_get_cpu_boot_method() in the acpi.c file. It only returns a string.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-20 14:52         ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-20 14:52 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi, Tomasz Nowicki

On Tue, Aug 19, 2014 at 09:32:25AM +0100, Hanjun Guo wrote:
> On 2014-8-18 22:27, Catalin Marinas wrote:
> > On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
> >> +#ifdef CONFIG_ACPI
> >> +/*
> >> + * Get a cpu's boot method in the ACPI way.
> >> + */
> >> +static char * __init acpi_get_cpu_boot_method(void)
> >> +{
> >> +	/*
> >> +	 * For ACPI 5.1, only two kind of methods are provided,
> >> +	 * Parking protocol and PSCI, but Parking protocol is
> >> +	 * specified for ARMv7 only, so make PSCI as the only method
> >> +	 * for SMP initialization before the ACPI spec or Parking
> >> +	 * protocol spec is updated.
> >> +	 */
> >> +	switch (smp_boot_protocol()) {
> >> +	case ACPI_SMP_BOOT_PSCI:
> >> +		return "psci";
> >> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> >> +	default:
> >> +		return NULL;
> >> +	}
> >> +}
> > 
> > Actually, do we even need to define smp_boot_protocol()? Is it used
> > anywhere else apart from this patch (I still haven't gone through all
> > patches)?
> 
> It is just used in this patch. I think we can make the ACPI boot protocol
> scalable in this way, if we support another boot protocol in ACPI in the
> future, we can easily update the function to support it, does it make sense?

Not really. You just add additional code, enums, functions when all you
do is check for acpi_psci_present() (or whatever new protocol you would
get). If the enum is never going to be used outside this file, don't
bother with additional functions.

BTW, it would be nicer if the acpi related functions are contained in as
fewer files as possible. So here you could keep
acpi_get_cpu_boot_method() in the acpi.c file. It only returns a string.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-20 14:52         ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-20 14:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 19, 2014 at 09:32:25AM +0100, Hanjun Guo wrote:
> On 2014-8-18 22:27, Catalin Marinas wrote:
> > On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
> >> +#ifdef CONFIG_ACPI
> >> +/*
> >> + * Get a cpu's boot method in the ACPI way.
> >> + */
> >> +static char * __init acpi_get_cpu_boot_method(void)
> >> +{
> >> +	/*
> >> +	 * For ACPI 5.1, only two kind of methods are provided,
> >> +	 * Parking protocol and PSCI, but Parking protocol is
> >> +	 * specified for ARMv7 only, so make PSCI as the only method
> >> +	 * for SMP initialization before the ACPI spec or Parking
> >> +	 * protocol spec is updated.
> >> +	 */
> >> +	switch (smp_boot_protocol()) {
> >> +	case ACPI_SMP_BOOT_PSCI:
> >> +		return "psci";
> >> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
> >> +	default:
> >> +		return NULL;
> >> +	}
> >> +}
> > 
> > Actually, do we even need to define smp_boot_protocol()? Is it used
> > anywhere else apart from this patch (I still haven't gone through all
> > patches)?
> 
> It is just used in this patch. I think we can make the ACPI boot protocol
> scalable in this way, if we support another boot protocol in ACPI in the
> future, we can easily update the function to support it, does it make sense?

Not really. You just add additional code, enums, functions when all you
do is check for acpi_psci_present() (or whatever new protocol you would
get). If the enum is never going to be used outside this file, don't
bother with additional functions.

BTW, it would be nicer if the acpi related functions are contained in as
fewer files as possible. So here you could keep
acpi_get_cpu_boot_method() in the acpi.c file. It only returns a string.

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
  2014-08-19  8:37       ` Hanjun Guo
  (?)
@ 2014-08-20 14:56         ` Catalin Marinas
  -1 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-20 14:56 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On Tue, Aug 19, 2014 at 09:37:34AM +0100, Hanjun Guo wrote:
> On 2014-8-18 22:27, Catalin Marinas wrote:
> > On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
> >> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
> >> index e32321c..4007313 100644
> >> --- a/drivers/acpi/processor_core.c
> >> +++ b/drivers/acpi/processor_core.c
> >> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
> >>  	return 0;
> >>  }
> >>  
> >> +/*
> >> + * On ARM platform, MPIDR value is the hardware ID as apic ID
> >> + * on Intel platforms
> >> + */
> >> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
> >> +		int device_declaration, u32 acpi_id, int *mpidr)
> >> +{
> >> +	struct acpi_madt_generic_interrupt *gicc =
> >> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
> >> +
> >> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
> >> +		return -ENODEV;
> >> +
> >> +	/* In the GIC interrupt model, logical processors are
> >> +	 * required to have a Processor Device object in the DSDT,
> >> +	 * so we should check device_declaration here
> >> +	 */
> >> +	if (device_declaration && (gicc->uid == acpi_id)) {
> >> +		/*
> >> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
> >> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
> >> +		 * fields into a single 32 bit identifier to accommodate the
> >> +		 * acpi processor drivers.
> >> +		 */
> >> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
> >> +			 | gicc->arm_mpidr;
> > 
> > You can use pack_mpidr_into_32_bits().
> 
> processor_core.c will be used by x86 and ia64 too, it will cause
> compile error on !ARM64 platforms.

Oh. So we do we have an ARM-specific function in core ACPI code?

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-20 14:56         ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-20 14:56 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi

On Tue, Aug 19, 2014 at 09:37:34AM +0100, Hanjun Guo wrote:
> On 2014-8-18 22:27, Catalin Marinas wrote:
> > On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
> >> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
> >> index e32321c..4007313 100644
> >> --- a/drivers/acpi/processor_core.c
> >> +++ b/drivers/acpi/processor_core.c
> >> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
> >>  	return 0;
> >>  }
> >>  
> >> +/*
> >> + * On ARM platform, MPIDR value is the hardware ID as apic ID
> >> + * on Intel platforms
> >> + */
> >> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
> >> +		int device_declaration, u32 acpi_id, int *mpidr)
> >> +{
> >> +	struct acpi_madt_generic_interrupt *gicc =
> >> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
> >> +
> >> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
> >> +		return -ENODEV;
> >> +
> >> +	/* In the GIC interrupt model, logical processors are
> >> +	 * required to have a Processor Device object in the DSDT,
> >> +	 * so we should check device_declaration here
> >> +	 */
> >> +	if (device_declaration && (gicc->uid == acpi_id)) {
> >> +		/*
> >> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
> >> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
> >> +		 * fields into a single 32 bit identifier to accommodate the
> >> +		 * acpi processor drivers.
> >> +		 */
> >> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
> >> +			 | gicc->arm_mpidr;
> > 
> > You can use pack_mpidr_into_32_bits().
> 
> processor_core.c will be used by x86 and ia64 too, it will cause
> compile error on !ARM64 platforms.

Oh. So we do we have an ARM-specific function in core ACPI code?

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-20 14:56         ` Catalin Marinas
  0 siblings, 0 replies; 180+ messages in thread
From: Catalin Marinas @ 2014-08-20 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 19, 2014 at 09:37:34AM +0100, Hanjun Guo wrote:
> On 2014-8-18 22:27, Catalin Marinas wrote:
> > On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
> >> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
> >> index e32321c..4007313 100644
> >> --- a/drivers/acpi/processor_core.c
> >> +++ b/drivers/acpi/processor_core.c
> >> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
> >>  	return 0;
> >>  }
> >>  
> >> +/*
> >> + * On ARM platform, MPIDR value is the hardware ID as apic ID
> >> + * on Intel platforms
> >> + */
> >> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
> >> +		int device_declaration, u32 acpi_id, int *mpidr)
> >> +{
> >> +	struct acpi_madt_generic_interrupt *gicc =
> >> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
> >> +
> >> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
> >> +		return -ENODEV;
> >> +
> >> +	/* In the GIC interrupt model, logical processors are
> >> +	 * required to have a Processor Device object in the DSDT,
> >> +	 * so we should check device_declaration here
> >> +	 */
> >> +	if (device_declaration && (gicc->uid == acpi_id)) {
> >> +		/*
> >> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
> >> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
> >> +		 * fields into a single 32 bit identifier to accommodate the
> >> +		 * acpi processor drivers.
> >> +		 */
> >> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
> >> +			 | gicc->arm_mpidr;
> > 
> > You can use pack_mpidr_into_32_bits().
> 
> processor_core.c will be used by x86 and ia64 too, it will cause
> compile error on !ARM64 platforms.

Oh. So we do we have an ARM-specific function in core ACPI code?

-- 
Catalin

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
  2014-08-20 14:38         ` Catalin Marinas
  (?)
@ 2014-08-21  2:51           ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-21  2:51 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On 2014-8-20 22:38, Catalin Marinas wrote:
> On Tue, Aug 19, 2014 at 08:36:46AM +0100, Hanjun Guo wrote:
>> On 2014-8-18 22:27, Catalin Marinas wrote:
>>> On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
>>>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>>>> index 6e04868..e877967 100644
>>>> --- a/arch/arm64/include/asm/acpi.h
>>>> +++ b/arch/arm64/include/asm/acpi.h
>>>> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>>>>  extern int (*acpi_suspend_lowlevel)(void);
>>>>  #define acpi_wakeup_address 0
>>>>  
>>>> +#define MAX_GIC_CPU_INTERFACE 65535
>>>
>>> Does this need to be more than NR_CPUS?
>>
>> Sometimes yes, CPU structure entries in MADT just like CPU nodes in
>> device tree, the number of them may more than NR_CPUS.
> 
> I have a more general question here. In ACPI, is MADT the only way to
> build a CPU topology? 

Unfortunately yes as far as I can tell.

> It looks weird that we use GIC properties to
> create the cpu_logical_map(). 

Actually information in GICC structures in MADT will both used
for GIC init and SMP init, GICC structures represents CPUs in the
system.

> A side-effect is that the GIC-related
> functions are now scattered all over the kernel rather than being
> contained in the GIC driver itself.

As patch 12/18 shows, all the GIC related code all contained in the
GIC driver, GICC structure is more than GIC-related but also CPUs in the
system (I have to admit that the name of GICC in ACPI is confusing).

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-21  2:51           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-21  2:51 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi, Tomasz Nowicki

On 2014-8-20 22:38, Catalin Marinas wrote:
> On Tue, Aug 19, 2014 at 08:36:46AM +0100, Hanjun Guo wrote:
>> On 2014-8-18 22:27, Catalin Marinas wrote:
>>> On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
>>>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>>>> index 6e04868..e877967 100644
>>>> --- a/arch/arm64/include/asm/acpi.h
>>>> +++ b/arch/arm64/include/asm/acpi.h
>>>> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>>>>  extern int (*acpi_suspend_lowlevel)(void);
>>>>  #define acpi_wakeup_address 0
>>>>  
>>>> +#define MAX_GIC_CPU_INTERFACE 65535
>>>
>>> Does this need to be more than NR_CPUS?
>>
>> Sometimes yes, CPU structure entries in MADT just like CPU nodes in
>> device tree, the number of them may more than NR_CPUS.
> 
> I have a more general question here. In ACPI, is MADT the only way to
> build a CPU topology? 

Unfortunately yes as far as I can tell.

> It looks weird that we use GIC properties to
> create the cpu_logical_map(). 

Actually information in GICC structures in MADT will both used
for GIC init and SMP init, GICC structures represents CPUs in the
system.

> A side-effect is that the GIC-related
> functions are now scattered all over the kernel rather than being
> contained in the GIC driver itself.

As patch 12/18 shows, all the GIC related code all contained in the
GIC driver, GICC structure is more than GIC-related but also CPUs in the
system (I have to admit that the name of GICC in ACPI is confusing).

Thanks
Hanjun


^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map
@ 2014-08-21  2:51           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-21  2:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-20 22:38, Catalin Marinas wrote:
> On Tue, Aug 19, 2014 at 08:36:46AM +0100, Hanjun Guo wrote:
>> On 2014-8-18 22:27, Catalin Marinas wrote:
>>> On Mon, Aug 04, 2014 at 04:28:13PM +0100, Hanjun Guo wrote:
>>>> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
>>>> index 6e04868..e877967 100644
>>>> --- a/arch/arm64/include/asm/acpi.h
>>>> +++ b/arch/arm64/include/asm/acpi.h
>>>> @@ -64,6 +64,8 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { }
>>>>  extern int (*acpi_suspend_lowlevel)(void);
>>>>  #define acpi_wakeup_address 0
>>>>  
>>>> +#define MAX_GIC_CPU_INTERFACE 65535
>>>
>>> Does this need to be more than NR_CPUS?
>>
>> Sometimes yes, CPU structure entries in MADT just like CPU nodes in
>> device tree, the number of them may more than NR_CPUS.
> 
> I have a more general question here. In ACPI, is MADT the only way to
> build a CPU topology? 

Unfortunately yes as far as I can tell.

> It looks weird that we use GIC properties to
> create the cpu_logical_map(). 

Actually information in GICC structures in MADT will both used
for GIC init and SMP init, GICC structures represents CPUs in the
system.

> A side-effect is that the GIC-related
> functions are now scattered all over the kernel rather than being
> contained in the GIC driver itself.

As patch 12/18 shows, all the GIC related code all contained in the
GIC driver, GICC structure is more than GIC-related but also CPUs in the
system (I have to admit that the name of GICC in ACPI is confusing).

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
  2014-08-20 14:52         ` Catalin Marinas
  (?)
@ 2014-08-21  3:06           ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-21  3:06 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On 2014-8-20 22:52, Catalin Marinas wrote:
> On Tue, Aug 19, 2014 at 09:32:25AM +0100, Hanjun Guo wrote:
>> On 2014-8-18 22:27, Catalin Marinas wrote:
>>> On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
>>>> +#ifdef CONFIG_ACPI
>>>> +/*
>>>> + * Get a cpu's boot method in the ACPI way.
>>>> + */
>>>> +static char * __init acpi_get_cpu_boot_method(void)
>>>> +{
>>>> +	/*
>>>> +	 * For ACPI 5.1, only two kind of methods are provided,
>>>> +	 * Parking protocol and PSCI, but Parking protocol is
>>>> +	 * specified for ARMv7 only, so make PSCI as the only method
>>>> +	 * for SMP initialization before the ACPI spec or Parking
>>>> +	 * protocol spec is updated.
>>>> +	 */
>>>> +	switch (smp_boot_protocol()) {
>>>> +	case ACPI_SMP_BOOT_PSCI:
>>>> +		return "psci";
>>>> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>>>> +	default:
>>>> +		return NULL;
>>>> +	}
>>>> +}
>>>
>>> Actually, do we even need to define smp_boot_protocol()? Is it used
>>> anywhere else apart from this patch (I still haven't gone through all
>>> patches)?
>>
>> It is just used in this patch. I think we can make the ACPI boot protocol
>> scalable in this way, if we support another boot protocol in ACPI in the
>> future, we can easily update the function to support it, does it make sense?
> 
> Not really. You just add additional code, enums, functions when all you
> do is check for acpi_psci_present() (or whatever new protocol you would
> get). If the enum is never going to be used outside this file, don't
> bother with additional functions.
> 
> BTW, it would be nicer if the acpi related functions are contained in as
> fewer files as possible. So here you could keep
> acpi_get_cpu_boot_method() in the acpi.c file. It only returns a string.

ok, I will update them.

Thanks
Hanjun



^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-21  3:06           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-21  3:06 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi, Tomasz Nowicki

On 2014-8-20 22:52, Catalin Marinas wrote:
> On Tue, Aug 19, 2014 at 09:32:25AM +0100, Hanjun Guo wrote:
>> On 2014-8-18 22:27, Catalin Marinas wrote:
>>> On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
>>>> +#ifdef CONFIG_ACPI
>>>> +/*
>>>> + * Get a cpu's boot method in the ACPI way.
>>>> + */
>>>> +static char * __init acpi_get_cpu_boot_method(void)
>>>> +{
>>>> +	/*
>>>> +	 * For ACPI 5.1, only two kind of methods are provided,
>>>> +	 * Parking protocol and PSCI, but Parking protocol is
>>>> +	 * specified for ARMv7 only, so make PSCI as the only method
>>>> +	 * for SMP initialization before the ACPI spec or Parking
>>>> +	 * protocol spec is updated.
>>>> +	 */
>>>> +	switch (smp_boot_protocol()) {
>>>> +	case ACPI_SMP_BOOT_PSCI:
>>>> +		return "psci";
>>>> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>>>> +	default:
>>>> +		return NULL;
>>>> +	}
>>>> +}
>>>
>>> Actually, do we even need to define smp_boot_protocol()? Is it used
>>> anywhere else apart from this patch (I still haven't gone through all
>>> patches)?
>>
>> It is just used in this patch. I think we can make the ACPI boot protocol
>> scalable in this way, if we support another boot protocol in ACPI in the
>> future, we can easily update the function to support it, does it make sense?
> 
> Not really. You just add additional code, enums, functions when all you
> do is check for acpi_psci_present() (or whatever new protocol you would
> get). If the enum is never going to be used outside this file, don't
> bother with additional functions.
> 
> BTW, it would be nicer if the acpi related functions are contained in as
> fewer files as possible. So here you could keep
> acpi_get_cpu_boot_method() in the acpi.c file. It only returns a string.

ok, I will update them.

Thanks
Hanjun



^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way
@ 2014-08-21  3:06           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-21  3:06 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-20 22:52, Catalin Marinas wrote:
> On Tue, Aug 19, 2014 at 09:32:25AM +0100, Hanjun Guo wrote:
>> On 2014-8-18 22:27, Catalin Marinas wrote:
>>> On Mon, Aug 04, 2014 at 04:28:15PM +0100, Hanjun Guo wrote:
>>>> +#ifdef CONFIG_ACPI
>>>> +/*
>>>> + * Get a cpu's boot method in the ACPI way.
>>>> + */
>>>> +static char * __init acpi_get_cpu_boot_method(void)
>>>> +{
>>>> +	/*
>>>> +	 * For ACPI 5.1, only two kind of methods are provided,
>>>> +	 * Parking protocol and PSCI, but Parking protocol is
>>>> +	 * specified for ARMv7 only, so make PSCI as the only method
>>>> +	 * for SMP initialization before the ACPI spec or Parking
>>>> +	 * protocol spec is updated.
>>>> +	 */
>>>> +	switch (smp_boot_protocol()) {
>>>> +	case ACPI_SMP_BOOT_PSCI:
>>>> +		return "psci";
>>>> +	case ACPI_SMP_BOOT_PARKING_PROTOCOL:
>>>> +	default:
>>>> +		return NULL;
>>>> +	}
>>>> +}
>>>
>>> Actually, do we even need to define smp_boot_protocol()? Is it used
>>> anywhere else apart from this patch (I still haven't gone through all
>>> patches)?
>>
>> It is just used in this patch. I think we can make the ACPI boot protocol
>> scalable in this way, if we support another boot protocol in ACPI in the
>> future, we can easily update the function to support it, does it make sense?
> 
> Not really. You just add additional code, enums, functions when all you
> do is check for acpi_psci_present() (or whatever new protocol you would
> get). If the enum is never going to be used outside this file, don't
> bother with additional functions.
> 
> BTW, it would be nicer if the acpi related functions are contained in as
> fewer files as possible. So here you could keep
> acpi_get_cpu_boot_method() in the acpi.c file. It only returns a string.

ok, I will update them.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
  2014-08-20 14:56         ` Catalin Marinas
  (?)
@ 2014-08-21  3:25           ` Hanjun Guo
  -1 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-21  3:25 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi

On 2014-8-20 22:56, Catalin Marinas wrote:
> On Tue, Aug 19, 2014 at 09:37:34AM +0100, Hanjun Guo wrote:
>> On 2014-8-18 22:27, Catalin Marinas wrote:
>>> On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
>>>> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
>>>> index e32321c..4007313 100644
>>>> --- a/drivers/acpi/processor_core.c
>>>> +++ b/drivers/acpi/processor_core.c
>>>> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>>>>  	return 0;
>>>>  }
>>>>  
>>>> +/*
>>>> + * On ARM platform, MPIDR value is the hardware ID as apic ID
>>>> + * on Intel platforms
>>>> + */
>>>> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
>>>> +		int device_declaration, u32 acpi_id, int *mpidr)
>>>> +{
>>>> +	struct acpi_madt_generic_interrupt *gicc =
>>>> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
>>>> +
>>>> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
>>>> +		return -ENODEV;
>>>> +
>>>> +	/* In the GIC interrupt model, logical processors are
>>>> +	 * required to have a Processor Device object in the DSDT,
>>>> +	 * so we should check device_declaration here
>>>> +	 */
>>>> +	if (device_declaration && (gicc->uid == acpi_id)) {
>>>> +		/*
>>>> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
>>>> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
>>>> +		 * fields into a single 32 bit identifier to accommodate the
>>>> +		 * acpi processor drivers.
>>>> +		 */
>>>> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
>>>> +			 | gicc->arm_mpidr;
>>>
>>> You can use pack_mpidr_into_32_bits().
>>
>> processor_core.c will be used by x86 and ia64 too, it will cause
>> compile error on !ARM64 platforms.
> 
> Oh. So we do we have an ARM-specific function in core ACPI code?

Yes, GICC is ARM-specific, but all the mapping functions (get apic_id/mpidr
via acpi_id in MADT) including x86/ia64 are all there, so it's better to put it
here to keep consistency.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* Re: [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-21  3:25           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-21  3:25 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Rafael J. Wysocki, Mark Rutland, graeme.gregory, Arnd Bergmann,
	Olof Johansson, grant.likely, Sudeep Holla, Will Deacon,
	Jason Cooper, Marc Zyngier, Bjorn Helgaas, Daniel Lezcano,
	Mark Brown, Rob Herring, Robert Richter, Lv Zheng, Robert Moore,
	Lorenzo Pieralisi, Liviu Dudau, Randy Dunlap,
	Charles Garcia-Tobin, linux-acpi, linux-arm-kernel, linux-kernel,
	linaro-acpi

On 2014-8-20 22:56, Catalin Marinas wrote:
> On Tue, Aug 19, 2014 at 09:37:34AM +0100, Hanjun Guo wrote:
>> On 2014-8-18 22:27, Catalin Marinas wrote:
>>> On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
>>>> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
>>>> index e32321c..4007313 100644
>>>> --- a/drivers/acpi/processor_core.c
>>>> +++ b/drivers/acpi/processor_core.c
>>>> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>>>>  	return 0;
>>>>  }
>>>>  
>>>> +/*
>>>> + * On ARM platform, MPIDR value is the hardware ID as apic ID
>>>> + * on Intel platforms
>>>> + */
>>>> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
>>>> +		int device_declaration, u32 acpi_id, int *mpidr)
>>>> +{
>>>> +	struct acpi_madt_generic_interrupt *gicc =
>>>> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
>>>> +
>>>> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
>>>> +		return -ENODEV;
>>>> +
>>>> +	/* In the GIC interrupt model, logical processors are
>>>> +	 * required to have a Processor Device object in the DSDT,
>>>> +	 * so we should check device_declaration here
>>>> +	 */
>>>> +	if (device_declaration && (gicc->uid == acpi_id)) {
>>>> +		/*
>>>> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
>>>> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
>>>> +		 * fields into a single 32 bit identifier to accommodate the
>>>> +		 * acpi processor drivers.
>>>> +		 */
>>>> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
>>>> +			 | gicc->arm_mpidr;
>>>
>>> You can use pack_mpidr_into_32_bits().
>>
>> processor_core.c will be used by x86 and ia64 too, it will cause
>> compile error on !ARM64 platforms.
> 
> Oh. So we do we have an ARM-specific function in core ACPI code?

Yes, GICC is ARM-specific, but all the mapping functions (get apic_id/mpidr
via acpi_id in MADT) including x86/ia64 are all there, so it's better to put it
here to keep consistency.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

* [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC
@ 2014-08-21  3:25           ` Hanjun Guo
  0 siblings, 0 replies; 180+ messages in thread
From: Hanjun Guo @ 2014-08-21  3:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 2014-8-20 22:56, Catalin Marinas wrote:
> On Tue, Aug 19, 2014 at 09:37:34AM +0100, Hanjun Guo wrote:
>> On 2014-8-18 22:27, Catalin Marinas wrote:
>>> On Mon, Aug 04, 2014 at 04:28:16PM +0100, Hanjun Guo wrote:
>>>> diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
>>>> index e32321c..4007313 100644
>>>> --- a/drivers/acpi/processor_core.c
>>>> +++ b/drivers/acpi/processor_core.c
>>>> @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
>>>>  	return 0;
>>>>  }
>>>>  
>>>> +/*
>>>> + * On ARM platform, MPIDR value is the hardware ID as apic ID
>>>> + * on Intel platforms
>>>> + */
>>>> +static int map_gicc_mpidr(struct acpi_subtable_header *entry,
>>>> +		int device_declaration, u32 acpi_id, int *mpidr)
>>>> +{
>>>> +	struct acpi_madt_generic_interrupt *gicc =
>>>> +	    container_of(entry, struct acpi_madt_generic_interrupt, header);
>>>> +
>>>> +	if (!(gicc->flags & ACPI_MADT_ENABLED))
>>>> +		return -ENODEV;
>>>> +
>>>> +	/* In the GIC interrupt model, logical processors are
>>>> +	 * required to have a Processor Device object in the DSDT,
>>>> +	 * so we should check device_declaration here
>>>> +	 */
>>>> +	if (device_declaration && (gicc->uid == acpi_id)) {
>>>> +		/*
>>>> +		 * Only bits [0:7] Aff0, bits [8:15] Aff1, bits [16:23] Aff2
>>>> +		 * and bits [32:39] Aff3 are meaningful, so pack the Affx
>>>> +		 * fields into a single 32 bit identifier to accommodate the
>>>> +		 * acpi processor drivers.
>>>> +		 */
>>>> +		*mpidr = ((gicc->arm_mpidr & 0xff00000000) >> 8)
>>>> +			 | gicc->arm_mpidr;
>>>
>>> You can use pack_mpidr_into_32_bits().
>>
>> processor_core.c will be used by x86 and ia64 too, it will cause
>> compile error on !ARM64 platforms.
> 
> Oh. So we do we have an ARM-specific function in core ACPI code?

Yes, GICC is ARM-specific, but all the mapping functions (get apic_id/mpidr
via acpi_id in MADT) including x86/ia64 are all there, so it's better to put it
here to keep consistency.

Thanks
Hanjun

^ permalink raw reply	[flat|nested] 180+ messages in thread

end of thread, other threads:[~2014-08-21  3:27 UTC | newest]

Thread overview: 180+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-04 15:28 [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1 Hanjun Guo
2014-08-04 15:28 ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 01/18] ARM64: Move the init of cpu_logical_map(0) before unflatten_device_tree() Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 02/18] ARM64 / ACPI: Get RSDP and ACPI boot-time tables Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-18 18:30   ` Sudeep Holla
2014-08-18 18:30     ` Sudeep Holla
2014-08-18 18:30     ` Sudeep Holla
2014-08-19  9:35     ` Hanjun Guo
2014-08-19  9:35       ` Hanjun Guo
2014-08-19  9:35       ` Hanjun Guo
2014-08-19  9:47       ` Sudeep Holla
2014-08-19  9:47         ` Sudeep Holla
2014-08-19  9:47         ` Sudeep Holla
2014-08-04 15:28 ` [PATCH v2 03/18] ARM64 / ACPI: Introduce lowlevel suspend function Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 04/18] ARM64 / ACPI: Make PCI optional for ACPI on ARM64 Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 05/18] ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-18 14:27   ` Catalin Marinas
2014-08-18 14:27     ` Catalin Marinas
2014-08-19  3:50     ` Hanjun Guo
2014-08-19  3:50       ` Hanjun Guo
2014-08-19  3:50       ` Hanjun Guo
2014-08-19 11:10       ` Mark Rutland
2014-08-19 11:10         ` Mark Rutland
2014-08-19 11:10         ` Mark Rutland
2014-08-19 12:13         ` Hanjun Guo
2014-08-19 12:13           ` Hanjun Guo
2014-08-19 12:13           ` Hanjun Guo
2014-08-19 22:55           ` Moore, Robert
2014-08-19 22:55             ` Moore, Robert
2014-08-19 22:55             ` Moore, Robert
2014-08-20  4:12             ` Hanjun Guo
2014-08-20  4:12               ` Hanjun Guo
2014-08-20  4:12               ` Hanjun Guo
2014-08-18 18:32   ` Sudeep Holla
2014-08-18 18:32     ` Sudeep Holla
2014-08-18 18:32     ` Sudeep Holla
2014-08-19 10:39     ` Hanjun Guo
2014-08-19 10:39       ` Hanjun Guo
2014-08-19 10:39       ` Hanjun Guo
2014-08-19 11:07       ` Sudeep Holla
2014-08-19 11:07         ` Sudeep Holla
2014-08-19 11:07         ` Sudeep Holla
2014-08-04 15:28 ` [PATCH v2 06/18] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-18 14:27   ` Catalin Marinas
2014-08-18 14:27     ` Catalin Marinas
2014-08-19  7:36     ` Hanjun Guo
2014-08-19  7:36       ` Hanjun Guo
2014-08-19  7:36       ` Hanjun Guo
2014-08-20 14:38       ` Catalin Marinas
2014-08-20 14:38         ` Catalin Marinas
2014-08-20 14:38         ` Catalin Marinas
2014-08-21  2:51         ` Hanjun Guo
2014-08-21  2:51           ` Hanjun Guo
2014-08-21  2:51           ` Hanjun Guo
2014-08-18 18:33   ` Sudeep Holla
2014-08-18 18:33     ` Sudeep Holla
2014-08-18 18:33     ` Sudeep Holla
2014-08-19 11:00     ` Hanjun Guo
2014-08-19 11:00       ` Hanjun Guo
2014-08-19 11:00       ` Hanjun Guo
2014-08-19 16:46       ` [Linaro-acpi] " Zi Shen Lim
2014-08-19 16:46         ` Zi Shen Lim
2014-08-19 16:46         ` Zi Shen Lim
2014-08-20  3:24         ` Hanjun Guo
2014-08-20  3:24           ` Hanjun Guo
2014-08-20  3:24           ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 07/18] ACPI / table: Print GIC information when MADT is parsed Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-07  1:41   ` Zheng, Lv
2014-08-07  1:41     ` Zheng, Lv
2014-08-07 10:28     ` Hanjun Guo
2014-08-07 10:28       ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 08/18] ARM64 / ACPI: Get the enable method for SMP initialization in ACPI way Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-18 14:27   ` Catalin Marinas
2014-08-18 14:27     ` Catalin Marinas
2014-08-19  8:32     ` Hanjun Guo
2014-08-19  8:32       ` Hanjun Guo
2014-08-19  8:32       ` Hanjun Guo
2014-08-20 14:52       ` Catalin Marinas
2014-08-20 14:52         ` Catalin Marinas
2014-08-20 14:52         ` Catalin Marinas
2014-08-21  3:06         ` Hanjun Guo
2014-08-21  3:06           ` Hanjun Guo
2014-08-21  3:06           ` Hanjun Guo
2014-08-18 18:34   ` Sudeep Holla
2014-08-18 18:34     ` Sudeep Holla
2014-08-18 18:34     ` Sudeep Holla
2014-08-19 11:26     ` Hanjun Guo
2014-08-19 11:26       ` Hanjun Guo
2014-08-19 11:26       ` Hanjun Guo
2014-08-18 18:56   ` Geoff Levand
2014-08-18 18:56     ` Geoff Levand
2014-08-18 18:56     ` Geoff Levand
2014-08-19 12:11     ` Hanjun Guo
2014-08-19 12:11       ` Hanjun Guo
2014-08-19 12:11       ` Hanjun Guo
2014-08-19 19:25       ` Geoff Levand
2014-08-19 19:25         ` Geoff Levand
2014-08-19 19:25         ` Geoff Levand
2014-08-20  3:25         ` Hanjun Guo
2014-08-20  3:25           ` Hanjun Guo
2014-08-20  3:25           ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 09/18] ACPI / processor: Make it possible to get CPU hardware ID via GICC Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-18 14:27   ` Catalin Marinas
2014-08-18 14:27     ` Catalin Marinas
2014-08-19  8:37     ` Hanjun Guo
2014-08-19  8:37       ` Hanjun Guo
2014-08-19  8:37       ` Hanjun Guo
2014-08-20 14:56       ` Catalin Marinas
2014-08-20 14:56         ` Catalin Marinas
2014-08-20 14:56         ` Catalin Marinas
2014-08-21  3:25         ` Hanjun Guo
2014-08-21  3:25           ` Hanjun Guo
2014-08-21  3:25           ` Hanjun Guo
2014-08-18 18:34   ` Sudeep Holla
2014-08-18 18:34     ` Sudeep Holla
2014-08-18 18:34     ` Sudeep Holla
2014-08-19 11:29     ` Hanjun Guo
2014-08-19 11:29       ` Hanjun Guo
2014-08-19 11:29       ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 10/18] ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-18 18:34   ` Sudeep Holla
2014-08-18 18:34     ` Sudeep Holla
2014-08-18 18:34     ` Sudeep Holla
2014-08-19 11:36     ` Hanjun Guo
2014-08-19 11:36       ` Hanjun Guo
2014-08-19 11:36       ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 11/18] ACPI / table: Add new function to get table entries Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 12/18] ARM64 / ACPI: Add GICv2 specific ACPI boot support Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 13/18] ARM64 / ACPI: Parse GTDT to initialize arch timer Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 14/18] ARM64 / ACPI: Select ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on ARM64 Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 15/18] ARM64 / ACPI: Introduce early_param for "acpi" and set ACPI default off Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 16/18] ARM64 / ACPI: If we chose to boot from acpi then disable FDT Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 17/18] ARM64 / ACPI: Enable ARM64 in Kconfig Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-18 14:27   ` Catalin Marinas
2014-08-18 14:27     ` Catalin Marinas
2014-08-19  8:38     ` Hanjun Guo
2014-08-19  8:38       ` Hanjun Guo
2014-08-19  8:38       ` Hanjun Guo
2014-08-04 15:28 ` [PATCH v2 18/18] Documentation: ACPI for ARM64 Hanjun Guo
2014-08-04 15:28   ` Hanjun Guo
2014-08-04 20:48   ` Randy Dunlap
2014-08-04 20:48     ` Randy Dunlap
2014-08-05  3:36     ` Hanjun Guo
2014-08-05  3:36       ` Hanjun Guo
2014-08-05  3:36       ` Hanjun Guo
     [not found] ` <CAJRNFK+UfJhGR65tOecy=X+YdHQHiNPZ4p_p8LUxhRL3GW5gFw@mail.gmail.com>
2014-08-05  3:34   ` [Linaro-acpi] [PATCH v2 00/18] Introduce ACPI for ARM64 based on ACPI 5.1 Hanjun Guo
2014-08-05  3:34     ` Hanjun Guo
2014-08-05  3:34     ` Hanjun Guo
2014-08-18 17:08     ` Alexander Spyridakis
2014-08-18 17:08       ` Alexander Spyridakis
2014-08-18 17:08       ` Alexander Spyridakis
2014-08-18 18:11       ` Graeme Gregory
2014-08-18 18:11         ` Graeme Gregory
2014-08-18 18:11         ` Graeme Gregory

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.