Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC ADC 100M 14b 4cha - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
FMC ADC 100M 14b 4cha - Software
Commits
da187f25
Commit
da187f25
authored
Apr 25, 2014
by
Federico Vaga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel: bugfix: on DMA error stop after clear CSET_BUSY flag
Signed-off-by:
Federico Vaga
<
federico.vaga@cern.ch
>
parent
00eccfd0
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
60 additions
and
56 deletions
+60
-56
fa-irq.c
kernel/fa-irq.c
+60
-56
No files found.
kernel/fa-irq.c
View file @
da187f25
...
...
@@ -4,6 +4,7 @@
*
* IRQ-related code
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/timer.h>
...
...
@@ -27,7 +28,58 @@
int
zfad_dma_start
(
struct
zio_cset
*
cset
)
{
struct
fa_dev
*
fa
=
cset
->
zdev
->
priv_d
;
int
err
;
struct
zfad_block
*
zfad_block
=
cset
->
interleave
->
priv_d
;
uint32_t
dev_mem_off
,
trg_pos
,
pre_samp
;
uint32_t
val
=
0
;
int
try
=
5
,
err
;
/*
* All programmed triggers fire, so the acquisition is ended.
* If the state machine is _idle_ we can start the DMA transfer.
* If the state machine it is not idle, try again 5 times
*/
while
(
try
--
&&
val
!=
ZFA_STATE_IDLE
)
{
/* udelay(2); */
val
=
fa_readl
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFA_STA_FSM
]);
}
if
(
val
!=
ZFA_STATE_IDLE
)
{
/* we can't DMA if the state machine is not idle */
dev_warn
(
&
fa
->
fmc
->
dev
,
"Can't start DMA on the last acquisition, "
"State Machine is not IDLE (status:%d)
\n
"
,
val
);
return
-
EBUSY
;
}
/*
* Disable all triggers to prevent fires between
* different DMA transfers required for multi-shots
*/
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_CFG_HW_EN
],
0
);
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_CFG_SW_EN
],
0
);
/* Fix dev_mem_addr in single-shot mode */
if
(
fa
->
n_shots
==
1
)
{
int
nchan
=
FA_NCHAN
;
struct
zio_control
*
ctrl
=
cset
->
chan
[
FA_NCHAN
].
current_ctrl
;
/* get pre-samples from the current control (interleave chan) */
pre_samp
=
ctrl
->
attr_trigger
.
std_val
[
ZIO_ATTR_TRIG_PRE_SAMP
];
/* Get trigger position in DDR */
trg_pos
=
fa_readl
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_POS
]);
/*
* compute mem offset (in bytes): pre-samp is converted to
* bytes
*/
dev_mem_off
=
trg_pos
-
(
pre_samp
*
cset
->
ssize
*
nchan
);
dev_dbg
(
&
fa
->
fmc
->
dev
,
"Trigger @ 0x%08x, pre_samp %i, offset 0x%08x
\n
"
,
trg_pos
,
pre_samp
,
dev_mem_off
);
zfad_block
[
0
].
dev_mem_off
=
dev_mem_off
;
}
dev_dbg
(
&
fa
->
fmc
->
dev
,
"Start DMA transfer
\n
"
);
err
=
fa
->
carrier_op
->
dma_start
(
cset
);
...
...
@@ -167,10 +219,6 @@ void zfad_dma_error(struct zio_cset *cset)
void
zfat_irq_acq_end
(
struct
zio_cset
*
cset
)
{
struct
fa_dev
*
fa
=
cset
->
zdev
->
priv_d
;
struct
zfad_block
*
zfad_block
=
cset
->
interleave
->
priv_d
;
uint32_t
dev_mem_off
,
trg_pos
,
pre_samp
;
uint32_t
val
=
0
;
int
try
=
5
;
dev_dbg
(
&
fa
->
fmc
->
dev
,
"Acquisition done
\n
"
);
/*FIXME: because the driver doesn't listen anymore trig-event
...
...
@@ -191,51 +239,6 @@ void zfat_irq_acq_end(struct zio_cset *cset)
*/
/* for the time being let assume n_shots have been executed */
fa
->
n_fires
=
fa
->
n_shots
;
/*
* All programmed triggers fire, so the acquisition is ended.
* If the state machine is _idle_ we can start the DMA transfer.
* If the state machine it is not idle, try again 5 times
*/
while
(
try
--
&&
val
!=
ZFA_STATE_IDLE
)
{
//udelay(2);
val
=
fa_readl
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFA_STA_FSM
]);
}
if
(
val
!=
ZFA_STATE_IDLE
)
{
/* we can't DMA if the state machine is not idle */
dev_warn
(
&
fa
->
fmc
->
dev
,
"Can't start DMA on the last acquisition, "
"State Machine is not IDLE (status:%d)
\n
"
,
val
);
zfad_fsm_command
(
fa
,
ZFA_STOP
);
return
;
}
/*
* Disable all triggers to prevent fires between
* different DMA transfers required for multi-shots
*/
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_CFG_HW_EN
],
0
);
fa_writel
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_CFG_SW_EN
],
0
);
/* Fix dev_mem_addr in single-shot mode */
if
(
fa
->
n_shots
==
1
)
{
int
nchan
=
FA_NCHAN
;
struct
zio_control
*
ctrl
=
cset
->
chan
[
FA_NCHAN
].
current_ctrl
;
/* get pre-samples from the current control (interleave chan) */
pre_samp
=
ctrl
->
attr_trigger
.
std_val
[
ZIO_ATTR_TRIG_PRE_SAMP
];
/* Get trigger position in DDR */
trg_pos
=
fa_readl
(
fa
,
fa
->
fa_adc_csr_base
,
&
zfad_regs
[
ZFAT_POS
]);
/* compute mem offset (in bytes): pre-samp is converted to bytes */
dev_mem_off
=
trg_pos
-
(
pre_samp
*
cset
->
ssize
*
nchan
);
dev_dbg
(
&
fa
->
fmc
->
dev
,
"Trigger @ 0x%08x, pre_samp %i, offset 0x%08x
\n
"
,
trg_pos
,
pre_samp
,
dev_mem_off
);
zfad_block
[
0
].
dev_mem_off
=
dev_mem_off
;
}
}
/*
...
...
@@ -257,11 +260,8 @@ static void fa_irq_work(struct work_struct *work)
int
res
;
zfat_irq_acq_end
(
cset
);
res
=
zfad_dma_start
(
cset
);
if
(
res
)
zfad_dma_error
(
cset
);
else
{
if
(
!
res
)
{
/*
* No error.
* If there is an IRQ DMA src to notify the ends of the DMA,
...
...
@@ -287,11 +287,15 @@ static void fa_irq_work(struct work_struct *work)
cset
->
flags
&=
~
ZIO_CSET_BUSY
;
spin_unlock
(
&
cset
->
lock
);
/* Automatic start next acquisition */
if
(
fa
->
enable_auto_start
)
{
if
(
res
)
{
/* Stop acquisition on error */
zfad_dma_error
(
cset
);
}
else
if
(
fa
->
enable_auto_start
)
{
/* Automatic start next acquisition */
dev_dbg
(
&
fa
->
fmc
->
dev
,
"Automatic start
\n
"
);
zfad_fsm_command
(
fa
,
ZFA_START
);
}
end:
/* ack the irq */
fa
->
fmc
->
op
->
irq_ack
(
fa
->
fmc
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment