[PATCH v5 6/8] drivers: cpuidle: initialize big.LITTLE driver through DT

Lorenzo Pieralisi lorenzo.pieralisi at arm.com
Wed Jun 25 09:44:04 PDT 2014


On Wed, Jun 25, 2014 at 04:06:23PM +0100, Mark Rutland wrote:
> On Wed, Jun 25, 2014 at 03:10:19PM +0100, Lorenzo Pieralisi wrote:
> > With the introduction of DT based idle states, CPUidle drivers for ARM
> > can now initialize idle states data through properties in the device tree.
> > 
> > This patch adds code to the big.LITTLE CPUidle driver to dynamically
> > initialize idle states data through the updated device tree source file.
> > 
> > Cc: Chander Kashyap <chander.kashyap at linaro.org>
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > ---
> >  Documentation/devicetree/bindings/arm/vexpress.txt | 25 +++++++++++++
> >  arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts         | 25 +++++++++++++
> >  drivers/cpuidle/Kconfig.arm                        |  1 +
> >  drivers/cpuidle/cpuidle-big_little.c               | 43 +++++++++++-----------
> >  4 files changed, 73 insertions(+), 21 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt
> > index 39844cd..7f52ac8 100644
> > --- a/Documentation/devicetree/bindings/arm/vexpress.txt
> > +++ b/Documentation/devicetree/bindings/arm/vexpress.txt
> > @@ -67,6 +67,28 @@ with device_type = "cpu" property for every available core, eg.:
> >  		};
> >  	};
> >  
> > +idle-states node
> > +----------------
> > +
> > +On Versatile Express platforms with power management capabilities, the device
> > +tree source file must contain the idle-states node[1]. As defined in [1] the
> > +idle-states node must contain an entry-method property that for Versatile
> > +Express platforms can be one of:
> > +
> > +	- "arm,vexpress-v2p-ca15_a7"
> 
> ... and what does this mean? It's the name we've assigned the platform
> in the Linux DT bindings, but this binding document tells me nothing
> about how this method works.

Ok, I should have omitted it, I added it to make it compliant with
current DT bindings where entry-method for idle-states is required and I
have just added TC2 compatible string to get code out for review.

I should have made the entry-method optional for arm32 and get rid of
this useless binding and entry-method string.

Thanks,
Lorenzo

> This feels like leaking Linux internals rather than a reusable
> interface.
> 
> Mark.
> 
> > +
> > +Versatile Express idle-states nodes example:
> > +
> > +	idle-states {
> > +		entry-method = "arm,vexpress-v2p-ca15_a7";
> > +
> > +		cluster-sleep-0 {
> > +			compatible = "arm,idle-state";
> > +			entry-latency-us = <1000>;
> > +			exit-latency-us = <700>;
> > +			min-residency-us = <3500>;
> > +		};
> > +	};
> >  
> >  Configuration infrastructure
> >  ----------------------------
> > @@ -227,3 +249,6 @@ Example of a VE tile description (simplified)
> >  	};
> >  };
> >  
> > +
> > +[1] ARM Linux Kernel documentation - Idle states bindings
> > +    Documentation/devicetree/bindings/arm/idle-states.txt
> > diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> > index a25c262..ad28242 100644
> > --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> > +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> > @@ -33,11 +33,32 @@
> >  		#address-cells = <1>;
> >  		#size-cells = <0>;
> >  
> > +		idle-states {
> > +			entry-method = "arm,vexpress-v2p-ca15_a7";
> > +
> > +			CLUSTER_SLEEP_BIG: cluster-sleep-big {
> > +				compatible = "arm,idle-state";
> > +				power-rank = <0>;
> > +				entry-latency-us = <1000>;
> > +				exit-latency-us = <700>;
> > +				min-residency-us = <3500>;
> > +			};
> > +
> > +			CLUSTER_SLEEP_LITTLE: cluster-sleep-little {
> > +				compatible = "arm,idle-state";
> > +				power-rank = <0>;
> > +				entry-latency-us = <1000>;
> > +				exit-latency-us = <500>;
> > +				min-residency-us = <3000>;
> > +			};
> > +		};
> > +
> >  		cpu0: cpu at 0 {
> >  			device_type = "cpu";
> >  			compatible = "arm,cortex-a15";
> >  			reg = <0>;
> >  			cci-control-port = <&cci_control1>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
> >  		};
> >  
> >  		cpu1: cpu at 1 {
> > @@ -45,6 +66,7 @@
> >  			compatible = "arm,cortex-a15";
> >  			reg = <1>;
> >  			cci-control-port = <&cci_control1>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_BIG>;
> >  		};
> >  
> >  		cpu2: cpu at 2 {
> > @@ -52,6 +74,7 @@
> >  			compatible = "arm,cortex-a7";
> >  			reg = <0x100>;
> >  			cci-control-port = <&cci_control2>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
> >  		};
> >  
> >  		cpu3: cpu at 3 {
> > @@ -59,6 +82,7 @@
> >  			compatible = "arm,cortex-a7";
> >  			reg = <0x101>;
> >  			cci-control-port = <&cci_control2>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
> >  		};
> >  
> >  		cpu4: cpu at 4 {
> > @@ -66,6 +90,7 @@
> >  			compatible = "arm,cortex-a7";
> >  			reg = <0x102>;
> >  			cci-control-port = <&cci_control2>;
> > +			cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>;
> >  		};
> >  	};
> >  
> > diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> > index b6d69e8..a9b089c 100644
> > --- a/drivers/cpuidle/Kconfig.arm
> > +++ b/drivers/cpuidle/Kconfig.arm
> > @@ -12,6 +12,7 @@ config ARM_BIG_LITTLE_CPUIDLE
> >  	depends on ARCH_VEXPRESS_TC2_PM
> >  	select ARM_CPU_SUSPEND
> >  	select CPU_IDLE_MULTIPLE_DRIVERS
> > +	select DT_IDLE_STATES
> >  	help
> >  	  Select this option to enable CPU idle driver for big.LITTLE based
> >  	  ARM systems. Driver manages CPUs coordination through MCPM and
> > diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c
> > index b45fc62..6712441 100644
> > --- a/drivers/cpuidle/cpuidle-big_little.c
> > +++ b/drivers/cpuidle/cpuidle-big_little.c
> > @@ -24,6 +24,8 @@
> >  #include <asm/smp_plat.h>
> >  #include <asm/suspend.h>
> >  
> > +#include "dt_idle_states.h"
> > +
> >  static int bl_enter_powerdown(struct cpuidle_device *dev,
> >  			      struct cpuidle_driver *drv, int idx);
> >  
> > @@ -61,32 +63,12 @@ static struct cpuidle_driver bl_idle_little_driver = {
> >  	.name = "little_idle",
> >  	.owner = THIS_MODULE,
> >  	.states[0] = ARM_CPUIDLE_WFI_STATE,
> > -	.states[1] = {
> > -		.enter			= bl_enter_powerdown,
> > -		.exit_latency		= 700,
> > -		.target_residency	= 2500,
> > -		.flags			= CPUIDLE_FLAG_TIME_VALID |
> > -					  CPUIDLE_FLAG_TIMER_STOP,
> > -		.name			= "C1",
> > -		.desc			= "ARM little-cluster power down",
> > -	},
> > -	.state_count = 2,
> >  };
> >  
> >  static struct cpuidle_driver bl_idle_big_driver = {
> >  	.name = "big_idle",
> >  	.owner = THIS_MODULE,
> >  	.states[0] = ARM_CPUIDLE_WFI_STATE,
> > -	.states[1] = {
> > -		.enter			= bl_enter_powerdown,
> > -		.exit_latency		= 500,
> > -		.target_residency	= 2000,
> > -		.flags			= CPUIDLE_FLAG_TIME_VALID |
> > -					  CPUIDLE_FLAG_TIMER_STOP,
> > -		.name			= "C1",
> > -		.desc			= "ARM big-cluster power down",
> > -	},
> > -	.state_count = 2,
> >  };
> >  
> >  /*
> > @@ -165,7 +147,8 @@ static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int cpu_id)
> >  
> >  static int __init bl_idle_init(void)
> >  {
> > -	int ret;
> > +	int ret, i;
> > +	struct cpuidle_driver *drv;
> >  
> >  	/*
> >  	 * Initialize the driver just for a compliant set of machines
> > @@ -187,6 +170,24 @@ static int __init bl_idle_init(void)
> >  	if (ret)
> >  		goto out_uninit_little;
> >  
> > +	 /* Start at index 1, index 0 standard WFI */
> > +	ret = dt_init_idle_driver(&bl_idle_big_driver, NULL, 1, false);
> > +	if (ret)
> > +		goto out_uninit_big;
> > +
> > +	 /* Start at index 1, index 0 standard WFI */
> > +	ret = dt_init_idle_driver(&bl_idle_little_driver, NULL, 1, false);
> > +	if (ret)
> > +		goto out_uninit_big;
> > +
> > +	drv = &bl_idle_big_driver;
> > +	for (i = 1; i < drv->state_count; i++)
> > +		drv->states[i].enter = bl_enter_powerdown;
> > +
> > +	drv = &bl_idle_little_driver;
> > +	for (i = 1; i < drv->state_count; i++)
> > +		drv->states[i].enter = bl_enter_powerdown;
> > +
> >  	ret = cpuidle_register(&bl_idle_little_driver, NULL);
> >  	if (ret)
> >  		goto out_uninit_big;
> > -- 
> > 1.9.1
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 




More information about the linux-arm-kernel mailing list