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
e29f91d3
Commit
e29f91d3
authored
Jul 17, 2012
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel: more work on spec.ko
parent
60980dbe
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
104 additions
and
33 deletions
+104
-33
Makefile
kernel/Makefile
+1
-0
fmc-core.c
kernel/fmc-core.c
+4
-4
spec-fmc.c
kernel/spec-fmc.c
+48
-0
spec-pci.c
kernel/spec-pci.c
+40
-15
spec.h
kernel/spec.h
+11
-14
No files found.
kernel/Makefile
View file @
e29f91d3
...
...
@@ -8,6 +8,7 @@ obj-m += spec.o
obj-m
+=
wr-nic.o
spec-objs
=
spec-pci.o
spec-objs
+=
spec-fmc.o
spec-objs
+=
spec-i2c.o
spec-objs
+=
loader-ll.o
...
...
kernel/fmc-core.c
View file @
e29f91d3
...
...
@@ -16,9 +16,9 @@
static
int
fmc_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
struct
fmc_driver
*
fdrv
=
to_fmc_driver
(
drv
);
struct
fmc_device
*
fdev
=
to_fmc_device
(
dev
);
const
struct
fmc_device_id
*
t
=
fdrv
->
id_table
;
//
struct fmc_driver *fdrv = to_fmc_driver(drv);
//
struct fmc_device *fdev = to_fmc_device(dev);
//
const struct fmc_device_id *t = fdrv->id_table;
/* Currently, return 1 every time, until we define policies */
return
1
;
...
...
@@ -26,7 +26,7 @@ static int fmc_match(struct device *dev, struct device_driver *drv)
static
int
fmc_uevent
(
struct
device
*
dev
,
struct
kobj_uevent_env
*
env
)
{
struct
fmc_device
*
fdev
=
to_fmc_device
(
dev
);
//
struct fmc_device *fdev = to_fmc_device(dev);
/* FIXME: The MODALIAS */
add_uevent_var
(
env
,
"MODALIAS=%s"
,
"fmc"
);
...
...
kernel/spec-fmc.c
0 → 100644
View file @
e29f91d3
/*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*
* This work is part of the White Rabbit project, a research effort led
* by CERN, the European Institute for Nuclear Research.
*/
#include <linux/slab.h>
#include <linux/fmc.h>
#include "spec.h"
int
spec_fmc_create
(
struct
spec_dev
*
spec
)
{
struct
fmc_device
*
fmc
;
int
ret
;
fmc
=
kzalloc
(
sizeof
(
*
fmc
),
GFP_KERNEL
);
if
(
!
fmc
)
return
-
ENOMEM
;
/* FIXME: many fields of the device are still NULL */
fmc
->
carrier_name
=
"SPEC"
;
fmc
->
carrier_data
=
spec
;
fmc
->
base
=
spec
->
remap
[
0
];
fmc
->
irq
=
spec
->
pdev
->
irq
;
ret
=
spec_i2c_init
(
fmc
);
if
(
ret
)
{
kfree
(
fmc
);
return
ret
;
}
spec
->
fmc
=
fmc
;
ret
=
fmc_device_register
(
fmc
);
if
(
ret
)
{
spec
->
fmc
=
NULL
;
kfree
(
fmc
);
}
return
ret
;
}
void
spec_fmc_destroy
(
struct
spec_dev
*
spec
)
{
fmc_device_unregister
(
spec
->
fmc
);
spec_i2c_exit
(
spec
->
fmc
);
spec
->
fmc
=
NULL
;
}
kernel/spec-pci.c
View file @
e29f91d3
...
...
@@ -19,7 +19,6 @@
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/fmc.h>
#include <asm/unaligned.h>
#include "spec.h"
...
...
@@ -38,8 +37,10 @@ static int spec_load_fpga(struct spec_dev *spec)
char
*
name
=
spec_fw_name
;
/* FIXME: temporary hack */
err
=
request_firmware
(
&
fw
,
name
,
dev
);
if
(
err
<
0
)
if
(
err
<
0
)
{
dev_err
(
dev
,
"request firmware
\"
%s
\"
: error %i
\n
"
,
name
,
err
);
return
err
;
}
dev_info
(
dev
,
"got file
\"
%s
\"
, %i (0x%x) bytes
\n
"
,
spec_fw_name
,
fw
->
size
,
fw
->
size
);
...
...
@@ -74,7 +75,8 @@ out:
return
err
;
}
static
int
spec_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
id
)
static
int
__devinit
spec_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
id
)
{
struct
spec_dev
*
spec
;
int
i
,
ret
;
...
...
@@ -91,40 +93,64 @@ static int spec_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return
-
ENOMEM
;
spec
->
pdev
=
pdev
;
if
(
(
i
=
pci_enable_msi_block
(
pdev
,
1
))
<
0
)
pr_err
(
"%s: enable ms block: %i
\n
"
,
__func__
,
i
);
if
(
(
ret
=
pci_enable_msi_block
(
pdev
,
1
))
<
0
)
dev_err
(
&
pdev
->
dev
,
"enable msi block: error %i
\n
"
,
ret
);
/* Remap our 3 bars */
for
(
i
=
0
;
i
<
3
;
i
++
)
{
for
(
i
=
ret
=
0
;
i
<
3
;
i
++
)
{
struct
resource
*
r
=
pdev
->
resource
+
(
2
*
i
);
if
(
!
r
->
start
)
continue
;
spec
->
area
[
i
]
=
r
;
if
(
r
->
flags
&
IORESOURCE_MEM
)
if
(
r
->
flags
&
IORESOURCE_MEM
)
{
spec
->
remap
[
i
]
=
ioremap
(
r
->
start
,
r
->
end
+
1
-
r
->
start
);
if
(
!
spec
->
remap
[
i
])
ret
=
-
ENOMEM
;
}
}
if
(
ret
)
goto
out_unmap
;
pci_set_drvdata
(
pdev
,
spec
);
/* Load the golden FPGA binary to read the eeprom */
spec_load_fpga
(
spec
);
ret
=
spec_load_fpga
(
spec
);
if
(
ret
)
goto
out_unmap
;
/* FIXME: eeprom */
ret
=
spec_fmc_create
(
spec
);
if
(
ret
)
goto
out_unmap
;
/* Done */
pci_set_drvdata
(
pdev
,
spec
);
return
0
;
out_unmap:
for
(
i
=
0
;
i
<
3
;
i
++
)
{
if
(
spec
->
remap
[
i
])
iounmap
(
spec
->
remap
[
i
]);
spec
->
remap
[
i
]
=
NULL
;
spec
->
area
[
i
]
=
NULL
;
}
pci_set_drvdata
(
pdev
,
NULL
);
pci_disable_msi
(
pdev
);
pci_disable_device
(
pdev
);
kfree
(
spec
);
return
ret
;
}
static
void
spec_remove
(
struct
pci_dev
*
pdev
)
static
void
__devexit
spec_remove
(
struct
pci_dev
*
pdev
)
{
struct
spec_dev
*
spec
=
pci_get_drvdata
(
pdev
);
int
i
;
dev_info
(
&
pdev
->
dev
,
"remove
\n
"
);
spec_fmc_destroy
(
spec
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
iounmap
(
spec
->
remap
[
i
]);
if
(
spec
->
remap
[
i
])
iounmap
(
spec
->
remap
[
i
]);
spec
->
remap
[
i
]
=
NULL
;
spec
->
area
[
i
]
=
NULL
;
}
...
...
@@ -149,13 +175,12 @@ static struct pci_driver spec_driver = {
.
remove
=
spec_remove
,
};
static
int
spec_init
(
void
)
static
int
__init
spec_init
(
void
)
{
INIT_LIST_HEAD
(
&
spec_list
);
return
pci_register_driver
(
&
spec_driver
);
}
static
void
spec_exit
(
void
)
static
void
__exit
spec_exit
(
void
)
{
pci_unregister_driver
(
&
spec_driver
);
...
...
kernel/spec.h
View file @
e29f91d3
...
...
@@ -14,6 +14,7 @@
#include <linux/firmware.h>
#include <linux/atomic.h>
#include <linux/list.h>
#include <linux/fmc.h>
#define PCI_VENDOR_ID_CERN 0x10dc
#define PCI_DEVICE_ID_SPEC 0x018d
...
...
@@ -22,21 +23,11 @@
#define SPEC_DEFAULT_LM32_ADDR 0x80000
/* used if "1" is passed */
#define SPEC_MAX_BOARDS 8
enum
spec_names
{
SPEC_NAME_FW
,
SPEC_NAME_PROG
,
SPEC_NAME_SUBMOD
,
SPEC_NAMES
,
};
/* Our device structure */
struct
spec_dev
{
struct
pci_dev
*
pdev
;
struct
resource
*
area
[
3
];
/* bar 0, 2, 4 */
void
*
remap
[
3
];
/* ioremap of bar 0, 2, 4 */
char
*
names
[
SPEC_NAMES
];
char
*
submod_name
;
struct
work_struct
work
;
const
struct
firmware
*
fw
;
...
...
@@ -44,12 +35,9 @@ struct spec_dev {
unsigned
long
irqcount
;
atomic_t
has_submod
;
void
*
sub_priv
;
struct
fmc_device
*
fmc
;
};
/* Used by sub-modules */
extern
struct
list_head
spec_list
;
/* Registers from the gennum header files */
enum
{
GNGPIO_BASE
=
0xA00
,
...
...
@@ -77,4 +65,13 @@ enum {
PCI_SYS_CFG_SYSTEM
=
0x800
};
/* Functions in spec-fmc.c, used by spec-pci.c */
extern
int
spec_fmc_create
(
struct
spec_dev
*
spec
);
extern
void
spec_fmc_destroy
(
struct
spec_dev
*
spec
);
/* Function in spec-i2c.c, used by spec-fmc.c */
extern
int
spec_i2c_init
(
struct
fmc_device
*
fmc
);
extern
void
spec_i2c_exit
(
struct
fmc_device
*
fmc
);
#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