Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple VME FMC Carrier SVEC
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
14
Issues
14
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
Commits
0520def5
Commit
0520def5
authored
Apr 14, 2020
by
Federico Vaga
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sw:drv: add top level device
Signed-off-by:
Federico Vaga
<
federico.vaga@cern.ch
>
parent
570e4342
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
97 additions
and
53 deletions
+97
-53
svec-compat.c
software/kernel/svec-compat.c
+1
-1
svec-core-fpga.c
software/kernel/svec-core-fpga.c
+32
-31
svec-core.c
software/kernel/svec-core.c
+58
-20
svec.h
software/kernel/svec.h
+6
-1
No files found.
software/kernel/svec-compat.c
View file @
0520def5
...
...
@@ -93,7 +93,7 @@ int compat_svec_fw_load(struct svec_dev *svec_dev, const char *name)
struct
fpga_manager
*
mgr
;
int
err
;
mgr
=
fpga_mgr_get
(
&
svec_dev
->
vdev
->
dev
);
mgr
=
fpga_mgr_get
(
&
svec_dev
->
dev
);
if
(
IS_ERR
(
mgr
))
return
-
ENODEV
;
...
...
software/kernel/svec-core-fpga.c
View file @
0520def5
...
...
@@ -74,7 +74,7 @@ static const struct debugfs_reg32 svec_fpga_debugfs_reg32[] = {
static
int
svec_fpga_dbg_bld_info
(
struct
seq_file
*
s
,
void
*
offset
)
{
struct
svec_fpga
*
svec_fpga
=
s
->
private
;
struct
svec_dev
*
svec_dev
=
dev_get_drvdata
(
svec_fpga
->
dev
.
parent
);
struct
svec_dev
*
svec_dev
=
to_svec_dev
(
svec_fpga
->
dev
.
parent
);
int
off
;
if
(
!
(
svec_dev
->
meta
.
cap
&
SVEC_META_CAP_BLD
))
{
...
...
@@ -118,7 +118,7 @@ static const struct file_operations svec_fpga_dbg_bld_info_ops = {
static
int
svec_fpga_dbg_init
(
struct
svec_fpga
*
svec_fpga
)
{
struct
svec_dev
*
svec_dev
=
dev_get_drvdata
(
svec_fpga
->
dev
.
parent
);
struct
svec_dev
*
svec_dev
=
to_svec_dev
(
svec_fpga
->
dev
.
parent
);
int
err
;
svec_fpga
->
dbg_dir
=
debugfs_create_dir
(
dev_name
(
&
svec_fpga
->
dev
),
...
...
@@ -196,9 +196,9 @@ static struct resource svec_fpga_vic_res[] = {
static
int
svec_fpga_vic_init
(
struct
svec_fpga
*
svec_fpga
)
{
struct
svec_dev
*
svec_dev
=
dev_get_drvdata
(
svec_fpga
->
dev
.
parent
);
unsigned
long
vme_start
=
vme_resource_start
(
svec_dev
->
vdev
,
svec_fpga
->
function_nr
);
struct
svec_dev
*
svec_dev
=
to_svec_dev
(
svec_fpga
->
dev
.
parent
);
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec_dev
->
dev
.
parent
);
unsigned
long
vme_start
=
vme_resource_start
(
vdev
,
svec_fpga
->
function_nr
);
const
unsigned
int
res_n
=
ARRAY_SIZE
(
svec_fpga_vic_res
);
struct
resource
res
[
ARRAY_SIZE
(
svec_fpga_vic_res
)];
struct
platform_device
*
pdev
;
...
...
@@ -209,7 +209,7 @@ static int svec_fpga_vic_init(struct svec_fpga *svec_fpga)
memcpy
(
&
res
,
svec_fpga_vic_res
,
sizeof
(
svec_fpga_vic_res
));
res
[
0
].
start
+=
vme_start
;
res
[
0
].
end
+=
vme_start
;
res
[
1
].
start
=
svec_dev
->
vdev
->
irq
;
res
[
1
].
start
=
vdev
->
irq
;
res
[
1
].
end
=
res
[
1
].
start
;
pdev
=
platform_device_register_resndata
(
&
svec_fpga
->
dev
,
"htvic-svec"
,
...
...
@@ -327,7 +327,7 @@ static inline size_t __fpga_mfd_devs_size(void)
static
int
svec_fpga_devices_init
(
struct
svec_fpga
*
svec_fpga
)
{
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec_fpga
->
dev
.
parent
);
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec_fpga
->
dev
.
parent
->
parent
);
struct
mfd_cell
*
fpga_mfd_devs
;
struct
irq_domain
*
vic_domain
;
unsigned
int
n_mfd
=
0
;
...
...
@@ -376,7 +376,7 @@ static ssize_t temperature_show(struct device *dev,
char
*
buf
)
{
struct
svec_fpga
*
svec_fpga
=
to_svec_fpga
(
dev
);
struct
svec_dev
*
svec_dev
=
dev_get_drvdata
(
svec_fpga
->
dev
.
parent
);
struct
svec_dev
*
svec_dev
=
to_svec_dev
(
svec_fpga
->
dev
.
parent
);
if
(
svec_dev
->
meta
.
cap
&
SVEC_META_CAP_THERM
)
{
uint32_t
temp
=
ioread32be
(
svec_fpga
->
fpga
...
...
@@ -396,7 +396,7 @@ static ssize_t serial_number_show(struct device *dev,
char
*
buf
)
{
struct
svec_fpga
*
svec_fpga
=
to_svec_fpga
(
dev
);
struct
svec_dev
*
svec_dev
=
dev_get_drvdata
(
svec_fpga
->
dev
.
parent
);
struct
svec_dev
*
svec_dev
=
to_svec_dev
(
svec_fpga
->
dev
.
parent
);
if
(
svec_dev
->
meta
.
cap
&
SVEC_META_CAP_THERM
)
{
uint32_t
msb
=
ioread32be
(
svec_fpga
->
fpga
...
...
@@ -727,14 +727,14 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev,
struct
svec_meta_id
*
meta
)
{
if
((
meta
->
bom
&
SVEC_META_BOM_END_MASK
)
!=
SVEC_META_BOM_BE
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Expected Big Endian devices BOM: 0x%x
\n
"
,
meta
->
bom
);
return
false
;
}
if
((
meta
->
bom
&
SVEC_META_BOM_VER_MASK
)
!=
0
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Unknow Metadata svecification version BOM: 0x%x
\n
"
,
meta
->
bom
);
return
false
;
...
...
@@ -742,14 +742,14 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev,
if
(
meta
->
vendor
!=
SVEC_META_VENDOR_ID
||
meta
->
device
!=
SVEC_META_DEVICE_ID
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Unknow vendor/device ID: %08x:%08x
\n
"
,
meta
->
vendor
,
meta
->
device
);
return
false
;
}
if
((
meta
->
version
&
SVEC_META_VERSION_MASK
)
!=
SVEC_META_VERSION_1_4
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Unknow version: %08x
\n
"
,
meta
->
version
);
return
false
;
}
...
...
@@ -757,33 +757,34 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev,
return
true
;
}
static
void
svec_release
(
struct
device
*
dev
)
static
void
svec_
fpga_
release
(
struct
device
*
dev
)
{
}
static
int
svec_uevent
(
struct
device
*
dev
,
struct
kobj_uevent_env
*
env
)
static
int
svec_
fpga_
uevent
(
struct
device
*
dev
,
struct
kobj_uevent_env
*
env
)
{
return
0
;
}
static
const
struct
attribute_group
*
svec_groups
[]
=
{
static
const
struct
attribute_group
*
svec_
fpga_
groups
[]
=
{
&
svec_fpga_therm_group
,
&
svec_fpga_csr_group
,
NULL
};
static
const
struct
device_type
svec_fpga_type
=
{
.
name
=
"svec"
,
.
release
=
svec_release
,
.
uevent
=
svec_uevent
,
.
groups
=
svec_groups
,
.
name
=
"svec
-fpga
"
,
.
release
=
svec_
fpga_
release
,
.
uevent
=
svec_
fpga_
uevent
,
.
groups
=
svec_
fpga_
groups
,
};
int
svec_fpga_init
(
struct
svec_dev
*
svec_dev
,
unsigned
int
function_nr
)
{
struct
svec_fpga
*
svec_fpga
;
struct
resource
*
r
=
&
svec_dev
->
vdev
->
resource
[
function_nr
];
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec_dev
->
dev
.
parent
);
struct
resource
*
r
=
&
vdev
->
resource
[
function_nr
];
int
err
;
svec_fpga
=
kzalloc
(
sizeof
(
*
svec_fpga
),
GFP_KERNEL
);
...
...
@@ -804,18 +805,18 @@ int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr)
goto
err_valid
;
}
svec_fpga
->
dev
.
parent
=
&
svec_dev
->
vdev
->
dev
;
svec_fpga
->
dev
.
driver
=
svec_dev
->
vdev
->
dev
.
driver
;
svec_fpga
->
dev
.
parent
=
&
svec_dev
->
dev
;
svec_fpga
->
dev
.
driver
=
svec_dev
->
dev
.
driver
;
svec_fpga
->
dev
.
type
=
&
svec_fpga_type
;
err
=
dev_set_name
(
&
svec_fpga
->
dev
,
"
svec-%s
"
,
dev_name
(
&
svec_dev
->
vdev
->
dev
));
err
=
dev_set_name
(
&
svec_fpga
->
dev
,
"
%s-fpga
"
,
dev_name
(
&
svec_dev
->
dev
));
if
(
err
)
goto
err_name
;
err
=
device_register
(
&
svec_fpga
->
dev
);
if
(
err
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
"Failed to register '%s'
\n
"
,
dev_name
(
&
svec_
dev
->
vdev
->
dev
));
dev_err
(
&
svec_dev
->
dev
,
"Failed to register '%s'
\n
"
,
dev_name
(
&
svec_
fpga
->
dev
));
goto
err_dev
;
}
...
...
@@ -823,25 +824,25 @@ int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr)
err
=
svec_fpga_vic_init
(
svec_fpga
);
if
(
err
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Failed to initialize VIC %d
\n
"
,
err
);
goto
err_vic
;
}
err
=
svec_fpga_devices_init
(
svec_fpga
);
if
(
err
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Failed to initialize Devices %d
\n
"
,
err
);
goto
err_devs
;
}
err
=
svec_fmc_init
(
svec_fpga
);
if
(
err
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Failed to initialize FMC %d
\n
"
,
err
);
goto
err_fmc
;
}
err
=
svec_fpga_app_init
(
svec_fpga
);
if
(
err
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Failed to initialize APP %d
\n
"
,
err
);
goto
err_app
;
}
...
...
software/kernel/svec-core.c
View file @
0520def5
...
...
@@ -53,10 +53,10 @@ static int svec_fw_load(struct svec_dev *svec_dev, const char *name)
{
int
err
;
dev_dbg
(
&
svec_dev
->
vdev
->
dev
,
"Writing firmware '%s'
\n
"
,
name
);
dev_dbg
(
&
svec_dev
->
dev
,
"Writing firmware '%s'
\n
"
,
name
);
err
=
svec_fpga_exit
(
svec_dev
);
if
(
err
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Cannot remove FPGA device instances. Try to remove them manually and to reload this device instance
\n
"
);
return
err
;
}
...
...
@@ -84,7 +84,7 @@ static ssize_t svec_dbg_fw_write(struct file *file,
int
err
,
ret
;
if
(
VBRIDGE_DBG_FW_BUF_LEN
<
count
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Firmware name too long max %u
\n
"
,
VBRIDGE_DBG_FW_BUF_LEN
);
...
...
@@ -101,7 +101,7 @@ static ssize_t svec_dbg_fw_write(struct file *file,
err
=
svec_fw_load
(
svec_dev
,
buf_l
);
if
(
err
)
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"FPGA Configuration failure %d
\n
"
,
err
);
/*
...
...
@@ -109,11 +109,11 @@ static ssize_t svec_dbg_fw_write(struct file *file,
* the SVEC device that we used to re-flash the FPGA disappeard and so
* this driver instance must disapear as well.
*/
dev_warn
(
&
svec_dev
->
vdev
->
dev
,
"VME Slave removed
\n
"
);
dev_warn
(
&
svec_dev
->
vdev
->
dev
,
"Remove this device driver instance
\n
"
);
ret
=
device_schedule_callback
(
&
svec_dev
->
vdev
->
dev
,
remove_callback
);
dev_warn
(
&
svec_dev
->
dev
,
"VME Slave removed
\n
"
);
dev_warn
(
&
svec_dev
->
dev
,
"Remove this device driver instance
\n
"
);
ret
=
device_schedule_callback
(
svec_dev
->
dev
.
parent
,
remove_callback
);
if
(
ret
)
{
dev_err
(
&
svec_dev
->
vdev
->
dev
,
dev_err
(
&
svec_dev
->
dev
,
"Can't remove device driver instance %d
\n
"
,
ret
);
return
ret
;
}
...
...
@@ -181,7 +181,7 @@ static const struct file_operations svec_dbg_meta_ops = {
static
int
svec_dbg_init
(
struct
svec_dev
*
svec_dev
)
{
struct
device
*
dev
=
&
svec_dev
->
vdev
->
dev
;
struct
device
*
dev
=
&
svec_dev
->
dev
;
svec_dev
->
dbg_dir
=
debugfs_create_dir
(
dev_name
(
dev
),
NULL
);
if
(
IS_ERR_OR_NULL
(
svec_dev
->
dbg_dir
))
{
...
...
@@ -229,7 +229,8 @@ static void svec_dbg_exit(struct svec_dev *svec_dev)
static
int
svec_fpga_reset
(
struct
fpga_manager
*
mgr
)
{
struct
svec_dev
*
svec
=
mgr
->
priv
;
void
*
loader_addr
=
svec
->
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec
->
dev
.
parent
);
void
*
loader_addr
=
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
int
i
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
...
...
@@ -252,7 +253,8 @@ static int svec_fpga_reset(struct fpga_manager *mgr)
static
int
svec_fpga_loader_is_active
(
struct
fpga_manager
*
mgr
)
{
struct
svec_dev
*
svec
=
mgr
->
priv
;
void
*
loader_addr
=
svec
->
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec
->
dev
.
parent
);
void
*
loader_addr
=
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
char
buf
[
5
];
uint32_t
idc
;
...
...
@@ -282,7 +284,8 @@ static int svec_fpga_write_word(struct fpga_manager *mgr,
unsigned
int
is_last
)
{
struct
svec_dev
*
svec
=
mgr
->
priv
;
void
*
loader_addr
=
svec
->
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec
->
dev
.
parent
);
void
*
loader_addr
=
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
uint32_t
xldr_fifo_r0
;
/* Bitstream data input control register */
uint32_t
xldr_fifo_r1
;
/* Bitstream data input register */
int
rv
,
try
=
10000
;
...
...
@@ -315,7 +318,8 @@ static int svec_fpga_write_word(struct fpga_manager *mgr,
static
int
svec_fpga_write_start
(
struct
fpga_manager
*
mgr
)
{
struct
svec_dev
*
svec
=
mgr
->
priv
;
void
*
loader_addr
=
svec
->
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec
->
dev
.
parent
);
void
*
loader_addr
=
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
int
err
,
succ
;
/* reset the FPGA */
...
...
@@ -355,7 +359,8 @@ static int svec_fpga_write_stop(struct fpga_manager *mgr,
struct
fpga_image_info
*
info
)
{
struct
svec_dev
*
svec
=
mgr
->
priv
;
void
*
loader_addr
=
svec
->
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec
->
dev
.
parent
);
void
*
loader_addr
=
vdev
->
map_cr
.
kernel_va
+
SVEC_BASE_LOADER
;
u64
timeout
;
int
rval
=
0
,
err
;
...
...
@@ -500,7 +505,7 @@ static const struct fpga_manager_ops svec_fpga_ops = {
static
int
svec_vme_init
(
struct
svec_dev
*
svec
)
{
struct
vme_dev
*
vdev
=
svec
->
vdev
;
struct
vme_dev
*
vdev
=
to_vme_dev
(
svec
->
dev
.
parent
)
;
int
err
;
err
=
vme_disable_device
(
vdev
);
...
...
@@ -515,6 +520,22 @@ static int svec_vme_init(struct svec_dev *svec)
return
vme_enable_device
(
vdev
);
}
static
void
svec_dev_release
(
struct
device
*
dev
)
{
}
static
int
svec_dev_uevent
(
struct
device
*
dev
,
struct
kobj_uevent_env
*
env
)
{
return
0
;
}
static
const
struct
device_type
svec_type
=
{
.
name
=
"svec"
,
.
release
=
svec_dev_release
,
.
uevent
=
svec_dev_uevent
,
};
/**
* It initialize a new SVEC instance
* @pdev correspondend Linux device instance
...
...
@@ -534,15 +555,27 @@ static int svec_probe(struct device *dev, unsigned int ndev)
goto
err
;
}
dev_set_drvdata
(
dev
,
svec
);
spin_lock_init
(
&
svec
->
lock
);
mutex_init
(
&
svec
->
mtx
);
svec
->
vdev
=
vdev
;
dev_set_drvdata
(
dev
,
svec
);
svec
->
dev
.
parent
=
&
vdev
->
dev
;
svec
->
dev
.
type
=
&
svec_type
;
svec
->
dev
.
driver
=
vdev
->
dev
.
driver
;
err
=
dev_set_name
(
&
svec
->
dev
,
"svec-%s"
,
dev_name
(
svec
->
dev
.
parent
));
if
(
err
)
goto
err_name
;
err
=
device_register
(
&
svec
->
dev
);
if
(
err
)
{
dev_err
(
dev
,
"Failed to register '%s'
\n
"
,
dev_name
(
&
svec
->
dev
));
goto
err_dev
;
}
svec_vme_init
(
svec
);
svec
->
fpga_status
=
FPGA_MGR_STATE_UNKNOWN
;
svec
->
mgr
=
fpga_mgr_create
(
dev
,
dev_name
(
dev
),
svec
->
mgr
=
fpga_mgr_create
(
&
svec
->
dev
,
dev_name
(
&
svec
->
dev
),
&
svec_fpga_ops
,
svec
);
if
(
!
svec
->
mgr
)
{
err
=
-
EPERM
;
...
...
@@ -565,6 +598,9 @@ static int svec_probe(struct device *dev, unsigned int ndev)
err_fpga_reg:
fpga_mgr_free
(
svec
->
mgr
);
err_fpga_new:
device_unregister
(
&
svec
->
dev
);
err_dev:
err_name:
dev_set_drvdata
(
dev
,
NULL
);
kfree
(
svec
);
err:
...
...
@@ -585,17 +621,19 @@ static int svec_remove(struct device *dev, unsigned int ndev)
svec_dbg_exit
(
svec
);
fpga_mgr_unregister
(
svec
->
mgr
);
fpga_mgr_free
(
svec
->
mgr
);
dev_set_drvdata
(
dev
,
NULL
);
if
((
svec
->
flags
&
SVEC_DEV_FLAGS_REPROGRAMMED
)
==
0
)
{
/*
* If FPGA is REPROGRAMMED then there is
* no device to disable
*/
vme_disable_device
(
svec
->
vdev
);
vme_disable_device
(
to_vme_dev
(
svec
->
dev
.
parent
)
);
}
device_unregister
(
&
svec
->
dev
);
kfree
(
svec
);
dev_set_drvdata
(
dev
,
NULL
);
return
0
;
}
...
...
software/kernel/svec.h
View file @
0520def5
...
...
@@ -126,7 +126,7 @@ static inline struct svec_fpga *to_svec_fpga(struct device *_dev)
* @mem: ioremapped memory
*/
struct
svec_dev
{
struct
vme_dev
*
v
dev
;
struct
device
dev
;
char
name
[
8
];
unsigned
long
flags
;
struct
svec_meta_id
meta
;
...
...
@@ -150,6 +150,11 @@ struct svec_dev {
struct
svec_fpga
*
svec_fpga
;
};
static
inline
struct
svec_dev
*
to_svec_dev
(
struct
device
*
_dev
)
{
return
container_of
(
_dev
,
struct
svec_dev
,
dev
);
}
extern
int
svec_fpga_init
(
struct
svec_dev
*
svec_dev
,
unsigned
int
function_nr
);
extern
int
svec_fpga_exit
(
struct
svec_dev
*
svec_dev
);
#endif
/* __SVEC_H__ */
Federico Vaga
@FedericoVaga
mentioned in commit
dd8c6a17
·
Jun 03, 2020
mentioned in commit
dd8c6a17
mentioned in commit dd8c6a17ac28714ab9d8a86cc3b0a3d6788cefdd
Toggle commit list
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