Commit 9026e588 authored by Federico Vaga's avatar Federico Vaga

kernel: store in ZIO as soon as the TS is ready

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 8a48c54a
......@@ -71,7 +71,6 @@ enum ft_command {
#include <linux/timer.h>
#include <linux/fmc.h>
#include <linux/version.h>
#include <linux/kfifo.h>
#define FT_USER_OFFSET_RANGE 1000000000 /* picoseconds */
......@@ -112,7 +111,7 @@ struct ft_hw_timestamp {
uint32_t metadata; /* channel, polarity, etc. */
} __packed;
/* White Rabbit timestamp (32Byte is nice for the kfifo) */
/* White Rabbit timestamp */
struct ft_wr_timestamp {
uint64_t seconds;
uint32_t coarse;
......@@ -134,9 +133,6 @@ struct ft_channel_state {
from HW */
struct ft_wr_timestamp last_ts; /**< used to compute delay
between pulses */
struct kfifo fifo;
uint32_t fifo_len;
};
/* Main TDC device context */
......@@ -235,8 +231,6 @@ void ft_set_vcxo_tune (struct fmctdc_dev *ft, int value);
struct zio_channel;
int ft_read_sw_fifo(struct fmctdc_dev *ft, int channel,
struct zio_channel *chan);
int ft_enable_termination(struct fmctdc_dev *ft, int channel, int enable);
signed long fmc_sdb_find_nth_device (struct sdb_array *tree, uint64_t vid,
......
......@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/io.h>
#include <linux/kfifo.h>
#include <linux/fmc.h>
#include <linux/fmc-sdb.h>
......@@ -42,20 +41,13 @@ static struct fmc_driver ft_drv; /* forward declaration */
FMC_PARAM_BUSID(ft_drv);
FMC_PARAM_GATEWARE(ft_drv);
static int ft_buffer_size = 64;
module_param_named(buffer_size, ft_buffer_size, int, 0444);
MODULE_PARM_DESC(verbose,
"Number of timestamps in each channel's software FIFO buffer (It must be a power of 2).");
static int ft_init_channel(struct fmctdc_dev *ft, int channel)
{
struct ft_channel_state *st = &ft->channels[channel - 1];
st->expected_edge = 1;
st->fifo_len = ft_buffer_size;
return kfifo_alloc(&st->fifo,
sizeof(struct ft_wr_timestamp) * st->fifo_len,
GFP_KERNEL);
return 0;
}
static void ft_reset_channel(struct fmctdc_dev *ft, int channel)
......@@ -65,8 +57,6 @@ static void ft_reset_channel(struct fmctdc_dev *ft, int channel)
st->cur_seq_id = 0;
st->expected_edge = 1;
ft_zio_kill_buffer(ft, channel);
kfifo_reset(&st->fifo);
}
int ft_enable_termination(struct fmctdc_dev *ft, int channel, int enable)
......@@ -97,23 +87,6 @@ int ft_enable_termination(struct fmctdc_dev *ft, int channel, int enable)
}
/**
* NOTE: this function must be invoked with st->lock taken
*/
static void ft_flush_sw_fifo(struct fmctdc_dev *ft)
{
struct ft_channel_state *st;
struct ft_wr_timestamp ts;
int i;
for (i = FT_CH_1; i <= FT_NUM_CHANNELS ; i++) {
st = &ft->channels[i - 1];
while (!kfifo_is_empty(&st->fifo))
kfifo_out(&st->fifo, &ts,
sizeof(struct ft_wr_timestamp));
}
}
void ft_enable_acquisition(struct fmctdc_dev *ft, int enable)
{
uint32_t ien, cmd;
......@@ -140,11 +113,8 @@ void ft_enable_acquisition(struct fmctdc_dev *ft, int enable)
ft->acquisition_on = enable;
if (!enable) {
if (!enable)
ft->prev_wr_ptr = ft->cur_wr_ptr = 0;
ft_flush_sw_fifo(ft);
}
spin_unlock(&ft->lock);
if (!enable) {
......@@ -179,10 +149,7 @@ static int ft_channels_init(struct fmctdc_dev *ft)
static void ft_channels_exit(struct fmctdc_dev *ft)
{
int i;
for (i = FT_CH_1; i <= FT_NUM_CHANNELS; i++)
kfifo_free(&ft->channels[i - 1].fifo);
return;
}
struct ft_modlist {
......
......@@ -50,28 +50,18 @@ static void copy_timestamps(struct fmctdc_dev *ft, int base_addr,
}
int ft_read_sw_fifo(struct fmctdc_dev *ft, int channel,
struct zio_channel *chan)
static int ft_read_sw_fifo(struct fmctdc_dev *ft, int channel,
struct zio_channel *chan,
struct ft_wr_timestamp *wrts)
{
struct zio_control *ctrl;
struct zio_ti *ti = chan->cset->ti;
uint32_t *v;
struct ft_wr_timestamp ts, *reflast;
struct ft_wr_timestamp ts = *wrts, *reflast;
struct ft_channel_state *st;
int ret;
st = &ft->channels[channel - 1];
ret = kfifo_out_spinlocked(&st->fifo, &ts,
sizeof(struct ft_wr_timestamp), &ft->lock);
if (!ret) {
return -EAGAIN;
} else if (ret < sizeof(struct ft_wr_timestamp)) {
dev_err(&ft->zdev->head.dev,
"Somethig wrong with kfifo buffer\n");
return -EINVAL;
}
ctrl = chan->current_ctrl;
v = ctrl->attr_channel.ext_val;
......@@ -213,15 +203,6 @@ static inline int process_timestamp(struct fmctdc_dev *ft,
/* Return a valid timestamp */
*wrts = ts;
ret = 1;
/* Put the timestamp in the FIFO */
kfifo_in_spinlocked(&st->fifo, &ts,
sizeof(struct ft_wr_timestamp), &ft->lock);
if (st->fifo_len <= kfifo_len(&st->fifo) / sizeof(struct ft_wr_timestamp)) {
kfifo_out_spinlocked(&st->fifo, &ts,
sizeof(struct ft_wr_timestamp),
&ft->lock);
}
}
/* Wait for the next raising edge */
......@@ -292,8 +273,9 @@ static void ft_readout_tasklet(unsigned long arg)
struct fmc_device *fmc = ft->fmc;
struct zio_device *zdev = ft->zdev;
struct ft_wr_timestamp wrts;
struct zio_cset *cset;
uint32_t rd_ptr;
int count, dacapo, i, err, ret;
int count, dacapo, err, ret;
ft->prev_wr_ptr = ft->cur_wr_ptr;
ft->cur_wr_ptr = ft_readl(ft, TDC_REG_BUFFER_PTR);
......@@ -318,29 +300,25 @@ static void ft_readout_tasklet(unsigned long arg)
rd_ptr = (rd_ptr + 1) % FT_BUFFER_EVENTS;
if (ret) {
dev_dbg(&ft->fmc->dev,
"processed TS(%p): ch %d: seq %d: gseq %d 0x%x 0x%x 0x%x\n",
wrts, wrts.channel, wrts.seq_id, wrts.gseq_id,
"processed TS: ch %d: seq %u: gseq %llu %llu %u %u\n",
wrts.channel, wrts.seq_id, wrts.gseq_id,
wrts.seconds, wrts.coarse, wrts.frac);
}
}
if (!zdev)
goto out;
for (i = FT_CH_1; i <= FT_NUM_CHANNELS; i++) {
struct zio_cset *cset = &zdev->cset[i - 1];
/* FIXME: race condition */
if (ZIO_TI_ARMED & cset->ti->flags) {
/* there is an active block, try reading an
accumulated sample */
err = ft_read_sw_fifo(ft, i, cset->chan);
if (!err)
zio_trigger_data_done(cset);
if (!zdev)
continue;
cset = &zdev->cset[wrts.channel - 1];
if (ZIO_TI_ARMED & cset->ti->flags) {
/* there is an active block, try reading an
accumulated sample */
err = ft_read_sw_fifo(ft, wrts.channel - 1,
cset->chan, &wrts);
if (!err)
zio_trigger_data_done(cset);
}
}
}
out:
/* ack the irq */
fmc_writel(ft->fmc, TDC_IRQ_TDC_TSTAMP,
ft->ft_irq_base + TDC_REG_EIC_ISR);
......
......@@ -219,20 +219,7 @@ static int ft_zio_conf_channel(struct device *dev, struct zio_attribute *zattr,
static int ft_zio_input(struct zio_cset *cset)
{
struct fmctdc_dev *ft;
struct ft_channel_state *st;
ft = cset->zdev->priv_d;
if (!ft->initialized)
return -EAGAIN;
st = &ft->channels[cset->index];
/* Ready for input. If there's already something, return it now */
if (ft_read_sw_fifo(ft, cset->index + 1, cset->chan) == 0)
return 0; /* don't call data_done, let the caller do it */
/* The trigger will fire on interrupt */
return -EAGAIN;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment