Skip to content

Commit a1cd2d6

Browse files
AlessandroLuoaescolar
authored andcommitted
drivers: pm: add pm_policy_state_lock for drivers
Added pm_policy_state_lock to prevent memory power off during data transfer Signed-off-by: Hao Luo <[email protected]>
1 parent 41580bd commit a1cd2d6

File tree

3 files changed

+62
-34
lines changed

3 files changed

+62
-34
lines changed

drivers/i2c/i2c_ambiq.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,35 @@ struct i2c_ambiq_data {
4747
void *callback_data;
4848
int inst_idx;
4949
uint32_t transfer_status;
50+
bool pm_policy_state_on;
5051
};
5152

53+
static void i2c_ambiq_pm_policy_state_lock_get(const struct device *dev)
54+
{
55+
if (IS_ENABLED(CONFIG_PM)) {
56+
struct i2c_ambiq_data *data = dev->data;
57+
58+
if (!data->pm_policy_state_on) {
59+
data->pm_policy_state_on = true;
60+
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_RAM, PM_ALL_SUBSTATES);
61+
pm_device_runtime_get(dev);
62+
}
63+
}
64+
}
65+
66+
static void i2c_ambiq_pm_policy_state_lock_put(const struct device *dev)
67+
{
68+
if (IS_ENABLED(CONFIG_PM)) {
69+
struct i2c_ambiq_data *data = dev->data;
70+
71+
if (data->pm_policy_state_on) {
72+
data->pm_policy_state_on = false;
73+
pm_device_runtime_put(dev);
74+
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_RAM, PM_ALL_SUBSTATES);
75+
}
76+
}
77+
}
78+
5279
#ifdef CONFIG_I2C_AMBIQ_DMA
5380
static __aligned(32) struct {
5481
__aligned(32) uint32_t buf[CONFIG_I2C_DMA_TCB_BUFFER_SIZE];
@@ -183,17 +210,13 @@ static int i2c_ambiq_transfer(const struct device *dev, struct i2c_msg *msgs, ui
183210
uint16_t addr)
184211
{
185212
struct i2c_ambiq_data *data = dev->data;
186-
int pm_ret, ret = 0;
213+
int ret = 0;
187214

188215
if (!num_msgs) {
189216
return 0;
190217
}
191218

192-
pm_ret = pm_device_runtime_get(dev);
193-
194-
if (pm_ret < 0) {
195-
LOG_ERR("pm_device_runtime_get failed: %d", pm_ret);
196-
}
219+
i2c_ambiq_pm_policy_state_lock_get(dev);
197220

198221
/* Send out messages */
199222
k_sem_take(&data->bus_sem, K_FOREVER);
@@ -213,16 +236,7 @@ static int i2c_ambiq_transfer(const struct device *dev, struct i2c_msg *msgs, ui
213236

214237
k_sem_give(&data->bus_sem);
215238

216-
/* Use async put to avoid useless device suspension/resumption
217-
* when doing consecutive transmission.
218-
*/
219-
if (!pm_ret) {
220-
pm_ret = pm_device_runtime_put_async(dev, K_MSEC(2));
221-
222-
if (pm_ret < 0) {
223-
LOG_ERR("pm_device_runtime_put failed: %d", pm_ret);
224-
}
225-
}
239+
i2c_ambiq_pm_policy_state_lock_put(dev);
226240

227241
return ret;
228242
}

drivers/spi/spi_ambiq.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct spi_ambiq_data {
4242
void *iom_handler;
4343
int inst_idx;
4444
bool cont;
45+
bool pm_policy_state_on;
4546
};
4647

4748
typedef void (*spi_context_update_trx)(struct spi_context *ctx, uint8_t dfs, uint32_t len);
@@ -50,6 +51,32 @@ typedef void (*spi_context_update_trx)(struct spi_context *ctx, uint8_t dfs, uin
5051

5152
#define SPI_CS_INDEX 3
5253

54+
static void spi_ambiq_pm_policy_state_lock_get(const struct device *dev)
55+
{
56+
if (IS_ENABLED(CONFIG_PM)) {
57+
struct spi_ambiq_data *data = dev->data;
58+
59+
if (!data->pm_policy_state_on) {
60+
data->pm_policy_state_on = true;
61+
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_RAM, PM_ALL_SUBSTATES);
62+
pm_device_runtime_get(dev);
63+
}
64+
}
65+
}
66+
67+
static void spi_ambiq_pm_policy_state_lock_put(const struct device *dev)
68+
{
69+
if (IS_ENABLED(CONFIG_PM)) {
70+
struct spi_ambiq_data *data = dev->data;
71+
72+
if (data->pm_policy_state_on) {
73+
data->pm_policy_state_on = false;
74+
pm_device_runtime_put(dev);
75+
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_RAM, PM_ALL_SUBSTATES);
76+
}
77+
}
78+
}
79+
5380
#ifdef CONFIG_SPI_AMBIQ_DMA
5481
static __aligned(32) struct {
5582
__aligned(32) uint32_t buf[CONFIG_SPI_DMA_TCB_BUFFER_SIZE];
@@ -349,15 +376,11 @@ static int spi_ambiq_transceive(const struct device *dev, const struct spi_confi
349376
return 0;
350377
}
351378

352-
pm_ret = pm_device_runtime_get(dev);
353-
354-
if (pm_ret < 0) {
355-
LOG_ERR("pm_device_runtime_get failed: %d", pm_ret);
356-
}
357-
358379
/* context setup */
359380
spi_context_lock(&data->ctx, false, NULL, NULL, config);
360381

382+
spi_ambiq_pm_policy_state_lock_get(dev);
383+
361384
ret = spi_config(dev, config);
362385

363386
if (ret) {
@@ -370,18 +393,9 @@ static int spi_ambiq_transceive(const struct device *dev, const struct spi_confi
370393
ret = spi_ambiq_xfer(dev, config);
371394

372395
xfer_end:
373-
spi_context_release(&data->ctx, ret);
374-
375-
/* Use async put to avoid useless device suspension/resumption
376-
* when doing consecutive transmission.
377-
*/
378-
if (!pm_ret) {
379-
pm_ret = pm_device_runtime_put_async(dev, K_MSEC(2));
396+
spi_ambiq_pm_policy_state_lock_put(dev);
380397

381-
if (pm_ret < 0) {
382-
LOG_ERR("pm_device_runtime_put failed: %d", pm_ret);
383-
}
384-
}
398+
spi_context_release(&data->ctx, ret);
385399

386400
return ret;
387401
}

west.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ manifest:
147147
groups:
148148
- hal
149149
- name: hal_ambiq
150-
revision: df4a9863f87cf75dc0b4a8e47483c87363d0e8f0
150+
revision: d3092f9b82874a1791baa3ac41c3795d108fbbdb
151151
path: modules/hal/ambiq
152152
groups:
153153
- hal

0 commit comments

Comments
 (0)