Commit 1938dde0 authored by Federico Vaga's avatar Federico Vaga

drv: wait for timing config to be applied

The update is not immediate, we need to monitor UPD_DONE to be reassured
that values are applied and we can continue.

If this does not happen, then it is a serious hardware problem. That's
why I chose to use WARN_ON.

By returning and error code, we will get a ZIO_ALARM_LOST_TRIGGER, that
userspace needs to check.
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent ab8edc42
......@@ -513,6 +513,7 @@ static int __fd_zio_output(struct fd_dev *fd, int index1_4, uint32_t *attrs)
int mode = attrs[FD_ATTR_OUT_MODE];
int rep = attrs[FD_ATTR_OUT_REP];
int dcr = 0;
unsigned long timeout;
if (mode == FD_OUT_MODE_DELAY || mode == FD_OUT_MODE_DISABLED) {
if(rep < 0 || rep > 16) /* delay mode allows trains of 1 to 16 pulses. */
......@@ -629,6 +630,13 @@ static int __fd_zio_output(struct fd_dev *fd, int index1_4, uint32_t *attrs)
/* Update the time stamps according to start/end registers */
fd_ch_writel(fd, ch, dcr | FD_DCR_UPDATE, FD_REG_DCR);
timeout = jiffies + msecs_to_jiffies(10);
while (!(fd_ch_readl(fd, ch, FD_REG_DCR) & FD_DCR_UPD_DONE)) {
if (WARN_ON(time_after(jiffies, timeout)))
return -ETIMEDOUT;
cpu_relax();
}
/* Enable channel output */
if (mode == FD_OUT_MODE_DELAY) {
fd_ch_writel(fd, ch, dcr | FD_DCR_ENABLE, FD_REG_DCR);
......@@ -642,7 +650,7 @@ static int __fd_zio_output(struct fd_dev *fd, int index1_4, uint32_t *attrs)
/* This is called on user write */
static int fd_zio_output(struct zio_cset *cset)
{
int i;
int i, err;
struct fd_dev *fd;
struct zio_control *ctrl;
......@@ -656,7 +664,10 @@ static int fd_zio_output(struct zio_cset *cset)
printk("%08x%c", ctrl->attr_channel.ext_val[i],
i == FD_ATTR_OUT__LAST -1 ? '\n' : ' ');
}
return __fd_zio_output(fd, cset->index, ctrl->attr_channel.ext_val);
err = __fd_zio_output(fd, cset->index, ctrl->attr_channel.ext_val);
if (err)
cset->chan[0].current_ctrl->drv_alarms |= FD_ZIO_ALARM_FAIL_CONFIG;
return err;
}
/*
......
......@@ -162,6 +162,8 @@ struct fd_calibration { /* All of these are big endian */
uint32_t vcxo_default_tune;
};
#define FD_ZIO_ALARM_FAIL_CONFIG (1 << 0) /* Delay configuration failed */
#ifdef __KERNEL__ /* All the rest is only of kernel users */
#include <linux/spinlock.h>
#include <linux/timer.h>
......
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