stats: i2c: I2C stats
Adds the ability for I2C drivers to report synchronous transfer stats using a I2C specific macro to define the device instance. The macro creates a container for device_state which allows for per instance device class common data structure to be used in the device class api (ex: i2c.h). This is used to maintain per driver instance stats for all i2c drivers. This is a reusable idea across other device classes as desired. Using Kconfig device class stats may be turned on/off individually this way as well, in this case I2C_STATS. Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
This commit is contained in:
parent
e29d9e1e2f
commit
7b1349cfe6
|
@ -22,6 +22,12 @@ config I2C_SHELL
|
|||
|
||||
The I2C shell currently support scanning and bus recovery.
|
||||
|
||||
config I2C_STATS
|
||||
bool "Enable I2C device Stats"
|
||||
depends on STATS
|
||||
help
|
||||
Enable I2C Stats.
|
||||
|
||||
# Include these first so that any properties (e.g. defaults) below can be
|
||||
# overridden (by defining symbols in multiple locations)
|
||||
source "drivers/i2c/Kconfig.b91"
|
||||
|
|
|
@ -177,7 +177,7 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) <= 1,
|
|||
.pinctrl_list = i2c_pins_##inst \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, i2c_b91_init, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(inst, i2c_b91_init, \
|
||||
NULL, \
|
||||
&i2c_b91_data_##inst, \
|
||||
&i2c_b91_cfg_##inst, \
|
||||
|
|
|
@ -437,7 +437,7 @@ static struct i2c_cc13xx_cc26xx_data i2c_cc13xx_cc26xx_data = {
|
|||
|
||||
PM_DEVICE_DT_INST_DEFINE(0, i2c_cc13xx_cc26xx_pm_action);
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0,
|
||||
I2C_DEVICE_DT_INST_DEFINE(0,
|
||||
i2c_cc13xx_cc26xx_init,
|
||||
PM_DEVICE_DT_INST_REF(0),
|
||||
&i2c_cc13xx_cc26xx_data, &i2c_cc13xx_cc26xx_config,
|
||||
|
|
|
@ -382,7 +382,7 @@ static const struct i2c_cc32xx_config i2c_cc32xx_config = {
|
|||
|
||||
static struct i2c_cc32xx_data i2c_cc32xx_data;
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, &i2c_cc32xx_init, NULL,
|
||||
I2C_DEVICE_DT_INST_DEFINE(0, i2c_cc32xx_init, NULL,
|
||||
&i2c_cc32xx_data, &i2c_cc32xx_config,
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||
&i2c_cc32xx_driver_api);
|
||||
|
|
|
@ -728,7 +728,7 @@ static int i2c_dw_initialize(const struct device *dev)
|
|||
I2C_DW_INIT_PCIE(n) \
|
||||
}; \
|
||||
static struct i2c_dw_dev_config i2c_##n##_runtime; \
|
||||
DEVICE_DT_INST_DEFINE(n, &i2c_dw_initialize, NULL, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, i2c_dw_initialize, NULL, \
|
||||
&i2c_##n##_runtime, &i2c_config_dw_##n, \
|
||||
POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
|
||||
&funcs); \
|
||||
|
|
|
@ -153,7 +153,7 @@ static struct i2c_driver_api i2c_emul_api = {
|
|||
.num_children = ARRAY_SIZE(emuls_##n), \
|
||||
}; \
|
||||
static struct i2c_emul_data i2c_emul_data_##n; \
|
||||
DEVICE_DT_INST_DEFINE(n, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, \
|
||||
i2c_emul_init, \
|
||||
NULL, \
|
||||
&i2c_emul_data_##n, \
|
||||
|
|
|
@ -706,8 +706,8 @@ static int IRAM_ATTR i2c_esp32_init(const struct device *dev)
|
|||
.bitrate = I2C_FREQUENCY(idx), \
|
||||
.default_config = I2C_MODE_MASTER, \
|
||||
}; \
|
||||
DEVICE_DT_DEFINE(DT_NODELABEL(i2c##idx), \
|
||||
&i2c_esp32_init, \
|
||||
I2C_DEVICE_DT_DEFINE(DT_NODELABEL(i2c##idx), \
|
||||
i2c_esp32_init, \
|
||||
NULL, \
|
||||
&i2c_esp32_data_##idx, \
|
||||
&i2c_esp32_config_##idx, \
|
||||
|
|
|
@ -226,7 +226,7 @@ static const struct i2c_gecko_config i2c_gecko_config_##idx = { \
|
|||
\
|
||||
static struct i2c_gecko_data i2c_gecko_data_##idx; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(idx, &i2c_gecko_init, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(idx, i2c_gecko_init, \
|
||||
NULL, \
|
||||
&i2c_gecko_data_##idx, &i2c_gecko_config_##idx, \
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
|
||||
|
|
|
@ -182,7 +182,7 @@ static const struct i2c_gpio_config i2c_gpio_dev_cfg_##_num = { \
|
|||
.bitrate = DT_INST_PROP(_num, clock_frequency), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(_num, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(_num, \
|
||||
i2c_gpio_init, \
|
||||
NULL, \
|
||||
&i2c_gpio_dev_data_##_num, \
|
||||
|
|
|
@ -371,8 +371,8 @@ static const struct i2c_driver_api i2c_imx_driver_api = {
|
|||
\
|
||||
static struct i2c_imx_data i2c_imx_data_##n; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, \
|
||||
&i2c_imx_init, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, \
|
||||
i2c_imx_init, \
|
||||
NULL, \
|
||||
&i2c_imx_data_##n, &i2c_imx_config_##n, \
|
||||
POST_KERNEL, \
|
||||
|
|
|
@ -1065,8 +1065,8 @@ static const struct i2c_driver_api i2c_it8xxx2_driver_api = {
|
|||
\
|
||||
static struct i2c_it8xxx2_data i2c_it8xxx2_data_##idx; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(idx, \
|
||||
&i2c_it8xxx2_init, NULL, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(idx, \
|
||||
i2c_it8xxx2_init, NULL, \
|
||||
&i2c_it8xxx2_data_##idx, \
|
||||
&i2c_it8xxx2_cfg_##idx, POST_KERNEL, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
|
||||
|
|
|
@ -124,7 +124,7 @@ static const struct i2c_driver_api i2c_litex_driver_api = {
|
|||
\
|
||||
static struct i2c_bitbang i2c_bitbang_##n; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, \
|
||||
i2c_litex_init, \
|
||||
NULL, \
|
||||
&i2c_bitbang_##n, \
|
||||
|
|
|
@ -343,7 +343,7 @@ static const struct i2c_stm32_config i2c_stm32_cfg_##name = { \
|
|||
\
|
||||
static struct i2c_stm32_data i2c_stm32_dev_data_##name; \
|
||||
\
|
||||
DEVICE_DT_DEFINE(DT_NODELABEL(name), &i2c_stm32_init, \
|
||||
I2C_DEVICE_DT_DEFINE(DT_NODELABEL(name), i2c_stm32_init, \
|
||||
NULL, &i2c_stm32_dev_data_##name, \
|
||||
&i2c_stm32_cfg_##name, \
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
|
||||
|
|
|
@ -401,8 +401,8 @@ static const struct lpc11u6x_i2c_config i2c_cfg_##idx = { \
|
|||
\
|
||||
static struct lpc11u6x_i2c_data i2c_data_##idx; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(idx, \
|
||||
&lpc11u6x_i2c_init, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(idx, \
|
||||
lpc11u6x_i2c_init, \
|
||||
NULL, \
|
||||
&i2c_data_##idx, &i2c_cfg_##idx, \
|
||||
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, \
|
||||
|
|
|
@ -1163,7 +1163,7 @@ static int i2c_xec_init(const struct device *dev)
|
|||
.pcr_bitpos = DT_INST_PROP_BY_IDX(n, pcrs, 1), \
|
||||
.irq_config_func = i2c_xec_irq_config_func_##n, \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(n, &i2c_xec_init, NULL, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, i2c_xec_init, NULL, \
|
||||
&i2c_xec_data_##n, &i2c_xec_config_##n, \
|
||||
POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
|
||||
&i2c_xec_driver_api); \
|
||||
|
|
|
@ -230,8 +230,8 @@ static const struct i2c_driver_api i2c_mcux_driver_api = {
|
|||
\
|
||||
static struct i2c_mcux_data i2c_mcux_data_ ## n; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, \
|
||||
&i2c_mcux_init, NULL, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, \
|
||||
i2c_mcux_init, NULL, \
|
||||
&i2c_mcux_data_ ## n, \
|
||||
&i2c_mcux_config_ ## n, POST_KERNEL, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
|
||||
|
|
|
@ -225,8 +225,8 @@ static const struct i2c_driver_api mcux_flexcomm_driver_api = {
|
|||
.bitrate = DT_INST_PROP(id, clock_frequency), \
|
||||
}; \
|
||||
static struct mcux_flexcomm_data mcux_flexcomm_data_##id; \
|
||||
DEVICE_DT_INST_DEFINE(id, \
|
||||
&mcux_flexcomm_init, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(id, \
|
||||
mcux_flexcomm_init, \
|
||||
NULL, \
|
||||
&mcux_flexcomm_data_##id, \
|
||||
&mcux_flexcomm_config_##id, \
|
||||
|
|
|
@ -260,7 +260,7 @@ static const struct i2c_driver_api mcux_lpi2c_driver_api = {
|
|||
\
|
||||
static struct mcux_lpi2c_data mcux_lpi2c_data_##n; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, &mcux_lpi2c_init, NULL, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, mcux_lpi2c_init, NULL, \
|
||||
&mcux_lpi2c_data_##n, \
|
||||
&mcux_lpi2c_config_##n, POST_KERNEL, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
|
||||
|
|
|
@ -165,7 +165,7 @@ static struct i2c_nios2_config i2c_nios2_cfg = {
|
|||
},
|
||||
};
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, &i2c_nios2_init, NULL,
|
||||
I2C_DEVICE_DT_INST_DEFINE(0, i2c_nios2_init, NULL,
|
||||
NULL, &i2c_nios2_cfg,
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||
&i2c_nios2_driver_api);
|
||||
|
|
|
@ -962,7 +962,7 @@ static int i2c_ctrl_init(const struct device *dev)
|
|||
\
|
||||
static struct i2c_ctrl_data i2c_ctrl_data_##inst; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(inst, \
|
||||
NPCX_I2C_CTRL_INIT_FUNC(inst), \
|
||||
NULL, \
|
||||
&i2c_ctrl_data_##inst, &i2c_ctrl_cfg_##inst, \
|
||||
|
|
|
@ -287,7 +287,7 @@ static int twi_nrfx_pm_action(const struct device *dev,
|
|||
} \
|
||||
}; \
|
||||
PM_DEVICE_DT_DEFINE(I2C(idx), twi_nrfx_pm_action); \
|
||||
DEVICE_DT_DEFINE(I2C(idx), \
|
||||
I2C_DEVICE_DT_DEFINE(I2C(idx), \
|
||||
twi_##idx##_init, \
|
||||
PM_DEVICE_DT_REF(I2C(idx)), \
|
||||
&twi_##idx##_data, \
|
||||
|
|
|
@ -372,7 +372,7 @@ static int twim_nrfx_pm_action(const struct device *dev,
|
|||
.flash_buf_max_size = FLASH_BUF_MAX_SIZE(idx), \
|
||||
}; \
|
||||
PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action); \
|
||||
DEVICE_DT_DEFINE(I2C(idx), \
|
||||
I2C_DEVICE_DT_DEFINE(I2C(idx), \
|
||||
twim_##idx##_init, \
|
||||
PM_DEVICE_DT_REF(I2C(idx)), \
|
||||
&twim_##idx##_data, \
|
||||
|
|
|
@ -367,7 +367,7 @@ static const struct i2c_driver_api i2c_rcar_driver_api = {
|
|||
\
|
||||
static struct i2c_rcar_data i2c_rcar_data_##n; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, \
|
||||
i2c_rcar_init, \
|
||||
NULL, \
|
||||
&i2c_rcar_data_##n, \
|
||||
|
|
|
@ -264,8 +264,8 @@ static const struct i2c_driver_api rv32m1_lpi2c_driver_api = {
|
|||
.completion_sync = Z_SEM_INITIALIZER( \
|
||||
rv32m1_lpi2c_##id##_data.completion_sync, 0, 1), \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(id, \
|
||||
&rv32m1_lpi2c_init, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(id, \
|
||||
rv32m1_lpi2c_init, \
|
||||
NULL, \
|
||||
&rv32m1_lpi2c_##id##_data, \
|
||||
&rv32m1_lpi2c_##id##_config, \
|
||||
|
|
|
@ -807,8 +807,8 @@ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \
|
|||
static void i2c_sam0_irq_config_##n(const struct device *dev); \
|
||||
I2C_SAM0_CONFIG(n); \
|
||||
static struct i2c_sam0_dev_data i2c_sam0_dev_data_##n; \
|
||||
DEVICE_DT_INST_DEFINE(n, \
|
||||
&i2c_sam0_initialize, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, \
|
||||
i2c_sam0_initialize, \
|
||||
NULL, \
|
||||
&i2c_sam0_dev_data_##n, \
|
||||
&i2c_sam0_dev_config_##n, POST_KERNEL, \
|
||||
|
|
|
@ -628,7 +628,7 @@ static const struct i2c_driver_api i2c_sam_twim_driver_api = {
|
|||
\
|
||||
static struct i2c_sam_twim_dev_data i2c##n##_sam_data; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, &i2c_sam_twim_initialize, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, i2c_sam_twim_initialize, \
|
||||
NULL, \
|
||||
&i2c##n##_sam_data, &i2c##n##_sam_config, \
|
||||
POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
|
||||
|
|
|
@ -360,7 +360,7 @@ static const struct i2c_driver_api i2c_sam_twi_driver_api = {
|
|||
\
|
||||
static struct i2c_sam_twi_dev_data i2c##n##_sam_data; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, &i2c_sam_twi_initialize, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, i2c_sam_twi_initialize, \
|
||||
NULL, \
|
||||
&i2c##n##_sam_data, &i2c##n##_sam_config, \
|
||||
POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
|
||||
|
|
|
@ -347,7 +347,7 @@ static const struct i2c_driver_api i2c_sam_twihs_driver_api = {
|
|||
\
|
||||
static struct i2c_sam_twihs_dev_data i2c##n##_sam_data; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, &i2c_sam_twihs_initialize, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, i2c_sam_twihs_initialize, \
|
||||
NULL, \
|
||||
&i2c##n##_sam_data, &i2c##n##_sam_config, \
|
||||
POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
|
||||
|
|
|
@ -116,7 +116,7 @@ static const struct i2c_sbcon_config i2c_sbcon_dev_cfg_##_num = { \
|
|||
.sbcon = (void *)DT_INST_REG_ADDR(_num), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(_num, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(_num, \
|
||||
i2c_sbcon_init, \
|
||||
NULL, \
|
||||
&i2c_sbcon_dev_data_##_num, \
|
||||
|
|
|
@ -329,7 +329,7 @@ static struct i2c_driver_api i2c_sifive_api = {
|
|||
.f_sys = DT_INST_PROP(n, input_frequency), \
|
||||
.f_bus = DT_INST_PROP(n, clock_frequency), \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(n, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, \
|
||||
i2c_sifive_init, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
|
|
|
@ -158,7 +158,7 @@ const struct i2c_driver_api tca9546a_api_funcs = {
|
|||
static struct tca9546a_root_data tca9546a_data_##inst = { \
|
||||
.lock = Z_MUTEX_INITIALIZER(tca9546a_data_##inst.lock), \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(inst, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(inst, \
|
||||
tca9546_root_init, NULL, \
|
||||
&tca9546a_data_##inst, &tca9546a_cfg_##inst, \
|
||||
POST_KERNEL, CONFIG_I2C_TCA9546_ROOT_INIT_PRIO, \
|
||||
|
|
|
@ -38,7 +38,7 @@ static int vnd_i2c_init(const struct device *dev)
|
|||
}
|
||||
|
||||
#define VND_I2C_INIT(n) \
|
||||
DEVICE_DT_INST_DEFINE(n, &vnd_i2c_init, NULL, \
|
||||
I2C_DEVICE_DT_INST_DEFINE(n, vnd_i2c_init, NULL, \
|
||||
NULL, NULL, POST_KERNEL, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
|
||||
&vnd_i2c_api);
|
||||
|
|
|
@ -92,6 +92,31 @@ typedef int16_t device_handle_t;
|
|||
DEVICE_DEFINE(Z_SYS_NAME(init_fn), drv_name, init_fn, NULL, \
|
||||
NULL, NULL, level, prio, NULL)
|
||||
|
||||
/* Node paths can exceed the maximum size supported by device_get_binding() in user mode,
|
||||
* so synthesize a unique dev_name from the devicetree node.
|
||||
*
|
||||
* The ordinal used in this name can be mapped to the path by
|
||||
* examining zephyr/include/generated/device_extern.h header. If the
|
||||
* format of this conversion changes, gen_defines should be updated to
|
||||
* match it.
|
||||
*/
|
||||
#define Z_DEVICE_DT_DEV_NAME(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
|
||||
|
||||
/* Synthesize a unique name for the device state associated with
|
||||
* dev_name.
|
||||
*/
|
||||
#define Z_DEVICE_STATE_NAME(dev_name) _CONCAT(__devstate_, dev_name)
|
||||
|
||||
/**
|
||||
* @brief Utility macro to define and initialize the device state.
|
||||
*
|
||||
* @param node_id Devicetree node id of the device.
|
||||
* @param dev_name Device name.
|
||||
*/
|
||||
#define Z_DEVICE_STATE_DEFINE(node_id, dev_name) \
|
||||
static struct device_state Z_DEVICE_STATE_NAME(dev_name) \
|
||||
__attribute__((__section__(".z_devstate")));
|
||||
|
||||
/**
|
||||
* @def DEVICE_DEFINE
|
||||
*
|
||||
|
@ -129,9 +154,11 @@ typedef int16_t device_handle_t;
|
|||
*/
|
||||
#define DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_device, \
|
||||
data_ptr, cfg_ptr, level, prio, api_ptr) \
|
||||
Z_DEVICE_STATE_DEFINE(DT_INVALID_NODE, dev_name) \
|
||||
Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_name, drv_name, init_fn, \
|
||||
pm_device, \
|
||||
data_ptr, cfg_ptr, level, prio, api_ptr)
|
||||
data_ptr, cfg_ptr, level, prio, api_ptr, \
|
||||
&Z_DEVICE_STATE_NAME(dev_name))
|
||||
|
||||
/**
|
||||
* @def DEVICE_DT_NAME
|
||||
|
@ -187,11 +214,14 @@ typedef int16_t device_handle_t;
|
|||
#define DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
|
||||
data_ptr, cfg_ptr, level, prio, \
|
||||
api_ptr, ...) \
|
||||
Z_DEVICE_STATE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id)) \
|
||||
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
|
||||
DEVICE_DT_NAME(node_id), init_fn, \
|
||||
pm_device, \
|
||||
data_ptr, cfg_ptr, level, prio, \
|
||||
api_ptr, __VA_ARGS__)
|
||||
api_ptr, \
|
||||
&Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_NAME(node_id)), \
|
||||
__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @def DEVICE_DT_INST_DEFINE
|
||||
|
@ -693,21 +723,6 @@ static inline bool device_is_ready(const struct device *dev)
|
|||
* @}
|
||||
*/
|
||||
|
||||
/* Node paths can exceed the maximum size supported by device_get_binding() in user mode,
|
||||
* so synthesize a unique dev_name from the devicetree node.
|
||||
*
|
||||
* The ordinal used in this name can be mapped to the path by
|
||||
* examining zephyr/include/generated/device_extern.h header. If the
|
||||
* format of this conversion changes, gen_defines should be updated to
|
||||
* match it.
|
||||
*/
|
||||
#define Z_DEVICE_DT_DEV_NAME(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
|
||||
|
||||
/* Synthesize a unique name for the device state associated with
|
||||
* dev_name.
|
||||
*/
|
||||
#define Z_DEVICE_STATE_NAME(dev_name) _CONCAT(__devstate_, dev_name)
|
||||
|
||||
/** Synthesize the name of the object that holds device ordinal and
|
||||
* dependency data. If the object doesn't come from a devicetree
|
||||
* node, use dev_name.
|
||||
|
@ -735,8 +750,7 @@ static inline bool device_is_ready(const struct device *dev)
|
|||
* include power management and dependency handles.
|
||||
*/
|
||||
#define Z_DEVICE_DEFINE_PRE(node_id, dev_name, ...) \
|
||||
Z_DEVICE_DEFINE_HANDLES(node_id, dev_name, __VA_ARGS__) \
|
||||
Z_DEVICE_STATE_DEFINE(node_id, dev_name)
|
||||
Z_DEVICE_DEFINE_HANDLES(node_id, dev_name, __VA_ARGS__)
|
||||
|
||||
/* Initial build provides a record that associates the device object
|
||||
* with its devicetree ordinal, and provides the dependency ordinals.
|
||||
|
@ -805,7 +819,7 @@ BUILD_ASSERT(sizeof(device_handle_t) == 2, "fix the linker scripts");
|
|||
* dependency handles that come from outside devicetree.
|
||||
*/
|
||||
#define Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, pm_device,\
|
||||
data_ptr, cfg_ptr, level, prio, api_ptr, ...) \
|
||||
data_ptr, cfg_ptr, level, prio, api_ptr, state_ptr, ...) \
|
||||
Z_DEVICE_DEFINE_PRE(node_id, dev_name, __VA_ARGS__) \
|
||||
COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
|
||||
const Z_DECL_ALIGN(struct device) \
|
||||
|
@ -814,7 +828,7 @@ BUILD_ASSERT(sizeof(device_handle_t) == 2, "fix the linker scripts");
|
|||
.name = drv_name, \
|
||||
.config = (cfg_ptr), \
|
||||
.api = (api_ptr), \
|
||||
.state = &Z_DEVICE_STATE_NAME(dev_name), \
|
||||
.state = (state_ptr), \
|
||||
.data = (data_ptr), \
|
||||
COND_CODE_1(CONFIG_PM_DEVICE, (.pm = pm_device,), ()) \
|
||||
Z_DEVICE_DEFINE_INIT(node_id, dev_name) \
|
||||
|
|
|
@ -337,6 +337,163 @@ struct i2c_slave_config {
|
|||
const struct i2c_slave_callbacks *callbacks;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_I2C_STATS) || defined(__DOXYGEN__)
|
||||
|
||||
#include <stats/stats.h>
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
|
||||
STATS_SECT_START(i2c)
|
||||
STATS_SECT_ENTRY32(bytes_read)
|
||||
STATS_SECT_ENTRY32(bytes_written)
|
||||
STATS_SECT_ENTRY32(message_count)
|
||||
STATS_SECT_ENTRY32(transfer_call_count)
|
||||
STATS_SECT_END;
|
||||
|
||||
STATS_NAME_START(i2c)
|
||||
STATS_NAME(i2c, bytes_read)
|
||||
STATS_NAME(i2c, bytes_written)
|
||||
STATS_NAME(i2c, message_count)
|
||||
STATS_NAME(i2c, transfer_call_count)
|
||||
STATS_NAME_END(i2c);
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/**
|
||||
* @brief I2C specific device state which allows for i2c device class specific additions
|
||||
*/
|
||||
struct i2c_device_state {
|
||||
struct device_state devstate;
|
||||
struct stats_i2c stats;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Updates the i2c stats for i2c transfers
|
||||
*
|
||||
* @param dev I2C device to update stats for
|
||||
* @param msgs Array of struct i2c_msg
|
||||
* @param num_msgs Number of i2c_msgs
|
||||
*/
|
||||
static inline void i2c_xfer_stats(const struct device *dev, struct i2c_msg *msgs,
|
||||
uint8_t num_msgs)
|
||||
{
|
||||
struct i2c_device_state *state =
|
||||
CONTAINER_OF(dev->state, struct i2c_device_state, devstate);
|
||||
uint32_t bytes_read = 0U;
|
||||
uint32_t bytes_written = 0U;
|
||||
|
||||
STATS_INC(state->stats, transfer_call_count);
|
||||
STATS_INCN(state->stats, message_count, num_msgs);
|
||||
for (uint8_t i = 0U; i < num_msgs; i++) {
|
||||
if (msgs[i].flags & I2C_MSG_READ) {
|
||||
bytes_read += msgs[i].len;
|
||||
}
|
||||
if (msgs[i].flags & I2C_MSG_WRITE) {
|
||||
bytes_written += msgs[i].len;
|
||||
}
|
||||
}
|
||||
STATS_INCN(state->stats, bytes_read, bytes_read);
|
||||
STATS_INCN(state->stats, bytes_written, bytes_written);
|
||||
}
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
|
||||
/**
|
||||
* @brief Define a statically allocated and section assigned i2c device state
|
||||
*/
|
||||
#define Z_I2C_DEVICE_STATE_DEFINE(node_id, dev_name) \
|
||||
static struct i2c_device_state Z_DEVICE_STATE_NAME(dev_name) \
|
||||
__attribute__((__section__(".z_devstate")));
|
||||
|
||||
/**
|
||||
* @brief Define an i2c device init wrapper function
|
||||
*
|
||||
* This does device instance specific initialization of common data (such as stats)
|
||||
* and calls the given init_fn
|
||||
*/
|
||||
#define Z_I2C_INIT_FN(dev_name, init_fn) \
|
||||
static inline int UTIL_CAT(dev_name, _init)(const struct device *dev) \
|
||||
{ \
|
||||
struct i2c_device_state *state = \
|
||||
CONTAINER_OF(dev->state, struct i2c_device_state, devstate); \
|
||||
stats_init(&state->stats.s_hdr, STATS_SIZE_32, 4, \
|
||||
STATS_NAME_INIT_PARMS(i2c)); \
|
||||
stats_register(dev->name, &(state->stats.s_hdr)); \
|
||||
return init_fn(dev); \
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @brief Like DEVICE_DT_DEFINE() with I2C specifics.
|
||||
*
|
||||
* @details Defines a device which implements the I2C API. May
|
||||
* generate a custom device_state container struct and init_fn
|
||||
* wrapper when needed depending on I2C @kconfig{CONFIG_I2C_STATS}.
|
||||
*
|
||||
* @param node_id The devicetree node identifier.
|
||||
*
|
||||
* @param init_fn Name of the init function of the driver.
|
||||
*
|
||||
* @param pm_device PM device resources reference (NULL if device does not use PM).
|
||||
*
|
||||
* @param data_ptr Pointer to the device's private data.
|
||||
*
|
||||
* @param cfg_ptr The address to the structure containing the
|
||||
* configuration information for this instance of the driver.
|
||||
*
|
||||
* @param level The initialization level. See SYS_INIT() for
|
||||
* details.
|
||||
*
|
||||
* @param prio Priority within the selected initialization level. See
|
||||
* SYS_INIT() for details.
|
||||
*
|
||||
* @param api_ptr Provides an initial pointer to the API function struct
|
||||
* used by the driver. Can be NULL.
|
||||
*/
|
||||
#define I2C_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
|
||||
data_ptr, cfg_ptr, level, prio, \
|
||||
api_ptr, ...) \
|
||||
Z_I2C_DEVICE_STATE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id)); \
|
||||
Z_I2C_INIT_FN(Z_DEVICE_DT_DEV_NAME(node_id), init_fn) \
|
||||
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
|
||||
DEVICE_DT_NAME(node_id), \
|
||||
&UTIL_CAT(Z_DEVICE_DT_DEV_NAME(node_id), _init), \
|
||||
pm_device, \
|
||||
data_ptr, cfg_ptr, level, prio, \
|
||||
api_ptr, \
|
||||
&(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_NAME(node_id)).devstate), \
|
||||
__VA_ARGS__)
|
||||
|
||||
#else /* CONFIG_I2C_STATS */
|
||||
|
||||
static inline void i2c_xfer_stats(const struct device *dev, struct i2c_msg *msgs,
|
||||
uint8_t num_msgs)
|
||||
{
|
||||
}
|
||||
|
||||
#define I2C_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
|
||||
data_ptr, cfg_ptr, level, prio, \
|
||||
api_ptr, ...) \
|
||||
DEVICE_DT_DEFINE(node_id, &init_fn, pm_device, \
|
||||
data_ptr, cfg_ptr, level, prio, \
|
||||
api_ptr, __VA_ARGS__)
|
||||
|
||||
#endif /* CONFIG_I2C_STATS */
|
||||
|
||||
/**
|
||||
* @brief Like I2C_DEVICE_DT_DEFINE() for an instance of a DT_DRV_COMPAT compatible
|
||||
*
|
||||
* @param inst instance number. This is replaced by
|
||||
* <tt>DT_DRV_COMPAT(inst)</tt> in the call to I2C_DEVICE_DT_DEFINE().
|
||||
*
|
||||
* @param ... other parameters as expected by I2C_DEVICE_DT_DEFINE().
|
||||
*/
|
||||
#define I2C_DEVICE_DT_INST_DEFINE(inst, ...) \
|
||||
I2C_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure operation of a host controller.
|
||||
*
|
||||
|
@ -429,7 +586,11 @@ static inline int z_impl_i2c_transfer(const struct device *dev,
|
|||
const struct i2c_driver_api *api =
|
||||
(const struct i2c_driver_api *)dev->api;
|
||||
|
||||
return api->transfer(dev, msgs, num_msgs, addr);
|
||||
int res = api->transfer(dev, msgs, num_msgs, addr);
|
||||
|
||||
i2c_xfer_stats(dev, msgs, num_msgs);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -828,9 +828,10 @@ static inline bool net_eth_get_vlan_status(struct net_if *iface)
|
|||
#if defined(CONFIG_NET_VLAN)
|
||||
#define Z_ETH_NET_DEVICE_INIT(node_id, dev_name, drv_name, init_fn, \
|
||||
pm_action_cb, data, cfg, prio, api, mtu) \
|
||||
Z_DEVICE_STATE_DEFINE(node_id, dev_name) \
|
||||
Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, \
|
||||
pm_action_cb, data, cfg, POST_KERNEL, \
|
||||
prio, api); \
|
||||
prio, api, &Z_DEVICE_STATE_NAME(dev_name)); \
|
||||
NET_L2_DATA_INIT(dev_name, 0, NET_L2_GET_CTX_TYPE(ETHERNET_L2));\
|
||||
NET_IF_INIT(dev_name, 0, ETHERNET_L2, mtu, NET_VLAN_MAX_COUNT)
|
||||
|
||||
|
|
|
@ -2250,9 +2250,11 @@ struct net_if_api {
|
|||
#define Z_NET_DEVICE_INIT(node_id, dev_name, drv_name, init_fn, \
|
||||
pm_action_cb, data, cfg, prio, api, l2, \
|
||||
l2_ctx_type, mtu) \
|
||||
Z_DEVICE_STATE_DEFINE(node_id, dev_name) \
|
||||
Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, \
|
||||
pm_action_cb, data, \
|
||||
cfg, POST_KERNEL, prio, api); \
|
||||
cfg, POST_KERNEL, prio, api, \
|
||||
&Z_DEVICE_STATE_NAME(dev_name)); \
|
||||
NET_L2_DATA_INIT(dev_name, 0, l2_ctx_type); \
|
||||
NET_IF_INIT(dev_name, 0, l2, mtu, NET_IF_MAX_CONFIGS)
|
||||
|
||||
|
@ -2328,9 +2330,10 @@ struct net_if_api {
|
|||
instance, init_fn, pm_action_cb, \
|
||||
data, cfg, prio, api, l2, \
|
||||
l2_ctx_type, mtu) \
|
||||
Z_DEVICE_STATE_DEFINE(node_id, dev_name) \
|
||||
Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, \
|
||||
pm_action_cb, data, cfg, POST_KERNEL, \
|
||||
prio, api); \
|
||||
prio, api, &Z_DEVICE_STATE_NAME(dev_name)); \
|
||||
NET_L2_DATA_INIT(dev_name, instance, l2_ctx_type); \
|
||||
NET_IF_INIT(dev_name, instance, l2, mtu, NET_IF_MAX_CONFIGS)
|
||||
|
||||
|
@ -2417,8 +2420,10 @@ struct net_if_api {
|
|||
#define Z_NET_DEVICE_OFFLOAD_INIT(node_id, dev_name, drv_name, init_fn, \
|
||||
pm_action_cb, data, cfg, prio, \
|
||||
api, mtu) \
|
||||
Z_DEVICE_STATE_DEFINE(node_id, dev_name) \
|
||||
Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, \
|
||||
pm_action_cb, data, cfg, POST_KERNEL, prio, api);\
|
||||
pm_action_cb, data, cfg, POST_KERNEL, prio, api, \
|
||||
&Z_DEVICE_STATE_NAME(dev_name)); \
|
||||
NET_IF_OFFLOAD_INIT(dev_name, 0, mtu)
|
||||
|
||||
/**
|
||||
|
|
|
@ -373,7 +373,7 @@ struct stats_hdr *stats_group_find(const char *name);
|
|||
#define STATS_NAME_MAP_NAME(sectname__) stats_map_ ## sectname__
|
||||
|
||||
#define STATS_NAME_START(sectname__) \
|
||||
const struct stats_name_map STATS_NAME_MAP_NAME(sectname__)[] = {
|
||||
static const struct stats_name_map STATS_NAME_MAP_NAME(sectname__)[] = {
|
||||
|
||||
#define STATS_NAME(sectname__, entry__) \
|
||||
{ offsetof(STATS_SECT_DECL(sectname__), entry__), #entry__ },
|
||||
|
|
Loading…
Reference in a new issue