12
12
#include <zephyr/kernel.h>
13
13
#include <zephyr/drivers/clock_control.h>
14
14
#include <zephyr/logging/log.h>
15
+ #include <zephyr/pm/device.h>
16
+ #include <zephyr/pm/policy.h>
15
17
16
18
#include <driverlib/clkctl.h>
17
19
#include <inc/hw_lgpt.h>
23
25
24
26
LOG_MODULE_REGISTER (counter_cc23x0_lgpt , CONFIG_COUNTER_LOG_LEVEL );
25
27
28
+ #define LGPT_CLK_PRESCALE (pres ) (((pres) + 1) << 8)
29
+
26
30
static void counter_cc23x0_lgpt_isr (const struct device * dev );
27
31
28
32
struct counter_cc23x0_lgpt_config {
29
33
struct counter_config_info counter_info ;
30
34
uint32_t base ;
35
+ uint32_t clk_idx ;
31
36
uint32_t prescale ;
32
37
};
33
38
@@ -36,6 +41,22 @@ struct counter_cc23x0_lgpt_data {
36
41
struct counter_top_cfg target_cfg ;
37
42
};
38
43
44
+ static inline void lgpt_cc23x0_pm_policy_state_lock_get (void )
45
+ {
46
+ #ifdef CONFIG_PM_DEVICE
47
+ pm_policy_state_lock_get (PM_STATE_RUNTIME_IDLE , PM_ALL_SUBSTATES );
48
+ pm_policy_state_lock_get (PM_STATE_STANDBY , PM_ALL_SUBSTATES );
49
+ #endif
50
+ }
51
+
52
+ static inline void lgpt_cc23x0_pm_policy_state_lock_put (void )
53
+ {
54
+ #ifdef CONFIG_PM_DEVICE
55
+ pm_policy_state_lock_put (PM_STATE_STANDBY , PM_ALL_SUBSTATES );
56
+ pm_policy_state_lock_put (PM_STATE_RUNTIME_IDLE , PM_ALL_SUBSTATES );
57
+ #endif
58
+ }
59
+
39
60
static int counter_cc23x0_lgpt_get_value (const struct device * dev , uint32_t * ticks )
40
61
{
41
62
const struct counter_cc23x0_lgpt_config * config = dev -> config ;
@@ -221,6 +242,8 @@ static int counter_cc23x0_lgpt_start(const struct device *dev)
221
242
{
222
243
const struct counter_cc23x0_lgpt_config * config = dev -> config ;
223
244
245
+ lgpt_cc23x0_pm_policy_state_lock_get ();
246
+
224
247
LOG_DBG ("[START] LGPT base[%x]\n" , config -> base );
225
248
226
249
HWREG (config -> base + LGPT_O_CTL ) = LGPT_CTL_MODE_UP_PER ;
@@ -240,9 +263,41 @@ static int counter_cc23x0_lgpt_stop(const struct device *dev)
240
263
/* Set to 0 to stop timer */
241
264
HWREG (config -> base + LGPT_O_STARTCFG ) = 0x0 ;
242
265
266
+ lgpt_cc23x0_pm_policy_state_lock_put ();
267
+
243
268
return 0 ;
244
269
}
245
270
271
+ static void counter_cc23x0_lgpt_init_common (const struct device * dev )
272
+ {
273
+ const struct counter_cc23x0_lgpt_config * config = dev -> config ;
274
+
275
+ HWREG (config -> base + LGPT_O_TGT ) = config -> counter_info .max_top_value ;
276
+ HWREG (config -> base + LGPT_O_PRECFG ) = LGPT_CLK_PRESCALE (config -> prescale );
277
+ HWREG (EVTSVT_BASE + EVTSVT_O_LGPTSYNCSEL ) = EVTSVT_LGPTSYNCSEL_PUBID_SYSTIM0 ;
278
+ }
279
+
280
+ #ifdef CONFIG_PM_DEVICE
281
+
282
+ static int lgpt_cc23x0_pm_action (const struct device * dev , enum pm_device_action action )
283
+ {
284
+ const struct counter_cc23x0_lgpt_config * config = dev -> config ;
285
+
286
+ switch (action ) {
287
+ case PM_DEVICE_ACTION_SUSPEND :
288
+ CLKCTLDisable (CLKCTL_BASE , config -> clk_idx );
289
+ return 0 ;
290
+ case PM_DEVICE_ACTION_RESUME :
291
+ CLKCTLEnable (CLKCTL_BASE , config -> clk_idx );
292
+ counter_cc23x0_lgpt_init_common (dev );
293
+ return 0 ;
294
+ default :
295
+ return - ENOTSUP ;
296
+ }
297
+ }
298
+
299
+ #endif /* CONFIG_PM_DEVICE */
300
+
246
301
static DEVICE_API (counter , cc23x0_lgpt_api ) = {
247
302
.start = counter_cc23x0_lgpt_start ,
248
303
.stop = counter_cc23x0_lgpt_stop ,
@@ -255,48 +310,51 @@ static DEVICE_API(counter, cc23x0_lgpt_api) = {
255
310
.get_freq = counter_cc23x0_lgpt_get_freq ,
256
311
};
257
312
258
- #define LGPT_CLK_PRESCALE (pres ) ((pres + 1) << 8)
259
-
260
- #define LGPT_CC23X0_INIT_FUNC (inst ) \
261
- static int counter_cc23x0_lgpt_init##inst(const struct device *dev) \
262
- { \
263
- const struct counter_cc23x0_lgpt_config *config = dev->config; \
264
- \
265
- CLKCTLEnable(CLKCTL_BASE, CLKCTL_LGPT##inst); \
266
- \
267
- IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \
268
- counter_cc23x0_lgpt_isr, DEVICE_DT_INST_GET(inst), 0); \
269
- \
270
- irq_enable(DT_INST_IRQN(inst)); \
271
- \
272
- HWREG(config->base + LGPT_O_TGT) = config->counter_info.max_top_value; \
273
- \
274
- HWREG(config->base + LGPT_O_PRECFG) = LGPT_CLK_PRESCALE(config->prescale); \
275
- \
276
- HWREG(EVTSVT_BASE + EVTSVT_O_LGPTSYNCSEL) = EVTSVT_LGPTSYNCSEL_PUBID_SYSTIM0; \
277
- \
278
- return 0; \
313
+ #define LGPT_CC23X0_INIT_FUNC (inst ) \
314
+ static int counter_cc23x0_lgpt_init##inst(const struct device *dev) \
315
+ { \
316
+ const struct counter_cc23x0_lgpt_config *config = dev->config; \
317
+ \
318
+ CLKCTLEnable(CLKCTL_BASE, config->clk_idx); \
319
+ \
320
+ IRQ_CONNECT(DT_INST_IRQN(inst), \
321
+ DT_INST_IRQ(inst, priority), \
322
+ counter_cc23x0_lgpt_isr, \
323
+ DEVICE_DT_INST_GET(inst), \
324
+ 0); \
325
+ \
326
+ irq_enable(DT_INST_IRQN(inst)); \
327
+ \
328
+ counter_cc23x0_lgpt_init_common(dev); \
329
+ \
330
+ return 0; \
279
331
}
280
332
281
- #define CC23X0_LGPT_INIT (inst ) \
282
- \
283
- LGPT_CC23X0_INIT_FUNC(inst); \
284
- \
285
- static const struct counter_cc23x0_lgpt_config cc23x0_lgpt_config_##inst = { \
286
- .counter_info = \
287
- { \
288
- .max_top_value = DT_INST_PROP(inst, max_top_value), \
289
- .flags = COUNTER_CONFIG_INFO_COUNT_UP, \
290
- .channels = 3, \
291
- }, \
292
- .base = DT_INST_REG_ADDR(inst), \
293
- .prescale = DT_INST_PROP(inst, clk_prescale), \
294
- }; \
295
- \
296
- static struct counter_cc23x0_lgpt_data cc23x0_lgpt_data_##inst; \
297
- \
298
- DEVICE_DT_INST_DEFINE(inst, &counter_cc23x0_lgpt_init##inst, NULL, \
299
- &cc23x0_lgpt_data_##inst, &cc23x0_lgpt_config_##inst, POST_KERNEL, \
300
- CONFIG_COUNTER_INIT_PRIORITY, &cc23x0_lgpt_api);
333
+ #define CC23X0_LGPT_INIT (inst ) \
334
+ \
335
+ LGPT_CC23X0_INIT_FUNC(inst); \
336
+ PM_DEVICE_DT_INST_DEFINE(inst, lgpt_cc23x0_pm_action); \
337
+ \
338
+ static const struct counter_cc23x0_lgpt_config cc23x0_lgpt_config_##inst = { \
339
+ .counter_info = { \
340
+ .max_top_value = DT_INST_PROP(inst, max_top_value), \
341
+ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \
342
+ .channels = 3, \
343
+ }, \
344
+ .base = DT_INST_REG_ADDR(inst), \
345
+ .clk_idx = CLKCTL_LGPT##inst, \
346
+ .prescale = DT_INST_PROP(inst, clk_prescale), \
347
+ }; \
348
+ \
349
+ static struct counter_cc23x0_lgpt_data cc23x0_lgpt_data_##inst; \
350
+ \
351
+ DEVICE_DT_INST_DEFINE(inst, \
352
+ &counter_cc23x0_lgpt_init##inst, \
353
+ PM_DEVICE_DT_INST_GET(inst), \
354
+ &cc23x0_lgpt_data_##inst, \
355
+ &cc23x0_lgpt_config_##inst, \
356
+ POST_KERNEL, \
357
+ CONFIG_COUNTER_INIT_PRIORITY, \
358
+ &cc23x0_lgpt_api);
301
359
302
360
DT_INST_FOREACH_STATUS_OKAY (CC23X0_LGPT_INIT );
0 commit comments