Skip to content

Commit d910aa6

Browse files
Ramakrishna Pallalanashif
authored andcommitted
samples: power: Add test for device Idle PM
Added test for Device Idle Power Management to invoke device_pm_get/put API's. Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
1 parent 6b21e1b commit d910aa6

File tree

9 files changed

+336
-0
lines changed

9 files changed

+336
-0
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@
228228
/samples/net/sockets/ @jukkar @tbursztyka @pfalcon
229229
/samples/sensor/ @bogdan-davidoaia
230230
/samples/subsys/usb/ @jfischer-phytec-iot @finikorg
231+
/samples/subsys/power/ @ramakrishnapallala @pizi-nordic
231232
/scripts/coccicheck @himanshujha199640 @JuliaLawall
232233
/scripts/coccinelle/ @himanshujha199640 @JuliaLawall
233234
/scripts/elf_helper.py @andrewboie
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
cmake_minimum_required(VERSION 3.13.1)
2+
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
3+
project(device)
4+
5+
FILE(GLOB app_sources src/*.c)
6+
target_sources(app PRIVATE ${app_sources})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CONFIG_SYS_POWER_MANAGEMENT=y
2+
CONFIG_DEVICE_POWER_MANAGEMENT=y
3+
CONFIG_DEVICE_IDLE_PM=y
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
sample:
2+
name: Device Idle Power Management
3+
tests:
4+
ospm.dev_idle_pm:
5+
platform_whitelist: nrf52840_pca10056 nrf52_pca10040
6+
tags: power
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* Copyright (c) 2018 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <misc/printk.h>
8+
#include "dummy_parent.h"
9+
#include "dummy_driver.h"
10+
11+
static struct k_poll_event async_evt;
12+
u32_t device_power_state;
13+
static struct device *parent;
14+
15+
static int dummy_open(struct device *dev)
16+
{
17+
int ret;
18+
int signaled = 0, result;
19+
20+
printk("open()\n");
21+
22+
/* Make sure parent is resumed */
23+
ret = device_pm_get_sync(parent);
24+
if (ret < 0) {
25+
return ret;
26+
}
27+
28+
ret = device_pm_get(dev);
29+
if (ret < 0) {
30+
return ret;
31+
}
32+
33+
printk("Async wakeup request queued\n");
34+
35+
do {
36+
(void)k_poll(&async_evt, 1, K_FOREVER);
37+
k_poll_signal_check(&dev->config->pm->signal,
38+
&signaled, &result);
39+
} while (!signaled);
40+
41+
async_evt.state = K_POLL_STATE_NOT_READY;
42+
k_poll_signal_reset(&dev->config->pm->signal);
43+
44+
if (result == DEVICE_PM_ACTIVE_STATE) {
45+
printk("Dummy device resumed\n");
46+
ret = 0;
47+
} else {
48+
printk("Dummy device Not resumed\n");
49+
ret = -1;
50+
}
51+
52+
return ret;
53+
}
54+
55+
static int dummy_read(struct device *dev, u32_t *val)
56+
{
57+
struct dummy_parent_api *api;
58+
int ret;
59+
60+
printk("read()\n");
61+
62+
api = (struct dummy_parent_api *)parent->driver_api;
63+
ret = api->transfer(parent, DUMMY_PARENT_RD, val);
64+
return ret;
65+
}
66+
67+
static int dummy_write(struct device *dev, u32_t val)
68+
{
69+
struct dummy_parent_api *api;
70+
int ret;
71+
72+
printk("write()\n");
73+
api = (struct dummy_parent_api *)parent->driver_api;
74+
ret = api->transfer(parent, DUMMY_PARENT_WR, &val);
75+
return ret;
76+
}
77+
78+
static int dummy_close(struct device *dev)
79+
{
80+
int ret;
81+
82+
printk("close()\n");
83+
ret = device_pm_put_sync(dev);
84+
if (ret == 1) {
85+
printk("Async suspend request ququed\n");
86+
}
87+
88+
/* Parent can be suspended */
89+
if (parent) {
90+
device_pm_put(parent);
91+
}
92+
93+
return ret;
94+
}
95+
96+
static u32_t dummy_get_power_state(struct device *dev)
97+
{
98+
return device_power_state;
99+
}
100+
101+
static int dummy_suspend(struct device *dev)
102+
{
103+
printk("child suspending..\n");
104+
device_power_state = DEVICE_PM_SUSPEND_STATE;
105+
106+
return 0;
107+
}
108+
109+
static int dummy_resume_from_suspend(struct device *dev)
110+
{
111+
printk("child resuming..\n");
112+
device_power_state = DEVICE_PM_ACTIVE_STATE;
113+
114+
return 0;
115+
}
116+
117+
static int dummy_device_pm_ctrl(struct device *dev, u32_t ctrl_command,
118+
void *context, device_pm_cb cb, void *arg)
119+
{
120+
int ret = 0;
121+
122+
switch (ctrl_command) {
123+
case DEVICE_PM_SET_POWER_STATE:
124+
if (*((u32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
125+
ret = dummy_resume_from_suspend(dev);
126+
} else {
127+
ret = dummy_suspend(dev);
128+
}
129+
break;
130+
case DEVICE_PM_GET_POWER_STATE:
131+
*((u32_t *)context) = dummy_get_power_state(dev);
132+
break;
133+
default:
134+
ret = -EINVAL;
135+
136+
}
137+
138+
cb(dev, ret, context, arg);
139+
140+
return ret;
141+
}
142+
143+
static const struct dummy_driver_api funcs = {
144+
.open = dummy_open,
145+
.read = dummy_read,
146+
.write = dummy_write,
147+
.close = dummy_close,
148+
};
149+
150+
int dummy_init(struct device *dev)
151+
{
152+
parent = device_get_binding(DUMMY_PARENT_NAME);
153+
if (!parent) {
154+
printk("parent not found\n");
155+
}
156+
157+
device_pm_enable(dev);
158+
device_power_state = DEVICE_PM_ACTIVE_STATE;
159+
160+
k_poll_event_init(&async_evt, K_POLL_TYPE_SIGNAL,
161+
K_POLL_MODE_NOTIFY_ONLY, &dev->config->pm->signal);
162+
return 0;
163+
}
164+
165+
DEVICE_DEFINE(dummy_driver, DUMMY_DRIVER_NAME, &dummy_init,
166+
dummy_device_pm_ctrl, NULL, NULL, APPLICATION,
167+
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2018 Intel Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr.h>
8+
#include <device.h>
9+
#define DUMMY_DRIVER_NAME "dummy_driver"
10+
11+
typedef int (*dummy_api_open_t)(struct device *dev);
12+
13+
typedef int (*dummy_api_read_t)(struct device *dev,
14+
u32_t *val);
15+
typedef int (*dummy_api_write_t)(struct device *dev,
16+
u32_t val);
17+
typedef int (*dummy_api_close_t)(struct device *dev);
18+
19+
struct dummy_driver_api {
20+
dummy_api_open_t open;
21+
dummy_api_read_t read;
22+
dummy_api_write_t write;
23+
dummy_api_close_t close;
24+
};
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2018 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <misc/printk.h>
8+
#include "dummy_parent.h"
9+
10+
static u32_t store_value;
11+
u32_t parent_power_state;
12+
13+
static int dummy_transfer(struct device *dev, u32_t cmd, u32_t *val)
14+
{
15+
printk("transfer()\n");
16+
17+
if (cmd == DUMMY_PARENT_WR) {
18+
store_value = *val;
19+
} else {
20+
*val = store_value;
21+
}
22+
23+
return 0;
24+
}
25+
26+
static u32_t dummy_get_power_state(struct device *dev)
27+
{
28+
return parent_power_state;
29+
}
30+
31+
static int dummy_suspend(struct device *dev)
32+
{
33+
printk("parent suspending..\n");
34+
parent_power_state = DEVICE_PM_SUSPEND_STATE;
35+
36+
return 0;
37+
}
38+
39+
static int dummy_resume_from_suspend(struct device *dev)
40+
{
41+
printk("parent resuming..\n");
42+
parent_power_state = DEVICE_PM_ACTIVE_STATE;
43+
44+
return 0;
45+
}
46+
47+
static int dummy_parent_pm_ctrl(struct device *dev, u32_t ctrl_command,
48+
void *context, device_pm_cb cb, void *arg)
49+
{
50+
int ret = 0;
51+
52+
switch (ctrl_command) {
53+
case DEVICE_PM_SET_POWER_STATE:
54+
if (*((u32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
55+
ret = dummy_resume_from_suspend(dev);
56+
} else {
57+
ret = dummy_suspend(dev);
58+
}
59+
break;
60+
case DEVICE_PM_GET_POWER_STATE:
61+
*((u32_t *)context) = dummy_get_power_state(dev);
62+
break;
63+
default:
64+
ret = -EINVAL;
65+
66+
}
67+
68+
cb(dev, ret, context, arg);
69+
return ret;
70+
}
71+
72+
static const struct dummy_parent_api funcs = {
73+
.transfer = dummy_transfer,
74+
};
75+
76+
int dummy_parent_init(struct device *dev)
77+
{
78+
device_pm_enable(dev);
79+
parent_power_state = DEVICE_PM_ACTIVE_STATE;
80+
return 0;
81+
}
82+
83+
DEVICE_DEFINE(dummy_parent, DUMMY_PARENT_NAME, &dummy_parent_init,
84+
dummy_parent_pm_ctrl, NULL, NULL, POST_KERNEL,
85+
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) 2018 Intel Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr.h>
8+
#include <device.h>
9+
#define DUMMY_PARENT_NAME "dummy_parent"
10+
11+
#define DUMMY_PARENT_RD 0
12+
#define DUMMY_PARENT_WR 1
13+
14+
typedef int (*dummy_api_transfer_t)(struct device *dev, u32_t cmd, u32_t *val);
15+
16+
struct dummy_parent_api {
17+
dummy_api_transfer_t transfer;
18+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2018 Intel Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <misc/printk.h>
8+
#include "dummy_driver.h"
9+
10+
/* Application main Thread */
11+
void main(void)
12+
{
13+
struct device *dev;
14+
struct dummy_driver_api *api;
15+
int ret, val;
16+
17+
printk("Device PM sample app start\n");
18+
dev = device_get_binding(DUMMY_DRIVER_NAME);
19+
api = (struct dummy_driver_api *)dev->driver_api;
20+
ret = api->open(dev);
21+
val = 10;
22+
ret = api->write(dev, val);
23+
ret = api->read(dev, &val);
24+
ret = api->close(dev);
25+
printk("Device PM sample app complete\n");
26+
}

0 commit comments

Comments
 (0)