lkml.org 
[lkml]   [2018]   [Mar]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 17/25] drivers: firmware: psci: Prepare to use OS initiated suspend mode
    Date
    To enable the OS initiated mode, the CPU topology needs to be described
    using the hierarchical model in DT. When used, the idle state bits for the
    CPU needs to be created by ORing the bits for CPU's selected idle state
    with the bits for CPU's PM domain (CPU's cluster) idle state.

    Let's prepare the PSCI driver to deal with this, via introducing a per CPU
    variable called domain_state and by adding internal helpers to read/write
    the value of variable.

    Cc: Lina Iyer <ilina@codeaurora.org>
    Co-developed-by: Lina Iyer <lina.iyer@linaro.org>
    Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
    ---
    drivers/firmware/psci.c | 26 ++++++++++++++++++++++----
    1 file changed, 22 insertions(+), 4 deletions(-)

    diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
    index e8f4f84..40b2b89 100644
    --- a/drivers/firmware/psci.c
    +++ b/drivers/firmware/psci.c
    @@ -87,8 +87,19 @@ static u32 psci_function_id[PSCI_FN_MAX];
    (PSCI_1_0_EXT_POWER_STATE_ID_MASK | \
    PSCI_1_0_EXT_POWER_STATE_TYPE_MASK)

    +static DEFINE_PER_CPU(u32, domain_state);
    static u32 psci_cpu_suspend_feature;

    +static inline u32 psci_get_domain_state(void)
    +{
    + return this_cpu_read(domain_state);
    +}
    +
    +static inline void psci_set_domain_state(u32 state)
    +{
    + this_cpu_write(domain_state, state);
    +}
    +
    static inline bool psci_has_ext_power_state(void)
    {
    return psci_cpu_suspend_feature &
    @@ -187,6 +198,8 @@ static int psci_cpu_on(unsigned long cpuid, unsigned long entry_point)

    fn = psci_function_id[PSCI_FN_CPU_ON];
    err = invoke_psci_fn(fn, cpuid, entry_point, 0);
    + /* Clear the domain state to start fresh. */
    + psci_set_domain_state(0);
    return psci_to_linux_errno(err);
    }

    @@ -408,15 +421,17 @@ int psci_cpu_init_idle(unsigned int cpu)
    static int psci_suspend_finisher(unsigned long index)
    {
    u32 *state = __this_cpu_read(psci_power_state);
    + u32 composite_state = state[index - 1] | psci_get_domain_state();

    - return psci_ops.cpu_suspend(state[index - 1],
    - __pa_symbol(cpu_resume));
    + return psci_ops.cpu_suspend(composite_state, __pa_symbol(cpu_resume));
    }

    int psci_cpu_suspend_enter(unsigned long index)
    {
    int ret;
    u32 *state = __this_cpu_read(psci_power_state);
    + u32 composite_state = state[index - 1] | psci_get_domain_state();
    +
    /*
    * idle state index 0 corresponds to wfi, should never be called
    * from the cpu_suspend operations
    @@ -424,11 +439,14 @@ int psci_cpu_suspend_enter(unsigned long index)
    if (WARN_ON_ONCE(!index))
    return -EINVAL;

    - if (!psci_power_state_loses_context(state[index - 1]))
    - ret = psci_ops.cpu_suspend(state[index - 1], 0);
    + if (!psci_power_state_loses_context(composite_state))
    + ret = psci_ops.cpu_suspend(composite_state, 0);
    else
    ret = cpu_suspend(index, psci_suspend_finisher);

    + /* Clear the domain state to start fresh when back from idle. */
    + psci_set_domain_state(0);
    +
    return ret;
    }

    --
    2.7.4
    \
     
     \ /
      Last update: 2018-03-14 18:02    [W:4.313 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site