All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
To: Sudeep Holla <sudeep.holla@arm.com>
Cc: ACPI List <linux-acpi@vger.kernel.org>,
	"Rafael J . Wysocki" <rjw@rjwysocki.net>,
	Vikas Sajjan <vikas.cha.sajjan@hpe.com>, Sunil <sunil.vl@hpe.com>,
	PrashanthPrakash <pprakash@codeaurora.org>,
	Al Stone <al.stone@linaro.org>,
	Ashwin Chaugule <ashwin.chaugule@linaro.org>,
	Daniel Lezcano <daniel.lezcano@linaro.org>,
	LKML <linux-kernel@vger.kernel.org>,
	ALKML <linux-arm-kernel@lists.infradead.org>,
	Mark Rutland <mark.rutland@arm.com>
Subject: Re: [PATCH v8 5/6] arm64: add support for ACPI Low Power Idle(LPI)
Date: Fri, 8 Jul 2016 15:47:19 +0100	[thread overview]
Message-ID: <20160708144719.GI3784@red-moon> (raw)
In-Reply-To: <1467911451-24731-6-git-send-email-sudeep.holla@arm.com>

On Thu, Jul 07, 2016 at 06:10:50PM +0100, Sudeep Holla wrote:
> 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: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
>  arch/arm64/kernel/cpuidle.c |  18 +++++++
>  drivers/firmware/psci.c     | 122 ++++++++++++++++++++++++++++++++++++--------

I would split this patch in two (ARM64 cpuidle and PSCI) and for
the PSCI code (apologies, blame taken, it is entirely my fault) I
think that the code in v6 was better, I asked you to factor out
DT/ACPI idle states count and parameter retrieval but the end result
is much more complicated than what it was in v6, so for PSCI ACPI
idle states parsing I would revert to v6, apologies.

With changes above:

Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

>  2 files changed, 118 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
> index 06786fdaadeb..7f16df7d7b23 100644
> --- a/arch/arm64/kernel/cpuidle.c
> +++ b/arch/arm64/kernel/cpuidle.c
> @@ -9,6 +9,9 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/acpi.h>
> +#include <linux/cpuidle.h>
> +#include <linux/cpu_pm.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  
> @@ -39,3 +42,18 @@ int arm_cpuidle_suspend(int index)
>  
>  	return cpu_ops[cpu]->cpu_suspend(index);
>  }
> +
> +#ifdef CONFIG_ACPI
> +
> +#include <acpi/processor.h>
> +
> +int acpi_processor_ffh_lpi_probe(unsigned int cpu)
> +{
> +	return arm_cpuidle_init(cpu);
> +}
> +
> +int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
> +{
> +	return CPU_IDLE_ENTER_WRAPPED(arm_cpuidle_suspend, lpi->index);
> +}
> +#endif
> diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
> index 03e04582791c..edd83c884a1d 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>
> @@ -250,12 +251,84 @@ static int __init psci_features(u32 psci_func_id)
>  #ifdef CONFIG_CPU_IDLE
>  static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
>  
> -static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
> +static int psci_dt_get_state_count(struct device_node *cpu_dn)
>  {
> -	int i, ret, count = 0;
> -	u32 *psci_states;
> +	int count = 0;
>  	struct device_node *state_node;
>  
> +	/* Count idle states */
> +	while ((state_node = of_parse_phandle(cpu_dn, "cpu-idle-states",
> +					      count))) {
> +		count++;
> +		of_node_put(state_node);
> +	}
> +
> +	return count;
> +}
> +
> +static int psci_dt_get_idle_state(struct device_node *node, int idx, u32 *state)
> +{
> +	int ret;
> +	struct device_node *state_node;
> +
> +	state_node = of_parse_phandle(node, "cpu-idle-states", idx);
> +
> +	ret = of_property_read_u32(state_node, "arm,psci-suspend-param",
> +				   state);
> +	if (ret)
> +		pr_warn(" * %s missing arm,psci-suspend-param property\n",
> +			state_node->full_name);
> +
> +	of_node_put(state_node);
> +
> +	return ret;
> +}
> +
> +#ifdef CONFIG_ACPI
> +#include <acpi/processor.h>
> +
> +static int psci_acpi_get_state_count(unsigned int cpu)
> +{
> +	struct acpi_processor *pr = per_cpu(processors, cpu);
> +
> +	if (unlikely(!pr || !pr->flags.has_lpi))
> +		return -EINVAL;
> +
> +	return pr->power.count - 1;
> +}
> +
> +static int psci_acpi_get_idle_state(unsigned int cpu, int idx, u32 *state)
> +{
> +	struct acpi_processor *pr = per_cpu(processors, cpu);
> +	struct acpi_lpi_state *lpi = &pr->power.lpi_states[idx + 1];
> +
> +	if (!lpi)
> +		return -EINVAL;
> +
> +	/*
> +	 * Only bits[31:0] represent a PSCI power_state while
> +	 * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
> +	 */
> +	*state = lpi->address;
> +	return 0;
> +}
> +#else
> +static int psci_acpi_get_state_count(unsigned int cpu)
> +{
> +	return -EINVAL;
> +}
> +
> +static int psci_acpi_get_idle_state(unsigned int cpu, int idx, u32 *state)
> +{
> +	return -EINVAL;
> +}
> +#endif
> +
> +static int __psci_cpu_init_idle(struct device_node *cpu_dn, int cpu, bool acpi)
> +{
> +	int i, count, ret;
> +	u32 *psci_states;
> +
>  	/*
>  	 * If the PSCI cpu_suspend function hook has not been initialized
>  	 * idle states must not be enabled, so bail out
> @@ -263,14 +336,12 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
>  	if (!psci_ops.cpu_suspend)
>  		return -EOPNOTSUPP;
>  
> -	/* Count idle states */
> -	while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
> -					      count))) {
> -		count++;
> -		of_node_put(state_node);
> -	}
> +	if (acpi)
> +		count = psci_acpi_get_state_count(cpu);
> +	else
> +		count = psci_dt_get_state_count(cpu_dn);
>  
> -	if (!count)
> +	if (count <= 0)
>  		return -ENODEV;
>  
>  	psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
> @@ -278,21 +349,15 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
>  		return -ENOMEM;
>  
>  	for (i = 0; i < count; i++) {
> -		u32 state;
> -
> -		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
> +		u32 state = 0;
>  
> -		ret = of_property_read_u32(state_node,
> -					   "arm,psci-suspend-param",
> -					   &state);
> -		if (ret) {
> -			pr_warn(" * %s missing arm,psci-suspend-param property\n",
> -				state_node->full_name);
> -			of_node_put(state_node);
> +		if (acpi)
> +			ret = psci_acpi_get_idle_state(cpu, i, &state);
> +		else
> +			ret = psci_dt_get_idle_state(cpu_dn, i, &state);
> +		if (ret)
>  			goto free_mem;
> -		}
>  
> -		of_node_put(state_node);
>  		pr_debug("psci-power-state %#x index %d\n", state, i);
>  		if (!psci_power_state_is_valid(state)) {
>  			pr_warn("Invalid PSCI power state %#x\n", state);
> @@ -310,11 +375,24 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
>  	return ret;
>  }
>  
> +static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
> +{
> +	return __psci_cpu_init_idle(cpu_node, cpu, false);
> +}
> +
> +static int psci_acpi_cpu_init_idle(unsigned int cpu)
> +{
> +	return __psci_cpu_init_idle(NULL, cpu, true);
> +}
> +
>  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;
> -- 
> 2.7.4
> 

WARNING: multiple messages have this Message-ID (diff)
From: lorenzo.pieralisi@arm.com (Lorenzo Pieralisi)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v8 5/6] arm64: add support for ACPI Low Power Idle(LPI)
Date: Fri, 8 Jul 2016 15:47:19 +0100	[thread overview]
Message-ID: <20160708144719.GI3784@red-moon> (raw)
In-Reply-To: <1467911451-24731-6-git-send-email-sudeep.holla@arm.com>

On Thu, Jul 07, 2016 at 06:10:50PM +0100, Sudeep Holla wrote:
> 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: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
>  arch/arm64/kernel/cpuidle.c |  18 +++++++
>  drivers/firmware/psci.c     | 122 ++++++++++++++++++++++++++++++++++++--------

I would split this patch in two (ARM64 cpuidle and PSCI) and for
the PSCI code (apologies, blame taken, it is entirely my fault) I
think that the code in v6 was better, I asked you to factor out
DT/ACPI idle states count and parameter retrieval but the end result
is much more complicated than what it was in v6, so for PSCI ACPI
idle states parsing I would revert to v6, apologies.

With changes above:

Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

>  2 files changed, 118 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
> index 06786fdaadeb..7f16df7d7b23 100644
> --- a/arch/arm64/kernel/cpuidle.c
> +++ b/arch/arm64/kernel/cpuidle.c
> @@ -9,6 +9,9 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/acpi.h>
> +#include <linux/cpuidle.h>
> +#include <linux/cpu_pm.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  
> @@ -39,3 +42,18 @@ int arm_cpuidle_suspend(int index)
>  
>  	return cpu_ops[cpu]->cpu_suspend(index);
>  }
> +
> +#ifdef CONFIG_ACPI
> +
> +#include <acpi/processor.h>
> +
> +int acpi_processor_ffh_lpi_probe(unsigned int cpu)
> +{
> +	return arm_cpuidle_init(cpu);
> +}
> +
> +int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
> +{
> +	return CPU_IDLE_ENTER_WRAPPED(arm_cpuidle_suspend, lpi->index);
> +}
> +#endif
> diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
> index 03e04582791c..edd83c884a1d 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>
> @@ -250,12 +251,84 @@ static int __init psci_features(u32 psci_func_id)
>  #ifdef CONFIG_CPU_IDLE
>  static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
>  
> -static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
> +static int psci_dt_get_state_count(struct device_node *cpu_dn)
>  {
> -	int i, ret, count = 0;
> -	u32 *psci_states;
> +	int count = 0;
>  	struct device_node *state_node;
>  
> +	/* Count idle states */
> +	while ((state_node = of_parse_phandle(cpu_dn, "cpu-idle-states",
> +					      count))) {
> +		count++;
> +		of_node_put(state_node);
> +	}
> +
> +	return count;
> +}
> +
> +static int psci_dt_get_idle_state(struct device_node *node, int idx, u32 *state)
> +{
> +	int ret;
> +	struct device_node *state_node;
> +
> +	state_node = of_parse_phandle(node, "cpu-idle-states", idx);
> +
> +	ret = of_property_read_u32(state_node, "arm,psci-suspend-param",
> +				   state);
> +	if (ret)
> +		pr_warn(" * %s missing arm,psci-suspend-param property\n",
> +			state_node->full_name);
> +
> +	of_node_put(state_node);
> +
> +	return ret;
> +}
> +
> +#ifdef CONFIG_ACPI
> +#include <acpi/processor.h>
> +
> +static int psci_acpi_get_state_count(unsigned int cpu)
> +{
> +	struct acpi_processor *pr = per_cpu(processors, cpu);
> +
> +	if (unlikely(!pr || !pr->flags.has_lpi))
> +		return -EINVAL;
> +
> +	return pr->power.count - 1;
> +}
> +
> +static int psci_acpi_get_idle_state(unsigned int cpu, int idx, u32 *state)
> +{
> +	struct acpi_processor *pr = per_cpu(processors, cpu);
> +	struct acpi_lpi_state *lpi = &pr->power.lpi_states[idx + 1];
> +
> +	if (!lpi)
> +		return -EINVAL;
> +
> +	/*
> +	 * Only bits[31:0] represent a PSCI power_state while
> +	 * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
> +	 */
> +	*state = lpi->address;
> +	return 0;
> +}
> +#else
> +static int psci_acpi_get_state_count(unsigned int cpu)
> +{
> +	return -EINVAL;
> +}
> +
> +static int psci_acpi_get_idle_state(unsigned int cpu, int idx, u32 *state)
> +{
> +	return -EINVAL;
> +}
> +#endif
> +
> +static int __psci_cpu_init_idle(struct device_node *cpu_dn, int cpu, bool acpi)
> +{
> +	int i, count, ret;
> +	u32 *psci_states;
> +
>  	/*
>  	 * If the PSCI cpu_suspend function hook has not been initialized
>  	 * idle states must not be enabled, so bail out
> @@ -263,14 +336,12 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
>  	if (!psci_ops.cpu_suspend)
>  		return -EOPNOTSUPP;
>  
> -	/* Count idle states */
> -	while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
> -					      count))) {
> -		count++;
> -		of_node_put(state_node);
> -	}
> +	if (acpi)
> +		count = psci_acpi_get_state_count(cpu);
> +	else
> +		count = psci_dt_get_state_count(cpu_dn);
>  
> -	if (!count)
> +	if (count <= 0)
>  		return -ENODEV;
>  
>  	psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
> @@ -278,21 +349,15 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
>  		return -ENOMEM;
>  
>  	for (i = 0; i < count; i++) {
> -		u32 state;
> -
> -		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
> +		u32 state = 0;
>  
> -		ret = of_property_read_u32(state_node,
> -					   "arm,psci-suspend-param",
> -					   &state);
> -		if (ret) {
> -			pr_warn(" * %s missing arm,psci-suspend-param property\n",
> -				state_node->full_name);
> -			of_node_put(state_node);
> +		if (acpi)
> +			ret = psci_acpi_get_idle_state(cpu, i, &state);
> +		else
> +			ret = psci_dt_get_idle_state(cpu_dn, i, &state);
> +		if (ret)
>  			goto free_mem;
> -		}
>  
> -		of_node_put(state_node);
>  		pr_debug("psci-power-state %#x index %d\n", state, i);
>  		if (!psci_power_state_is_valid(state)) {
>  			pr_warn("Invalid PSCI power state %#x\n", state);
> @@ -310,11 +375,24 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
>  	return ret;
>  }
>  
> +static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
> +{
> +	return __psci_cpu_init_idle(cpu_node, cpu, false);
> +}
> +
> +static int psci_acpi_cpu_init_idle(unsigned int cpu)
> +{
> +	return __psci_cpu_init_idle(NULL, cpu, true);
> +}
> +
>  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;
> -- 
> 2.7.4
> 

  parent reply	other threads:[~2016-07-08 14:46 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-07 17:10 [PATCH v8 0/6] ACPI / processor_idle: Add ACPI v6.0 LPI support Sudeep Holla
2016-07-07 17:10 ` Sudeep Holla
2016-07-07 17:10 ` [PATCH v8 1/6] ACPI / processor_idle: introduce ACPI_PROCESSOR_CSTATE Sudeep Holla
2016-07-07 17:10   ` Sudeep Holla
2016-07-07 17:10   ` Sudeep Holla
2016-07-07 17:10   ` [PATCH v8 2/6] ACPI / processor_idle: Add support for Low Power Idle(LPI) states Sudeep Holla
2016-07-07 17:10     ` Sudeep Holla
2016-07-07 17:10     ` [PATCH v8 3/6] arm64: cpuidle: drop __init section marker to arm_cpuidle_init Sudeep Holla
2016-07-07 17:10       ` Sudeep Holla
2016-07-07 17:10       ` Sudeep Holla
2016-07-07 17:10       ` [PATCH v8 4/6] cpuidle: introduce CPU_IDLE_ENTER_WRAPPED macro for ARM{32,64} Sudeep Holla
2016-07-07 17:10         ` [PATCH v8 4/6] cpuidle: introduce CPU_IDLE_ENTER_WRAPPED macro for ARM{32, 64} Sudeep Holla
2016-07-07 17:10         ` [PATCH v8 5/6] arm64: add support for ACPI Low Power Idle(LPI) Sudeep Holla
2016-07-07 17:10           ` Sudeep Holla
2016-07-07 17:10           ` [PATCH v8 6/6] ACPI : enable ACPI_PROCESSOR_IDLE on ARM64 Sudeep Holla
2016-07-07 17:10             ` Sudeep Holla
2016-07-08 14:47           ` Lorenzo Pieralisi [this message]
2016-07-08 14:47             ` [PATCH v8 5/6] arm64: add support for ACPI Low Power Idle(LPI) Lorenzo Pieralisi
2016-07-08 15:21             ` Sudeep Holla
2016-07-08 15:21               ` Sudeep Holla
2016-07-07 21:02 ` [PATCH v8 0/6] ACPI / processor_idle: Add ACPI v6.0 LPI support Rafael J. Wysocki
2016-07-07 21:02   ` Rafael J. Wysocki
2016-07-08 11:04   ` Sudeep Holla
2016-07-08 11:04     ` Sudeep Holla
2016-07-08 14:43     ` Lorenzo Pieralisi
2016-07-08 14:43       ` Lorenzo Pieralisi
2016-07-08 15:19       ` Sudeep Holla
2016-07-08 15:19         ` 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=20160708144719.GI3784@red-moon \
    --to=lorenzo.pieralisi@arm.com \
    --cc=al.stone@linaro.org \
    --cc=ashwin.chaugule@linaro.org \
    --cc=daniel.lezcano@linaro.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=pprakash@codeaurora.org \
    --cc=rjw@rjwysocki.net \
    --cc=sudeep.holla@arm.com \
    --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.