staging: most: add channel property dbr_size
authorChristian Gromm <christian.gromm@microchip.com>
Tue, 8 May 2018 09:44:53 +0000 (11:44 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 May 2018 11:41:48 +0000 (13:41 +0200)
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 <christian.gromm@microchip.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/most/core.c
drivers/staging/most/core.h
drivers/staging/most/dim2/dim2.c
drivers/staging/most/dim2/hal.c

index 965409e..db3c7e2 100644 (file)
@@ -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,
 };
 
index 884bd71..5b184e6 100644 (file)
@@ -128,6 +128,7 @@ struct most_channel_config {
        u16 extra_len;
        u16 subbuffer_size;
        u16 packets_per_xact;
+       u16 dbr_size;
 };
 
 /*
index fa4559b..d15867a 100644 (file)
@@ -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;
 }
index 17c04e1..699e02f 100644 (file)
@@ -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;