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
next prev 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: linkBe 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.