From 79bca830b790d91c36003608ad299f05d8872283 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 24 Sep 2025 16:49:54 +0300 Subject: [PATCH] modem: modem_cellular: Allow PPP interface to wake up the device Allow PPP device to wake up the underlying cellular modem. Signed-off-by: Seppo Takalo --- drivers/modem/modem_cellular.c | 26 ++++++++++++------------- include/zephyr/modem/ppp.h | 35 ++++++++++++++++++++++++++++++---- subsys/modem/Kconfig | 1 + subsys/modem/modem_ppp.c | 17 +++++++++++++++-- 4 files changed, 60 insertions(+), 19 deletions(-) diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 939cd2927c389..3e5a4c4fcdba5 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -2916,7 +2916,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &modem_cellular_api); #define MODEM_CELLULAR_DEVICE_QUECTEL_BG9X(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -2936,7 +2936,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &quectel_bg9x_shutdown_chat_script) #define MODEM_CELLULAR_DEVICE_QUECTEL_EG25_G(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -2955,7 +2955,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &quectel_eg25_g_periodic_chat_script, NULL) #define MODEM_CELLULAR_DEVICE_QUECTEL_EG800Q(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -2974,7 +2974,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &quectel_eg800q_periodic_chat_script, NULL) #define MODEM_CELLULAR_DEVICE_SIMCOM_SIM7080(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -2993,7 +2993,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &simcom_sim7080_periodic_chat_script, NULL) #define MODEM_CELLULAR_DEVICE_SIMCOM_A76XX(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -3013,7 +3013,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &simcom_a76xx_shutdown_chat_script) #define MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -3032,7 +3032,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &u_blox_sara_r4_periodic_chat_script, NULL) #define MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R5(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -3051,7 +3051,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &u_blox_sara_r5_periodic_chat_script, NULL) #define MODEM_CELLULAR_DEVICE_U_BLOX_LARA_R6(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -3071,7 +3071,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, NULL) #define MODEM_CELLULAR_DEVICE_SWIR_HL7800(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -3090,7 +3090,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &swir_hl7800_periodic_chat_script, NULL) #define MODEM_CELLULAR_DEVICE_TELIT_ME910G1(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -3109,7 +3109,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, NULL) #define MODEM_CELLULAR_DEVICE_TELIT_ME310G1(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ @@ -3128,7 +3128,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &telit_me310g1_shutdown_chat_script) #define MODEM_CELLULAR_DEVICE_NORDIC_NRF91_SLM(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 1500); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 1500); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r\n", \ @@ -3145,7 +3145,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, &nordic_nrf91_slm_periodic_chat_script, NULL) #define MODEM_CELLULAR_DEVICE_SQN_GM02S(inst) \ - MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ + MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \ \ static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ .chat_delimiter = "\r", \ diff --git a/include/zephyr/modem/ppp.h b/include/zephyr/modem/ppp.h index 2b91e51a35c99..b3dbcfdeb7fb3 100644 --- a/include/zephyr/modem/ppp.h +++ b/include/zephyr/modem/ppp.h @@ -123,6 +123,10 @@ struct modem_ppp { #endif }; +struct modem_ppp_config { + const struct device *dev; +}; + /** * @endcond */ @@ -172,13 +176,17 @@ int modem_ppp_init_internal(const struct device *dev); * network device instance, and binds the modem_ppp instance to the PPP L2 * instance. * + * If underlying cellular device is given, the PPP interface will manage the + * power state of the cellular device when starting and stopping the PPP. + * + * @param _dev Cellular device instance for power management or NULL if not used * @param _name Name of the statically defined modem_ppp instance * @param _init_iface Hook for the PPP L2 network interface init function * @param _prio Initialization priority of the PPP L2 net iface * @param _mtu Max size of net_pkt data sent and received on PPP L2 net iface * @param _buf_size Size of partial PPP frame transmit and receive buffers */ -#define MODEM_PPP_DEFINE(_name, _init_iface, _prio, _mtu, _buf_size) \ +#define MODEM_DEV_PPP_DEFINE(_dev, _name, _init_iface, _prio, _mtu, _buf_size) \ extern const struct ppp_api modem_ppp_ppp_api; \ \ static uint8_t _CONCAT(_name, _receive_buf)[_buf_size]; \ @@ -189,11 +197,30 @@ int modem_ppp_init_internal(const struct device *dev); .receive_buf = _CONCAT(_name, _receive_buf), \ .transmit_buf = _CONCAT(_name, _transmit_buf), \ .buf_size = _buf_size, \ + }; \ + static const struct modem_ppp_config _CONCAT(_name, _config) = { \ + .dev = _dev, \ }; \ \ - NET_DEVICE_INIT(_CONCAT(ppp_net_dev_, _name), "modem_ppp_" # _name, \ - modem_ppp_init_internal, NULL, &_name, NULL, _prio, &modem_ppp_ppp_api, \ - PPP_L2, NET_L2_GET_CTX_TYPE(PPP_L2), _mtu) + NET_DEVICE_INIT(_CONCAT(ppp_net_dev_, _name), "modem_ppp_" #_name, \ + modem_ppp_init_internal, NULL, &_name, &_CONCAT(_name, _config), _prio, \ + &modem_ppp_ppp_api, PPP_L2, NET_L2_GET_CTX_TYPE(PPP_L2), _mtu) + +/** + * @brief Define a modem PPP module for cellular device tree instance. + * + * @see MODEM_DEV_PPP_DEFINE + */ +#define MODEM_DT_INST_PPP_DEFINE(inst, _name, _init_iface, _prio, _mtu, _buf_size) \ + MODEM_DEV_PPP_DEFINE(DEVICE_DT_INST_GET(inst), _name, _init_iface, _prio, _mtu, _buf_size) + +/** + * @brief Define a modem PPP module without a device and bind it to a network interface. + * + * @see MODEM_DEV_PPP_DEFINE + */ +#define MODEM_PPP_DEFINE(_name, _init_iface, _prio, _mtu, _buf_size) \ + MODEM_DEV_PPP_DEFINE(NULL, _name, _init_iface, _prio, _mtu, _buf_size) /** * @} diff --git a/subsys/modem/Kconfig b/subsys/modem/Kconfig index b7c3f7ba9014c..087b4d79be8c7 100644 --- a/subsys/modem/Kconfig +++ b/subsys/modem/Kconfig @@ -71,6 +71,7 @@ config MODEM_PPP select MODEM_PIPE select RING_BUFFER select CRC + select PM_DEVICE_RUNTIME_ASYNC if PM_DEVICE_RUNTIME if MODEM_PPP diff --git a/subsys/modem/modem_ppp.c b/subsys/modem/modem_ppp.c index 537f198251f7b..9e2e2b5d71b7c 100644 --- a/subsys/modem/modem_ppp.c +++ b/subsys/modem/modem_ppp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -445,12 +446,24 @@ static void modem_ppp_ppp_api_init(struct net_if *iface) static int modem_ppp_ppp_api_start(const struct device *dev) { - return 0; + const struct modem_ppp_config *config = (const struct modem_ppp_config *)dev->config; + + if (config == NULL || config->dev == NULL) { + return 0; + } + + return pm_device_runtime_get(config->dev); } static int modem_ppp_ppp_api_stop(const struct device *dev) { - return 0; + const struct modem_ppp_config *config = (const struct modem_ppp_config *)dev->config; + + if (config == NULL || config->dev == NULL) { + return 0; + } + + return pm_device_runtime_put_async(config->dev, K_NO_WAIT); } static int modem_ppp_ppp_api_send(const struct device *dev, struct net_pkt *pkt)