Merge tag 'riscv-for-linus-5.18-mw1' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Apr 2022 20:31:57 +0000 (13:31 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Apr 2022 20:31:57 +0000 (13:31 -0700)
Pull more RISC-V updates from Palmer Dabbelt:
 "This has a handful of new features:

   - Support for CURRENT_STACK_POINTER, which enables some extra stack
     debugging for HARDENED_USERCOPY.

   - Support for the new SBI CPU idle extension, via cpuidle and suspend
     drivers.

   - Profiling has been enabled in the defconfigs.

  but is mostly fixes and cleanups"

* tag 'riscv-for-linus-5.18-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (21 commits)
  RISC-V: K210 defconfigs: Drop redundant MEMBARRIER=n
  RISC-V: defconfig: Drop redundant SBI HVC and earlycon
  Documentation: riscv: remove non-existent directory from table of contents
  riscv: cpu.c: don't use kernel-doc markers for comments
  RISC-V: Enable profiling by default
  RISC-V: module: fix apply_r_riscv_rcv_branch_rela typo
  RISC-V: Declare per cpu boot data as static
  RISC-V: Fix a comment typo in riscv_of_parent_hartid()
  riscv: Increase stack size under KASAN
  riscv: Fix fill_callchain return value
  riscv: dts: canaan: Fix SPI3 bus width
  riscv: Rename "sp_in_global" to "current_stack_pointer"
  riscv module: remove (NOLOAD)
  RISC-V: Enable RISC-V SBI CPU Idle driver for QEMU virt machine
  dt-bindings: Add common bindings for ARM and RISC-V idle states
  cpuidle: Add RISC-V SBI CPU idle driver
  cpuidle: Factor-out power domain related code from PSCI domain driver
  RISC-V: Add SBI HSM suspend related defines
  RISC-V: Add arch functions for non-retentive suspend entry/exit
  RISC-V: Rename relocate() and make it global
  ...

1  2 
Documentation/devicetree/bindings/cpu/idle-states.yaml
MAINTAINERS

index 0000000,95506ff..5daa219
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,855 +1,855 @@@
 -            cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
 -                   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+ %YAML 1.2
+ ---
+ $id: http://devicetree.org/schemas/cpu/idle-states.yaml#
+ $schema: http://devicetree.org/meta-schemas/core.yaml#
+ title: Idle states binding description
+ maintainers:
+   - Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+   - Anup Patel <anup@brainfault.org>
+ description: |+
+   ==========================================
+   1 - Introduction
+   ==========================================
+   ARM and RISC-V systems contain HW capable of managing power consumption
+   dynamically, where cores can be put in different low-power states (ranging
+   from simple wfi to power gating) according to OS PM policies. The CPU states
+   representing the range of dynamic idle states that a processor can enter at
+   run-time, can be specified through device tree bindings representing the
+   parameters required to enter/exit specific idle states on a given processor.
+   ==========================================
+   2 - ARM idle states
+   ==========================================
+   According to the Server Base System Architecture document (SBSA, [3]), the
+   power states an ARM CPU can be put into are identified by the following list:
+   - Running
+   - Idle_standby
+   - Idle_retention
+   - Sleep
+   - Off
+   The power states described in the SBSA document define the basic CPU states on
+   top of which ARM platforms implement power management schemes that allow an OS
+   PM implementation to put the processor in different idle states (which include
+   states listed above; "off" state is not an idle state since it does not have
+   wake-up capabilities, hence it is not considered in this document).
+   Idle state parameters (e.g. entry latency) are platform specific and need to
+   be characterized with bindings that provide the required information to OS PM
+   code so that it can build the required tables and use them at runtime.
+   The device tree binding definition for ARM idle states is the subject of this
+   document.
+   ==========================================
+   3 - RISC-V idle states
+   ==========================================
+   On RISC-V systems, the HARTs (or CPUs) [6] can be put in platform specific
+   suspend (or idle) states (ranging from simple WFI, power gating, etc). The
+   RISC-V SBI v0.3 (or higher) [7] hart state management extension provides a
+   standard mechanism for OS to request HART state transitions.
+   The platform specific suspend (or idle) states of a hart can be either
+   retentive or non-rententive in nature. A retentive suspend state will
+   preserve HART registers and CSR values for all privilege modes whereas
+   a non-retentive suspend state will not preserve HART registers and CSR
+   values.
+   ===========================================
+   4 - idle-states definitions
+   ===========================================
+   Idle states are characterized for a specific system through a set of
+   timing and energy related properties, that underline the HW behaviour
+   triggered upon idle states entry and exit.
+   The following diagram depicts the CPU execution phases and related timing
+   properties required to enter and exit an idle state:
+   ..__[EXEC]__|__[PREP]__|__[ENTRY]__|__[IDLE]__|__[EXIT]__|__[EXEC]__..
+               |          |           |          |          |
+               |<------ entry ------->|
+               |       latency        |
+                                                 |<- exit ->|
+                                                 |  latency |
+               |<-------- min-residency -------->|
+                          |<-------  wakeup-latency ------->|
+       Diagram 1: CPU idle state execution phases
+   EXEC:  Normal CPU execution.
+   PREP:  Preparation phase before committing the hardware to idle mode
+     like cache flushing. This is abortable on pending wake-up
+     event conditions. The abort latency is assumed to be negligible
+     (i.e. less than the ENTRY + EXIT duration). If aborted, CPU
+     goes back to EXEC. This phase is optional. If not abortable,
+     this should be included in the ENTRY phase instead.
+   ENTRY:  The hardware is committed to idle mode. This period must run
+     to completion up to IDLE before anything else can happen.
+   IDLE:  This is the actual energy-saving idle period. This may last
+     between 0 and infinite time, until a wake-up event occurs.
+   EXIT:  Period during which the CPU is brought back to operational
+     mode (EXEC).
+   entry-latency: Worst case latency required to enter the idle state. The
+   exit-latency may be guaranteed only after entry-latency has passed.
+   min-residency: Minimum period, including preparation and entry, for a given
+   idle state to be worthwhile energywise.
+   wakeup-latency: Maximum delay between the signaling of a wake-up event and the
+   CPU being able to execute normal code again. If not specified, this is assumed
+   to be entry-latency + exit-latency.
+   These timing parameters can be used by an OS in different circumstances.
+   An idle CPU requires the expected min-residency time to select the most
+   appropriate idle state based on the expected expiry time of the next IRQ
+   (i.e. wake-up) that causes the CPU to return to the EXEC phase.
+   An operating system scheduler may need to compute the shortest wake-up delay
+   for CPUs in the system by detecting how long will it take to get a CPU out
+   of an idle state, e.g.:
+   wakeup-delay = exit-latency + max(entry-latency - (now - entry-timestamp), 0)
+   In other words, the scheduler can make its scheduling decision by selecting
+   (e.g. waking-up) the CPU with the shortest wake-up delay.
+   The wake-up delay must take into account the entry latency if that period
+   has not expired. The abortable nature of the PREP period can be ignored
+   if it cannot be relied upon (e.g. the PREP deadline may occur much sooner than
+   the worst case since it depends on the CPU operating conditions, i.e. caches
+   state).
+   An OS has to reliably probe the wakeup-latency since some devices can enforce
+   latency constraint guarantees to work properly, so the OS has to detect the
+   worst case wake-up latency it can incur if a CPU is allowed to enter an
+   idle state, and possibly to prevent that to guarantee reliable device
+   functioning.
+   The min-residency time parameter deserves further explanation since it is
+   expressed in time units but must factor in energy consumption coefficients.
+   The energy consumption of a cpu when it enters a power state can be roughly
+   characterised by the following graph:
+                  |
+                  |
+                  |
+              e   |
+              n   |                                      /---
+              e   |                               /------
+              r   |                        /------
+              g   |                  /-----
+              y   |           /------
+                  |       ----
+                  |      /|
+                  |     / |
+                  |    /  |
+                  |   /   |
+                  |  /    |
+                  | /     |
+                  |/      |
+             -----|-------+----------------------------------
+                 0|       1                              time(ms)
+       Graph 1: Energy vs time example
+   The graph is split in two parts delimited by time 1ms on the X-axis.
+   The graph curve with X-axis values = { x | 0 < x < 1ms } has a steep slope
+   and denotes the energy costs incurred while entering and leaving the idle
+   state.
+   The graph curve in the area delimited by X-axis values = {x | x > 1ms } has
+   shallower slope and essentially represents the energy consumption of the idle
+   state.
+   min-residency is defined for a given idle state as the minimum expected
+   residency time for a state (inclusive of preparation and entry) after
+   which choosing that state become the most energy efficient option. A good
+   way to visualise this, is by taking the same graph above and comparing some
+   states energy consumptions plots.
+   For sake of simplicity, let's consider a system with two idle states IDLE1,
+   and IDLE2:
+             |
+             |
+             |
+             |                                                  /-- IDLE1
+          e  |                                              /---
+          n  |                                         /----
+          e  |                                     /---
+          r  |                                /-----/--------- IDLE2
+          g  |                    /-------/---------
+          y  |        ------------    /---|
+             |       /           /----    |
+             |      /        /---         |
+             |     /    /----             |
+             |    / /---                  |
+             |   ---                      |
+             |  /                         |
+             | /                          |
+             |/                           |                  time
+          ---/----------------------------+------------------------
+             |IDLE1-energy < IDLE2-energy | IDLE2-energy < IDLE1-energy
+                                          |
+                                   IDLE2-min-residency
+       Graph 2: idle states min-residency example
+   In graph 2 above, that takes into account idle states entry/exit energy
+   costs, it is clear that if the idle state residency time (i.e. time till next
+   wake-up IRQ) is less than IDLE2-min-residency, IDLE1 is the better idle state
+   choice energywise.
+   This is mainly down to the fact that IDLE1 entry/exit energy costs are lower
+   than IDLE2.
+   However, the lower power consumption (i.e. shallower energy curve slope) of
+   idle state IDLE2 implies that after a suitable time, IDLE2 becomes more energy
+   efficient.
+   The time at which IDLE2 becomes more energy efficient than IDLE1 (and other
+   shallower states in a system with multiple idle states) is defined
+   IDLE2-min-residency and corresponds to the time when energy consumption of
+   IDLE1 and IDLE2 states breaks even.
+   The definitions provided in this section underpin the idle states
+   properties specification that is the subject of the following sections.
+   ===========================================
+   5 - idle-states node
+   ===========================================
+   The processor idle states are defined within the idle-states node, which is
+   a direct child of the cpus node [1] and provides a container where the
+   processor idle states, defined as device tree nodes, are listed.
+   On ARM systems, it is a container of processor idle states nodes. If the
+   system does not provide CPU power management capabilities, or the processor
+   just supports idle_standby, an idle-states node is not required.
+   ===========================================
+   6 - References
+   ===========================================
+   [1] ARM Linux Kernel documentation - CPUs bindings
+       Documentation/devicetree/bindings/arm/cpus.yaml
+   [2] ARM Linux Kernel documentation - PSCI bindings
+       Documentation/devicetree/bindings/arm/psci.yaml
+   [3] ARM Server Base System Architecture (SBSA)
+       http://infocenter.arm.com/help/index.jsp
+   [4] ARM Architecture Reference Manuals
+       http://infocenter.arm.com/help/index.jsp
+   [5] ARM Linux Kernel documentation - Booting AArch64 Linux
+       Documentation/arm64/booting.rst
+   [6] RISC-V Linux Kernel documentation - CPUs bindings
+       Documentation/devicetree/bindings/riscv/cpus.yaml
+   [7] RISC-V Supervisor Binary Interface (SBI)
+       http://github.com/riscv/riscv-sbi-doc/riscv-sbi.adoc
+ properties:
+   $nodename:
+     const: idle-states
+   entry-method:
+     description: |
+       Usage and definition depend on ARM architecture version.
+       On ARM v8 64-bit this property is required.
+       On ARM 32-bit systems this property is optional
+       This assumes that the "enable-method" property is set to "psci" in the cpu
+       node[5] that is responsible for setting up CPU idle management in the OS
+       implementation.
+     const: psci
+ patternProperties:
+   "^(cpu|cluster)-":
+     type: object
+     description: |
+       Each state node represents an idle state description and must be defined
+       as follows.
+       The idle state entered by executing the wfi instruction (idle_standby
+       SBSA,[3][4]) is considered standard on all ARM and RISC-V platforms and
+       therefore must not be listed.
+       In addition to the properties listed above, a state node may require
+       additional properties specific to the entry-method defined in the
+       idle-states node. Please refer to the entry-method bindings
+       documentation for properties definitions.
+     properties:
+       compatible:
+         enum:
+           - arm,idle-state
+           - riscv,idle-state
+       arm,psci-suspend-param:
+         $ref: /schemas/types.yaml#/definitions/uint32
+         description: |
+           power_state parameter to pass to the ARM PSCI suspend call.
+           Device tree nodes that require usage of PSCI CPU_SUSPEND function
+           (i.e. idle states node with entry-method property is set to "psci")
+           must specify this property.
+       riscv,sbi-suspend-param:
+         $ref: /schemas/types.yaml#/definitions/uint32
+         description: |
+           suspend_type parameter to pass to the RISC-V SBI HSM suspend call.
+           This property is required in idle state nodes of device tree meant
+           for RISC-V systems. For more details on the suspend_type parameter
+           refer the SBI specifiation v0.3 (or higher) [7].
+       local-timer-stop:
+         description:
+           If present the CPU local timer control logic is
+              lost on state entry, otherwise it is retained.
+         type: boolean
+       entry-latency-us:
+         description:
+           Worst case latency in microseconds required to enter the idle state.
+       exit-latency-us:
+         description:
+           Worst case latency in microseconds required to exit the idle state.
+           The exit-latency-us duration may be guaranteed only after
+           entry-latency-us has passed.
+       min-residency-us:
+         description:
+           Minimum residency duration in microseconds, inclusive of preparation
+           and entry, for this idle state to be considered worthwhile energy wise
+           (refer to section 2 of this document for a complete description).
+       wakeup-latency-us:
+         description: |
+           Maximum delay between the signaling of a wake-up event and the CPU
+           being able to execute normal code again. If omitted, this is assumed
+           to be equal to:
+             entry-latency-us + exit-latency-us
+           It is important to supply this value on systems where the duration of
+           PREP phase (see diagram 1, section 2) is non-neglibigle. In such
+           systems entry-latency-us + exit-latency-us will exceed
+           wakeup-latency-us by this duration.
+       idle-state-name:
+         $ref: /schemas/types.yaml#/definitions/string
+         description:
+           A string used as a descriptive name for the idle state.
+     additionalProperties: false
+     required:
+       - compatible
+       - entry-latency-us
+       - exit-latency-us
+       - min-residency-us
+ additionalProperties: false
+ examples:
+   - |
+     cpus {
+         #size-cells = <0>;
+         #address-cells = <2>;
+         cpu@0 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a57";
+             reg = <0x0 0x0>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
 -                   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
++            cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>,
++                    <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>;
+         };
+         cpu@1 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a57";
+             reg = <0x0 0x1>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
 -                   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
++            cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>,
++                    <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>;
+         };
+         cpu@100 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a57";
+             reg = <0x0 0x100>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
 -                   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
++            cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>,
++                    <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>;
+         };
+         cpu@101 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a57";
+             reg = <0x0 0x101>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
 -                   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
++            cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>,
++                    <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>;
+         };
+         cpu@10000 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a57";
+             reg = <0x0 0x10000>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
 -                   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
++            cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>,
++                    <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>;
+         };
+         cpu@10001 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a57";
+             reg = <0x0 0x10001>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
 -                   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
++            cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>,
++                    <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>;
+         };
+         cpu@10100 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a57";
+             reg = <0x0 0x10100>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
 -                   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
++            cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>,
++                    <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>;
+         };
+         cpu@10101 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a57";
+             reg = <0x0 0x10101>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
 -                   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
++            cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>,
++                    <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>;
+         };
+         cpu@100000000 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a53";
+             reg = <0x1 0x0>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
 -                   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
++            cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>,
++                    <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>;
+         };
+         cpu@100000001 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a53";
+             reg = <0x1 0x1>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
 -                   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
++            cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>,
++                    <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>;
+         };
+         cpu@100000100 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a53";
+             reg = <0x1 0x100>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
 -                   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
++            cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>,
++                    <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>;
+         };
+         cpu@100000101 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a53";
+             reg = <0x1 0x101>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
 -                   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
++            cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>,
++                    <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>;
+         };
+         cpu@100010000 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a53";
+             reg = <0x1 0x10000>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
 -                   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
++            cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>,
++                    <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>;
+         };
+         cpu@100010001 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a53";
+             reg = <0x1 0x10001>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
 -                   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
++            cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>,
++                    <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>;
+         };
+         cpu@100010100 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a53";
+             reg = <0x1 0x10100>;
+             enable-method = "psci";
 -            cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
 -                   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
++            cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>,
++                    <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>;
+         };
+         cpu@100010101 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a53";
+             reg = <0x1 0x10101>;
+             enable-method = "psci";
 -            cpu-idle-states = <&cpu_sleep_0_0 &cluster_sleep_0>;
++            cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>,
++                    <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>;
+         };
+         idle-states {
+             entry-method = "psci";
+             CPU_RETENTION_0_0: cpu-retention-0-0 {
+                 compatible = "arm,idle-state";
+                 arm,psci-suspend-param = <0x0010000>;
+                 entry-latency-us = <20>;
+                 exit-latency-us = <40>;
+                 min-residency-us = <80>;
+             };
+             CLUSTER_RETENTION_0: cluster-retention-0 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 arm,psci-suspend-param = <0x1010000>;
+                 entry-latency-us = <50>;
+                 exit-latency-us = <100>;
+                 min-residency-us = <250>;
+                 wakeup-latency-us = <130>;
+             };
+             CPU_SLEEP_0_0: cpu-sleep-0-0 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 arm,psci-suspend-param = <0x0010000>;
+                 entry-latency-us = <250>;
+                 exit-latency-us = <500>;
+                 min-residency-us = <950>;
+             };
+             CLUSTER_SLEEP_0: cluster-sleep-0 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 arm,psci-suspend-param = <0x1010000>;
+                 entry-latency-us = <600>;
+                 exit-latency-us = <1100>;
+                 min-residency-us = <2700>;
+                 wakeup-latency-us = <1500>;
+             };
+             CPU_RETENTION_1_0: cpu-retention-1-0 {
+                 compatible = "arm,idle-state";
+                 arm,psci-suspend-param = <0x0010000>;
+                 entry-latency-us = <20>;
+                 exit-latency-us = <40>;
+                 min-residency-us = <90>;
+             };
+             CLUSTER_RETENTION_1: cluster-retention-1 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 arm,psci-suspend-param = <0x1010000>;
+                 entry-latency-us = <50>;
+                 exit-latency-us = <100>;
+                 min-residency-us = <270>;
+                 wakeup-latency-us = <100>;
+             };
+             CPU_SLEEP_1_0: cpu-sleep-1-0 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 arm,psci-suspend-param = <0x0010000>;
+                 entry-latency-us = <70>;
+                 exit-latency-us = <100>;
+                 min-residency-us = <300>;
+                 wakeup-latency-us = <150>;
+             };
+             CLUSTER_SLEEP_1: cluster-sleep-1 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 arm,psci-suspend-param = <0x1010000>;
+                 entry-latency-us = <500>;
+                 exit-latency-us = <1200>;
+                 min-residency-us = <3500>;
+                 wakeup-latency-us = <1300>;
+             };
+         };
+     };
+   - |
+     // Example 2 (ARM 32-bit, 8-cpu system, two clusters):
+     cpus {
+         #size-cells = <0>;
+         #address-cells = <1>;
+         cpu@0 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a15";
+             reg = <0x0>;
 -            cpu-idle-states = <&cpu_sleep_0_0 &cluster_sleep_0>;
++            cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>;
+         };
+         cpu@1 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a15";
+             reg = <0x1>;
 -            cpu-idle-states = <&cpu_sleep_0_0 &cluster_sleep_0>;
++            cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>;
+         };
+         cpu@2 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a15";
+             reg = <0x2>;
 -            cpu-idle-states = <&cpu_sleep_0_0 &cluster_sleep_0>;
++            cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>;
+         };
+         cpu@3 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a15";
+             reg = <0x3>;
 -            cpu-idle-states = <&cpu_sleep_1_0 &cluster_sleep_1>;
++            cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>;
+         };
+         cpu@100 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a7";
+             reg = <0x100>;
 -            cpu-idle-states = <&cpu_sleep_1_0 &cluster_sleep_1>;
++            cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>;
+         };
+         cpu@101 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a7";
+             reg = <0x101>;
 -            cpu-idle-states = <&cpu_sleep_1_0 &cluster_sleep_1>;
++            cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>;
+         };
+         cpu@102 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a7";
+             reg = <0x102>;
 -            cpu-idle-states = <&cpu_sleep_1_0 &cluster_sleep_1>;
++            cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>;
+         };
+         cpu@103 {
+             device_type = "cpu";
+             compatible = "arm,cortex-a7";
+             reg = <0x103>;
++            cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>;
+         };
+         idle-states {
+             cpu_sleep_0_0: cpu-sleep-0-0 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 entry-latency-us = <200>;
+                 exit-latency-us = <100>;
+                 min-residency-us = <400>;
+                 wakeup-latency-us = <250>;
+             };
+             cluster_sleep_0: cluster-sleep-0 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 entry-latency-us = <500>;
+                 exit-latency-us = <1500>;
+                 min-residency-us = <2500>;
+                 wakeup-latency-us = <1700>;
+             };
+             cpu_sleep_1_0: cpu-sleep-1-0 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 entry-latency-us = <300>;
+                 exit-latency-us = <500>;
+                 min-residency-us = <900>;
+                 wakeup-latency-us = <600>;
+             };
+             cluster_sleep_1: cluster-sleep-1 {
+                 compatible = "arm,idle-state";
+                 local-timer-stop;
+                 entry-latency-us = <800>;
+                 exit-latency-us = <2000>;
+                 min-residency-us = <6500>;
+                 wakeup-latency-us = <2300>;
+             };
+         };
+     };
+   - |
+     // Example 3 (RISC-V 64-bit, 4-cpu systems, two clusters):
+     cpus {
+         #size-cells = <0>;
+         #address-cells = <1>;
+         cpu@0 {
+             device_type = "cpu";
+             compatible = "riscv";
+             reg = <0x0>;
+             riscv,isa = "rv64imafdc";
+             mmu-type = "riscv,sv48";
+             cpu-idle-states = <&CPU_RET_0_0 &CPU_NONRET_0_0
+                             &CLUSTER_RET_0 &CLUSTER_NONRET_0>;
+             cpu_intc0: interrupt-controller {
+                 #interrupt-cells = <1>;
+                 compatible = "riscv,cpu-intc";
+                 interrupt-controller;
+             };
+         };
+         cpu@1 {
+             device_type = "cpu";
+             compatible = "riscv";
+             reg = <0x1>;
+             riscv,isa = "rv64imafdc";
+             mmu-type = "riscv,sv48";
+             cpu-idle-states = <&CPU_RET_0_0 &CPU_NONRET_0_0
+                             &CLUSTER_RET_0 &CLUSTER_NONRET_0>;
+             cpu_intc1: interrupt-controller {
+                 #interrupt-cells = <1>;
+                 compatible = "riscv,cpu-intc";
+                 interrupt-controller;
+             };
+         };
+         cpu@10 {
+             device_type = "cpu";
+             compatible = "riscv";
+             reg = <0x10>;
+             riscv,isa = "rv64imafdc";
+             mmu-type = "riscv,sv48";
+             cpu-idle-states = <&CPU_RET_1_0 &CPU_NONRET_1_0
+                             &CLUSTER_RET_1 &CLUSTER_NONRET_1>;
+             cpu_intc10: interrupt-controller {
+                 #interrupt-cells = <1>;
+                 compatible = "riscv,cpu-intc";
+                 interrupt-controller;
+             };
+         };
+         cpu@11 {
+             device_type = "cpu";
+             compatible = "riscv";
+             reg = <0x11>;
+             riscv,isa = "rv64imafdc";
+             mmu-type = "riscv,sv48";
+             cpu-idle-states = <&CPU_RET_1_0 &CPU_NONRET_1_0
+                             &CLUSTER_RET_1 &CLUSTER_NONRET_1>;
+             cpu_intc11: interrupt-controller {
+                 #interrupt-cells = <1>;
+                 compatible = "riscv,cpu-intc";
+                 interrupt-controller;
+             };
+         };
+         idle-states {
+             CPU_RET_0_0: cpu-retentive-0-0 {
+                 compatible = "riscv,idle-state";
+                 riscv,sbi-suspend-param = <0x10000000>;
+                 entry-latency-us = <20>;
+                 exit-latency-us = <40>;
+                 min-residency-us = <80>;
+             };
+             CPU_NONRET_0_0: cpu-nonretentive-0-0 {
+                 compatible = "riscv,idle-state";
+                 riscv,sbi-suspend-param = <0x90000000>;
+                 entry-latency-us = <250>;
+                 exit-latency-us = <500>;
+                 min-residency-us = <950>;
+             };
+             CLUSTER_RET_0: cluster-retentive-0 {
+                 compatible = "riscv,idle-state";
+                 riscv,sbi-suspend-param = <0x11000000>;
+                 local-timer-stop;
+                 entry-latency-us = <50>;
+                 exit-latency-us = <100>;
+                 min-residency-us = <250>;
+                 wakeup-latency-us = <130>;
+             };
+             CLUSTER_NONRET_0: cluster-nonretentive-0 {
+                 compatible = "riscv,idle-state";
+                 riscv,sbi-suspend-param = <0x91000000>;
+                 local-timer-stop;
+                 entry-latency-us = <600>;
+                 exit-latency-us = <1100>;
+                 min-residency-us = <2700>;
+                 wakeup-latency-us = <1500>;
+             };
+             CPU_RET_1_0: cpu-retentive-1-0 {
+                 compatible = "riscv,idle-state";
+                 riscv,sbi-suspend-param = <0x10000010>;
+                 entry-latency-us = <20>;
+                 exit-latency-us = <40>;
+                 min-residency-us = <80>;
+             };
+             CPU_NONRET_1_0: cpu-nonretentive-1-0 {
+                 compatible = "riscv,idle-state";
+                 riscv,sbi-suspend-param = <0x90000010>;
+                 entry-latency-us = <250>;
+                 exit-latency-us = <500>;
+                 min-residency-us = <950>;
+             };
+             CLUSTER_RET_1: cluster-retentive-1 {
+                 compatible = "riscv,idle-state";
+                 riscv,sbi-suspend-param = <0x11000010>;
+                 local-timer-stop;
+                 entry-latency-us = <50>;
+                 exit-latency-us = <100>;
+                 min-residency-us = <250>;
+                 wakeup-latency-us = <130>;
+             };
+             CLUSTER_NONRET_1: cluster-nonretentive-1 {
+                 compatible = "riscv,idle-state";
+                 riscv,sbi-suspend-param = <0x91000010>;
+                 local-timer-stop;
+                 entry-latency-us = <600>;
+                 exit-latency-us = <1100>;
+                 min-residency-us = <2700>;
+                 wakeup-latency-us = <1500>;
+             };
+         };
+     };
+ ...
diff --cc MAINTAINERS
Simple merge