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
95e9c500
Commit
95e9c500
authored
Jun 26, 2019
by
Federico Vaga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sw:drv: use MFD for SPEC devices on FPGA
Signed-off-by:
Federico Vaga
<
federico.vaga@cern.ch
>
parent
e4966784
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
62 additions
and
51 deletions
+62
-51
spec-core-fpga.c
software/kernel/spec-core-fpga.c
+61
-49
spec-fmc.c
software/kernel/spec-fmc.c
+1
-1
spec.h
software/kernel/spec.h
+0
-1
No files found.
software/kernel/spec-core-fpga.c
View file @
95e9c500
...
...
@@ -8,6 +8,7 @@
#include <linux/ioport.h>
#include <linux/gpio/consumer.h>
#include <linux/irqdomain.h>
#include <linux/mfd/core.h>
#include "spec.h"
#include "spec-compat.h"
...
...
@@ -15,7 +16,7 @@
/* FIXME find better ID */
static
int
vic_id
;
static
int
i2c
_id
;
static
int
mfd
_id
;
static
int
app_id
;
enum
spec_core_fpga_irq_lines
{
...
...
@@ -90,24 +91,12 @@ static void spec_core_fpga_vic_exit(struct spec_dev *spec)
}
}
static
int
spec_core_fpga_vic_irq_find_mapping
(
struct
platform_device
*
vic
,
unsigned
int
hwirq
)
{
struct
irq_domain
*
domain
;
if
(
!
vic
)
return
-
ENXIO
;
domain
=
irq_find_host
((
void
*
)
&
vic
->
dev
);
if
(
!
domain
)
return
-
ENXIO
;
return
irq_find_mapping
(
domain
,
hwirq
);
}
/* MFD devices */
enum
spce_core_fpga_mfd_devs_enum
{
SPEC_CORE_FPGA_MFD_FMC_I2C
=
0
,
};
/* FMC I2C Master */
static
const
struct
ocores_i2c_platform_data
i2c_pdata
=
{
static
struct
ocores_i2c_platform_data
spec_core_fpga_fmc_i2c_pdata
=
{
.
reg_shift
=
2
,
/* 32bit aligned */
.
reg_io_width
=
4
,
.
clock_khz
=
62500
,
...
...
@@ -116,41 +105,64 @@ static const struct ocores_i2c_platform_data i2c_pdata = {
.
devices
=
NULL
,
};
static
int
spec_core_fpga_i2c_init
(
struct
spec_dev
*
spec
)
static
const
struct
mfd_cell
spec_core_fpga_mfd_devs
[]
=
{
[
SPEC_CORE_FPGA_MFD_FMC_I2C
]
=
{
.
name
=
"i2c-ohwr"
,
.
platform_data
=
&
spec_core_fpga_fmc_i2c_pdata
,
.
pdata_size
=
sizeof
(
spec_core_fpga_fmc_i2c_pdata
),
.
num_resources
=
ARRAY_SIZE
(
spec_core_fpga_fmc_i2c_res
),
.
resources
=
spec_core_fpga_fmc_i2c_res
,
},
};
static
inline
size_t
__fpga_mfd_devs_size
(
void
)
{
struct
pci_dev
*
pcidev
=
to_pci_dev
(
spec
->
dev
.
parent
);
unsigned
long
pci_start
=
pci_resource_start
(
pcidev
,
0
);
unsigned
int
res_n
=
ARRAY_SIZE
(
spec_core_fpga_fmc_i2c_res
);
struct
resource
res
[
ARRAY_SIZE
(
spec_core_fpga_fmc_i2c_res
)];
struct
platform_device
*
pdev
;
#define SPEC_CORE_FPGA_MFD_DEVS_MAX 4
return
(
sizeof
(
struct
mfd_cell
)
*
SPEC_CORE_FPGA_MFD_DEVS_MAX
);
}
memcpy
(
&
res
,
spec_core_fpga_fmc_i2c_res
,
sizeof
(
spec_core_fpga_fmc_i2c_res
));
res
[
0
].
start
+=
pci_start
;
res
[
0
].
end
+=
pci_start
;
static
int
spec_core_fpga_devices_init
(
struct
spec_dev
*
spec
)
{
struct
pci_dev
*
pcidev
=
to_pci_dev
(
spec
->
dev
.
parent
);
struct
mfd_cell
*
fpga_mfd_devs
;
struct
irq_domain
*
vic_domain
;
unsigned
int
n_mfd
=
0
;
int
err
;
res
[
1
].
start
=
spec_core_fpga_vic_irq_find_mapping
(
spec
->
vic_pdev
,
res
[
1
].
start
);
fpga_mfd_devs
=
devm_kzalloc
(
&
spec
->
dev
,
__fpga_mfd_devs_size
(),
GFP_KERNEL
);
if
(
!
fpga_mfd_devs
)
return
-
ENOMEM
;
memcpy
(
&
fpga_mfd_devs
[
n_mfd
],
&
spec_core_fpga_mfd_devs
[
SPEC_CORE_FPGA_MFD_FMC_I2C
],
sizeof
(
fpga_mfd_devs
[
n_mfd
]));
n_mfd
++
;
vic_domain
=
irq_find_host
((
void
*
)
&
spec
->
vic_pdev
->
dev
);
if
(
!
vic_domain
)
{
/* Remove IRQ resource from all devices */
fpga_mfd_devs
[
0
].
num_resources
=
1
;
}
err
=
mfd_add_devices
(
&
spec
->
dev
,
mfd_id
++
,
fpga_mfd_devs
,
n_mfd
,
&
pcidev
->
resource
[
0
],
0
,
vic_domain
);
if
(
err
)
goto
err_mfd
;
pdev
=
platform_device_register_resndata
(
&
spec
->
dev
,
"i2c-ohwr"
,
i2c_id
++
,
res
,
res_n
,
&
i2c_pdata
,
sizeof
(
i2c_pdata
));
if
(
IS_ERR
(
pdev
))
return
PTR_ERR
(
pdev
);
return
0
;
spec
->
i2c_pdev
=
pdev
;
err_mfd:
devm_kfree
(
&
spec
->
dev
,
fpga_mfd_devs
);
return
0
;
return
err
;
}
static
void
spec_core_fpga_
i2c
_exit
(
struct
spec_dev
*
spec
)
static
void
spec_core_fpga_
devices
_exit
(
struct
spec_dev
*
spec
)
{
if
(
spec
->
i2c_pdev
)
{
platform_device_unregister
(
spec
->
i2c_pdev
);
spec
->
i2c_pdev
=
NULL
;
}
mfd_remove_devices
(
&
spec
->
dev
);
}
/* Thermometer */
...
...
@@ -361,9 +373,9 @@ int spec_core_fpga_init(struct spec_dev *spec)
err
=
spec_core_fpga_vic_init
(
spec
);
if
(
err
)
goto
err_vic
;
err
=
spec_core_fpga_
i2c
_init
(
spec
);
err
=
spec_core_fpga_
devices
_init
(
spec
);
if
(
err
)
goto
err_
i2c
;
goto
err_
dev
;
err
=
spec_fmc_init
(
spec
);
if
(
err
)
goto
err_fmc
;
...
...
@@ -381,8 +393,8 @@ err_app:
err_therm:
spec_fmc_exit
(
spec
);
err_fmc:
spec_core_fpga_
i2c
_exit
(
spec
);
err_
i2c
:
spec_core_fpga_
devices
_exit
(
spec
);
err_
dev
:
spec_core_fpga_vic_exit
(
spec
);
err_vic:
return
err
;
...
...
@@ -393,7 +405,7 @@ int spec_core_fpga_exit(struct spec_dev *spec)
spec_core_fpga_app_exit
(
spec
);
spec_core_fpga_therm_exit
(
spec
);
spec_fmc_exit
(
spec
);
spec_core_fpga_
i2c
_exit
(
spec
);
spec_core_fpga_
devices
_exit
(
spec
);
spec_core_fpga_vic_exit
(
spec
);
return
0
;
...
...
software/kernel/spec-fmc.c
View file @
95e9c500
...
...
@@ -46,7 +46,7 @@ static int spec_i2c_find_adapter(struct device *dev, void *data)
return
0
;
/* We have a muxed I2C master */
if
(
&
spec
->
i2c_pdev
->
dev
!=
adap_parent
->
dev
.
parent
)
if
(
&
spec
->
dev
!=
adap_parent
->
dev
.
parent
->
parent
)
return
0
;
/* Found! Return the bus ID */
...
...
software/kernel/spec.h
View file @
95e9c500
...
...
@@ -113,7 +113,6 @@ struct spec_dev {
void
__iomem
*
fpga
;
struct
spec_meta_id
__iomem
*
meta
;
struct
platform_device
*
i2c_pdev
;
struct
platform_device
*
vic_pdev
;
struct
platform_device
*
app_pdev
;
...
...
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