Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple PCIe FMC carrier SPEC
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
50
Issues
50
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 PCIe FMC carrier SPEC
Commits
f5423aec
Commit
f5423aec
authored
Jul 09, 2019
by
Federico Vaga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sw:drv: split the device in two parts
Signed-off-by:
Federico Vaga
<
federico.vaga@cern.ch
>
parent
5f7187a0
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
339 additions
and
308 deletions
+339
-308
spec-compat.c
software/kernel/spec-compat.c
+2
-2
spec-compat.h
software/kernel/spec-compat.h
+1
-1
spec-core-fpga.c
software/kernel/spec-core-fpga.c
+159
-138
spec-core.c
software/kernel/spec-core.c
+42
-40
spec-dbg.c
software/kernel/spec-dbg.c
+57
-53
spec-gpio.c
software/kernel/spec-gpio.c
+37
-37
spec.h
software/kernel/spec.h
+41
-37
No files found.
software/kernel/spec-compat.c
View file @
f5423aec
...
...
@@ -124,13 +124,13 @@ static struct platform_device *mfd_find_device(struct device *parent,
return
to_platform_device
(
dev
);
}
int
compat_spec_fw_load
(
struct
spec_
dev
*
spec
,
const
char
*
name
)
int
compat_spec_fw_load
(
struct
spec_
gn412x
*
spec_gn412x
,
const
char
*
name
)
{
struct
fpga_manager
*
mgr
;
struct
platform_device
*
fpga_pdev
;
int
err
;
fpga_pdev
=
mfd_find_device
(
spec
->
dev
.
parent
,
"gn412x-fcl"
,
-
1
);
fpga_pdev
=
mfd_find_device
(
&
spec_gn412x
->
pdev
->
dev
,
"gn412x-fcl"
,
-
1
);
if
(
!
fpga_pdev
)
return
-
ENODEV
;
mgr
=
fpga_mgr_get
(
&
fpga_pdev
->
dev
);
...
...
software/kernel/spec-compat.h
View file @
f5423aec
...
...
@@ -49,7 +49,7 @@ int compat_spec_fpga_write_complete(struct fpga_manager *mgr,
#endif
int
compat_get_fpga_last_word_size
(
struct
fpga_image_info
*
info
,
size_t
count
);
int
compat_spec_fw_load
(
struct
spec_
dev
*
spec
,
const
char
*
name
);
int
compat_spec_fw_load
(
struct
spec_
gn412x
*
spec_gn412x
,
const
char
*
name
);
#if KERNEL_VERSION(3, 11, 0) > LINUX_VERSION_CODE
#define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \
...
...
software/kernel/spec-core-fpga.c
View file @
f5423aec
This diff is collapsed.
Click to expand it.
software/kernel/spec-core.c
View file @
f5423aec
...
...
@@ -90,12 +90,12 @@ static const struct mfd_cell spec_mfd_devs[] = {
*
* Return: FPGA firmware name
*/
static
const
char
*
spec_fw_name_init_get
(
struct
spec_
dev
*
spec
)
static
const
char
*
spec_fw_name_init_get
(
struct
spec_
gn412x
*
spec_gn412x
)
{
if
(
strlen
(
spec_fw_name
)
>
0
)
return
spec_fw_name
;
switch
(
spec
->
pdev
->
device
)
{
switch
(
spec
_gn412x
->
pdev
->
device
)
{
case
PCI_DEVICE_ID_SPEC_45T
:
return
spec_fw_name_45t
;
case
PCI_DEVICE_ID_SPEC_100T
:
...
...
@@ -114,35 +114,36 @@ static const char *spec_fw_name_init_get(struct spec_dev *spec)
*
* Return: 0 on success, otherwise a negative error number
*/
int
spec_fw_load
(
struct
spec_
dev
*
spec
,
const
char
*
name
)
int
spec_fw_load
(
struct
spec_
gn412x
*
spec_gn412x
,
const
char
*
name
)
{
enum
spec_fpga_select
sel
;
int
err
;
err
=
spec_fpga_exit
(
spec
);
err
=
spec_fpga_exit
(
spec
_gn412x
);
if
(
err
)
{
dev_err
(
&
spec
->
pdev
->
dev
,
dev_err
(
&
spec
_gn412x
->
pdev
->
dev
,
"Cannot remove FPGA device instances. Try to remove them manually and to reload this device instance
\n
"
);
return
err
;
}
mutex_lock
(
&
spec
->
mtx
);
sel
=
spec_gpio_fpga_select_get
(
spec
);
mutex_lock
(
&
spec
_gn412x
->
mtx
);
sel
=
spec_gpio_fpga_select_get
(
spec
_gn412x
);
spec_gpio_fpga_select_set
(
spec
,
SPEC_FPGA_SELECT_GN4124_FPGA
);
spec_gpio_fpga_select_set
(
spec
_gn412x
,
SPEC_FPGA_SELECT_GN4124_FPGA
);
err
=
compat_spec_fw_load
(
spec
,
name
);
err
=
compat_spec_fw_load
(
spec
_gn412x
,
name
);
if
(
err
)
goto
out
;
err
=
spec_fpga_init
(
spec
);
err
=
spec_fpga_init
(
spec
_gn412x
);
if
(
err
)
dev_warn
(
&
spec
->
pdev
->
dev
,
"FPGA incorrectly programmed
\n
"
);
dev_warn
(
&
spec_gn412x
->
pdev
->
dev
,
"FPGA incorrectly programmed
\n
"
);
out:
spec_gpio_fpga_select_set
(
spec
,
sel
);
mutex_unlock
(
&
spec
->
mtx
);
spec_gpio_fpga_select_set
(
spec
_gn412x
,
sel
);
mutex_unlock
(
&
spec
_gn412x
->
mtx
);
return
err
;
}
...
...
@@ -152,7 +153,7 @@ static ssize_t bootselect_store(struct device *dev,
const
char
*
buf
,
size_t
count
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
dev
);
struct
spec_
dev
*
spec
=
pci_get_drvdata
(
pdev
);
struct
spec_
gn412x
*
spec_gn412x
=
pci_get_drvdata
(
pdev
);
enum
spec_fpga_select
sel
;
if
(
strncmp
(
"fpga-flash"
,
buf
,
8
)
==
0
)
{
...
...
@@ -167,9 +168,9 @@ static ssize_t bootselect_store(struct device *dev,
return
-
EINVAL
;
}
mutex_lock
(
&
spec
->
mtx
);
spec_gpio_fpga_select_set
(
spec
,
sel
);
mutex_unlock
(
&
spec
->
mtx
);
mutex_lock
(
&
spec
_gn412x
->
mtx
);
spec_gpio_fpga_select_set
(
spec
_gn412x
,
sel
);
mutex_unlock
(
&
spec
_gn412x
->
mtx
);
return
count
;
...
...
@@ -179,10 +180,10 @@ static ssize_t bootselect_show(struct device *dev,
char
*
buf
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
dev
);
struct
spec_
dev
*
spec
=
pci_get_drvdata
(
pdev
);
struct
spec_
gn412x
*
spec_gn412x
=
pci_get_drvdata
(
pdev
);
enum
spec_fpga_select
sel
;
sel
=
spec_gpio_fpga_select_get
(
spec
);
sel
=
spec_gpio_fpga_select_get
(
spec
_gn412x
);
switch
(
sel
)
{
case
SPEC_FPGA_SELECT_FPGA_FLASH
:
return
snprintf
(
buf
,
PAGE_SIZE
,
"fpga-flash
\n
"
);
...
...
@@ -206,10 +207,10 @@ static ssize_t load_golden_fpga_store(struct device *dev,
const
char
*
buf
,
size_t
count
)
{
struct
pci_dev
*
pdev
=
to_pci_dev
(
dev
);
struct
spec_
dev
*
spec
=
pci_get_drvdata
(
pdev
);
struct
spec_
gn412x
*
spec_gn412x
=
pci_get_drvdata
(
pdev
);
int
err
;
err
=
spec_fw_load
(
spec
,
spec_fw_name_init_get
(
spec
));
err
=
spec_fw_load
(
spec
_gn412x
,
spec_fw_name_init_get
(
spec_gn412x
));
return
err
<
0
?
err
:
count
;
}
...
...
@@ -229,16 +230,16 @@ static const struct attribute_group gn412x_fpga_group = {
static
int
spec_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
id
)
{
struct
spec_
dev
*
spec
;
struct
spec_
gn412x
*
spec_gn412x
;
int
err
;
spec
=
kzalloc
(
sizeof
(
*
spec
),
GFP_KERNEL
);
if
(
!
spec
)
spec
_gn412x
=
kzalloc
(
sizeof
(
*
spec_gn412x
),
GFP_KERNEL
);
if
(
!
spec
_gn412x
)
return
-
ENOMEM
;
mutex_init
(
&
spec
->
mtx
);
pci_set_drvdata
(
pdev
,
spec
);
spec
->
pdev
=
pdev
;
mutex_init
(
&
spec
_gn412x
->
mtx
);
pci_set_drvdata
(
pdev
,
spec
_gn412x
);
spec
_gn412x
->
pdev
=
pdev
;
err
=
pci_enable_device
(
pdev
);
if
(
err
)
{
...
...
@@ -253,12 +254,13 @@ static int spec_probe(struct pci_dev *pdev,
ARRAY_SIZE
(
spec_mfd_devs
),
&
pdev
->
resource
[
4
],
pdev
->
irq
,
NULL
);
if
(
err
)
{
dev_err
(
&
spec
->
pdev
->
dev
,
"Failed to add MFD devices (%d)
\n
"
,
dev_err
(
&
spec_gn412x
->
pdev
->
dev
,
"Failed to add MFD devices (%d)
\n
"
,
err
);
goto
err_mfd
;
}
err
=
spec_gpio_init
(
spec
);
err
=
spec_gpio_init
(
spec
_gn412x
);
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to get GPIOs (%d)
\n
"
,
err
);
goto
err_sgpio
;
...
...
@@ -268,41 +270,41 @@ static int spec_probe(struct pci_dev *pdev,
if
(
err
)
goto
err_sysfs
;
spec_dbg_init
(
spec
);
spec_dbg_init
(
spec
_gn412x
);
mutex_lock
(
&
spec
->
mtx
);
err
=
spec_fpga_init
(
spec
);
mutex_lock
(
&
spec
_gn412x
->
mtx
);
err
=
spec_fpga_init
(
spec
_gn412x
);
if
(
err
)
dev_warn
(
&
pdev
->
dev
,
"FPGA incorrectly programmed or empty (%d)
\n
"
,
err
);
mutex_unlock
(
&
spec
->
mtx
);
mutex_unlock
(
&
spec
_gn412x
->
mtx
);
return
0
;
err_sysfs:
spec_gpio_exit
(
spec
);
spec_gpio_exit
(
spec
_gn412x
);
err_sgpio:
mfd_remove_devices
(
&
pdev
->
dev
);
err_mfd:
pci_disable_device
(
pdev
);
err_enable:
kfree
(
spec
);
kfree
(
spec
_gn412x
);
return
err
;
}
static
void
spec_remove
(
struct
pci_dev
*
pdev
)
{
struct
spec_
dev
*
spec
=
pci_get_drvdata
(
pdev
);
struct
spec_
gn412x
*
spec_gn412x
=
pci_get_drvdata
(
pdev
);
spec_dbg_exit
(
spec
);
spec_fpga_exit
(
spec
);
spec_dbg_exit
(
spec
_gn412x
);
spec_fpga_exit
(
spec
_gn412x
);
sysfs_remove_group
(
&
pdev
->
dev
.
kobj
,
&
gn412x_fpga_group
);
spec_gpio_exit
(
spec
);
spec_gpio_exit
(
spec
_gn412x
);
mfd_remove_devices
(
&
pdev
->
dev
);
pci_disable_device
(
pdev
);
kfree
(
spec
);
kfree
(
spec
_gn412x
);
}
...
...
software/kernel/spec-dbg.c
View file @
f5423aec
...
...
@@ -13,25 +13,25 @@
static
int
spec_irq_dbg_info
(
struct
seq_file
*
s
,
void
*
offset
)
{
struct
spec_
dev
*
spec
=
s
->
private
;
struct
spec_
gn412x
*
spec_gn412x
=
s
->
private
;
seq_printf
(
s
,
"'%s':
\n
"
,
dev_name
(
&
spec
->
pdev
->
dev
));
seq_printf
(
s
,
"'%s':
\n
"
,
dev_name
(
&
spec
_gn412x
->
pdev
->
dev
));
seq_printf
(
s
,
" redirect: %d
\n
"
,
to_pci_dev
(
&
spec
->
pdev
->
dev
)
->
irq
);
seq_printf
(
s
,
" redirect: %d
\n
"
,
to_pci_dev
(
&
spec
_gn412x
->
pdev
->
dev
)
->
irq
);
seq_puts
(
s
,
" irq-mapping:
\n
"
);
seq_puts
(
s
,
" - hardware: 8
\n
"
);
seq_printf
(
s
,
" linux: %d
\n
"
,
gpiod_to_irq
(
spec
->
gpiod
[
GN4124_GPIO_IRQ0
]));
gpiod_to_irq
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ0
]));
seq_puts
(
s
,
" - hardware: 9
\n
"
);
seq_printf
(
s
,
" linux: %d
\n
"
,
gpiod_to_irq
(
spec
->
gpiod
[
GN4124_GPIO_IRQ1
]));
gpiod_to_irq
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ1
]));
return
0
;
}
static
int
spec_irq_dbg_info_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
spec_
dev
*
spec
=
inode
->
i_private
;
struct
spec_
gn412x
*
spec
=
inode
->
i_private
;
return
single_open
(
file
,
spec_irq_dbg_info
,
spec
);
}
...
...
@@ -48,10 +48,10 @@ static ssize_t spec_dbg_fw_write(struct file *file,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
spec_
dev
*
spec
=
file
->
private_data
;
struct
spec_
gn412x
*
spec_gn412x
=
file
->
private_data
;
int
err
;
err
=
spec_fw_load
(
spec
,
buf
);
err
=
spec_fw_load
(
spec
_gn412x
,
buf
);
if
(
err
)
return
err
;
return
count
;
...
...
@@ -73,32 +73,32 @@ static const struct file_operations spec_dbg_fw_ops = {
static
int
spec_dbg_meta
(
struct
seq_file
*
s
,
void
*
offset
)
{
struct
spec_
dev
*
spec
=
s
->
private
;
struct
spec_
gn412x
*
spec_gn412x
=
s
->
private
;
seq_printf
(
s
,
"'%s':
\n
"
,
dev_name
(
&
spec
->
pdev
->
dev
));
seq_printf
(
s
,
"'%s':
\n
"
,
dev_name
(
&
spec
_gn412x
->
pdev
->
dev
));
seq_puts
(
s
,
"Metadata:
\n
"
);
seq_printf
(
s
,
" - Vendor: 0x%08x
\n
"
,
spec
->
meta
->
vendor
);
seq_printf
(
s
,
" - Device: 0x%08x
\n
"
,
spec
->
meta
->
device
);
seq_printf
(
s
,
" - Version: 0x%08x
\n
"
,
spec
->
meta
->
version
);
seq_printf
(
s
,
" - BOM: 0x%08x
\n
"
,
spec
->
meta
->
bom
);
seq_printf
(
s
,
" - Vendor: 0x%08x
\n
"
,
spec
_gn412x
->
meta
->
vendor
);
seq_printf
(
s
,
" - Device: 0x%08x
\n
"
,
spec
_gn412x
->
meta
->
device
);
seq_printf
(
s
,
" - Version: 0x%08x
\n
"
,
spec
_gn412x
->
meta
->
version
);
seq_printf
(
s
,
" - BOM: 0x%08x
\n
"
,
spec
_gn412x
->
meta
->
bom
);
seq_printf
(
s
,
" - SourceID: 0x%08x%08x%08x%08x
\n
"
,
spec
->
meta
->
src
[
0
],
spec
->
meta
->
src
[
1
],
spec
->
meta
->
src
[
2
],
spec
->
meta
->
src
[
3
]);
seq_printf
(
s
,
" - CapabilityMask: 0x%08x
\n
"
,
spec
->
meta
->
cap
);
spec
_gn412x
->
meta
->
src
[
0
],
spec
_gn412x
->
meta
->
src
[
1
],
spec
_gn412x
->
meta
->
src
[
2
],
spec
_gn412x
->
meta
->
src
[
3
]);
seq_printf
(
s
,
" - CapabilityMask: 0x%08x
\n
"
,
spec
_gn412x
->
meta
->
cap
);
seq_printf
(
s
,
" - VendorUUID: 0x%08x%08x%08x%08x
\n
"
,
spec
->
meta
->
uuid
[
0
],
spec
->
meta
->
uuid
[
1
],
spec
->
meta
->
uuid
[
2
],
spec
->
meta
->
uuid
[
3
]);
spec
_gn412x
->
meta
->
uuid
[
0
],
spec
_gn412x
->
meta
->
uuid
[
1
],
spec
_gn412x
->
meta
->
uuid
[
2
],
spec
_gn412x
->
meta
->
uuid
[
3
]);
return
0
;
}
static
int
spec_dbg_meta_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
spec_
dev
*
spec
=
inode
->
i_private
;
struct
spec_
gn412x
*
spec
=
inode
->
i_private
;
return
single_open
(
file
,
spec_dbg_meta
,
spec
);
}
...
...
@@ -117,44 +117,48 @@ static const struct file_operations spec_dbg_meta_ops = {
*
* Return: 0 on success, otherwise a negative error number
*/
int
spec_dbg_init
(
struct
spec_
dev
*
spec
)
int
spec_dbg_init
(
struct
spec_
gn412x
*
spec_gn412x
)
{
spec
->
dbg_dir
=
debugfs_create_dir
(
dev_name
(
&
spec
->
pdev
->
dev
),
NULL
);
if
(
IS_ERR_OR_NULL
(
spec
->
dbg_dir
))
{
dev_err
(
&
spec
->
dev
,
spec_gn412x
->
dbg_dir
=
debugfs_create_dir
(
dev_name
(
&
spec_gn412x
->
pdev
->
dev
),
NULL
);
if
(
IS_ERR_OR_NULL
(
spec_gn412x
->
dbg_dir
))
{
dev_err
(
&
spec_gn412x
->
pdev
->
dev
,
"Cannot create debugfs directory (%ld)
\n
"
,
PTR_ERR
(
spec
->
dbg_dir
));
return
PTR_ERR
(
spec
->
dbg_dir
);
PTR_ERR
(
spec
_gn412x
->
dbg_dir
));
return
PTR_ERR
(
spec
_gn412x
->
dbg_dir
);
}
spec
->
dbg_info
=
debugfs_create_file
(
SPEC_DBG_INFO_NAME
,
0444
,
spec
->
dbg_dir
,
spec
,
&
spec_irq_dbg_info_ops
);
if
(
IS_ERR_OR_NULL
(
spec
->
dbg_info
))
{
dev_err
(
&
spec
->
dev
,
spec_gn412x
->
dbg_info
=
debugfs_create_file
(
SPEC_DBG_INFO_NAME
,
0444
,
spec_gn412x
->
dbg_dir
,
spec_gn412x
,
&
spec_irq_dbg_info_ops
);
if
(
IS_ERR_OR_NULL
(
spec_gn412x
->
dbg_info
))
{
dev_err
(
&
spec_gn412x
->
pdev
->
dev
,
"Cannot create debugfs file
\"
%s
\"
(%ld)
\n
"
,
SPEC_DBG_INFO_NAME
,
PTR_ERR
(
spec
->
dbg_info
));
return
PTR_ERR
(
spec
->
dbg_info
);
SPEC_DBG_INFO_NAME
,
PTR_ERR
(
spec
_gn412x
->
dbg_info
));
return
PTR_ERR
(
spec
_gn412x
->
dbg_info
);
}
spec
->
dbg_fw
=
debugfs_create_file
(
SPEC_DBG_FW_NAME
,
0200
,
spec
->
dbg_dir
,
spec
,
&
spec_dbg_fw_ops
);
if
(
IS_ERR_OR_NULL
(
spec
->
dbg_fw
))
{
dev_err
(
&
spec
->
dev
,
spec_gn412x
->
dbg_fw
=
debugfs_create_file
(
SPEC_DBG_FW_NAME
,
0200
,
spec_gn412x
->
dbg_dir
,
spec_gn412x
,
&
spec_dbg_fw_ops
);
if
(
IS_ERR_OR_NULL
(
spec_gn412x
->
dbg_fw
))
{
dev_err
(
&
spec_gn412x
->
pdev
->
dev
,
"Cannot create debugfs file
\"
%s
\"
(%ld)
\n
"
,
SPEC_DBG_FW_NAME
,
PTR_ERR
(
spec
->
dbg_fw
));
return
PTR_ERR
(
spec
->
dbg_fw
);
SPEC_DBG_FW_NAME
,
PTR_ERR
(
spec
_gn412x
->
dbg_fw
));
return
PTR_ERR
(
spec
_gn412x
->
dbg_fw
);
}
spec
->
dbg_meta
=
debugfs_create_file
(
SPEC_DBG_META_NAME
,
0200
,
spec
->
dbg_dir
,
spec
,
&
spec_dbg_meta_ops
);
if
(
IS_ERR_OR_NULL
(
spec
->
dbg_meta
))
{
dev_err
(
&
spec
->
dev
,
spec_gn412x
->
dbg_meta
=
debugfs_create_file
(
SPEC_DBG_META_NAME
,
0200
,
spec_gn412x
->
dbg_dir
,
spec_gn412x
,
&
spec_dbg_meta_ops
);
if
(
IS_ERR_OR_NULL
(
spec_gn412x
->
dbg_meta
))
{
dev_err
(
&
spec_gn412x
->
pdev
->
dev
,
"Cannot create debugfs file
\"
%s
\"
(%ld)
\n
"
,
SPEC_DBG_META_NAME
,
PTR_ERR
(
spec
->
dbg_meta
));
return
PTR_ERR
(
spec
->
dbg_meta
);
SPEC_DBG_META_NAME
,
PTR_ERR
(
spec
_gn412x
->
dbg_meta
));
return
PTR_ERR
(
spec
_gn412x
->
dbg_meta
);
}
return
0
;
...
...
@@ -164,7 +168,7 @@ int spec_dbg_init(struct spec_dev *spec)
* It removes the debugfs interface
* @spec: SPEC device instance
*/
void
spec_dbg_exit
(
struct
spec_
dev
*
spec
)
void
spec_dbg_exit
(
struct
spec_
gn412x
*
spec_gn412x
)
{
debugfs_remove_recursive
(
spec
->
dbg_dir
);
debugfs_remove_recursive
(
spec
_gn412x
->
dbg_dir
);
}
software/kernel/spec-gpio.c
View file @
f5423aec
...
...
@@ -8,16 +8,16 @@
#include "spec.h"
#include "spec-compat.h"
void
spec_gpio_fpga_select_set
(
struct
spec_
dev
*
spec
,
void
spec_gpio_fpga_select_set
(
struct
spec_
gn412x
*
spec_gn412x
,
enum
spec_fpga_select
sel
)
{
switch
(
sel
)
{
case
SPEC_FPGA_SELECT_FPGA_FLASH
:
case
SPEC_FPGA_SELECT_GN4124_FPGA
:
case
SPEC_FPGA_SELECT_GN4124_FLASH
:
gpiod_set_value
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL0
],
gpiod_set_value
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL0
],
!!
(
sel
&
0x1
));
gpiod_set_value
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL1
],
gpiod_set_value
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL1
],
!!
(
sel
&
0x2
));
break
;
default:
...
...
@@ -25,12 +25,12 @@ void spec_gpio_fpga_select_set(struct spec_dev *spec,
}
}
enum
spec_fpga_select
spec_gpio_fpga_select_get
(
struct
spec_
dev
*
spec
)
enum
spec_fpga_select
spec_gpio_fpga_select_get
(
struct
spec_
gn412x
*
spec_gn412x
)
{
enum
spec_fpga_select
sel
=
0
;
sel
|=
!!
gpiod_get_value
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL1
])
<<
1
;
sel
|=
!!
gpiod_get_value
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL0
])
<<
0
;
sel
|=
!!
gpiod_get_value
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL1
])
<<
1
;
sel
|=
!!
gpiod_get_value
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL0
])
<<
0
;
return
sel
;
}
...
...
@@ -72,13 +72,13 @@ static inline size_t spec_gpiod_table_size(void)
(
sizeof
(
struct
gpiod_lookup
)
*
9
);
}
int
spec_gpio_init
(
struct
spec_
dev
*
spec
)
int
spec_gpio_init
(
struct
spec_
gn412x
*
spec_gn412x
)
{
struct
gpio_desc
*
gpiod
;
struct
gpiod_lookup_table
*
lookup
;
int
err
=
0
;
lookup
=
devm_kzalloc
(
&
spec
->
pdev
->
dev
,
lookup
=
devm_kzalloc
(
&
spec
_gn412x
->
pdev
->
dev
,
spec_gpiod_table_size
(),
GFP_KERNEL
);
if
(
!
lookup
)
{
...
...
@@ -88,57 +88,57 @@ int spec_gpio_init(struct spec_dev *spec)
memcpy
(
lookup
,
&
spec_gpiod_table
,
spec_gpiod_table_size
());
lookup
->
dev_id
=
kstrdup
(
dev_name
(
&
spec
->
pdev
->
dev
),
GFP_KERNEL
);
lookup
->
dev_id
=
kstrdup
(
dev_name
(
&
spec
_gn412x
->
pdev
->
dev
),
GFP_KERNEL
);
if
(
!
lookup
->
dev_id
)
goto
err_dup
;
spec
->
gpiod_table
=
lookup
;
err
=
compat_gpiod_add_lookup_table
(
spec
->
gpiod_table
);
spec
_gn412x
->
gpiod_table
=
lookup
;
err
=
compat_gpiod_add_lookup_table
(
spec
_gn412x
->
gpiod_table
);
if
(
err
)
goto
err_lookup
;
gpiod
=
gpiod_get_index
(
&
spec
->
pdev
->
dev
,
"bootsel"
,
0
,
GPIOD_OUT_HIGH
);
gpiod
=
gpiod_get_index
(
&
spec
_gn412x
->
pdev
->
dev
,
"bootsel"
,
0
,
GPIOD_OUT_HIGH
);
if
(
IS_ERR
(
gpiod
))
{
err
=
PTR_ERR
(
gpiod
);
goto
err_sel0
;
}
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL0
]
=
gpiod
;
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL0
]
=
gpiod
;
gpiod
=
gpiod_get_index
(
&
spec
->
pdev
->
dev
,
"bootsel"
,
1
,
GPIOD_OUT_HIGH
);
gpiod
=
gpiod_get_index
(
&
spec
_gn412x
->
pdev
->
dev
,
"bootsel"
,
1
,
GPIOD_OUT_HIGH
);
if
(
IS_ERR
(
gpiod
))
{
err
=
PTR_ERR
(
gpiod
);
goto
err_sel1
;
}
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL1
]
=
gpiod
;
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL1
]
=
gpiod
;
/* Because of a BUG in RedHat kernel 3.10 we re-set direction */
err
=
gpiod_direction_output
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL0
],
1
);
err
=
gpiod_direction_output
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL0
],
1
);
if
(
err
)
goto
err_out0
;
err
=
gpiod_direction_output
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL1
],
1
);
err
=
gpiod_direction_output
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL1
],
1
);
if
(
err
)
goto
err_out1
;
gpiod
=
gpiod_get_index
(
&
spec
->
pdev
->
dev
,
"irq"
,
0
,
GPIOD_IN
);
gpiod
=
gpiod_get_index
(
&
spec
_gn412x
->
pdev
->
dev
,
"irq"
,
0
,
GPIOD_IN
);
if
(
IS_ERR
(
gpiod
))
{
err
=
PTR_ERR
(
gpiod
);
goto
err_irq0
;
}
spec
->
gpiod
[
GN4124_GPIO_IRQ0
]
=
gpiod
;
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ0
]
=
gpiod
;
gpiod
=
gpiod_get_index
(
&
spec
->
pdev
->
dev
,
"irq"
,
1
,
GPIOD_IN
);
gpiod
=
gpiod_get_index
(
&
spec
_gn412x
->
pdev
->
dev
,
"irq"
,
1
,
GPIOD_IN
);
if
(
IS_ERR
(
gpiod
))
{
err
=
PTR_ERR
(
gpiod
);
goto
err_irq1
;
}
spec
->
gpiod
[
GN4124_GPIO_IRQ1
]
=
gpiod
;
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ1
]
=
gpiod
;
/* Because of a BUG in RedHat kernel 3.10 we re-set direction */
err
=
gpiod_direction_input
(
spec
->
gpiod
[
GN4124_GPIO_IRQ0
]);
err
=
gpiod_direction_input
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ0
]);
if
(
err
)
goto
err_in0
;
err
=
gpiod_direction_input
(
spec
->
gpiod
[
GN4124_GPIO_IRQ1
]);
err
=
gpiod_direction_input
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ1
]);
if
(
err
)
goto
err_in1
;
...
...
@@ -146,33 +146,33 @@ int spec_gpio_init(struct spec_dev *spec)
err_in1:
err_in0:
gpiod_put
(
spec
->
gpiod
[
GN4124_GPIO_IRQ1
]);
gpiod_put
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ1
]);
err_irq1:
gpiod_put
(
spec
->
gpiod
[
GN4124_GPIO_IRQ0
]);
gpiod_put
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ0
]);
err_irq0:
err_out1:
err_out0:
gpiod_put
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL1
]);
gpiod_put
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL1
]);
err_sel1:
gpiod_put
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL0
]);
gpiod_put
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL0
]);
err_sel0:
gpiod_remove_lookup_table
(
spec
->
gpiod_table
);
gpiod_remove_lookup_table
(
spec
_gn412x
->
gpiod_table
);
err_lookup:
kfree
(
lookup
->
dev_id
);
err_dup:
devm_kfree
(
&
spec
->
pdev
->
dev
,
lookup
);
spec
->
gpiod_table
=
NULL
;
devm_kfree
(
&
spec
_gn412x
->
pdev
->
dev
,
lookup
);
spec
_gn412x
->
gpiod_table
=
NULL
;
err_alloc:
return
err
;
}
void
spec_gpio_exit
(
struct
spec_
dev
*
spec
)
void
spec_gpio_exit
(
struct
spec_
gn412x
*
spec_gn412x
)
{
gpiod_put
(
spec
->
gpiod
[
GN4124_GPIO_IRQ1
]);
gpiod_put
(
spec
->
gpiod
[
GN4124_GPIO_IRQ0
]);
gpiod_put
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL1
]);
gpiod_put
(
spec
->
gpiod
[
GN4124_GPIO_BOOTSEL0
]);
gpiod_remove_lookup_table
(
spec
->
gpiod_table
);
kfree
(
spec
->
gpiod_table
->
dev_id
);
gpiod_put
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ1
]);
gpiod_put
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_IRQ0
]);
gpiod_put
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL1
]);
gpiod_put
(
spec
_gn412x
->
gpiod
[
GN4124_GPIO_BOOTSEL0
]);
gpiod_remove_lookup_table
(
spec
_gn412x
->
gpiod_table
);
kfree
(
spec
_gn412x
->
gpiod_table
->
dev_id
);
}
software/kernel/spec.h
View file @
f5423aec
...
...
@@ -99,30 +99,42 @@ struct spec_meta_id {
};
/**
* struct spec_dev - SPEC instance
* It describes a SPEC device instance.
* @dev Linux device instance descriptor
* @mtx: protect bootselect usage, fpga device load
* @flags collection of bit flags
* @slot_info: information about FMC slot
* @i2c_pdev: platform device for I2C master
* @i2c_adapter: the I2C master device to be used
* struct spec_fpga - it contains data to handle the FPGA
*
* @pdev: pointer to the PCI device
* @fpga:
* @meta:
* @vic_pdev:
* @app_pdev:
* @slot_info:
* @dbg_dir_fpga:
* @dbg_csr:
* @dbg_csr_reg:
*/
struct
spec_dev
{
struct
pci_dev
*
pdev
;
struct
spec_fpga
{
struct
device
dev
;
DECLARE_BITMAP
(
flags
,
SPEC_FLAG_BITS
);
void
__iomem
*
fpga
;
struct
spec_meta_id
__iomem
*
meta
;
struct
mutex
mtx
;
struct
platform_device
*
vic_pdev
;
struct
platform_device
*
app_pdev
;
struct
fmc_slot_info
slot_info
;
struct
dentry
*
dbg_dir_fpga
;
#define SPEC_DBG_CSR_NAME "csr_regs"
struct
dentry
*
dbg_csr
;
struct
debugfs_regset32
dbg_csr_reg
;
};
/**
* struct spec_gn412x - it contains data to handle the PCB
*
* @pdev: pointer to the PCI device
* @mtx: it protects FPGA device/configuration loading
*/
struct
spec_gn412x
{
struct
pci_dev
*
pdev
;
struct
mutex
mtx
;
struct
spec_meta_id
__iomem
*
meta
;
struct
gpiod_lookup_table
*
gpiod_table
;
struct
gpio_desc
*
gpiod
[
GN4124_GPIO_MAX
];
struct
dentry
*
dbg_dir
;
#define SPEC_DBG_INFO_NAME "info"
struct
dentry
*
dbg_info
;
...
...
@@ -130,35 +142,27 @@ struct spec_dev {
struct
dentry
*
dbg_fw
;
#define SPEC_DBG_META_NAME "fpga_device_metadata"
struct
dentry
*
dbg_meta
;
struct
dentry
*
dbg_dir_fpga
;
#define SPEC_DBG_CSR_NAME "csr_regs"
struct
dentry
*
dbg_csr
;
struct
debugfs_regset32
dbg_csr_reg
;
struct
gpiod_lookup_table
*
gpiod_table
;
struct
gpio_desc
*
gpiod
[
GN4124_GPIO_MAX
];
struct
spec_fpga
*
spec_fpga
;
};
static
inline
struct
spec_dev
*
to_spec_dev
(
struct
device
*
_dev
)
static
inline
struct
spec_fpga
*
to_spec_fpga
(
struct
device
*
_dev
)
{
return
container_of
(
_dev
,
struct
spec_
dev
,
dev
);
return
container_of
(
_dev
,
struct
spec_
fpga
,
dev
);
}
extern
int
spec_fw_load
(
struct
spec_
dev
*
spec
,
const
char
*
name
);
extern
int
spec_fw_load
(
struct
spec_
gn412x
*
spec_gn412x
,
const
char
*
name
);
extern
int
spec_dbg_init
(
struct
spec_
dev
*
spec
);
extern
void
spec_dbg_exit
(
struct
spec_
dev
*
spec
);
extern
int
spec_dbg_init
(
struct
spec_
gn412x
*
spec_gn412x
);
extern
void
spec_dbg_exit
(
struct
spec_
gn412x
*
spec_gn412x
);
extern
void
spec_gpio_fpga_select_set
(
struct
spec_
dev
*
spec
,
extern
void
spec_gpio_fpga_select_set
(
struct
spec_
gn412x
*
spec_gn412x
,
enum
spec_fpga_select
sel
);
extern
enum
spec_fpga_select
spec_gpio_fpga_select_get
(
struct
spec_
dev
*
spec
);
extern
enum
spec_fpga_select
spec_gpio_fpga_select_get
(
struct
spec_
gn412x
*
spec_gn412x
);
extern
int
spec_gpio_init
(
struct
spec_
dev
*
spec
);
extern
void
spec_gpio_exit
(
struct
spec_
dev
*
spec
);
extern
int
spec_gpio_init
(
struct
spec_
gn412x
*
spec_gn412x
);
extern
void
spec_gpio_exit
(
struct
spec_
gn412x
*
spec_gn412x
);
extern
int
spec_fpga_init
(
struct
spec_
dev
*
spec
);
extern
int
spec_fpga_exit
(
struct
spec_
dev
*
spec
);
extern
int
spec_fpga_init
(
struct
spec_
gn412x
*
spec_gn412x
);
extern
int
spec_fpga_exit
(
struct
spec_
gn412x
*
spec_gn412x
);
#endif
/* __SPEC_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