Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1251069 > unrolled thread

Re: [RFC v2 0/6] Managing cluser-level c-states with generic power domains

Started byLina Iyer <lina.iyer@linaro.org>
First post2015-10-19 23:00 +0200
Last post2015-10-27 18:50 +0100
Articles 9 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [RFC v2 0/6] Managing cluser-level c-states with generic power  domains Lina Iyer <lina.iyer@linaro.org> - 2015-10-19 23:00 +0200
    Re: [RFC v2 0/6] Managing cluser-level c-states with generic power  domains Marc Titinger <mtitinger@baylibre.com> - 2015-10-20 11:20 +0200
    [RFC v3 0/7] Managing cluser-level idle-states with generic power domains Marc Titinger <mtitinger@baylibre.com> - 2015-10-27 18:50 +0100
      [RFC v3 6/7] arm64: PM /Domains: Initialize CPU-domains from DT. Marc Titinger <mtitinger@baylibre.com> - 2015-10-27 18:50 +0100
      [RFC v3 1/7] PM / Domains: prepare for devices that might register a power state Marc Titinger <mtitinger@baylibre.com> - 2015-10-27 18:50 +0100
      [RFC v3 2/7] PM / Domains: support idle-states as genpd multiple-state. Marc Titinger <mtitinger@baylibre.com> - 2015-10-27 18:50 +0100
      [RFC v3 5/7] drivers: cpu-pd: allow calling of_cpu_pd_init from platform code. Marc Titinger <mtitinger@baylibre.com> - 2015-10-27 18:50 +0100
      [RFC v3 4/7] arm64: Juno: declare generic power domains for both clusters. Marc Titinger <mtitinger@baylibre.com> - 2015-10-27 18:50 +0100
      [RFC v3 7/7] arm64: Juno: declare idle-state cluster-sleep-0 as genpd state Marc Titinger <mtitinger@baylibre.com> - 2015-10-27 18:50 +0100

#1251069 — Re: [RFC v2 0/6] Managing cluser-level c-states with generic power domains

FromLina Iyer <lina.iyer@linaro.org>
Date2015-10-19 23:00 +0200
SubjectRe: [RFC v2 0/6] Managing cluser-level c-states with generic power domains
Message-ID<qlpHc-7uj-13@gated-at.bofh.it>
Hi Marc,

I am trying to apply this on top of Axel's patches on linux-next (after
fixing issues I saw with his v9), and running to issues applying your
patches. Could you rebase on top of his v10 (he said he would send to
the ML soon) ?

Thanks,
Lina

On Tue, Oct 06 2015 at 08:27 -0600, Marc Titinger wrote:
>v2:
> - rebase on Lina Iyer's latest series
> - remove unnecessary dependency on perf-state patches from Axel Haslam
>
>-----------------------
>
>Summary
>
>1) DESCRIPTION
>2) DEPENDENCIES
>3) URL
>------------------------
>
>
>1) DESCRIPTION
>
>
>	This patch set's underlying idea is that cluster-level c-states can be managed
>by the power domain, building upon Lina Iyers recent work on CPU-domain, and Axel Haslam's
>genpd multiple states. The power domain may contain CPU devices and non-CPU devices.
>
>Non-CPU Devices may expose latency constraints by registering intermediate power-states upon
>probing, for instance shallower states than the deepest cluster-off state. The generic
>power domain governor may chose a device retention state in place of the cluster-sleep
>state demanded by the menu governor, and call the platform specific handling to enter/leave
>that retention state.
>
>
>power-states
>-----------
>
>
>The proposed way how cluster-level c-states are declared as manageable by the
>power domain, rather than through the cpuidle-ops, relies on the introduction of
>"power-states", consistent with c-states. Here is an example of the DT bindings,
>the c-state CLUSTER_SLEEP_0 is exposed as a power-state in the compatible property:
>
>juno.dts:           idle-states {
>                        entry-method = "arm,psci";
>
>                        CPU_SLEEP_0: cpu-sleep-0 {
>                                compatible = "arm,idle-state";
>                                arm,psci-suspend-param = <0x0010000>;
>                                local-timer-stop;
>                                entry-latency-us = <100>;
>                                exit-latency-us = <250>;
>                                min-residency-us = <2000>;
>                        };
>
>                        CLUSTER_SLEEP_0: cluster-sleep-0 {
>                                compatible = "arm,power-state";
>                                arm,psci-suspend-param = <0x1010000>;
>                                local-timer-stop;
>                                entry-latency-us = <800>;
>                                exit-latency-us = <700>;
>                                min-residency-us = <2500>;
>                        };
>		}
>
>This will tell cpuidle runtime_put/get the CPU devices for this c-state. Eventually, the
>actual platform handlers may be called from the genpd platform ops (in place of cpuidle_ops).
>
>"drivers/cpuidle/cpuidle-arm.c":
>
>static const struct of_device_id arm_idle_state_match[] __initconst = {
>        {.compatible = "arm,idle-state",
>         .data = arm_enter_idle_state},
>        {.compatible = "arm,power-state",
>         .data = arm_enter_power_state},
>};
>
>
>In case of a power-state, arm_enter_power_state will only call pm_runtime_put/get_sync
>The power doamin will handle the power off, currently this patch set lacks the final
>call to the psci interface to have a fully fonctionnal setup
>(and there are some genpd_lock'ing issues if put/get actually suspend the CPU device.)
>
>Ultimately, we would like the Power Domain's simple governor to being able to chose
>the cluster power-state based on the c-states defered to it (power-states) and constraints
>added by the devices. Consequently, we need to "soak" those power-states into the
>power-domain intermediate states from Axel. Since power-states are declared and handled
>the same manner than c-states (idle-states in DT), these patches add a soaking used when
>attaching to a genpd, where power-states are parsed from the DT into the genpd states:
>
>
>"drivers/base/power/domain.c":
>
>static const struct of_device_id power_state_match[] = {
>        {.compatible = "arm,power-state",
>         },
>};
>
>int of_genpd_device_parse_states(struct device_node *np,
>                                 struct generic_pm_domain *genpd)
>
>debugfs addition
>---------------
>
>To easy debug, this patch set adds a seq-file names "states" to the pm_genpd debugfs:
>
>    cat /sys/kernel/debug/pm_genpd/*
>
>      Domain             State name        Enter (ns) / Exit (ns)
>    -------------------------------------------------------------
>    a53_pd               cluster-sleep-0      1500000 / 800000
>    a57_pd               cluster-sleep-0      1500000 / 800000
>
>And also a seq-file "timings", to help visualize the constrains of the non-CPU
>devices in a cluster PD.
>
>    Domain Devices, Timings in ns
>                       Stop/Start Save/Restore, Effective
>----------------------------------------------------  ---
>a57_pd
>    /cpus/cpu@0          800   /740    1320  /1720  ,0 (cached stop)
>    /cpus/cpu@1          800   /740    1420  /1780  ,0 (cached stop)
>    /D1                  660   /580    16560 /6080  ,2199420 (cached stop)
>
>
>Device power-states
>-------------------
>
>some devices, like L2 caches, may feature a shallower retention mode, between CPU_SLEEP_0
>and CLUSTER_SLEEP_0, in which mode the L2 memory is not powered off, leading to faster
>resume than CLUSTER_SLEEP_0.
>
>One way to handle device constrains and retention features in the power-domain, is to
>allow devices to register a new power-state (consistent with a c-state).
>
>idle-states:
>
>                        D1_RETENTION: d1-retention {
>                                compatible = "arm,power-state";
>                                /*leave the psci param, for demo/testing:
>                                * the psci cpuidle driver will not currently
>                                * understand that a c-state shall not have it's
>                                * table entry with a firmware command.
>                                * the actual .power_on/off would be registered
>                                * by the DECLARE macro for a given domain*/
>                                arm,psci-suspend-param = <0x1010000>;
>                                local-timer-stop;
>                                entry-latency-us = <800>;
>                                exit-latency-us = <200>;
>                                min-residency-us = <2500>;
>                        };
>
>
>        D1 {
>                compatible = "fake,fake-driver";
>                name = "D1";
>                constraint = <30000>;
>                power-domains = <&a53_pd>;
>		power-states =<&D1_RETENTION>;
>        };
>
>
>The genpd simple governor can now upon suspend of the last-man CPU chose a shallower
>retention state than CLUSTER_SLEEP_0.
>
>In order to achieve this, this patch set added the power-state parsing during the
>genpd_dev_pm_attach call. Multiple genpd states are now inserted in a sorted manner
>according to their depth: see pm_genpd_insert_state in "drivers/base/power/domain.c".
>
>
>
>2) DEPENDENCIES
>
>	This patch set applies over linux-4.2rc5 plus the following ordered dependencies:
>
> * Ulf Hansson:
>
>6637131 New          [V4] PM / Domains: Remove intermediate states from the power off sequence
>
> * Lina Iyer's patch series:
>
>7118981 Not Applicable [v2,1/7] PM / Domains: Allocate memory outside domain locks
>7118991 Not Applicable [v2,2/7] PM / Domains: Support IRQ safe PM domains
>7119001 Not Applicable [v2,3/7] drivers: cpu: Define CPU devices as IRQ safe
>7119011 Not Applicable [v2,4/7] PM / Domains: Introduce PM domains for CPUs/clusters
>7119021 Not Applicable [v2,5/7] ARM: cpuidle: Add runtime PM support for CPU idle
>7119031 Not Applicable [v2,6/7] ARM64: smp: Add runtime PM support for CPU hotplug
>7119041 Not Applicable [v2,7/7] ARM: smp: Add runtime PM support for CPU hotplug
>
> * John Medhurst:
>
>6303671 New          arm64: dts: Add idle-states for Juno
>
> * Axel Haslam:
>
>6301741 Not Applicable [v7,1/5] PM / Domains: prepare for multiple states
>6301751 Not Applicable [v7,2/5] PM / Domains: core changes for multiple states
>6301781 Not Applicable [v7,3/5] PM / Domains: make governor select deepest state
>6301771 Not Applicable [v7,4/5] ARM: imx6: pm: declare pm domain latency on power_state struct.
>6301761 Not Applicable [v7,5/5] PM / Domains: remove old power on/off latencies.
>
>2) URL
>
>playable from https://github.com/mtitinger/linux-pm.git
>
>by adding the "fake driver D1" and launching the test-dev-state.sh script.
>this will show the power domain suspending to an intermediate state, based on the
>device constraints.
>
>    domain                      status pstate     slaves
>           /device                                      runtime status
>-----------------------------------------------------------------------------------
>a53_pd                          on
>    /devices/system/cpu/cpu0                            active
>    /devices/system/cpu/cpu3                            suspended
>    /devices/system/cpu/cpu4                            suspended
>    /devices/system/cpu/cpu5                            suspended
>a57_pd                          d1-retention
>    /devices/system/cpu/cpu1                            suspended
>    /devices/system/cpu/cpu2                            suspended
>    /devices/platform/D1
>
>----------------------------------------------------------------------
>
>Marc Titinger (6):
>  arm64: Juno: declare generic power domains for both clusters.
>  PM / Domains: prepare for devices that might register a power state
>  PM / Domains: introduce power-states consistent with c-states.
>  PM / Domains: succeed & warn when attaching non-irqsafe devices to an
>    irq-safe domain.
>  arm: cpuidle: let genpd handle the cluster power transition with
>    'power-states'
>  PM / Domains: add debugfs 'states' and 'timings' seq files
>
> .../devicetree/bindings/arm/idle-states.txt        |  21 +-
> .../devicetree/bindings/power/power_domain.txt     |  29 ++
> arch/arm64/boot/dts/arm/juno.dts                   |  25 +-
> drivers/base/power/cpu-pd.c                        |   5 +
> drivers/base/power/domain.c                        | 415 +++++++++++++++------
> drivers/cpuidle/cpuidle-arm.c                      |  52 ++-
> include/linux/pm_domain.h                          |  21 +-
> 7 files changed, 437 insertions(+), 131 deletions(-)
>
>-- 
>1.9.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1251495

FromMarc Titinger <mtitinger@baylibre.com>
Date2015-10-20 11:20 +0200
Message-ID<qlBfm-7L2-53@gated-at.bofh.it>
In reply to#1251069
On 19/10/2015 22:58, Lina Iyer wrote:
> Hi Marc,
>
> I am trying to apply this on top of Axel's patches on linux-next (after
> fixing issues I saw with his v9), and running to issues applying your
> patches. Could you rebase on top of his v10 (he said he would send to
> the ML soon) ?
>

Hi Lina,

I want to replay this with Juno this afternoon first, I'll post ASAP.

Also, based on Kevin's comment I was wondering if I should drop this 
path already and try the other way as discussed (hook l2 devices to 
runtime-pm, through the CPU device), but I still need to think about 
this first.

Cheers,
Marc.



> Thanks,
> Lina
>
> On Tue, Oct 06 2015 at 08:27 -0600, Marc Titinger wrote:
>> v2:
>> - rebase on Lina Iyer's latest series
>> - remove unnecessary dependency on perf-state patches from Axel Haslam
>>
>> -----------------------
>>
>> Summary
>>
>> 1) DESCRIPTION
>> 2) DEPENDENCIES
>> 3) URL
>> ------------------------
>>
>>
>> 1) DESCRIPTION
>>
>>
>>     This patch set's underlying idea is that cluster-level c-states
>> can be managed
>> by the power domain, building upon Lina Iyers recent work on
>> CPU-domain, and Axel Haslam's
>> genpd multiple states. The power domain may contain CPU devices and
>> non-CPU devices.
>>
>> Non-CPU Devices may expose latency constraints by registering
>> intermediate power-states upon
>> probing, for instance shallower states than the deepest cluster-off
>> state. The generic
>> power domain governor may chose a device retention state in place of
>> the cluster-sleep
>> state demanded by the menu governor, and call the platform specific
>> handling to enter/leave
>> that retention state.
>>
>>
>> power-states
>> -----------
>>
>>
>> The proposed way how cluster-level c-states are declared as manageable
>> by the
>> power domain, rather than through the cpuidle-ops, relies on the
>> introduction of
>> "power-states", consistent with c-states. Here is an example of the DT
>> bindings,
>> the c-state CLUSTER_SLEEP_0 is exposed as a power-state in the
>> compatible property:
>>
>> juno.dts:           idle-states {
>>                        entry-method = "arm,psci";
>>
>>                        CPU_SLEEP_0: cpu-sleep-0 {
>>                                compatible = "arm,idle-state";
>>                                arm,psci-suspend-param = <0x0010000>;
>>                                local-timer-stop;
>>                                entry-latency-us = <100>;
>>                                exit-latency-us = <250>;
>>                                min-residency-us = <2000>;
>>                        };
>>
>>                        CLUSTER_SLEEP_0: cluster-sleep-0 {
>>                                compatible = "arm,power-state";
>>                                arm,psci-suspend-param = <0x1010000>;
>>                                local-timer-stop;
>>                                entry-latency-us = <800>;
>>                                exit-latency-us = <700>;
>>                                min-residency-us = <2500>;
>>                        };
>>         }
>>
>> This will tell cpuidle runtime_put/get the CPU devices for this
>> c-state. Eventually, the
>> actual platform handlers may be called from the genpd platform ops (in
>> place of cpuidle_ops).
>>
>> "drivers/cpuidle/cpuidle-arm.c":
>>
>> static const struct of_device_id arm_idle_state_match[] __initconst = {
>>        {.compatible = "arm,idle-state",
>>         .data = arm_enter_idle_state},
>>        {.compatible = "arm,power-state",
>>         .data = arm_enter_power_state},
>> };
>>
>>
>> In case of a power-state, arm_enter_power_state will only call
>> pm_runtime_put/get_sync
>> The power doamin will handle the power off, currently this patch set
>> lacks the final
>> call to the psci interface to have a fully fonctionnal setup
>> (and there are some genpd_lock'ing issues if put/get actually suspend
>> the CPU device.)
>>
>> Ultimately, we would like the Power Domain's simple governor to being
>> able to chose
>> the cluster power-state based on the c-states defered to it
>> (power-states) and constraints
>> added by the devices. Consequently, we need to "soak" those
>> power-states into the
>> power-domain intermediate states from Axel. Since power-states are
>> declared and handled
>> the same manner than c-states (idle-states in DT), these patches add a
>> soaking used when
>> attaching to a genpd, where power-states are parsed from the DT into
>> the genpd states:
>>
>>
>> "drivers/base/power/domain.c":
>>
>> static const struct of_device_id power_state_match[] = {
>>        {.compatible = "arm,power-state",
>>         },
>> };
>>
>> int of_genpd_device_parse_states(struct device_node *np,
>>                                 struct generic_pm_domain *genpd)
>>
>> debugfs addition
>> ---------------
>>
>> To easy debug, this patch set adds a seq-file names "states" to the
>> pm_genpd debugfs:
>>
>>    cat /sys/kernel/debug/pm_genpd/*
>>
>>      Domain             State name        Enter (ns) / Exit (ns)
>>    -------------------------------------------------------------
>>    a53_pd               cluster-sleep-0      1500000 / 800000
>>    a57_pd               cluster-sleep-0      1500000 / 800000
>>
>> And also a seq-file "timings", to help visualize the constrains of the
>> non-CPU
>> devices in a cluster PD.
>>
>>    Domain Devices, Timings in ns
>>                       Stop/Start Save/Restore, Effective
>> ----------------------------------------------------  ---
>> a57_pd
>>    /cpus/cpu@0          800   /740    1320  /1720  ,0 (cached stop)
>>    /cpus/cpu@1          800   /740    1420  /1780  ,0 (cached stop)
>>    /D1                  660   /580    16560 /6080  ,2199420 (cached stop)
>>
>>
>> Device power-states
>> -------------------
>>
>> some devices, like L2 caches, may feature a shallower retention mode,
>> between CPU_SLEEP_0
>> and CLUSTER_SLEEP_0, in which mode the L2 memory is not powered off,
>> leading to faster
>> resume than CLUSTER_SLEEP_0.
>>
>> One way to handle device constrains and retention features in the
>> power-domain, is to
>> allow devices to register a new power-state (consistent with a c-state).
>>
>> idle-states:
>>
>>                        D1_RETENTION: d1-retention {
>>                                compatible = "arm,power-state";
>>                                /*leave the psci param, for demo/testing:
>>                                * the psci cpuidle driver will not
>> currently
>>                                * understand that a c-state shall not
>> have it's
>>                                * table entry with a firmware command.
>>                                * the actual .power_on/off would be
>> registered
>>                                * by the DECLARE macro for a given
>> domain*/
>>                                arm,psci-suspend-param = <0x1010000>;
>>                                local-timer-stop;
>>                                entry-latency-us = <800>;
>>                                exit-latency-us = <200>;
>>                                min-residency-us = <2500>;
>>                        };
>>
>>
>>        D1 {
>>                compatible = "fake,fake-driver";
>>                name = "D1";
>>                constraint = <30000>;
>>                power-domains = <&a53_pd>;
>>         power-states =<&D1_RETENTION>;
>>        };
>>
>>
>> The genpd simple governor can now upon suspend of the last-man CPU
>> chose a shallower
>> retention state than CLUSTER_SLEEP_0.
>>
>> In order to achieve this, this patch set added the power-state parsing
>> during the
>> genpd_dev_pm_attach call. Multiple genpd states are now inserted in a
>> sorted manner
>> according to their depth: see pm_genpd_insert_state in
>> "drivers/base/power/domain.c".
>>
>>
>>
>> 2) DEPENDENCIES
>>
>>     This patch set applies over linux-4.2rc5 plus the following
>> ordered dependencies:
>>
>> * Ulf Hansson:
>>
>> 6637131 New          [V4] PM / Domains: Remove intermediate states
>> from the power off sequence
>>
>> * Lina Iyer's patch series:
>>
>> 7118981 Not Applicable [v2,1/7] PM / Domains: Allocate memory outside
>> domain locks
>> 7118991 Not Applicable [v2,2/7] PM / Domains: Support IRQ safe PM domains
>> 7119001 Not Applicable [v2,3/7] drivers: cpu: Define CPU devices as
>> IRQ safe
>> 7119011 Not Applicable [v2,4/7] PM / Domains: Introduce PM domains for
>> CPUs/clusters
>> 7119021 Not Applicable [v2,5/7] ARM: cpuidle: Add runtime PM support
>> for CPU idle
>> 7119031 Not Applicable [v2,6/7] ARM64: smp: Add runtime PM support for
>> CPU hotplug
>> 7119041 Not Applicable [v2,7/7] ARM: smp: Add runtime PM support for
>> CPU hotplug
>>
>> * John Medhurst:
>>
>> 6303671 New          arm64: dts: Add idle-states for Juno
>>
>> * Axel Haslam:
>>
>> 6301741 Not Applicable [v7,1/5] PM / Domains: prepare for multiple states
>> 6301751 Not Applicable [v7,2/5] PM / Domains: core changes for
>> multiple states
>> 6301781 Not Applicable [v7,3/5] PM / Domains: make governor select
>> deepest state
>> 6301771 Not Applicable [v7,4/5] ARM: imx6: pm: declare pm domain
>> latency on power_state struct.
>> 6301761 Not Applicable [v7,5/5] PM / Domains: remove old power on/off
>> latencies.
>>
>> 2) URL
>>
>> playable from https://github.com/mtitinger/linux-pm.git
>>
>> by adding the "fake driver D1" and launching the test-dev-state.sh
>> script.
>> this will show the power domain suspending to an intermediate state,
>> based on the
>> device constraints.
>>
>>    domain                      status pstate     slaves
>>           /device                                      runtime status
>> -----------------------------------------------------------------------------------
>>
>> a53_pd                          on
>>    /devices/system/cpu/cpu0                            active
>>    /devices/system/cpu/cpu3                            suspended
>>    /devices/system/cpu/cpu4                            suspended
>>    /devices/system/cpu/cpu5                            suspended
>> a57_pd                          d1-retention
>>    /devices/system/cpu/cpu1                            suspended
>>    /devices/system/cpu/cpu2                            suspended
>>    /devices/platform/D1
>>
>> ----------------------------------------------------------------------
>>
>> Marc Titinger (6):
>>  arm64: Juno: declare generic power domains for both clusters.
>>  PM / Domains: prepare for devices that might register a power state
>>  PM / Domains: introduce power-states consistent with c-states.
>>  PM / Domains: succeed & warn when attaching non-irqsafe devices to an
>>    irq-safe domain.
>>  arm: cpuidle: let genpd handle the cluster power transition with
>>    'power-states'
>>  PM / Domains: add debugfs 'states' and 'timings' seq files
>>
>> .../devicetree/bindings/arm/idle-states.txt        |  21 +-
>> .../devicetree/bindings/power/power_domain.txt     |  29 ++
>> arch/arm64/boot/dts/arm/juno.dts                   |  25 +-
>> drivers/base/power/cpu-pd.c                        |   5 +
>> drivers/base/power/domain.c                        | 415
>> +++++++++++++++------
>> drivers/cpuidle/cpuidle-arm.c                      |  52 ++-
>> include/linux/pm_domain.h                          |  21 +-
>> 7 files changed, 437 insertions(+), 131 deletions(-)
>>
>> --
>> 1.9.1
>>

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1257037 — [RFC v3 0/7] Managing cluser-level idle-states with generic power domains

FromMarc Titinger <mtitinger@baylibre.com>
Date2015-10-27 18:50 +0100
Subject[RFC v3 0/7] Managing cluser-level idle-states with generic power domains
Message-ID<qogxH-87V-5@gated-at.bofh.it>
In reply to#1251069
Hi Lina,

this is the rebased version of my patches to handle cluster sleep with genpd.
I rebased over your current patches in the linaro git, and Axels v10, and
finally linux-next.

The arm64/Juno stuff is mainly for testing, it may not be 100% up-to-date with
the CPU-pd discussion outcomes, and I've left the patch for dynamic states
registration by devices in this series for now (will do things differently
using the CPU devices as suggested by Kevin).

Changes in v3 (based on comments from you and Kevin)
 - removed the "power-states" binding. Instead, look for a ppty called
   cpu-idle-states in each PD node. this is a list of idle-states that will be
   mapped as domain states.
 - quit referring to c-states, but refer to idle-states instead.


Jon Medhurst (1):
  arm64: dts: Add idle-states for Juno

Marc Titinger (6):
  PM / Domains: prepare for devices that might register a power state
  PM / Domains: support idle-states as genpd multiple-state.
  arm64: Juno: declare generic power domains for both clusters.
  drivers: cpu-pd: allow calling of_cpu_pd_init from platform code.
  arm64: PM /Domains: Initialize CPU-domains from DT.
  arm64: Juno: declare idle-state cluster-sleep-0 as genpd state

 .../devicetree/bindings/power/power_domain.txt     |  29 +++
 arch/arm64/boot/dts/arm/juno.dts                   |  50 ++++
 arch/arm64/kernel/Makefile                         |   1 +
 arch/arm64/kernel/cpu_domain.c                     |  19 ++
 drivers/base/power/cpu-pd.c                        |  31 +--
 drivers/base/power/domain.c                        | 278 ++++++++++++++-------
 include/linux/cpu-pd.h                             |   2 +
 include/linux/pm_domain.h                          |  13 +-
 8 files changed, 308 insertions(+), 115 deletions(-)
 create mode 100644 arch/arm64/kernel/cpu_domain.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1257042 — [RFC v3 6/7] arm64: PM /Domains: Initialize CPU-domains from DT.

FromMarc Titinger <mtitinger@baylibre.com>
Date2015-10-27 18:50 +0100
Subject[RFC v3 6/7] arm64: PM /Domains: Initialize CPU-domains from DT.
Message-ID<qogxH-87V-11@gated-at.bofh.it>
In reply to#1257037
From: Marc Titinger <mtitinger@baylibre.com>

Signed-off-by: Marc Titinger <mtitinger+renesas@baylibre.com>
---
 arch/arm64/kernel/Makefile     |  1 +
 arch/arm64/kernel/cpu_domain.c | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 arch/arm64/kernel/cpu_domain.c

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 1b6bda2..5f8b59f 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -46,6 +46,7 @@ arm64-obj-$(CONFIG_EFI)			+= efi.o $(stub-obj)
 arm64-obj-$(CONFIG_PCI)			+= pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.o
+arm64-obj-$(CONFIG_PM_GENERIC_DOMAINS)	+= cpu_domain.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/cpu_domain.c b/arch/arm64/kernel/cpu_domain.c
new file mode 100644
index 0000000..06a3949
--- /dev/null
+++ b/arch/arm64/kernel/cpu_domain.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015, Linaro 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 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/cpu-pd.h>
+
+static int __init arm64_cpu_pd_init(void)
+{
+	return of_cpu_pd_init("arm,cpu-pd");
+}
+device_initcall(arm64_cpu_pd_init);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1257046 — [RFC v3 1/7] PM / Domains: prepare for devices that might register a power state

FromMarc Titinger <mtitinger@baylibre.com>
Date2015-10-27 18:50 +0100
Subject[RFC v3 1/7] PM / Domains: prepare for devices that might register a power state
Message-ID<qogxI-87V-35@gated-at.bofh.it>
In reply to#1257037
From: Marc Titinger <mtitinger@baylibre.com>

Devices may register an intermediate retention state into the domain
upon attaching. Currently generic domain would register an array of
states upon init. This patch prepares for later insertion (sort per
depth, remove).

Signed-off-by: Marc Titinger <mtitinger+renesas@baylibre.com>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
 - Lina: Rebase related changes]
 - Lina: Initialize domain states after the domain is initalized to
   ensure the domain lock is initialized before calling the function
   to add states dynamically.
---
 drivers/base/power/cpu-pd.c |   2 -
 drivers/base/power/domain.c | 178 +++++++++++++++++++++-----------------------
 include/linux/pm_domain.h   |  10 ++-
 3 files changed, 94 insertions(+), 96 deletions(-)

diff --git a/drivers/base/power/cpu-pd.c b/drivers/base/power/cpu-pd.c
index aa276fc..eddee98 100644
--- a/drivers/base/power/cpu-pd.c
+++ b/drivers/base/power/cpu-pd.c
@@ -21,8 +21,6 @@
 #include <linux/rculist.h>
 #include <linux/slab.h>
 
-#define NAME_MAX 36
-
 /* List of CPU PM domains we care about */
 static LIST_HEAD(of_cpu_pd_list);
 static DEFINE_SPINLOCK(cpu_pd_list_lock);
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index cc8134d..6b2d771 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/suspend.h>
 #include <linux/export.h>
+#include <linux/sort.h>
 
 #define GENPD_RETRY_MAX_MS	250		/* Approximate */
 
@@ -50,12 +51,6 @@
 	__retval;								\
 })
 
-#define GENPD_MAX_NAME_SIZE 20
-
-static int pm_genpd_alloc_states_names(struct generic_pm_domain *genpd,
-				       const struct genpd_power_state *st,
-				       unsigned int st_count);
-
 static LIST_HEAD(gpd_list);
 static DEFINE_MUTEX(gpd_list_lock);
 
@@ -1297,45 +1292,6 @@ static void genpd_free_dev_data(struct device *dev,
 	dev_pm_put_subsys_data(dev);
 }
 
-static int genpd_alloc_states_data(struct generic_pm_domain *genpd,
-				   const struct genpd_power_state *st,
-				   unsigned int st_count)
-{
-	int ret = 0;
-	unsigned int i;
-
-	if (IS_ERR_OR_NULL(genpd)) {
-		ret = -EINVAL;
-		goto err;
-	}
-
-	if (!st || (st_count < 1)) {
-		ret = -EINVAL;
-		goto err;
-	}
-
-	/* Allocate the local memory to keep the states for this genpd */
-	genpd->states = kcalloc(st_count, sizeof(*st), GFP_KERNEL);
-	if (!genpd->states) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	for (i = 0; i < st_count; i++) {
-		genpd->states[i].power_on_latency_ns =
-			st[i].power_on_latency_ns;
-		genpd->states[i].power_off_latency_ns =
-			st[i].power_off_latency_ns;
-	}
-
-	genpd->state_count = st_count;
-
-	/* to save memory, Name allocation will happen if debug is enabled */
-	pm_genpd_alloc_states_names(genpd, st, st_count);
-
-err:
-	return ret;
-}
 
 /**
  * __pm_genpd_add_device - Add a device to an I/O PM domain.
@@ -1614,6 +1570,73 @@ static void genpd_lock_init(struct generic_pm_domain *genpd)
 	}
 }
 
+/*
+ * state depth comparison function.
+ */
+static int state_cmp(const void *a, const void *b)
+{
+	struct genpd_power_state *state_a = (struct genpd_power_state *)(a);
+	struct genpd_power_state *state_b = (struct genpd_power_state *)(b);
+
+	s64 depth_a =
+		state_a->power_on_latency_ns + state_a->power_off_latency_ns;
+	s64 depth_b =
+		state_b->power_on_latency_ns + state_b->power_off_latency_ns;
+
+	return (depth_a > depth_b) ? 0 : -1;
+}
+
+/*
+ * TODO: antagonist routine.
+ */
+int pm_genpd_insert_state(struct generic_pm_domain *genpd,
+		const struct genpd_power_state *state)
+{
+	int ret = 0;
+	int state_count = genpd->state_count;
+
+	if (IS_ERR_OR_NULL(genpd) || (!state))
+		ret = -EINVAL;
+
+	if (state_count >= GENPD_POWER_STATES_MAX)
+		ret = -ENOMEM;
+
+#ifdef CONFIG_PM_ADVANCED_DEBUG
+	/* to save memory, Name allocation will happen if debug is enabled */
+	genpd->states[state_count].name = kstrndup(state->name,
+			GENPD_MAX_NAME_SIZE,
+			GFP_KERNEL);
+	if (!genpd->states[state_count].name) {
+		pr_err("%s Failed to allocate state '%s' name.\n",
+				genpd->name, state->name);
+		ret = -ENOMEM;
+	}
+#endif
+	genpd_lock(genpd);
+
+	if (!ret) {
+		genpd->states[state_count].power_on_latency_ns =
+			state->power_on_latency_ns;
+		genpd->states[state_count].power_off_latency_ns =
+			state->power_off_latency_ns;
+		genpd->state_count++;
+	}
+
+	/* sort from shallowest to deepest */
+	sort(genpd->states, genpd->state_count,
+			sizeof(genpd->states[0]), state_cmp, NULL);
+
+	/* Sanity check for current state index */
+	if (genpd->state_idx >= genpd->state_count) {
+		pr_warn("pm domain %s Invalid initial state.\n", genpd->name);
+		genpd->state_idx = genpd->state_count - 1;
+	}
+
+	genpd_unlock(genpd);
+
+	return ret;
+}
+
 /**
  * pm_genpd_init - Initialize a generic I/O PM domain object.
  * @genpd: PM domain object to initialize.
@@ -1627,23 +1650,11 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
 		   const struct genpd_power_state *states,
 		   unsigned int state_count, bool is_off)
 {
-	int ret;
+	int i;
 
 	if (IS_ERR_OR_NULL(genpd))
 		return;
 
-	/* State data should be provided */
-	if (!states || (state_count < 1)) {
-		pr_err("Invalid state data\n");
-		return;
-	}
-
-	ret = genpd_alloc_states_data(genpd, states, state_count);
-	if (ret) {
-		pr_err("Failed to allocate states for %s\n", genpd->name);
-		return;
-	}
-
 	INIT_LIST_HEAD(&genpd->master_links);
 	INIT_LIST_HEAD(&genpd->slave_links);
 	INIT_LIST_HEAD(&genpd->dev_list);
@@ -1688,9 +1699,25 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
 		genpd->dev_ops.start = pm_clk_resume;
 	}
 
+	/* simply use an array, we wish to add/remove new retention states
+	 *    from later device init/exit.
+	 */
+	memset(genpd->states, 0, GENPD_POWER_STATES_MAX
+			* sizeof(struct genpd_power_state));
+
+	if (!states || !state_count) {
+		/* require a provider for a default state */
+		genpd->state_count = 0;
+		genpd->state_idx = 0;
+	} else
+		for (i = 0; i < state_count; i++)
+			if (pm_genpd_insert_state(genpd, &states[i]))
+				return;
+
 	mutex_lock(&gpd_list_lock);
 	list_add(&genpd->gpd_list_node, &gpd_list);
 	mutex_unlock(&gpd_list_lock);
+
 }
 EXPORT_SYMBOL_GPL(pm_genpd_init);
 
@@ -2029,33 +2056,6 @@ EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
 #include <linux/kobject.h>
 static struct dentry *pm_genpd_debugfs_dir;
 
-static int pm_genpd_alloc_states_names(struct generic_pm_domain *genpd,
-				       const struct genpd_power_state *st,
-				       unsigned int st_count)
-{
-	unsigned int i;
-
-	if (IS_ERR_OR_NULL(genpd))
-		return -EINVAL;
-
-	if (genpd->state_count != st_count) {
-		pr_err("Invalid allocated state count\n");
-		return -EINVAL;
-	}
-
-	for (i = 0; i < st_count; i++) {
-		genpd->states[i].name = kstrndup(st[i].name,
-				GENPD_MAX_NAME_SIZE, GFP_KERNEL);
-		if (!genpd->states[i].name) {
-			pr_err("%s Failed to allocate state %d name.\n",
-				genpd->name, i);
-			return -ENOMEM;
-		}
-	}
-
-	return 0;
-}
-
 /*
  * TODO: This function is a slightly modified version of rtpm_status_show
  * from sysfs.c, so generalize it.
@@ -2292,12 +2292,4 @@ static void __exit pm_genpd_debug_exit(void)
 {
 	debugfs_remove_recursive(pm_genpd_debugfs_dir);
 }
-__exitcall(pm_genpd_debug_exit);
-#else
-static inline int pm_genpd_alloc_states_names(struct generic_pm_domain *genpd,
-					const struct genpd_power_state *st,
-					unsigned int st_count)
-{
-	return 0;
-}
 #endif /* CONFIG_PM_ADVANCED_DEBUG */
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 57ee8d8..24621be 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -44,6 +44,12 @@ struct gpd_cpuidle_data {
 	struct cpuidle_state *idle_state;
 };
 
+/* Arbitrary max number of devices registering a special
+ * retention state with the PD, to keep things simple.
+ */
+#define GENPD_POWER_STATES_MAX 12
+#define GENPD_MAX_NAME_SIZE    40
+
 struct genpd_power_state {
 	char *name;
 	s64 power_off_latency_ns;
@@ -77,7 +83,7 @@ struct generic_pm_domain {
 	void (*detach_dev)(struct generic_pm_domain *domain,
 			   struct device *dev);
 	unsigned int flags;		/* Bit field of configs for genpd */
-	struct genpd_power_state *states;
+	struct genpd_power_state states[GENPD_POWER_STATES_MAX];
 	unsigned int state_count; /* number of states */
 	unsigned int state_idx; /* state that genpd will go to when off */
 	bool irq_safe;
@@ -154,6 +160,8 @@ extern void pm_genpd_init_simple(struct generic_pm_domain *genpd,
 extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
 extern int pm_genpd_name_poweron(const char *domain_name);
 extern void pm_genpd_poweroff_unused(void);
+extern int pm_genpd_insert_state(struct generic_pm_domain *genpd,
+	const struct genpd_power_state *state);
 
 extern struct dev_power_governor simple_qos_governor;
 extern struct dev_power_governor pm_domain_always_on_gov;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1257054 — [RFC v3 2/7] PM / Domains: support idle-states as genpd multiple-state.

FromMarc Titinger <mtitinger@baylibre.com>
Date2015-10-27 18:50 +0100
Subject[RFC v3 2/7] PM / Domains: support idle-states as genpd multiple-state.
Message-ID<qogxI-87V-41@gated-at.bofh.it>
In reply to#1257037
From: Marc Titinger <mtitinger@baylibre.com>

This patch allows cluster-level idle-states to being soaked in as generic
domain power states, in order for the domain governor to chose the most
efficient power state compatible with the device constraints. Similarly,
devices can register power-states into the cluster domain, in a manner
consistent with idle-states.

This is a attempt to address device-retention states for devices that
are not hooked to runtime-pm, but feature a retention state handled by
the same firmware that handles idle-states. For instance a L2 caches.

With Juno, in this example the idle-state 'cluster-sleep-0 ' is known from
each cluster generic domain, as the deepest sate.

cat /sys/kernel/debug/pm_genpd/*

  Domain             State name        Enter (ns) / Exit (ns)
-------------------------------------------------------------
a53_pd               cluster-sleep-0      1500000 / 800000
a57_pd               cluster-sleep-0      1500000 / 800000

    domain                      status pstate     slaves
           /device                                      runtime status
-----------------------------------------------------------------------
a53_pd                          on
    /devices/system/cpu/cpu0                            active
    /devices/system/cpu/cpu3                            suspended
    /devices/system/cpu/cpu4                            suspended
    /devices/system/cpu/cpu5                            suspended
    /devices/platform/D1                                suspended
a57_pd                          cluster-sleep-0
    /devices/system/cpu/cpu1                            suspended
    /devices/system/cpu/cpu2                            suspended

Signed-off-by: Marc Titinger <mtitinger+renesas@baylibre.com>
---
 .../devicetree/bindings/power/power_domain.txt     |  29 ++++++
 drivers/base/power/domain.c                        | 102 ++++++++++++++++++++-
 include/linux/pm_domain.h                          |   3 +
 3 files changed, 131 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
index 025b5e7..2657e19 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -29,6 +29,16 @@ Optional properties:
    specified by this binding. More details about power domain specifier are
    available in the next section.
 
+ - cpu-idle-states : a phandle of an idle-state that shall be soaked into a
+		  generic domain power state.
+   CPU domains: Deep c-states that match a cluster power-off can be delegated to the
+   generic power domain. Device other than CPUs may have register intermediate
+   power states in the same domain. The domain governor can do a good job in
+   electing a power state when the last cpu is powered off as devices in the
+   same genpd may register intermediate states.
+   Devices : a device may register an intermediate c-state matching a memory
+   retention feature for instance.
+
 Example:
 
 	power: power-controller@12340000 {
@@ -55,6 +65,25 @@ Example 2:
 		#power-domain-cells = <1>;
 	};
 
+Example 3:
+
+        pm-domains {
+                a57_pd: a57_pd@ {
+                        /* will have a57 platform ARM_PD_METHOD_OF_DECLARE*/
+                        compatible = "arm,pd","arm,cortex-a57";
+                        #power-domain-cells = <0>;
+                        cpu-idle-states = <&CLUSTER_SLEEP_0>;
+                };
+
+                a53_pd: a53_pd@ {
+                        /* will have a a53 platform ARM_PD_METHOD_OF_DECLARE*/
+                        compatible = "arm,pd","arm,cortex-a53";
+                        #power-domain-cells = <0>;
+                        cpu-idle-states = <&CLUSTER_SLEEP_0>;
+                };
+        };
+
+
 The nodes above define two power controllers: 'parent' and 'child'.
 Domains created by the 'child' power controller are subdomains of '0' power
 domain provided by the 'parent' power controller.
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 6b2d771..8512e28 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1345,7 +1345,8 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 	else {
 		dev_pm_qos_add_notifier(dev, &gpd_data->nb);
 		atomic_inc(&genpd->usage_count);
-		printk("Add device %d\n", atomic_read(&genpd->usage_count));
+		dev_info(dev, "Add device %d\n",
+					atomic_read(&genpd->usage_count));
 	}
 	return ret;
 }
@@ -1592,7 +1593,7 @@ static int state_cmp(const void *a, const void *b)
 int pm_genpd_insert_state(struct generic_pm_domain *genpd,
 		const struct genpd_power_state *state)
 {
-	int ret = 0;
+	int i, ret = 0;
 	int state_count = genpd->state_count;
 
 	if (IS_ERR_OR_NULL(genpd) || (!state))
@@ -1601,11 +1602,18 @@ int pm_genpd_insert_state(struct generic_pm_domain *genpd,
 	if (state_count >= GENPD_POWER_STATES_MAX)
 		ret = -ENOMEM;
 
+	/* Bail out, this state was already registered.*/
+	for (i = 0; i < state_count; i++)
+		if (!strncmp(state->name, genpd->states[i].name,
+			GENPD_MAX_NAME_SIZE))
+			return 0;
+
 #ifdef CONFIG_PM_ADVANCED_DEBUG
 	/* to save memory, Name allocation will happen if debug is enabled */
 	genpd->states[state_count].name = kstrndup(state->name,
 			GENPD_MAX_NAME_SIZE,
 			GFP_KERNEL);
+
 	if (!genpd->states[state_count].name) {
 		pr_err("%s Failed to allocate state '%s' name.\n",
 				genpd->name, state->name);
@@ -1963,6 +1971,93 @@ static void genpd_dev_pm_sync(struct device *dev)
 	genpd_queue_power_off_work(pd);
 }
 
+
+static int dt_cpuidle_to_genpd_power_state(struct genpd_power_state
+					   *genpd_state,
+					   struct device_node *state_node)
+{
+	int err = 0;
+	u32 latency;
+
+	err = of_property_read_u32(state_node, "wakeup-latency-us", &latency);
+	if (err) {
+		u32 entry_latency, exit_latency;
+
+		err = of_property_read_u32(state_node, "entry-latency-us",
+					   &entry_latency);
+		if (err) {
+			pr_debug(" * %s missing entry-latency-us property\n",
+				 state_node->full_name);
+			return -EINVAL;
+		}
+
+		err = of_property_read_u32(state_node, "exit-latency-us",
+					   &exit_latency);
+		if (err) {
+			pr_debug(" * %s missing exit-latency-us property\n",
+				 state_node->full_name);
+			return -EINVAL;
+		}
+		/*
+		 * If wakeup-latency-us is missing, default to entry+exit
+		 * latencies as defined in idle states bindings
+		 */
+		latency = entry_latency + exit_latency;
+	}
+
+	genpd_state->power_on_latency_ns = 1000 * latency;
+
+	err = of_property_read_u32(state_node, "entry-latency-us", &latency);
+	if (err) {
+		pr_debug(" * %s missing min-residency-us property\n",
+			 state_node->full_name);
+		return -EINVAL;
+	}
+
+	genpd_state->power_off_latency_ns = 1000 * latency;
+
+	return 0;
+}
+
+int of_genpd_device_parse_states(struct device_node *np,
+				 struct generic_pm_domain *genpd)
+{
+	struct device_node *state_node;
+	int i, err = 0;
+
+	for (i = 0;; i++) {
+		struct genpd_power_state genpd_state;
+
+		state_node = of_parse_phandle(np, "domain-idle-states", i);
+		if (!state_node)
+			break;
+
+		err = dt_cpuidle_to_genpd_power_state(&genpd_state,
+						      state_node);
+		if (err) {
+			pr_err
+			    ("Parsing idle state node %s failed with err %d\n",
+			     state_node->full_name, err);
+			err = -EINVAL;
+			break;
+		}
+#ifdef CONFIG_PM_ADVANCED_DEBUG
+		genpd_state.name = kstrndup(state_node->name,
+					    GENPD_MAX_NAME_SIZE, GFP_KERNEL);
+		if (!genpd_state.name)
+			err = -ENOMEM;
+#endif
+		of_node_put(state_node);
+		err = pm_genpd_insert_state(genpd, &genpd_state);
+		if (err)
+			break;
+#ifdef CONFIG_PM_ADVANCED_DEBUG
+		kfree(genpd_state.name);
+#endif
+	}
+	return err;
+}
+
 /**
  * genpd_dev_pm_attach - Attach a device to its PM domain using DT.
  * @dev: Device to attach.
@@ -1996,7 +2091,6 @@ int genpd_dev_pm_attach(struct device *dev)
 	if (ret < 0) {
 		if (ret != -ENOENT)
 			return ret;
-
 		/*
 		 * Try legacy Samsung-specific bindings
 		 * (for backwards compatibility of DT ABI)
@@ -2034,6 +2128,8 @@ int genpd_dev_pm_attach(struct device *dev)
 		goto out;
 	}
 
+	of_genpd_device_parse_states(pd_args.np, pd);
+
 	dev->pm_domain->detach = genpd_dev_pm_detach;
 	dev->pm_domain->sync = genpd_dev_pm_sync;
 	ret = genpd_poweron(pd);
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 24621be..48ab3b1 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -248,6 +248,9 @@ struct generic_pm_domain *__of_genpd_xlate_onecell(
 					struct of_phandle_args *genpdspec,
 					void *data);
 
+int of_genpd_device_parse_states(struct device_node *np,
+	struct generic_pm_domain *genpd);
+
 int genpd_dev_pm_attach(struct device *dev);
 #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
 static inline int __of_genpd_add_provider(struct device_node *np,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1257058 — [RFC v3 5/7] drivers: cpu-pd: allow calling of_cpu_pd_init from platform code.

FromMarc Titinger <mtitinger@baylibre.com>
Date2015-10-27 18:50 +0100
Subject[RFC v3 5/7] drivers: cpu-pd: allow calling of_cpu_pd_init from platform code.
Message-ID<qogxJ-87V-51@gated-at.bofh.it>
In reply to#1257037
From: Marc Titinger <mtitinger@baylibre.com>

re-instate a two step init, first register the CPU-power domains, then
attach the CPUs, because CPU ordering does not match cluster/PD boundaries.

Signed-off-by: Marc Titinger <mtitinger+renesas@baylibre.com>
---
 drivers/base/power/cpu-pd.c | 29 ++++++++++++-----------------
 include/linux/cpu-pd.h      |  2 ++
 2 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/drivers/base/power/cpu-pd.c b/drivers/base/power/cpu-pd.c
index eddee98..701a68f 100644
--- a/drivers/base/power/cpu-pd.c
+++ b/drivers/base/power/cpu-pd.c
@@ -8,8 +8,6 @@
  * published by the Free Software Foundation.
  */
 
-#define DEBUG
-
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/cpu.h>
@@ -160,8 +158,6 @@ static int cpu_hotplug(struct notifier_block *nb,
 int of_register_cpu_pm_domain(struct device_node *dn,
 		struct cpu_pm_domain *pd)
 {
-	int ret;
-
 	if (!pd || !pd->genpd)
 		return -EINVAL;
 
@@ -187,14 +183,6 @@ int of_register_cpu_pm_domain(struct device_node *dn,
 	pm_genpd_init_simple(pd->genpd, &simple_qos_governor, false);
 	of_genpd_add_provider_simple(dn, pd->genpd);
 
-	/* Attach the CPUs to the CPU PM domain */
-	ret = of_pm_domain_attach_cpus();
-	if (ret) {
-		of_genpd_del_provider(dn);
-		return ret;
-	}
-
-	hotcpu_notifier(cpu_hotplug, 0)
 	return 0;
 }
 EXPORT_SYMBOL(of_register_cpu_pm_domain);
@@ -245,21 +233,28 @@ int of_init_cpu_pm_domain(struct device_node *dn, struct cpu_pm_ops *ops)
 EXPORT_SYMBOL(of_init_cpu_pm_domain);
 
 
-static int __init of_cpu_pd_init(void)
+int __init of_cpu_pd_init(const char *compatible)
 {
 	struct device_node *dn;
 	int ret;
 
-	for_each_compatible_node(dn, NULL, "cpu,pd") {
+	if (!compatible)
+		return -EINVAL;
+
+	for_each_compatible_node(dn, NULL, compatible) {
 
 		if (!of_device_is_available(dn))
 			continue;
 
 		ret = of_init_cpu_pm_domain(dn, NULL);
-		if (!ret)
+		if (ret)
 			return ret;
 
 	}
-	return 0;
+
+	ret = of_pm_domain_attach_cpus();
+	if (!ret)
+		hotcpu_notifier(cpu_hotplug, 0);
+
+	return ret;
 }
-device_initcall(of_cpu_pd_init);
diff --git a/include/linux/cpu-pd.h b/include/linux/cpu-pd.h
index 9ae6f5b..f3066d0 100644
--- a/include/linux/cpu-pd.h
+++ b/include/linux/cpu-pd.h
@@ -32,4 +32,6 @@ extern int of_register_cpu_pm_domain(struct device_node *dn,
 extern int of_init_cpu_pm_domain(struct device_node *dn,
 		struct cpu_pm_ops *ops);
 
+extern int __init of_cpu_pd_init(const char *compatible);
+
 #endif /* __CPU_PD_H__ */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1257063 — [RFC v3 4/7] arm64: Juno: declare generic power domains for both clusters.

FromMarc Titinger <mtitinger@baylibre.com>
Date2015-10-27 18:50 +0100
Subject[RFC v3 4/7] arm64: Juno: declare generic power domains for both clusters.
Message-ID<qogxJ-87V-61@gated-at.bofh.it>
In reply to#1257037
From: Marc Titinger <mtitinger@baylibre.com>

Signed-off-by: Marc Titinger <mtitinger+renesas@baylibre.com>
---
 arch/arm64/boot/dts/arm/juno.dts | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
index b3fcee8..0a72c07 100644
--- a/arch/arm64/boot/dts/arm/juno.dts
+++ b/arch/arm64/boot/dts/arm/juno.dts
@@ -91,6 +91,7 @@
 			next-level-cache = <&A57_L2>;
 			clocks = <&scpi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			power-domains = <&a57_pd>;
 		};
 
 		A57_1: cpu@1 {
@@ -101,6 +102,7 @@
 			next-level-cache = <&A57_L2>;
 			clocks = <&scpi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			power-domains = <&a57_pd>;
 		};
 
 		A53_0: cpu@100 {
@@ -111,6 +113,7 @@
 			next-level-cache = <&A53_L2>;
 			clocks = <&scpi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			power-domains = <&a53_pd>;
 		};
 
 		A53_1: cpu@101 {
@@ -121,6 +124,7 @@
 			next-level-cache = <&A53_L2>;
 			clocks = <&scpi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			power-domains = <&a53_pd>;
 		};
 
 		A53_2: cpu@102 {
@@ -131,6 +135,7 @@
 			next-level-cache = <&A53_L2>;
 			clocks = <&scpi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			power-domains = <&a53_pd>;
 		};
 
 		A53_3: cpu@103 {
@@ -141,6 +146,7 @@
 			next-level-cache = <&A53_L2>;
 			clocks = <&scpi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			power-domains = <&a53_pd>;
 		};
 
 		A57_L2: l2-cache0 {
@@ -152,6 +158,19 @@
 		};
 	};
 
+	CPU_PD: cpu-domains {
+
+		a57_pd: a57_pd@ {
+			compatible = "arm,cpu-pd";
+			#power-domain-cells = <0>;
+		};
+
+		a53_pd: a53_pd@ {
+			compatible = "arm,cpu-pd";
+			#power-domain-cells = <0>;
+		};
+	};
+
 	pmu_a57 {
 		compatible = "arm,cortex-a57-pmu";
 		interrupts = <GIC_SPI 02 IRQ_TYPE_LEVEL_HIGH>,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1257065 — [RFC v3 7/7] arm64: Juno: declare idle-state cluster-sleep-0 as genpd state

FromMarc Titinger <mtitinger@baylibre.com>
Date2015-10-27 18:50 +0100
Subject[RFC v3 7/7] arm64: Juno: declare idle-state cluster-sleep-0 as genpd state
Message-ID<qogxJ-87V-65@gated-at.bofh.it>
In reply to#1257037
From: Marc Titinger <mtitinger@baylibre.com>

Using Juno to exercise the code that prepares for OS-initiated idle-state
handling, using genpd platform callbacks. In opposition to platform-
initiated mode as currently with pcsi/ATF.

Signed-off-by: Marc Titinger <mtitinger+renesas@baylibre.com>
---
 arch/arm64/boot/dts/arm/juno.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
index 0a72c07..f42d5f9 100644
--- a/arch/arm64/boot/dts/arm/juno.dts
+++ b/arch/arm64/boot/dts/arm/juno.dts
@@ -163,11 +163,13 @@
 		a57_pd: a57_pd@ {
 			compatible = "arm,cpu-pd";
 			#power-domain-cells = <0>;
+			domain-idle-states = <&CLUSTER_SLEEP_0>;
 		};
 
 		a53_pd: a53_pd@ {
 			compatible = "arm,cpu-pd";
 			#power-domain-cells = <0>;
+			domain-idle-states = <&CLUSTER_SLEEP_0>;
 		};
 	};
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web