Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pm_idle.c add support for smp case. #13541

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 43 additions & 6 deletions Documentation/components/drivers/special/power/pm/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -229,24 +229,61 @@ All PM interfaces are declared in the file ``include/nuttx/power/pm.h``.

:param handler: The execution after PM_IDLE_DOMAIN state changed

.. c:function:: void pm_idle_unlock(void)

This function provide assist of smp pm idle work progress, for pm sequence
other cores will not release before the core hold cpus lock.
Call this function to release SMP idle cpus lock.

.. c:function:: bool pm_idle_lock(int cpu)

This function provide assist of smp pm idle work progress, for pm sequence
other cores will not release before the core hold cpus lock.
Call this function to ensure other core will not run until released.

:param cpu: The current CPU, used to update cpu_set_t

:return:
None
true, Current CPU is the first one woken from sleep, should handle system domain restore process also.
false, Current CPU is not the first one woken from sleep, should only handle cpu domain restore process.

**Assumptions:** Restore operation pm_changestate(, PM_RESTORE) will done
inside pm_idle. Handler don't have to care about it.

Callbacks
=========

.. c:typedef::pm_idle_handler_t
.. c:type:: pm_idle_handler_t

This type declare is provide for pm_idle interface.
Handle the pm low power action and execution for not SMP case.
Handle the pm low power action and execution.
Possible execution for long time because of WFI inside.

- for not SMP case.

.. code-block:: c

typedef void (*pm_idle_handler_t)(enum pm_state_e);
typedef void (*pm_idle_handler_t)(enum pm_state_e systemstate);

:param systemstate:
Indicate the new system power state.

- for SMP case.

.. code-block:: c

:param pm_state_e:
Indicate the new system power state.
typedef bool (*pm_idle_handler_t)(int cpu,
enum pm_state_e cpustate,
enum pm_state_e systemstate);

:param cpu:
Indicate the current working cpu.
:param cpustate:
Indicate the current cpu power state.
:param systemstate:
Indicate the new system power state. If not the lastcore enter idle,
systemstate always PM_RESTORE. If not PM_RESTORE, handler should
cover system pm operations.

.. c:struct:: pm_callback_s

Expand Down
3 changes: 3 additions & 0 deletions arch/arm64/src/qemu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ endif()
if(CONFIG_ARCH_USE_TEXT_HEAP)
list(APPEND SRCS qemu_textheap.c)
endif()
if(CONFIG_PM)
list(APPEND SRCS qemu_initialize.c)
endif()
target_sources(arch PRIVATE ${SRCS})
4 changes: 4 additions & 0 deletions arch/arm64/src/qemu/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ endif
ifeq ($(CONFIG_ARCH_USE_TEXT_HEAP),y)
CHIP_CSRCS += qemu_textheap.c
endif

ifeq ($(CONFIG_PM), y)
CHIP_CSRCS += qemu_initialize.c
endif
116 changes: 116 additions & 0 deletions arch/arm64/src/qemu/qemu_initialize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/****************************************************************************
* arch/arm64/src/qemu/qemu_initialize.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <nuttx/config.h>
#include <nuttx/power/pm.h>
#include <stdbool.h>

/****************************************************************************
* Public Functions
****************************************************************************/

void arm64_pminitialize(void)
{
pm_initialize();
}

#ifdef CONFIG_SMP
static bool pm_idle_handler(int cpu,
enum pm_state_e cpu_state,
enum pm_state_e system_state)
{
bool first = false;
switch (cpu_state)
{
case PM_NORMAL:
case PM_IDLE:
case PM_STANDBY:
case PM_SLEEP:

/* do cpu domain pm enter operations */

asm("NOP");

if (system_state >= PM_NORMAL)
{
switch (system_state)
{
case PM_NORMAL:
case PM_IDLE:
case PM_STANDBY:
case PM_SLEEP:

/* do system domain pm enter operations */

asm("NOP");

break;
default:
break;
}
}

pm_idle_unlock();

/* do no cross-core relative operations */

asm("WFI");

first = pm_idle_lock(cpu);
if (first)
{
/* do system domain pm leave operations */

asm("NOP");
}

/* do cpu domain pm leave operations */

asm("NOP");

break;
default:
break;
}

return first;
}
#else

static void pm_idle_handler(enum pm_state_e state)
{
switch (state)
{
default:
asm("WFI");
break;
}
}

#endif

void up_idle(void)
{
pm_idle(pm_idle_handler);
}
2 changes: 2 additions & 0 deletions drivers/power/pm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ config PM_NDOMAINS
For example, you may want to separately manage the power from the
Network domain, shutting down the network when it is not be used,
from the UI domain, shutting down the UI when it is not in use.
For SMP case, should add CONFIG_SMP_NCPU manually, or will lead to
a static assert.

config PM_PROCFS
bool "PM proc fs support"
Expand Down
Loading
Loading