Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple PCIe FMC carrier SPEC - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
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 - Software
Commits
50a86c94
Commit
50a86c94
authored
Aug 29, 2019
by
Miguel Jimenez Lopez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update IRQ mechanism for SPEC driver.
parent
4fe1ede4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
105 additions
and
57 deletions
+105
-57
spec-irq.c
kernel/spec-irq.c
+10
-20
spec-sdb-scan.c
kernel/spec-sdb-scan.c
+95
-37
No files found.
kernel/spec-irq.c
View file @
50a86c94
...
...
@@ -158,30 +158,20 @@ static struct irq_chip spec_irq_gpio_chip = {
.
irq_set_type
=
spec_irq_gpio_set_type
,
};
// FIXME: To be commented
static
int
spec_irq_gpio_domain_select
(
struct
irq_domain
*
d
,
struct
irq_fwspec
*
fwspec
,
enum
irq_domain_bus_token
bus_token
)
{
char
*
name
;
if
(
!
d
)
{
printk
(
"%s: IRQ Domain is NULL
\n
"
,
__func__
);
return
0
;
}
if
(
!
fwspec
)
{
printk
(
"%s: Device node is NULL
\n
"
,
__func__
);
return
0
;
}
name
=
(
char
*
)
fwspec
->
fwnode
;
if
(
strcmp
(
d
->
name
,
name
)
==
0
)
return
1
;
else
//struct spec_dev *spec = d->host_data;
//struct device *dev = &spec->pdev->dev;
uint32_t
dev_u32
,
req_u32
;
if
(
fwspec
->
param_count
!=
1
)
return
0
;
return
0
;
dev_u32
=
0
;
req_u32
=
fwspec
->
param
[
0
];
return
(
dev_u32
==
req_u32
);
}
/**
...
...
kernel/spec-sdb-scan.c
View file @
50a86c94
...
...
@@ -9,6 +9,10 @@
#include <linux/firmware.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/fmc.h>
#include <linux/fmc-sdb.h>
...
...
@@ -87,6 +91,7 @@ struct fpga_dev {
unsigned
int
n_cores
;
/**< Number of elements in the cores list **/
struct
platform_device
dev
;
/**< Linux platform device for the FPGA device **/
void
*
priv
;
/**< Private data for FPGA dev */
int
dev_registered
;
/**< Linux platform device has been registered into system **/
};
...
...
@@ -130,8 +135,16 @@ static void fpga_dev_release(struct device *dev){}
#define FPGA_DEV_CREATE(id,name_dev,vendor_id,product_id) \
FPGA_DEV_CREATE_FULL(id,name_dev,vendor_id,product_id,0,0)
// VIC FPGA device
#define FPGA_DEVS_VIC_DEV 0
#define FPGA_DEVS_VIC_DEV_NAME "spec-vic"
#define FPGA_DEVS_VIC_DEV_VIC 0
#define FPGA_DEVS_VIC_DEV_VIC_IRQ 9
#define FPGA_DEVS_VIC_DEV_NUM 1
#define FPGA_DEVS_VIC_DEV_PDEV_NAME "htvic-spec"
#define FPGA_DEVS_VIC_DEV_PDEV_RELEASE_F fpga_dev_release
// NIC FPGA device
#define FPGA_DEVS_NIC_DEV
0
#define FPGA_DEVS_NIC_DEV
1
#define FPGA_DEVS_NIC_DEV_NAME "spec-nic"
#define FPGA_DEVS_NIC_DEV_NIC 0
#define FPGA_DEVS_NIC_DEV_NIC_IRQ 1
...
...
@@ -142,14 +155,6 @@ static void fpga_dev_release(struct device *dev){}
#define FPGA_DEVS_NIC_DEV_NUM 4
#define FPGA_DEVS_NIC_DEV_PDEV_NAME "spec-nic"
#define FPGA_DEVS_NIC_DEV_PDEV_RELEASE_F fpga_dev_release
// VIC FPGA device
#define FPGA_DEVS_VIC_DEV 1
#define FPGA_DEVS_VIC_DEV_NAME "spec-vic"
#define FPGA_DEVS_VIC_DEV_VIC 0
#define FPGA_DEVS_VIC_DEV_VIC_IRQ 9
#define FPGA_DEVS_VIC_DEV_NUM 1
#define FPGA_DEVS_VIC_DEV_PDEV_NAME "htvic-spec"
#define FPGA_DEVS_VIC_DEV_PDEV_RELEASE_F fpga_dev_release
// DIO FPGA device
#define FPGA_DEVS_DIO_DEV 2
#define FPGA_DEVS_DIO_DEV_NAME "spec-fmc-dio"
...
...
@@ -164,6 +169,10 @@ static void fpga_dev_release(struct device *dev){}
// Global structure for FPGA devices
static
struct
fpga_dev
fpga_devs
[]
=
{
/* VIC */
FPGA_DEVS_CREATE_BEGIN_DEV
(
FPGA_DEVS_VIC_DEV
,
FPGA_DEVS_VIC_DEV_NAME
)
FPGA_DEV_CREATE_SFULL
(
FPGA_DEVS_VIC_DEV_VIC
,
SDB_VIC_NAME
,
SDB_CERN_VENDOR
,
SDB_VIC_PID
,
FPGA_DEVS_VIC_DEV_VIC_IRQ
)
FPGA_DEVS_CREATE_END_DEV
(
FPGA_DEVS_VIC_DEV_NUM
,
FPGA_DEVS_VIC_DEV_PDEV_NAME
,
FPGA_DEVS_VIC_DEV_PDEV_RELEASE_F
)
/* NIC */
FPGA_DEVS_CREATE_BEGIN_DEV
(
FPGA_DEVS_NIC_DEV
,
FPGA_DEVS_NIC_DEV_NAME
)
FPGA_DEV_CREATE_SFULL
(
FPGA_DEVS_NIC_DEV_NIC
,
SDB_NIC_NAME
,
SDB_CERN_VENDOR
,
SDB_NIC_PID
,
FPGA_DEVS_NIC_DEV_NIC_IRQ
)
...
...
@@ -171,10 +180,6 @@ static struct fpga_dev fpga_devs[] =
FPGA_DEV_CREATE_SFULL
(
FPGA_DEVS_NIC_DEV_TXTSU
,
SDB_TXTSU_NAME
,
SDB_CERN_VENDOR
,
SDB_TXTSU_PID
,
FPGA_DEVS_NIC_DEV_TXTSU_IRQ
)
FPGA_DEV_CREATE
(
FPGA_DEVS_NIC_DEV_PPSG
,
SDB_PPSG_NAME
,
SDB_CERN_VENDOR
,
SDB_PPSG_PID
)
FPGA_DEVS_CREATE_END_DEV
(
FPGA_DEVS_NIC_DEV_NUM
,
FPGA_DEVS_NIC_DEV_PDEV_NAME
,
FPGA_DEVS_NIC_DEV_PDEV_RELEASE_F
)
/* VIC */
FPGA_DEVS_CREATE_BEGIN_DEV
(
FPGA_DEVS_VIC_DEV
,
FPGA_DEVS_VIC_DEV_NAME
)
FPGA_DEV_CREATE_SFULL
(
FPGA_DEVS_VIC_DEV_VIC
,
SDB_VIC_NAME
,
SDB_CERN_VENDOR
,
SDB_VIC_PID
,
FPGA_DEVS_VIC_DEV_VIC_IRQ
)
FPGA_DEVS_CREATE_END_DEV
(
FPGA_DEVS_VIC_DEV_NUM
,
FPGA_DEVS_VIC_DEV_PDEV_NAME
,
FPGA_DEVS_VIC_DEV_PDEV_RELEASE_F
)
/* DIO */
FPGA_DEVS_CREATE_BEGIN_DEV
(
FPGA_DEVS_DIO_DEV
,
FPGA_DEVS_DIO_DEV_NAME
)
FPGA_DEV_CREATE_SFULL
(
FPGA_DEVS_DIO_DEV_DIO
,
SDB_DIO_NAME
,
SDB_7SOLS_VENDOR
,
SDB_DIO_PID
,
FPGA_DEVS_DIO_DEV_DIO_IRQ
)
...
...
@@ -196,7 +201,7 @@ static struct fpga_dev fpga_devs[] =
*
* @return 0 if success and a negative error code otherwise
*/
static
int
spec_sdb_fpga_dev_register
(
struct
fmc_device
*
fmc
,
struct
fpga_dev
*
fdev
,
void
*
priv
)
static
int
spec_sdb_fpga_dev_register
(
struct
fmc_device
*
fmc
,
struct
fpga_dev
*
fdev
)
{
signed
long
start
;
unsigned
long
size
;
...
...
@@ -214,7 +219,7 @@ static int spec_sdb_fpga_dev_register(struct fmc_device *fmc, struct fpga_dev *f
if
(
fdev
->
cores
[
i
].
has_irq
)
n_irqs
++
;
n_res
=
fdev
->
n_cores
+
n_irqs
+
1
;
n_res
=
fdev
->
n_cores
+
n_irqs
;
res
=
kzalloc
(
sizeof
(
*
res
)
*
n_res
,
GFP_KERNEL
);
if
(
!
res
)
...
...
@@ -248,16 +253,10 @@ static int spec_sdb_fpga_dev_register(struct fmc_device *fmc, struct fpga_dev *f
}
// Resource for the PCIe Bus identifiers
res
[
j
].
name
=
"PCIe-BUS"
;
res
[
j
].
flags
=
IORESOURCE_BUS
;
res
[
j
].
start
=
spec
->
pdev
->
bus
->
number
;
res
[
j
].
end
=
spec
->
pdev
->
devfn
;
fdev
->
dev
.
resource
=
res
;
fdev
->
dev
.
num_resources
=
n_res
;
platform_set_drvdata
(
&
fdev
->
dev
,
priv
);
platform_set_drvdata
(
&
fdev
->
dev
,
fdev
->
priv
);
r
=
platform_device_register
(
&
fdev
->
dev
);
if
(
r
)
{
...
...
@@ -271,6 +270,58 @@ static int spec_sdb_fpga_dev_register(struct fmc_device *fmc, struct fpga_dev *f
return
r
;
}
//static struct irq_domain * irq_find_irqdomain(uint32_t id)
static
struct
irq_domain
*
irq_find_irqdomain
(
struct
device
*
dev
)
{
struct
irq_fwspec
fwspec
;
memset
(
&
fwspec
,
0
,
sizeof
(
fwspec
));
//fwspec.param_count = 1;
//fwspec.param[0] = id;
fwspec
.
param_count
=
2
;
fwspec
.
param
[
0
]
=
(
uint32_t
)
(((
unsigned
long
)
dev
)
>>
32
);
fwspec
.
param
[
1
]
=
(
uint32_t
)
(((
unsigned
long
)
dev
)
&
0xFFFFFFFF
);
return
irq_find_matching_fwspec
(
&
fwspec
,
DOMAIN_BUS_ANY
);
}
struct
work_struct
fpga_cores_register_wq
;
#define FPGA_CORES_REG_WQ_SLEEP_MS 1000
void
spec_sdb_fpga_dev_register_wq
(
struct
work_struct
*
work
)
{
struct
device
*
dev
=
&
fpga_devs
[
FPGA_DEVS_VIC_DEV
].
dev
.
dev
;
struct
irq_domain
*
d
;
struct
fmc_device
*
fmc
=
fpga_devs
[
FPGA_DEVS_DIO_DEV
].
priv
;
int
i
,
j
,
r
;
// Wait until VIC driver has been installed
while
(
dev
->
driver
==
NULL
)
{
msleep
(
FPGA_CORES_REG_WQ_SLEEP_MS
);
}
// Map IRQs for the rest of the modules
d
=
irq_find_irqdomain
(
dev
);
for
(
i
=
1
;
i
<
ARRAY_SIZE
(
fpga_devs
)
;
i
++
)
{
for
(
j
=
0
;
j
<
fpga_devs
[
i
].
n_cores
;
j
++
)
{
if
(
fpga_devs
[
i
].
cores
[
j
].
has_irq
)
{
fpga_devs
[
i
].
cores
[
j
].
irq
=
irq_find_mapping
(
d
,
fpga_devs
[
i
].
cores
[
j
].
irq
);
}
}
}
// Register the rest of modules
for
(
i
=
1
;
i
<
ARRAY_SIZE
(
fpga_devs
)
;
i
++
)
{
r
=
spec_sdb_fpga_dev_register
(
fmc
,
&
fpga_devs
[
i
]);
if
(
r
!=
0
)
dev_err
(
&
fmc
->
dev
,
"%s: %s could not be registered!
\n
"
,
__func__
,
fpga_devs
[
i
].
name
);
}
}
/**
* Register Linux platform devices for the all FPGA resources.
*
...
...
@@ -282,21 +333,28 @@ int spec_sdb_fpga_dev_register_all(struct fmc_device *fmc)
{
int
i
;
int
r
;
void
*
priv
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
fpga_devs
)
;
i
++
)
{
if
(
i
==
FPGA_DEVS_DIO_DEV
)
{
priv
=
(
void
*
)
fmc
;
}
else
{
priv
=
(
void
*
)
fmc
->
fpga_base
;
}
r
=
spec_sdb_fpga_dev_register
(
fmc
,
&
fpga_devs
[
i
],
priv
);
if
(
r
!=
0
)
dev_err
(
&
fmc
->
dev
,
"%s: %s could not be registered!
\n
"
,
__func__
,
fpga_devs
[
i
].
name
);
}
struct
spec_dev
*
spec
=
fmc
->
carrier_data
;
struct
irq_domain
*
domain
=
spec
->
gpio_domain
;
// Init workqueue for the delayed registration
INIT_WORK
(
&
fpga_cores_register_wq
,
spec_sdb_fpga_dev_register_wq
);
// Set private information
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
fpga_devs
)
;
i
++
)
fpga_devs
[
i
].
priv
=
(
i
==
FPGA_DEVS_DIO_DEV
)
?
(
void
*
)
fmc
:
fmc
->
fpga_base
;
// Find Linux IRQ for VIC
fpga_devs
[
FPGA_DEVS_VIC_DEV
].
cores
[
FPGA_DEVS_VIC_DEV_VIC
].
irq
=
irq_find_mapping
(
domain
,
FPGA_DEVS_VIC_DEV_VIC_IRQ
);
// Register VIC
r
=
spec_sdb_fpga_dev_register
(
fmc
,
&
fpga_devs
[
FPGA_DEVS_VIC_DEV
]);
if
(
r
!=
0
)
dev_err
(
&
fmc
->
dev
,
"%s: %s could not be registered!
\n
"
,
__func__
,
fpga_devs
[
0
].
name
);
// Schedule worqueue
schedule_work
(
&
fpga_cores_register_wq
);
return
0
;
}
...
...
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