drivers: can: mcan: refactor to get rid of wrapper functions

Refactor the Bosch M_CAN shared driver functions to get rid of the
front-end driver wrapper functions.

This requires flipping the relationship between shared config/data
structs and front-end config/data structs. Front-end drivers can now
store a pointer to their custom config/data structs in the .custom
fields of the can_mcan_config and can_mcan_data data structures.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
Henrik Brix Andersen 2022-04-19 13:46:30 +02:00 committed by Carles Cufí
commit 5b3712a9ac
7 changed files with 300 additions and 703 deletions

View file

@ -1,4 +1,5 @@
/*
* Copyright (c) 2022 Vestas Wind Systems A/S
* Copyright (c) 2020 Alexander Wachter
*
* SPDX-License-Identifier: Apache-2.0
@ -120,7 +121,7 @@ static int can_leave_init_mode(struct can_mcan_reg *can, k_timeout_t timeout)
return 0;
}
void can_mcan_configure_timing(struct can_mcan_reg *can,
void can_mcan_configure_timing(struct can_mcan_reg *can,
const struct can_timing *timing,
const struct can_timing *timing_data)
{
@ -183,10 +184,11 @@ void can_mcan_configure_timing(struct can_mcan_reg *can,
#endif
}
int can_mcan_set_timing(const struct can_mcan_config *cfg,
int can_mcan_set_timing(const struct device *dev,
const struct can_timing *timing,
const struct can_timing *timing_data)
{
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_reg *can = cfg->can;
int ret;
@ -210,8 +212,9 @@ int can_mcan_set_timing(const struct can_mcan_config *cfg,
return 0;
}
int can_mcan_set_mode(const struct can_mcan_config *cfg, enum can_mode mode)
int can_mcan_set_mode(const struct device *dev, enum can_mode mode)
{
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_reg *can = cfg->can;
int ret;
@ -279,18 +282,18 @@ int can_mcan_set_mode(const struct can_mcan_config *cfg, enum can_mode mode)
return 0;
}
int can_mcan_init(const struct device *dev, const struct can_mcan_config *cfg,
struct can_mcan_msg_sram *msg_ram,
struct can_mcan_data *data)
int can_mcan_init(const struct device *dev)
{
struct can_mcan_reg *can = cfg->can;
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_data *data = dev->data;
struct can_mcan_reg *can = cfg->can;
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
struct can_timing timing;
#ifdef CONFIG_CAN_FD_MODE
struct can_timing timing_data;
#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);
@ -495,25 +498,27 @@ done:
return ret;
}
static void can_mcan_state_change_handler(const struct can_mcan_config *cfg,
struct can_mcan_data *data)
static void can_mcan_state_change_handler(const struct device *dev)
{
enum can_state state;
struct can_bus_err_cnt err_cnt;
struct can_mcan_data *data = dev->data;
const can_state_change_callback_t cb = data->state_change_cb;
void *cb_data = data->state_change_cb_data;
struct can_bus_err_cnt err_cnt;
enum can_state state;
(void)can_mcan_get_state(cfg, &state, &err_cnt);
(void)can_mcan_get_state(dev, &state, &err_cnt);
if (cb != NULL) {
cb(data->dev, state, err_cnt, cb_data);
cb(dev, state, err_cnt, cb_data);
}
}
static void can_mcan_tc_event_handler(struct can_mcan_reg *can,
struct can_mcan_msg_sram *msg_ram,
struct can_mcan_data *data)
static void can_mcan_tc_event_handler(const struct device *dev)
{
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_data *data = dev->data;
struct can_mcan_reg *can = cfg->can;
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
volatile struct can_mcan_tx_event_fifo *tx_event;
can_tx_callback_t tx_cb;
uint32_t event_idx, tx_idx;
@ -534,15 +539,15 @@ 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(data->dev, 0, data->tx_fin_cb_arg[tx_idx]);
tx_cb(dev, 0, data->tx_fin_cb_arg[tx_idx]);
}
}
}
void can_mcan_line_0_isr(const struct can_mcan_config *cfg,
struct can_mcan_msg_sram *msg_ram,
struct can_mcan_data *data)
void can_mcan_line_0_isr(const struct device *dev)
{
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_data *data = dev->data;
struct can_mcan_reg *can = cfg->can;
do {
@ -550,12 +555,12 @@ void can_mcan_line_0_isr(const struct can_mcan_config *cfg,
CAN_MCAN_IR_EW)) {
can->ir = CAN_MCAN_IR_BO | CAN_MCAN_IR_EP |
CAN_MCAN_IR_EW;
can_mcan_state_change_handler(cfg, data);
can_mcan_state_change_handler(dev);
}
/* TX event FIFO new entry */
if (can->ir & CAN_MCAN_IR_TEFN) {
can->ir = CAN_MCAN_IR_TEFN;
can_mcan_tc_event_handler(can, msg_ram, data);
can_mcan_tc_event_handler(dev);
}
if (can->ir & CAN_MCAN_IR_TEFL) {
@ -578,11 +583,12 @@ void can_mcan_line_0_isr(const struct can_mcan_config *cfg,
CAN_MCAN_IR_TEFL | CAN_MCAN_IR_TEFN));
}
static void can_mcan_get_message(struct can_mcan_data *data,
static void can_mcan_get_message(const struct device *dev,
volatile struct can_mcan_rx_fifo *fifo,
volatile uint32_t *fifo_status_reg,
volatile uint32_t *fifo_ack_reg)
{
struct can_mcan_data *data = dev->data;
uint32_t get_idx, filt_idx;
struct zcan_frame frame;
can_rx_callback_t cb;
@ -647,7 +653,7 @@ static void can_mcan_get_message(struct can_mcan_data *data,
}
if (cb) {
cb(data->dev, &frame, cb_arg);
cb(dev, &frame, cb_arg);
} else {
LOG_DBG("cb missing");
}
@ -659,24 +665,25 @@ static void can_mcan_get_message(struct can_mcan_data *data,
}
}
void can_mcan_line_1_isr(const struct can_mcan_config *cfg,
struct can_mcan_msg_sram *msg_ram,
struct can_mcan_data *data)
void can_mcan_line_1_isr(const struct device *dev)
{
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_data *data = dev->data;
struct can_mcan_reg *can = cfg->can;
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
do {
if (can->ir & CAN_MCAN_IR_RF0N) {
can->ir = CAN_MCAN_IR_RF0N;
LOG_DBG("RX FIFO0 INT");
can_mcan_get_message(data, msg_ram->rx_fifo0,
can_mcan_get_message(dev, msg_ram->rx_fifo0,
&can->rxf0s, &can->rxf0a);
}
if (can->ir & CAN_MCAN_IR_RF1N) {
can->ir = CAN_MCAN_IR_RF1N;
LOG_DBG("RX FIFO1 INT");
can_mcan_get_message(data, msg_ram->rx_fifo1,
can_mcan_get_message(dev, msg_ram->rx_fifo1,
&can->rxf1s, &can->rxf1a);
}
@ -694,9 +701,10 @@ void can_mcan_line_1_isr(const struct can_mcan_config *cfg,
CAN_MCAN_IR_RF0L | CAN_MCAN_IR_RF1L));
}
int can_mcan_get_state(const struct can_mcan_config *cfg, enum can_state *state,
int can_mcan_get_state(const struct device *dev, enum can_state *state,
struct can_bus_err_cnt *err_cnt)
{
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_reg *can = cfg->can;
if (state != NULL) {
@ -723,8 +731,9 @@ int can_mcan_get_state(const struct can_mcan_config *cfg, enum can_state *state,
}
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
int can_mcan_recover(const struct can_mcan_config *cfg, k_timeout_t timeout)
int can_mcan_recover(const struct device *dev, k_timeout_t timeout)
{
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_reg *can = cfg->can;
return can_leave_init_mode(can, timeout);
@ -732,14 +741,15 @@ int can_mcan_recover(const struct can_mcan_config *cfg, k_timeout_t timeout)
#endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
int can_mcan_send(const struct can_mcan_config *cfg,
struct can_mcan_data *data,
struct can_mcan_msg_sram *msg_ram,
int can_mcan_send(const struct device *dev,
const struct zcan_frame *frame,
k_timeout_t timeout,
can_tx_callback_t callback, void *user_data)
{
struct can_mcan_reg *can = cfg->can;
const struct can_mcan_config *cfg = dev->config;
struct can_mcan_data *data = dev->data;
struct can_mcan_reg *can = cfg->can;
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
size_t data_length = can_dlc_to_bytes(frame->dlc);
struct can_mcan_tx_buffer_hdr tx_hdr = {
.rtr = frame->rtr == CAN_REMOTEREQUEST,
@ -850,11 +860,12 @@ int can_mcan_get_max_filters(const struct device *dev, enum can_ide id_type)
* Dual mode gets tricky, because we can only activate both filters.
* If one of the IDs is not used anymore, we would need to mark it as unused.
*/
int can_mcan_add_rx_filter_std(struct can_mcan_data *data,
struct can_mcan_msg_sram *msg_ram,
int can_mcan_add_rx_filter_std(const struct device *dev,
can_rx_callback_t callback, void *user_data,
const struct zcan_filter *filter)
{
struct can_mcan_data *data = dev->data;
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
struct can_mcan_std_filter filter_element = {
.id1 = filter->id,
.id2 = filter->id_mask,
@ -912,11 +923,12 @@ static int can_mcan_get_free_ext(volatile struct can_mcan_ext_filter *filters)
return -ENOSPC;
}
static int can_mcan_add_rx_filter_ext(struct can_mcan_data *data,
struct can_mcan_msg_sram *msg_ram,
static int can_mcan_add_rx_filter_ext(const struct device *dev,
can_rx_callback_t callback, void *user_data,
const struct zcan_filter *filter)
{
struct can_mcan_data *data = dev->data;
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
struct can_mcan_ext_filter filter_element = {
.id2 = filter->id_mask,
.id1 = filter->id,
@ -963,8 +975,7 @@ static int can_mcan_add_rx_filter_ext(struct can_mcan_data *data,
return filter_id;
}
int can_mcan_add_rx_filter(struct can_mcan_data *data,
struct can_mcan_msg_sram *msg_ram,
int can_mcan_add_rx_filter(const struct device *dev,
can_rx_callback_t callback, void *user_data,
const struct zcan_filter *filter)
{
@ -975,11 +986,9 @@ int can_mcan_add_rx_filter(struct can_mcan_data *data,
}
if (filter->id_type == CAN_STANDARD_IDENTIFIER) {
filter_id = can_mcan_add_rx_filter_std(data, msg_ram, callback,
user_data, filter);
filter_id = can_mcan_add_rx_filter_std(dev, callback, user_data, filter);
} else {
filter_id = can_mcan_add_rx_filter_ext(data, msg_ram, callback,
user_data, filter);
filter_id = can_mcan_add_rx_filter_ext(dev, callback, user_data, filter);
if (filter_id >= 0) {
filter_id += NUM_STD_FILTER_DATA;
}
@ -988,9 +997,11 @@ int can_mcan_add_rx_filter(struct can_mcan_data *data,
return filter_id;
}
void can_mcan_remove_rx_filter(struct can_mcan_data *data,
struct can_mcan_msg_sram *msg_ram, int filter_id)
void can_mcan_remove_rx_filter(const struct device *dev, int filter_id)
{
struct can_mcan_data *data = dev->data;
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
k_mutex_lock(&data->inst_mutex, K_FOREVER);
if (filter_id >= NUM_STD_FILTER_DATA) {
filter_id -= NUM_STD_FILTER_DATA;
@ -1012,3 +1023,22 @@ void can_mcan_remove_rx_filter(struct can_mcan_data *data,
k_mutex_unlock(&data->inst_mutex);
}
void can_mcan_set_state_change_callback(const struct device *dev,
can_state_change_callback_t callback,
void *user_data)
{
struct can_mcan_data *data = dev->data;
data->state_change_cb = callback;
data->state_change_cb_data = user_data;
}
int can_mcan_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate)
{
const struct can_mcan_config *cfg = dev->config;
*max_bitrate = cfg->max_bitrate;
return 0;
}