All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: Sudeep Holla <sudeep.holla@arm.com>
To: linux-acpi@vger.kernel.org, "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Sudeep Holla <sudeep.holla@arm.com>,
	linux-kernel@vger.kernel.org,
	Vikas Sajjan <vikas.cha.sajjan@hpe.com>, Sunil <sunil.vl@hpe.com>,
	Prashanth Prakash <pprakash@codeaurora.org>,
	Ashwin Chaugule <ashwin.chaugule@linaro.org>,
	Al Stone <al.stone@linaro.org>,
	Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	Mark Rutland <mark.rutland@arm.com>,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 4/5] arm64: add support for ACPI Low Power Idle(LPI)
Date: Wed, 11 May 2016 16:37:41 +0100	[thread overview]
Message-ID: <1462981062-24909-5-git-send-email-sudeep.holla@arm.com> (raw)
In-Reply-To: <1462981062-24909-1-git-send-email-sudeep.holla@arm.com>

This patch adds appropriate callbacks to support ACPI Low Power Idle
(LPI) on ARM64.

Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 arch/arm64/kernel/acpi.c | 48 +++++++++++++++++++++++++++++++++++++++++
 drivers/firmware/psci.c  | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index d1ce8e2f98b9..bf82ce5c8fce 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -18,6 +18,7 @@
 #include <linux/acpi.h>
 #include <linux/bootmem.h>
 #include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
@@ -25,6 +26,9 @@
 #include <linux/of_fdt.h>
 #include <linux/smp.h>
 
+#include <acpi/processor.h>
+
+#include <asm/cpuidle.h>
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
 #include <asm/smp_plat.h>
@@ -211,6 +215,50 @@ void __init acpi_boot_table_init(void)
 	}
 }
 
+int acpi_processor_ffh_lpi_probe(unsigned int cpu)
+{
+	return arm_cpuidle_init(cpu);
+}
+
+#define ACPI_FFH_LPI_ARM_FLAGS_CORE_CONTEXT	BIT(0)
+#define ACPI_FFH_LPI_ARM_FLAGS_TRACE_CONTEXT	BIT(1)
+#define ACPI_FFH_LPI_ARM_FLAGS_GICR_CONTEXT	BIT(2)
+#define ACPI_FFH_LPI_ARM_FLAGS_GICD_CONTEXT	BIT(3)
+#define ACPI_FFH_LPI_ARM_FLAGS_ALL_CONTEXT	\
+	(ACPI_FFH_LPI_ARM_FLAGS_CORE_CONTEXT |	\
+	 ACPI_FFH_LPI_ARM_FLAGS_TRACE_CONTEXT |	\
+	 ACPI_FFH_LPI_ARM_FLAGS_GICR_CONTEXT |	\
+	 ACPI_FFH_LPI_ARM_FLAGS_GICD_CONTEXT)
+
+struct acpi_lpi_state *lpi;
+int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi, int idx)
+{
+	int ret = 0;
+	bool save_ctx = lpi->arch_flags & ACPI_FFH_LPI_ARM_FLAGS_ALL_CONTEXT;
+
+	if (!idx) {
+		cpu_do_idle();
+		return idx;
+	}
+
+	/* TODO cpu_pm_{enter,exit} can be done in generic code ? */
+	if (save_ctx)
+		ret = cpu_pm_enter();
+	if (!ret) {
+		/*
+		 * Pass idle state index to cpu_suspend which in turn will
+		 * call the CPU ops suspend protocol with idle index as a
+		 * parameter.
+		 */
+		ret = arm_cpuidle_suspend(idx);
+
+		if (save_ctx)
+			cpu_pm_exit();
+	}
+
+	return ret ? -1 : idx;
+}
+
 #ifdef CONFIG_ACPI_APEI
 pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
 {
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index fa4ea22ca12e..e06bfee68e1d 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -13,6 +13,7 @@
 
 #define pr_fmt(fmt) "psci: " fmt
 
+#include <linux/acpi.h>
 #include <linux/arm-smccc.h>
 #include <linux/cpuidle.h>
 #include <linux/errno.h>
@@ -310,11 +311,66 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
 	return ret;
 }
 
+#ifdef CONFIG_ACPI
+#include <acpi/processor.h>
+
+static int __maybe_unused psci_acpi_cpu_init_idle(unsigned int cpu)
+{
+	int i, count;
+	u32 *psci_states;
+	struct acpi_processor *pr;
+	struct acpi_lpi_state *lpi;
+
+	pr = per_cpu(processors, cpu);
+	if (unlikely(!pr || !pr->flags.has_lpi))
+		return -EINVAL;
+
+	/*
+	 * If the PSCI cpu_suspend function hook has not been initialized
+	 * idle states must not be enabled, so bail out
+	 */
+	if (!psci_ops.cpu_suspend)
+		return -EOPNOTSUPP;
+
+	count = pr->power.count - 1;
+	if (!count)
+		return -ENODEV;
+
+	psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
+	if (!psci_states)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		u32 state;
+
+		lpi = &pr->power.lpi_states[i + 1];
+		state = lpi->address & 0xFFFFFFFF;
+		if (!psci_power_state_is_valid(state)) {
+			pr_warn("Invalid PSCI power state %#x\n", state);
+			kfree(psci_states);
+			return -EINVAL;
+		}
+		psci_states[i] = state;
+	}
+	/* Idle states parsed correctly, initialize per-cpu pointer */
+	per_cpu(psci_power_state, cpu) = psci_states;
+	return 0;
+}
+#else
+static int __maybe_unused psci_acpi_cpu_init_idle(unsigned int cpu)
+{
+	return -EINVAL;
+}
+#endif
+
 int psci_cpu_init_idle(unsigned int cpu)
 {
 	struct device_node *cpu_node;
 	int ret;
 
+	if (!acpi_disabled)
+		return psci_acpi_cpu_init_idle(cpu);
+
 	cpu_node = of_get_cpu_node(cpu, NULL);
 	if (!cpu_node)
 		return -ENODEV;
-- 
1.9.1

WARNING: multiple messages have this Message-ID (diff)
From: sudeep.holla@arm.com (Sudeep Holla)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 4/5] arm64: add support for ACPI Low Power Idle(LPI)
Date: Wed, 11 May 2016 16:37:41 +0100	[thread overview]
Message-ID: <1462981062-24909-5-git-send-email-sudeep.holla@arm.com> (raw)
In-Reply-To: <1462981062-24909-1-git-send-email-sudeep.holla@arm.com>

This patch adds appropriate callbacks to support ACPI Low Power Idle
(LPI) on ARM64.

Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 arch/arm64/kernel/acpi.c | 48 +++++++++++++++++++++++++++++++++++++++++
 drivers/firmware/psci.c  | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index d1ce8e2f98b9..bf82ce5c8fce 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -18,6 +18,7 @@
 #include <linux/acpi.h>
 #include <linux/bootmem.h>
 #include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
@@ -25,6 +26,9 @@
 #include <linux/of_fdt.h>
 #include <linux/smp.h>
 
+#include <acpi/processor.h>
+
+#include <asm/cpuidle.h>
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
 #include <asm/smp_plat.h>
@@ -211,6 +215,50 @@ void __init acpi_boot_table_init(void)
 	}
 }
 
+int acpi_processor_ffh_lpi_probe(unsigned int cpu)
+{
+	return arm_cpuidle_init(cpu);
+}
+
+#define ACPI_FFH_LPI_ARM_FLAGS_CORE_CONTEXT	BIT(0)
+#define ACPI_FFH_LPI_ARM_FLAGS_TRACE_CONTEXT	BIT(1)
+#define ACPI_FFH_LPI_ARM_FLAGS_GICR_CONTEXT	BIT(2)
+#define ACPI_FFH_LPI_ARM_FLAGS_GICD_CONTEXT	BIT(3)
+#define ACPI_FFH_LPI_ARM_FLAGS_ALL_CONTEXT	\
+	(ACPI_FFH_LPI_ARM_FLAGS_CORE_CONTEXT |	\
+	 ACPI_FFH_LPI_ARM_FLAGS_TRACE_CONTEXT |	\
+	 ACPI_FFH_LPI_ARM_FLAGS_GICR_CONTEXT |	\
+	 ACPI_FFH_LPI_ARM_FLAGS_GICD_CONTEXT)
+
+struct acpi_lpi_state *lpi;
+int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi, int idx)
+{
+	int ret = 0;
+	bool save_ctx = lpi->arch_flags & ACPI_FFH_LPI_ARM_FLAGS_ALL_CONTEXT;
+
+	if (!idx) {
+		cpu_do_idle();
+		return idx;
+	}
+
+	/* TODO cpu_pm_{enter,exit} can be done in generic code ? */
+	if (save_ctx)
+		ret = cpu_pm_enter();
+	if (!ret) {
+		/*
+		 * Pass idle state index to cpu_suspend which in turn will
+		 * call the CPU ops suspend protocol with idle index as a
+		 * parameter.
+		 */
+		ret = arm_cpuidle_suspend(idx);
+
+		if (save_ctx)
+			cpu_pm_exit();
+	}
+
+	return ret ? -1 : idx;
+}
+
 #ifdef CONFIG_ACPI_APEI
 pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
 {
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index fa4ea22ca12e..e06bfee68e1d 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -13,6 +13,7 @@
 
 #define pr_fmt(fmt) "psci: " fmt
 
+#include <linux/acpi.h>
 #include <linux/arm-smccc.h>
 #include <linux/cpuidle.h>
 #include <linux/errno.h>
@@ -310,11 +311,66 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
 	return ret;
 }
 
+#ifdef CONFIG_ACPI
+#include <acpi/processor.h>
+
+static int __maybe_unused psci_acpi_cpu_init_idle(unsigned int cpu)
+{
+	int i, count;
+	u32 *psci_states;
+	struct acpi_processor *pr;
+	struct acpi_lpi_state *lpi;
+
+	pr = per_cpu(processors, cpu);
+	if (unlikely(!pr || !pr->flags.has_lpi))
+		return -EINVAL;
+
+	/*
+	 * If the PSCI cpu_suspend function hook has not been initialized
+	 * idle states must not be enabled, so bail out
+	 */
+	if (!psci_ops.cpu_suspend)
+		return -EOPNOTSUPP;
+
+	count = pr->power.count - 1;
+	if (!count)
+		return -ENODEV;
+
+	psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
+	if (!psci_states)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		u32 state;
+
+		lpi = &pr->power.lpi_states[i + 1];
+		state = lpi->address & 0xFFFFFFFF;
+		if (!psci_power_state_is_valid(state)) {
+			pr_warn("Invalid PSCI power state %#x\n", state);
+			kfree(psci_states);
+			return -EINVAL;
+		}
+		psci_states[i] = state;
+	}
+	/* Idle states parsed correctly, initialize per-cpu pointer */
+	per_cpu(psci_power_state, cpu) = psci_states;
+	return 0;
+}
+#else
+static int __maybe_unused psci_acpi_cpu_init_idle(unsigned int cpu)
+{
+	return -EINVAL;
+}
+#endif
+
 int psci_cpu_init_idle(unsigned int cpu)
 {
 	struct device_node *cpu_node;
 	int ret;
 
+	if (!acpi_disabled)
+		return psci_acpi_cpu_init_idle(cpu);
+
 	cpu_node = of_get_cpu_node(cpu, NULL);
 	if (!cpu_node)
 		return -ENODEV;
-- 
1.9.1

  parent reply	other threads:[~2016-05-11 15:38 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-11 15:37 [PATCH v5 0/5] ACPI / processor_idle: Add ACPI v6.0 LPI support Sudeep Holla
2016-05-11 15:37 ` [PATCH v5 1/5] ACPI / processor_idle: introduce ACPI_PROCESSOR_CSTATE Sudeep Holla
2016-05-11 15:37   ` Sudeep Holla
2016-05-11 16:23   ` Rafael J. Wysocki
2016-05-11 16:23     ` Rafael J. Wysocki
2016-05-11 16:57     ` Sudeep Holla
2016-05-11 16:57       ` Sudeep Holla
     [not found]   ` <CAJvTdKnJPZ9Nfib=CqBczMP4BERqfqAzeSR-+jjFOGZR51oVmg@mail.gmail.com>
2016-05-11 18:28     ` Len Brown
2016-05-11 18:28       ` Len Brown
2016-05-12  9:10       ` Sudeep Holla
2016-05-12  9:10         ` Sudeep Holla
2016-05-12 13:21   ` [UPDATE][PATCH v5] " Sudeep Holla
2016-05-11 15:37 ` [PATCH v5 2/5] ACPI / processor_idle: Add support for Low Power Idle(LPI) states Sudeep Holla
2016-05-17 17:46   ` Prakash, Prashanth
2016-05-18 17:37     ` Sudeep Holla
2016-05-18 19:13       ` Prakash, Prashanth
2016-05-19 13:26         ` Sudeep Holla
2016-06-10 17:38   ` Sudeep Holla
2016-06-13 21:05     ` Rafael J. Wysocki
2016-06-14 14:24       ` Sudeep Holla
2016-05-11 15:37 ` [PATCH v5 3/5] arm64: cpuidle: drop __init section marker to arm_cpuidle_init Sudeep Holla
2016-05-11 15:37   ` Sudeep Holla
2016-05-11 15:37 ` Sudeep Holla [this message]
2016-05-11 15:37   ` [PATCH v5 4/5] arm64: add support for ACPI Low Power Idle(LPI) Sudeep Holla
2016-06-10 12:50   ` Lorenzo Pieralisi
2016-06-10 12:50     ` Lorenzo Pieralisi
2016-06-13 16:27     ` Daniel Lezcano
2016-06-13 16:27       ` Daniel Lezcano
2016-06-13  4:47   ` Sajjan, Vikas C
2016-06-13  4:47     ` Sajjan, Vikas C
2016-06-13  9:40     ` Sudeep Holla
2016-06-13  9:40       ` Sudeep Holla
2016-05-11 15:37 ` [PATCH v5 5/5] ACPI : enable ACPI_PROCESSOR_IDLE on ARM64 Sudeep Holla
2016-05-11 15:37   ` Sudeep Holla

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1462981062-24909-5-git-send-email-sudeep.holla@arm.com \
    --to=sudeep.holla@arm.com \
    --cc=al.stone@linaro.org \
    --cc=ashwin.chaugule@linaro.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=pprakash@codeaurora.org \
    --cc=rjw@rjwysocki.net \
    --cc=sunil.vl@hpe.com \
    --cc=vikas.cha.sajjan@hpe.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.