drivers: can: add struct device argument to callback functions

Include a pointer to the CAN controller device for the CAN
transmit, receive, and state change callback functions.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
Henrik Brix Andersen 2022-03-17 22:06:51 +01:00 committed by Anas Nashif
commit 67ba9900f0
16 changed files with 137 additions and 105 deletions

View file

@ -14,16 +14,18 @@ LOG_MODULE_REGISTER(can_common, CONFIG_CAN_LOG_LEVEL);
/* CAN sync segment is always one time quantum */
#define CAN_SYNC_SEG 1
static void can_msgq_put(struct zcan_frame *frame, void *arg)
static void can_msgq_put(const struct device *dev, struct zcan_frame *frame, void *user_data)
{
struct k_msgq *msgq = (struct k_msgq *)arg;
struct k_msgq *msgq = (struct k_msgq *)user_data;
int ret;
ARG_UNUSED(dev);
__ASSERT_NO_MSG(msgq);
ret = k_msgq_put(msgq, frame, K_NO_WAIT);
if (ret) {
LOG_ERR("Msgq %p overflowed. Frame ID: 0x%x", arg, frame->id);
LOG_ERR("Msgq %p overflowed. Frame ID: 0x%x", msgq, frame->id);
}
}

View file

@ -41,7 +41,8 @@ struct can_loopback_data {
CONFIG_CAN_LOOPBACK_TX_THREAD_STACK_SIZE);
};
static void dispatch_frame(const struct zcan_frame *frame,
static void dispatch_frame(const struct device *dev,
const struct zcan_frame *frame,
struct can_loopback_filter *filter)
{
struct zcan_frame frame_tmp = *frame;
@ -52,7 +53,7 @@ static void dispatch_frame(const struct zcan_frame *frame,
"standard" : "extended",
frame->rtr == CAN_DATAFRAME ? "" : ", RTR frame");
filter->rx_cb(&frame_tmp, filter->cb_arg);
filter->rx_cb(dev, &frame_tmp, filter->cb_arg);
}
static inline int check_filter_match(const struct zcan_frame *frame,
@ -62,13 +63,15 @@ static inline int check_filter_match(const struct zcan_frame *frame,
(frame->id & filter->id_mask));
}
void tx_thread(void *data_arg, void *arg2, void *arg3)
void tx_thread(void *arg1, void *arg2, void *arg3)
{
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
const struct device *dev = arg1;
struct can_loopback_data *data = dev->data;
struct can_loopback_frame frame;
struct can_loopback_filter *filter;
struct can_loopback_data *data = (struct can_loopback_data *)data_arg;
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
while (1) {
k_msgq_get(&data->tx_msgq, &frame, K_FOREVER);
@ -78,7 +81,7 @@ void tx_thread(void *data_arg, void *arg2, void *arg3)
filter = &data->filters[i];
if (filter->rx_cb &&
check_filter_match(&frame.frame, &filter->filter)) {
dispatch_frame(&frame.frame, filter);
dispatch_frame(dev, &frame.frame, filter);
}
}
@ -87,7 +90,7 @@ void tx_thread(void *data_arg, void *arg2, void *arg3)
if (!frame.cb) {
k_sem_give(frame.tx_compl);
} else {
frame.cb(0, frame.cb_arg);
frame.cb(dev, 0, frame.cb_arg);
}
}
}
@ -307,7 +310,7 @@ static int can_loopback_init(const struct device *dev)
tx_tid = k_thread_create(&data->tx_thread_data, data->tx_thread_stack,
K_KERNEL_STACK_SIZEOF(data->tx_thread_stack),
tx_thread, data, NULL, NULL,
tx_thread, (void *)dev, NULL, NULL,
CONFIG_CAN_LOOPBACK_TX_THREAD_PRIORITY,
0, K_NO_WAIT);
if (!tx_tid) {

View file

@ -288,9 +288,11 @@ int can_mcan_init(const struct device *dev, const struct can_mcan_config *cfg,
#endif
int ret;
data->dev = dev;
k_mutex_init(&data->inst_mutex);
k_mutex_init(&data->tx_mtx);
k_sem_init(&data->tx_sem, NUM_TX_BUF_ELEMENTS, NUM_TX_BUF_ELEMENTS);
for (int i = 0; i < ARRAY_SIZE(data->tx_fin_sem); ++i) {
k_sem_init(&data->tx_fin_sem[i], 0, 1);
}
@ -502,7 +504,7 @@ static void can_mcan_state_change_handler(const struct can_mcan_config *cfg,
(void)can_mcan_get_state(cfg, &state, &err_cnt);
if (cb != NULL) {
cb(state, err_cnt, cb_data);
cb(data->dev, state, err_cnt, cb_data);
}
}
@ -530,7 +532,7 @@ static void can_mcan_tc_event_handler(struct can_mcan_reg *can,
if (tx_cb == NULL) {
k_sem_give(&data->tx_fin_sem[tx_idx]);
} else {
tx_cb(0, data->tx_fin_cb_arg[tx_idx]);
tx_cb(data->dev, 0, data->tx_fin_cb_arg[tx_idx]);
}
}
}
@ -643,7 +645,7 @@ static void can_mcan_get_message(struct can_mcan_data *data,
}
if (cb) {
cb(&frame, cb_arg);
cb(data->dev, &frame, cb_arg);
} else {
LOG_DBG("cb missing");
}

View file

@ -166,6 +166,7 @@ struct can_mcan_msg_sram {
} __packed __aligned(4);
struct can_mcan_data {
const struct device *dev;
struct k_mutex inst_mutex;
struct k_sem tx_sem;
struct k_mutex tx_mtx;

View file

@ -635,7 +635,7 @@ static void mcp2515_rx_filter(const struct device *dev,
/*Make a temporary copy in case the user modifies the message*/
tmp_frame = *frame;
callback(&tmp_frame, dev_data->cb_arg[filter_id]);
callback(dev, &tmp_frame, dev_data->cb_arg[filter_id]);
}
k_mutex_unlock(&dev_data->mutex);
@ -665,7 +665,7 @@ static void mcp2515_tx_done(const struct device *dev, uint8_t tx_idx)
if (dev_data->tx_cb[tx_idx].cb == NULL) {
k_sem_give(&dev_data->tx_cb[tx_idx].sem);
} else {
dev_data->tx_cb[tx_idx].cb(0, dev_data->tx_cb[tx_idx].cb_arg);
dev_data->tx_cb[tx_idx].cb(dev, 0, dev_data->tx_cb[tx_idx].cb_arg);
}
k_mutex_lock(&dev_data->mutex, K_FOREVER);
@ -731,7 +731,7 @@ static void mcp2515_handle_errors(const struct device *dev)
if (state_change_cb && dev_data->old_state != state) {
dev_data->old_state = state;
state_change_cb(state, err_cnt, state_change_cb_data);
state_change_cb(dev, state, err_cnt, state_change_cb_data);
}
}

View file

@ -547,7 +547,7 @@ static inline void mcux_flexcan_transfer_error_status(const struct device *dev,
data->state = state;
if (cb != NULL) {
cb(state, err_cnt, cb_data);
cb(dev, state, err_cnt, cb_data);
}
}
@ -562,7 +562,7 @@ static inline void mcux_flexcan_transfer_error_status(const struct device *dev,
FLEXCAN_TransferAbortSend(config->base, &data->handle,
ALLOC_IDX_TO_TXMB_IDX(alloc));
if (function != NULL) {
function(-ENETDOWN, arg);
function(dev, -ENETDOWN, arg);
} else {
data->tx_cbs[alloc].status = -ENETDOWN;
k_sem_give(&data->tx_cbs[alloc].done);
@ -590,7 +590,7 @@ static inline void mcux_flexcan_transfer_tx_idle(const struct device *dev,
if (atomic_test_and_clear_bit(data->tx_allocs, alloc)) {
if (function != NULL) {
function(0, arg);
function(dev, 0, arg);
} else {
data->tx_cbs[alloc].status = 0;
k_sem_give(&data->tx_cbs[alloc].done);
@ -618,7 +618,7 @@ static inline void mcux_flexcan_transfer_rx_idle(const struct device *dev,
if (atomic_test_bit(data->rx_allocs, alloc)) {
mcux_flexcan_copy_frame_to_zframe(&data->rx_cbs[alloc].frame,
&frame);
function(&frame, arg);
function(dev, &frame, arg);
/* Setup RX message buffer to receive next message */
FLEXCAN_SetRxMbConfig(config->base, mb,

View file

@ -233,7 +233,7 @@ static void can_rcar_tx_done(const struct device *dev)
data->tx_unsent--;
if (tx_cb->cb != NULL) {
tx_cb->cb(0, tx_cb->cb_arg);
tx_cb->cb(dev, 0, tx_cb->cb_arg);
} else {
k_sem_give(&tx_cb->sem);
}
@ -267,7 +267,7 @@ static void can_rcar_state_change(const struct device *dev, uint32_t newstate)
return;
}
can_rcar_get_error_count(config, &err_cnt);
cb(newstate, err_cnt, state_change_cb_data);
cb(dev, newstate, err_cnt, state_change_cb_data);
}
static void can_rcar_error(const struct device *dev)
@ -366,7 +366,8 @@ static void can_rcar_error(const struct device *dev)
}
}
static void can_rcar_rx_filter_isr(struct can_rcar_data *data,
static void can_rcar_rx_filter_isr(const struct device *dev,
struct can_rcar_data *data,
const struct zcan_frame *frame)
{
struct zcan_frame tmp_frame;
@ -385,7 +386,7 @@ static void can_rcar_rx_filter_isr(struct can_rcar_data *data,
* modifies the message.
*/
tmp_frame = *frame;
data->rx_callback[i](&tmp_frame, data->rx_callback_arg[i]);
data->rx_callback[i](dev, &tmp_frame, data->rx_callback_arg[i]);
}
}
@ -437,7 +438,7 @@ static void can_rcar_rx_isr(const struct device *dev)
/* Increment CPU side pointer */
sys_write8(0xff, config->reg_addr + RCAR_CAN_RFPCR);
can_rcar_rx_filter_isr(data, &frame);
can_rcar_rx_filter_isr(dev, data, &frame);
}
static void can_rcar_isr(const struct device *dev)

View file

@ -55,10 +55,10 @@ LOG_MODULE_REGISTER(can_stm32, CONFIG_CAN_LOG_LEVEL);
static const uint8_t filter_in_bank[] = {2, 4, 1, 2};
static const uint8_t reg_demand[] = {2, 1, 4, 2};
static void can_stm32_signal_tx_complete(struct can_mailbox *mb)
static void can_stm32_signal_tx_complete(const struct device *dev, struct can_mailbox *mb)
{
if (mb->tx_callback) {
mb->tx_callback(mb->error, mb->callback_arg);
mb->tx_callback(dev, mb->error, mb->callback_arg);
} else {
k_sem_give(&mb->tx_int_sem);
}
@ -85,8 +85,11 @@ static void can_stm32_get_msg_fifo(CAN_FIFOMailBox_TypeDef *mbox,
}
static inline
void can_stm32_rx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data)
void can_stm32_rx_isr_handler(const struct device *dev)
{
struct can_stm32_data *data = dev->data;
const struct can_stm32_config *cfg = dev->config;
CAN_TypeDef *can = cfg->can;
CAN_FIFOMailBox_TypeDef *mbox;
int filter_match_index;
struct zcan_frame frame;
@ -107,7 +110,7 @@ void can_stm32_rx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data)
callback = data->rx_cb[filter_match_index];
if (callback) {
callback(&frame, data->cb_arg[filter_match_index]);
callback(dev, &frame, data->cb_arg[filter_match_index]);
}
/* Release message */
@ -192,14 +195,17 @@ static inline void can_stm32_bus_state_change_isr(const struct device *dev)
data->state = state;
if (cb != NULL) {
cb(state, err_cnt, state_change_cb_data);
cb(dev, state, err_cnt, state_change_cb_data);
}
}
}
static inline
void can_stm32_tx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data)
void can_stm32_tx_isr_handler(const struct device *dev)
{
struct can_stm32_data *data = dev->data;
const struct can_stm32_config *cfg = dev->config;
CAN_TypeDef *can = cfg->can;
uint32_t bus_off;
bus_off = can->ESR & CAN_ESR_BOFF;
@ -213,7 +219,7 @@ void can_stm32_tx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data)
-EIO;
/* clear the request. */
can->TSR |= CAN_TSR_RQCP0;
can_stm32_signal_tx_complete(&data->mb0);
can_stm32_signal_tx_complete(dev, &data->mb0);
}
if ((can->TSR & CAN_TSR_RQCP1) | bus_off) {
@ -225,7 +231,7 @@ void can_stm32_tx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data)
-EIO;
/* clear the request. */
can->TSR |= CAN_TSR_RQCP1;
can_stm32_signal_tx_complete(&data->mb1);
can_stm32_signal_tx_complete(dev, &data->mb1);
}
if ((can->TSR & CAN_TSR_RQCP2) | bus_off) {
@ -237,7 +243,7 @@ void can_stm32_tx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data)
-EIO;
/* clear the request. */
can->TSR |= CAN_TSR_RQCP2;
can_stm32_signal_tx_complete(&data->mb2);
can_stm32_signal_tx_complete(dev, &data->mb2);
}
if (can->TSR & CAN_TSR_TME) {
@ -249,16 +255,12 @@ void can_stm32_tx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data)
static void can_stm32_isr(const struct device *dev)
{
struct can_stm32_data *data;
const struct can_stm32_config *cfg;
CAN_TypeDef *can;
const struct can_stm32_config *cfg = dev->config;
CAN_TypeDef *can = cfg->can;
data = dev->data;
cfg = dev->config;
can = cfg->can;
can_stm32_tx_isr_handler(dev);
can_stm32_rx_isr_handler(dev);
can_stm32_tx_isr_handler(can, data);
can_stm32_rx_isr_handler(can, data);
if (can->MSR & CAN_MSR_ERRI) {
can_stm32_bus_state_change_isr(dev);
can->MSR |= CAN_MSR_ERRI;
@ -269,44 +271,22 @@ static void can_stm32_isr(const struct device *dev)
static void can_stm32_rx_isr(const struct device *dev)
{
struct can_stm32_data *data;
const struct can_stm32_config *cfg;
CAN_TypeDef *can;
data = dev->data;
cfg = dev->config;
can = cfg->can;
can_stm32_rx_isr_handler(can, data);
can_stm32_rx_isr_handler(dev);
}
static void can_stm32_tx_isr(const struct device *dev)
{
struct can_stm32_data *data;
const struct can_stm32_config *cfg;
CAN_TypeDef *can;
data = dev->data;
cfg = dev->config;
can = cfg->can;
can_stm32_tx_isr_handler(can, data);
can_stm32_tx_isr_handler(dev);
}
static void can_stm32_state_change_isr(const struct device *dev)
{
struct can_stm32_data *data;
const struct can_stm32_config *cfg;
CAN_TypeDef *can;
const struct can_stm32_config *cfg = dev->config;
CAN_TypeDef *can = cfg->can;
data = dev->data;
cfg = dev->config;
can = cfg->can;
/*Signal bus-off to waiting tx*/
/* Signal bus-off to waiting tx */
if (can->MSR & CAN_MSR_ERRI) {
can_stm32_tx_isr_handler(can, data);
can_stm32_tx_isr_handler(dev);
can_stm32_bus_state_change_isr(dev);
can->MSR |= CAN_MSR_ERRI;
}

View file

@ -45,9 +45,12 @@ static inline void socket_can_iface_init(struct net_if *iface)
LOG_DBG("Init CAN interface %p dev %p", iface, dev);
}
static inline void tx_irq_callback(int error, void *arg)
static inline void tx_irq_callback(const struct device *dev, int error, void *arg)
{
char *caller_str = (char *)arg;
ARG_UNUSED(dev);
if (error != 0) {
LOG_DBG("TX error from %s! error-code: %d",
caller_str, error);