Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple VME FMC Carrier SVEC - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
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
Simple VME FMC Carrier SVEC - Software
Commits
c4391382
Commit
c4391382
authored
Sep 19, 2014
by
Federico Vaga
Browse files
Options
Browse Files
Download
Plain Diff
Merge commit 'vic-fix-improve'
parents
3cfe8864
877b4ecb
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
50 additions
and
45 deletions
+50
-45
svec-drv.c
kernel/svec-drv.c
+0
-4
svec-fmc.c
kernel/svec-fmc.c
+6
-0
svec-irq.c
kernel/svec-irq.c
+7
-19
svec-sysfs.c
kernel/svec-sysfs.c
+0
-3
svec-vic.c
kernel/svec-vic.c
+36
-16
svec.h
kernel/svec.h
+1
-3
No files found.
kernel/svec-drv.c
View file @
c4391382
...
...
@@ -368,8 +368,6 @@ static int svec_remove(struct device *pdev, unsigned int ndev)
clear_bit
(
SVEC_FLAG_FMCS_REGISTERED
,
&
svec
->
flags
);
}
svec_irq_exit
(
svec
);
svec_unmap_window
(
svec
,
MAP_CR_CSR
);
svec_unmap_window
(
svec
,
MAP_REG
);
svec_remove_sysfs_files
(
svec
);
...
...
@@ -653,8 +651,6 @@ int svec_reconfigure(struct svec_dev *svec)
if
(
svec
->
map
[
MAP_REG
])
svec_unmap_window
(
svec
,
MAP_REG
);
svec_irq_exit
(
svec
);
error
=
svec_setup_csr
(
svec
);
if
(
error
)
return
error
;
...
...
kernel/svec-fmc.c
View file @
c4391382
...
...
@@ -274,6 +274,12 @@ void svec_fmc_destroy(struct svec_dev *svec)
return
;
fmc_device_unregister_n
(
svec
->
fmcs
,
svec
->
fmcs_n
);
WARN
(
test_bit
(
SVEC_FLAG_IRQS_REQUESTED
,
&
svec
->
flags
)
||
svec
->
vic
,
"A Mezzanine driver didn't release all its IRQ handlers (VIC %p, FLAG 0x%x)
\n
"
,
svec
->
vic
,
svec
->
flags
);
memset
(
svec
->
fmcs
,
0
,
sizeof
(
struct
fmc_devices
*
)
*
SVEC_N_SLOTS
);
if
(
svec
->
verbose
)
dev_info
(
svec
->
dev
,
"%d fmc devices unregistered
\n
"
,
svec
->
fmcs_n
);
...
...
kernel/svec-irq.c
View file @
c4391382
...
...
@@ -100,12 +100,13 @@ int svec_irq_free(struct fmc_device *fmc)
if
(
!
test_bit
(
SVEC_FLAG_IRQS_REQUESTED
,
&
svec
->
flags
))
return
-
EINVAL
;
if
(
svec
->
vic
)
return
svec_vic_irq_free
(
svec
,
fmc
->
irq
);
spin_lock
(
&
svec
->
irq_lock
);
svec
->
fmc_handlers
[
fmc
->
slot_id
]
=
NULL
;
spin_unlock
(
&
svec
->
irq_lock
);
if
(
svec
->
vic
)
{
svec_vic_irq_free
(
svec
,
fmc
->
irq
);
}
else
{
spin_lock
(
&
svec
->
irq_lock
);
svec
->
fmc_handlers
[
fmc
->
slot_id
]
=
NULL
;
spin_unlock
(
&
svec
->
irq_lock
);
}
/* shared IRQ mode: disable VME interrupt when freeing last FMC handler */
if
(
!
svec
->
vic
&&
!
svec
->
fmc_handlers
[
0
]
&&
!
svec
->
fmc_handlers
[
1
])
{
...
...
@@ -118,16 +119,3 @@ int svec_irq_free(struct fmc_device *fmc)
return
0
;
}
/* cleanup function, disables VME master interrupt when the driver is unloaded */
void
svec_irq_exit
(
struct
svec_dev
*
svec
)
{
if
(
!
test_bit
(
SVEC_FLAG_IRQS_REQUESTED
,
&
svec
->
flags
))
return
;
vme_free_irq
(
svec
->
current_vector
);
memset
(
svec
->
fmc_handlers
,
0
,
sizeof
(
svec
->
fmc_handlers
));
if
(
svec
->
vic
)
svec_vic_cleanup
(
svec
);
}
kernel/svec-sysfs.c
View file @
c4391382
...
...
@@ -33,10 +33,7 @@ static int svec_fw_cmd_reset (struct svec_dev * card)
{
int
err
=
0
;
if
(
test_bit
(
SVEC_FLAG_FMCS_REGISTERED
,
&
card
->
flags
))
{
svec_fmc_destroy
(
card
);
svec_irq_exit
(
card
);
}
if
(
!
card
->
map
[
MAP_CR_CSR
])
err
=
svec_map_window
(
card
,
MAP_CR_CSR
);
...
...
kernel/svec-vic.c
View file @
c4391382
...
...
@@ -24,6 +24,8 @@
/* A Vectored Interrupt Controller object */
struct
vic_irq_controller
{
/* It protects the handlers' vector */
spinlock_t
vec_lock
;
/* already-initialized flag */
int
initialized
;
/* Base address (FPGA-relative) */
...
...
@@ -78,6 +80,7 @@ static int svec_vic_init(struct svec_dev *svec, struct fmc_device *fmc)
if
(
!
vic
)
return
-
ENOMEM
;
spin_lock_init
(
&
vic
->
vec_lock
);
vic
->
kernel_va
=
svec
->
map
[
MAP_REG
]
->
kernel_va
+
vic_base
;
vic
->
base
=
(
uint32_t
)
vic_base
;
...
...
@@ -98,16 +101,15 @@ static int svec_vic_init(struct svec_dev *svec, struct fmc_device *fmc)
return
0
;
}
void
svec_vic_
cleanup
(
struct
svec_dev
*
sve
c
)
void
svec_vic_
exit
(
struct
vic_irq_controller
*
vi
c
)
{
if
(
!
svec
->
vic
)
if
(
!
vic
)
return
;
/* Disable all irq lines and the VIC in general */
vic_writel
(
svec
->
vic
,
0xffffffff
,
VIC_REG_IDR
);
vic_writel
(
svec
->
vic
,
0
,
VIC_REG_CTL
);
kfree
(
svec
->
vic
);
svec
->
vic
=
NULL
;
vic_writel
(
vic
,
0xffffffff
,
VIC_REG_IDR
);
vic_writel
(
vic
,
0
,
VIC_REG_CTL
);
kfree
(
vic
);
}
irqreturn_t
svec_vic_irq_dispatch
(
struct
svec_dev
*
svec
)
...
...
@@ -162,15 +164,14 @@ int svec_vic_irq_request(struct svec_dev *svec, struct fmc_device *fmc,
for
(
i
=
0
;
i
<
VIC_MAX_VECTORS
;
i
++
)
{
/* find the vector in the stored table, assign handler and enable the line if exists */
if
(
vic
->
vectors
[
i
].
saved_id
==
id
)
{
spin_lock
(
&
svec
->
irq
_lock
);
spin_lock
(
&
svec
->
vic
->
vec
_lock
);
vic_writel
(
vic
,
i
,
VIC_IVT_RAM_BASE
+
4
*
i
);
vic
->
vectors
[
i
].
requestor
=
fmc
;
vic
->
vectors
[
i
].
handler
=
handler
;
vic_writel
(
vic
,
(
1
<<
i
),
VIC_REG_IER
);
spin_unlock
(
&
svec
->
irq_lock
);
spin_unlock
(
&
svec
->
vic
->
vec_lock
);
return
0
;
}
...
...
@@ -180,24 +181,43 @@ int svec_vic_irq_request(struct svec_dev *svec, struct fmc_device *fmc,
}
int
svec_vic_irq_free
(
struct
svec_dev
*
svec
,
unsigned
long
id
)
/*
* vic_handler_count
* It counts how many handlers are registered within the VIC controller
*/
static
inline
int
vic_handler_count
(
struct
vic_irq_controller
*
vic
)
{
int
i
,
count
;
for
(
i
=
0
,
count
=
0
;
i
<
VIC_MAX_VECTORS
;
++
i
)
if
(
vic
->
vectors
[
i
].
handler
)
count
++
;
return
count
;
}
void
svec_vic_irq_free
(
struct
svec_dev
*
svec
,
unsigned
long
id
)
{
int
i
;
for
(
i
=
0
;
i
<
VIC_MAX_VECTORS
;
i
++
)
{
uint32_t
vec
=
svec
->
vic
->
vectors
[
i
].
saved_id
;
if
(
vec
==
id
)
{
spin_lock
(
&
svec
->
irq_lock
);
if
(
svec
->
vic
->
vectors
[
i
].
saved_id
==
id
)
{
spin_lock
(
&
svec
->
vic
->
vec_lock
);
vic_writel
(
svec
->
vic
,
1
<<
i
,
VIC_REG_IDR
);
vic_writel
(
svec
->
vic
,
vec
,
VIC_IVT_RAM_BASE
+
4
*
i
);
vic_writel
(
svec
->
vic
,
id
,
VIC_IVT_RAM_BASE
+
4
*
i
);
svec
->
vic
->
vectors
[
i
].
handler
=
NULL
;
spin_unlock
(
&
svec
->
irq
_lock
);
spin_unlock
(
&
svec
->
vic
->
vec
_lock
);
}
}
return
0
;
/* Clean up the VIC if there are no more handlers */
if
(
!
vic_handler_count
(
svec
->
vic
))
{
svec_vic_exit
(
svec
->
vic
);
svec
->
vic
=
NULL
;
}
}
void
svec_vic_irq_ack
(
struct
svec_dev
*
svec
,
unsigned
long
id
)
...
...
kernel/svec.h
View file @
c4391382
...
...
@@ -147,9 +147,8 @@ int svec_load_golden(struct svec_dev *svec);
/* VIC interrupt controller stuff */
irqreturn_t
svec_vic_irq_dispatch
(
struct
svec_dev
*
svec
);
int
svec_vic_irq_request
(
struct
svec_dev
*
svec
,
struct
fmc_device
*
fmc
,
unsigned
long
id
,
irq_handler_t
handler
);
int
svec_vic_irq_free
(
struct
svec_dev
*
svec
,
unsigned
long
id
);
void
svec_vic_irq_free
(
struct
svec_dev
*
svec
,
unsigned
long
id
);
void
svec_vic_irq_ack
(
struct
svec_dev
*
svec
,
unsigned
long
id
);
void
svec_vic_cleanup
(
struct
svec_dev
*
svec
);
/* Generic IRQ routines */
...
...
@@ -157,7 +156,6 @@ int svec_irq_request(struct fmc_device *fmc, irq_handler_t handler, char *name,
int
flags
);
void
svec_irq_ack
(
struct
fmc_device
*
fmc
);
int
svec_irq_free
(
struct
fmc_device
*
fmc
);
void
svec_irq_exit
(
struct
svec_dev
*
svec
);
#endif
/* __SVEC_H__ */
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