From dbd36d5772f7e49e1e638391941de358d84ce379 Mon Sep 17 00:00:00 2001 From: Christian Gromm Date: Tue, 8 May 2018 11:44:53 +0200 Subject: staging: most: add channel property dbr_size This patch adds the channel property dbr_size to control the corresponding buffer size of the channels of the DIM2 interface. Signed-off-by: Christian Gromm Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/core.c | 22 ++++++++++++++++++++++ drivers/staging/most/core.h | 1 + drivers/staging/most/dim2/dim2.c | 10 ++++++++++ drivers/staging/most/dim2/hal.c | 9 ++++++--- 4 files changed, 39 insertions(+), 3 deletions(-) (limited to 'drivers/staging/most') diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c index 965409efc8bf..db3c7e243deb 100644 --- a/drivers/staging/most/core.c +++ b/drivers/staging/most/core.c @@ -420,6 +420,26 @@ static ssize_t set_packets_per_xact_store(struct device *dev, return count; } +static ssize_t set_dbr_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct most_channel *c = to_channel(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.dbr_size); +} + +static ssize_t set_dbr_size_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct most_channel *c = to_channel(dev); + int ret = kstrtou16(buf, 0, &c->cfg.dbr_size); + + if (ret) + return ret; + return count; +} + #define DEV_ATTR(_name) (&dev_attr_##_name.attr) static DEVICE_ATTR_RO(available_directions); @@ -435,6 +455,7 @@ static DEVICE_ATTR_RW(set_direction); static DEVICE_ATTR_RW(set_datatype); static DEVICE_ATTR_RW(set_subbuffer_size); static DEVICE_ATTR_RW(set_packets_per_xact); +static DEVICE_ATTR_RW(set_dbr_size); static struct attribute *channel_attrs[] = { DEV_ATTR(available_directions), @@ -450,6 +471,7 @@ static struct attribute *channel_attrs[] = { DEV_ATTR(set_datatype), DEV_ATTR(set_subbuffer_size), DEV_ATTR(set_packets_per_xact), + DEV_ATTR(set_dbr_size), NULL, }; diff --git a/drivers/staging/most/core.h b/drivers/staging/most/core.h index 884bd71fafce..5b184e6d4721 100644 --- a/drivers/staging/most/core.h +++ b/drivers/staging/most/core.h @@ -128,6 +128,7 @@ struct most_channel_config { u16 extra_len; u16 subbuffer_size; u16 packets_per_xact; + u16 dbr_size; }; /* diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index fa4559b8f536..d15867a1ba2d 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -61,6 +61,7 @@ struct hdm_channel { char name[sizeof "caNNN"]; bool is_initialized; struct dim_channel ch; + u16 *reset_dbr_size; struct list_head pending_list; /* before dim_enqueue_buffer() */ struct list_head started_list; /* after dim_enqueue_buffer() */ enum most_channel_direction direction; @@ -494,6 +495,12 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, if (hdm_ch->is_initialized) return -EPERM; + /* do not reset if the property was set by user, see poison_channel */ + hdm_ch->reset_dbr_size = ccfg->dbr_size ? NULL : &ccfg->dbr_size; + + /* zero value is default dbr_size, see dim2 hal */ + hdm_ch->ch.dbr_size = ccfg->dbr_size; + switch (ccfg->data_type) { case MOST_CH_CONTROL: new_size = dim_norm_ctrl_async_buffer_size(buf_size); @@ -574,6 +581,7 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx, dev->atx_idx = ch_idx; spin_unlock_irqrestore(&dim_lock, flags); + ccfg->dbr_size = hdm_ch->ch.dbr_size; return 0; } @@ -689,6 +697,8 @@ static int poison_channel(struct most_interface *most_iface, int ch_idx) complete_all_mbos(&hdm_ch->started_list); complete_all_mbos(&hdm_ch->pending_list); + if (hdm_ch->reset_dbr_size) + *hdm_ch->reset_dbr_size = 0; return ret; } diff --git a/drivers/staging/most/dim2/hal.c b/drivers/staging/most/dim2/hal.c index 17c04e1c5e62..699e02f83bd4 100644 --- a/drivers/staging/most/dim2/hal.c +++ b/drivers/staging/most/dim2/hal.c @@ -760,7 +760,8 @@ static u8 init_ctrl_async(struct dim_channel *ch, u8 type, u8 is_tx, if (!check_channel_address(ch_address)) return DIM_INIT_ERR_CHANNEL_ADDRESS; - ch->dbr_size = ROUND_UP_TO(hw_buffer_size, DBR_BLOCK_SIZE); + if (!ch->dbr_size) + ch->dbr_size = ROUND_UP_TO(hw_buffer_size, DBR_BLOCK_SIZE); ch->dbr_addr = alloc_dbr(ch->dbr_size); if (ch->dbr_addr >= DBR_SIZE) return DIM_INIT_ERR_OUT_OF_MEMORY; @@ -846,7 +847,8 @@ u8 dim_init_isoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, if (!check_packet_length(packet_length)) return DIM_ERR_BAD_CONFIG; - ch->dbr_size = packet_length * ISOC_DBR_FACTOR; + if (!ch->dbr_size) + ch->dbr_size = packet_length * ISOC_DBR_FACTOR; ch->dbr_addr = alloc_dbr(ch->dbr_size); if (ch->dbr_addr >= DBR_SIZE) return DIM_INIT_ERR_OUT_OF_MEMORY; @@ -873,7 +875,8 @@ u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address, if (!check_bytes_per_frame(bytes_per_frame)) return DIM_ERR_BAD_CONFIG; - ch->dbr_size = bytes_per_frame << bd_factor; + if (!ch->dbr_size) + ch->dbr_size = bytes_per_frame << bd_factor; ch->dbr_addr = alloc_dbr(ch->dbr_size); if (ch->dbr_addr >= DBR_SIZE) return DIM_INIT_ERR_OUT_OF_MEMORY; -- cgit v1.2.3-59-g8ed1b