Commit 5e1dc8e1 authored by Federico Vaga's avatar Federico Vaga

Merge branch 'release/v1.4.10'

parents 5c64edc9 410df44d
...@@ -2,6 +2,26 @@ ...@@ -2,6 +2,26 @@
Change Log Change Log
========== ==========
[1.4.10] 2020-05-12
==================
Added
-----
- [hdl] metadata source-id automatic assignment
- [hdl] add option to consider AM in VME slave decoder
Fixed
-----
- [hdl] fix typos when ddr is not configured. This froze the board when
reading a ddr data register.
Changed
-------
- [sw] Linux device hierarchy seen in sysfs. It is incompatible but
tools, today do not rely in this. So we take the freedom to change
it without a major release.
- [sw] on device removal the IRQ vector number in the CR/CSR space is set
to 0x0
[1.4.9] 2020-03-10 [1.4.9] 2020-03-10
================== ==================
Fixed Fixed
...@@ -31,7 +51,7 @@ Fixed ...@@ -31,7 +51,7 @@ Fixed
[1.4.6] 2019-12-16 [1.4.6] 2019-12-16
================== ==================
Changed Changed
----- -------
- [sw] better integration in coht, rename environment variable to FPGA_MGR - [sw] better integration in coht, rename environment variable to FPGA_MGR
[1.4.5] 2019-12-16 [1.4.5] 2019-12-16
...@@ -55,7 +75,7 @@ Added ...@@ -55,7 +75,7 @@ Added
[1.4.2] 2019-10-17 [1.4.2] 2019-10-17
================== ==================
Changed Changed
----- -------
- [sw] show application metadata in debugfs - [sw] show application metadata in debugfs
[1.4.1] 2019-10-15 [1.4.1] 2019-10-15
......
Subproject commit 75d51c0b92015b48b176374f9a387b2d25fa8198 Subproject commit 6f2c1dbd5021debe6233c9495cb1b9d10f4a79de
files = [ files = [
"svec_base_regs.vhd", "svec_base_regs.vhd",
"svec_base_wr.vhd", "svec_base_wr.vhd",
"sourceid_svec_base_pkg.vhd",
] ]
try:
# Assume this module is in fact a git submodule of a main project that
# is in the same directory as general-cores...
exec(open("../../../" + "/general-cores/tools/gen_sourceid.py").read(),
None, {'project': 'svec_base'})
except Exception as e:
print("Error: cannot generate source id file")
raise
...@@ -145,6 +145,7 @@ memory-map: ...@@ -145,6 +145,7 @@ memory-map:
name: wrc_regs name: wrc_regs
address: 0x1000 address: 0x1000
description: white-rabbit core registers description: white-rabbit core registers
comment: In particular, the vuart is at 0x1500
size: 0x1000 size: 0x1000
interface: wb-32-be interface: wb-32-be
x-hdl: x-hdl:
......
...@@ -36,12 +36,15 @@ use work.wr_svec_pkg.all; ...@@ -36,12 +36,15 @@ use work.wr_svec_pkg.all;
use work.buildinfo_pkg.all; use work.buildinfo_pkg.all;
use work.wr_fabric_pkg.all; use work.wr_fabric_pkg.all;
use work.streamers_pkg.all; use work.streamers_pkg.all;
use work.sourceid_svec_base_pkg;
library unisim; library unisim;
use unisim.vcomponents.all; use unisim.vcomponents.all;
entity svec_base_wr is entity svec_base_wr is
generic ( generic (
-- For the VME64x interface: if true, also consider AM in the decoder.
g_DECODE_AM : boolean := TRUE;
-- If true, instantiate a VIC/ONEWIRE/SPI/WR/DDRAM+DMA. -- If true, instantiate a VIC/ONEWIRE/SPI/WR/DDRAM+DMA.
g_WITH_VIC : boolean := True; g_WITH_VIC : boolean := True;
g_WITH_ONEWIRE : boolean := True; g_WITH_ONEWIRE : boolean := True;
...@@ -481,7 +484,7 @@ begin -- architecture top ...@@ -481,7 +484,7 @@ begin -- architecture top
cmp_vme_core : entity work.xvme64x_core cmp_vme_core : entity work.xvme64x_core
generic map ( generic map (
g_CLOCK_PERIOD => 16, g_CLOCK_PERIOD => 16,
g_DECODE_AM => TRUE, g_DECODE_AM => g_DECODE_AM,
g_USER_CSR_EXT => FALSE, g_USER_CSR_EXT => FALSE,
g_WB_GRANULARITY => BYTE, g_WB_GRANULARITY => BYTE,
g_WB_MODE => PIPELINED, g_WB_MODE => PIPELINED,
...@@ -649,13 +652,22 @@ begin -- architecture top ...@@ -649,13 +652,22 @@ begin -- architecture top
metadata_data <= x"53564543"; metadata_data <= x"53564543";
when x"2" => when x"2" =>
-- Version -- Version
metadata_data <= x"01040000"; metadata_data <= x"0104000a";
when x"3" => when x"3" =>
-- BOM -- BOM
metadata_data <= x"fffe0000"; metadata_data <= x"fffe0000";
when x"4" | x"5" | x"6" | x"7" => when x"4" =>
-- source id -- source id
metadata_data <= x"00000000"; metadata_data <= sourceid_svec_base_pkg.sourceid(127 downto 96);
when x"5" =>
-- source id
metadata_data <= sourceid_svec_base_pkg.sourceid(95 downto 64);
when x"6" =>
-- source id
metadata_data <= sourceid_svec_base_pkg.sourceid(63 downto 32);
when x"7" =>
-- source id
metadata_data <= sourceid_svec_base_pkg.sourceid(31 downto 0);
when x"8" => when x"8" =>
-- capability mask -- capability mask
metadata_data <= x"00000000"; metadata_data <= x"00000000";
...@@ -1241,7 +1253,7 @@ begin -- architecture top ...@@ -1241,7 +1253,7 @@ begin -- architecture top
ddr4_wb_out <= (adr => (others => 'X'), cyc => '0', stb => '0', sel => x"0", we => '0', ddr4_wb_out <= (adr => (others => 'X'), cyc => '0', stb => '0', sel => x"0", we => '0',
dat => (others => 'X')); dat => (others => 'X'));
csr_ddr4_data_in <= x"0000_0000"; csr_ddr4_data_in <= x"0000_0000";
csr_ddr4_data_rack <= csr_ddr4_data_wr; csr_ddr4_data_rack <= csr_ddr4_data_rd;
csr_ddr4_data_wack <= csr_ddr4_data_wr; csr_ddr4_data_wack <= csr_ddr4_data_wr;
end generate gen_without_ddr4; end generate gen_without_ddr4;
...@@ -1414,7 +1426,7 @@ begin -- architecture top ...@@ -1414,7 +1426,7 @@ begin -- architecture top
ddr5_wb_out <= (adr => (others => 'X'), cyc => '0', stb => '0', sel => x"0", we => '0', ddr5_wb_out <= (adr => (others => 'X'), cyc => '0', stb => '0', sel => x"0", we => '0',
dat => (others => 'X')); dat => (others => 'X'));
csr_ddr5_data_in <= x"0000_0000"; csr_ddr5_data_in <= x"0000_0000";
csr_ddr5_data_rack <= csr_ddr5_data_wr; csr_ddr5_data_rack <= csr_ddr5_data_rd;
csr_ddr5_data_wack <= csr_ddr5_data_wr; csr_ddr5_data_wack <= csr_ddr5_data_wr;
end generate gen_without_ddr5; end generate gen_without_ddr5;
......
...@@ -28,6 +28,8 @@ clean-spec-core-fpga.h: ...@@ -28,6 +28,8 @@ clean-spec-core-fpga.h:
install: modules_install install: modules_install
clean: clean-spec-core-fpga.h clean: clean-spec-core-fpga.h
$(MAKE) -C $(LINUX) M=$(shell pwd) $@
modules help coccicheck modules_install: svec-core-fpga.h modules help coccicheck modules_install: svec-core-fpga.h
$(MAKE) -C $(LINUX) M=$(shell pwd) \ $(MAKE) -C $(LINUX) M=$(shell pwd) \
VERSION=$(VERSION) \ VERSION=$(VERSION) \
......
...@@ -93,9 +93,9 @@ int compat_svec_fw_load(struct svec_dev *svec_dev, const char *name) ...@@ -93,9 +93,9 @@ int compat_svec_fw_load(struct svec_dev *svec_dev, const char *name)
struct fpga_manager *mgr; struct fpga_manager *mgr;
int err; int err;
mgr = fpga_mgr_get(&svec_dev->vdev->dev); mgr = fpga_mgr_get(&svec_dev->dev);
if (IS_ERR(mgr)) if (IS_ERR_OR_NULL(mgr))
return -ENODEV; return IS_ERR(mgr) ? PTR_ERR(mgr) : -ENODEV;
err = fpga_mgr_lock(mgr); err = fpga_mgr_lock(mgr);
if (err) if (err)
......
...@@ -74,7 +74,7 @@ static const struct debugfs_reg32 svec_fpga_debugfs_reg32[] = { ...@@ -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) static int svec_fpga_dbg_bld_info(struct seq_file *s, void *offset)
{ {
struct svec_fpga *svec_fpga = s->private; 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; int off;
if (!(svec_dev->meta.cap & SVEC_META_CAP_BLD)) { if (!(svec_dev->meta.cap & SVEC_META_CAP_BLD)) {
...@@ -118,7 +118,7 @@ static const struct file_operations svec_fpga_dbg_bld_info_ops = { ...@@ -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) 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; int err;
svec_fpga->dbg_dir = debugfs_create_dir(dev_name(&svec_fpga->dev), svec_fpga->dbg_dir = debugfs_create_dir(dev_name(&svec_fpga->dev),
...@@ -196,9 +196,9 @@ static struct resource svec_fpga_vic_res[] = { ...@@ -196,9 +196,9 @@ static struct resource svec_fpga_vic_res[] = {
static int svec_fpga_vic_init(struct svec_fpga *svec_fpga) static int svec_fpga_vic_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);
unsigned long vme_start = vme_resource_start(svec_dev->vdev, struct vme_dev *vdev = to_vme_dev(svec_dev->dev.parent);
svec_fpga->function_nr); unsigned long vme_start = vme_resource_start(vdev, svec_fpga->function_nr);
const unsigned int res_n = ARRAY_SIZE(svec_fpga_vic_res); const unsigned int res_n = ARRAY_SIZE(svec_fpga_vic_res);
struct resource res[ARRAY_SIZE(svec_fpga_vic_res)]; struct resource res[ARRAY_SIZE(svec_fpga_vic_res)];
struct platform_device *pdev; struct platform_device *pdev;
...@@ -209,7 +209,7 @@ static int svec_fpga_vic_init(struct svec_fpga *svec_fpga) ...@@ -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)); memcpy(&res, svec_fpga_vic_res, sizeof(svec_fpga_vic_res));
res[0].start += vme_start; res[0].start += vme_start;
res[0].end += 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; res[1].end = res[1].start;
pdev = platform_device_register_resndata(&svec_fpga->dev, pdev = platform_device_register_resndata(&svec_fpga->dev,
"htvic-svec", "htvic-svec",
...@@ -327,7 +327,7 @@ static inline size_t __fpga_mfd_devs_size(void) ...@@ -327,7 +327,7 @@ static inline size_t __fpga_mfd_devs_size(void)
static int svec_fpga_devices_init(struct svec_fpga *svec_fpga) 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 mfd_cell *fpga_mfd_devs;
struct irq_domain *vic_domain; struct irq_domain *vic_domain;
unsigned int n_mfd = 0; unsigned int n_mfd = 0;
...@@ -376,7 +376,7 @@ static ssize_t temperature_show(struct device *dev, ...@@ -376,7 +376,7 @@ static ssize_t temperature_show(struct device *dev,
char *buf) char *buf)
{ {
struct svec_fpga *svec_fpga = to_svec_fpga(dev); 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) { if (svec_dev->meta.cap & SVEC_META_CAP_THERM) {
uint32_t temp = ioread32be(svec_fpga->fpga uint32_t temp = ioread32be(svec_fpga->fpga
...@@ -396,7 +396,7 @@ static ssize_t serial_number_show(struct device *dev, ...@@ -396,7 +396,7 @@ static ssize_t serial_number_show(struct device *dev,
char *buf) char *buf)
{ {
struct svec_fpga *svec_fpga = to_svec_fpga(dev); 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) { if (svec_dev->meta.cap & SVEC_META_CAP_THERM) {
uint32_t msb = ioread32be(svec_fpga->fpga uint32_t msb = ioread32be(svec_fpga->fpga
...@@ -727,14 +727,14 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev, ...@@ -727,14 +727,14 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev,
struct svec_meta_id *meta) struct svec_meta_id *meta)
{ {
if ((meta->bom & SVEC_META_BOM_END_MASK) != SVEC_META_BOM_BE) { 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", "Expected Big Endian devices BOM: 0x%x\n",
meta->bom); meta->bom);
return false; return false;
} }
if ((meta->bom & SVEC_META_BOM_VER_MASK) != 0) { 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", "Unknow Metadata svecification version BOM: 0x%x\n",
meta->bom); meta->bom);
return false; return false;
...@@ -742,14 +742,14 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev, ...@@ -742,14 +742,14 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev,
if (meta->vendor != SVEC_META_VENDOR_ID || if (meta->vendor != SVEC_META_VENDOR_ID ||
meta->device != SVEC_META_DEVICE_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", "Unknow vendor/device ID: %08x:%08x\n",
meta->vendor, meta->device); meta->vendor, meta->device);
return false; return false;
} }
if ((meta->version & SVEC_META_VERSION_MASK) != SVEC_META_VERSION_1_4) { 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); "Unknow version: %08x\n", meta->version);
return false; return false;
} }
...@@ -757,33 +757,34 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev, ...@@ -757,33 +757,34 @@ static bool svec_fpga_is_valid(struct svec_dev *svec_dev,
return true; 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; return 0;
} }
static const struct attribute_group *svec_groups[] = { static const struct attribute_group *svec_fpga_groups[] = {
&svec_fpga_therm_group, &svec_fpga_therm_group,
&svec_fpga_csr_group, &svec_fpga_csr_group,
NULL NULL
}; };
static const struct device_type svec_fpga_type = { static const struct device_type svec_fpga_type = {
.name = "svec", .name = "svec-fpga",
.release = svec_release, .release = svec_fpga_release,
.uevent = svec_uevent, .uevent = svec_fpga_uevent,
.groups = svec_groups, .groups = svec_fpga_groups,
}; };
int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr) int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr)
{ {
struct svec_fpga *svec_fpga; 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; int err;
svec_fpga = kzalloc(sizeof(*svec_fpga), GFP_KERNEL); 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) ...@@ -804,18 +805,18 @@ int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr)
goto err_valid; goto err_valid;
} }
svec_fpga->dev.parent = &svec_dev->vdev->dev; svec_fpga->dev.parent = &svec_dev->dev;
svec_fpga->dev.driver = svec_dev->vdev->dev.driver; svec_fpga->dev.driver = svec_dev->dev.driver;
svec_fpga->dev.type = &svec_fpga_type; svec_fpga->dev.type = &svec_fpga_type;
err = dev_set_name(&svec_fpga->dev, "svec-%s", err = dev_set_name(&svec_fpga->dev, "%s-fpga",
dev_name(&svec_dev->vdev->dev)); dev_name(&svec_dev->dev));
if (err) if (err)
goto err_name; goto err_name;
err = device_register(&svec_fpga->dev); err = device_register(&svec_fpga->dev);
if (err) { if (err) {
dev_err(&svec_dev->vdev->dev, "Failed to register '%s'\n", dev_err(&svec_dev->dev, "Failed to register '%s'\n",
dev_name(&svec_dev->vdev->dev)); dev_name(&svec_fpga->dev));
goto err_dev; goto err_dev;
} }
...@@ -823,25 +824,25 @@ int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr) ...@@ -823,25 +824,25 @@ int svec_fpga_init(struct svec_dev *svec_dev, unsigned int function_nr)
err = svec_fpga_vic_init(svec_fpga); err = svec_fpga_vic_init(svec_fpga);
if (err) { if (err) {
dev_err(&svec_dev->vdev->dev, dev_err(&svec_dev->dev,
"Failed to initialize VIC %d\n", err); "Failed to initialize VIC %d\n", err);
goto err_vic; goto err_vic;
} }
err = svec_fpga_devices_init(svec_fpga); err = svec_fpga_devices_init(svec_fpga);
if (err) { if (err) {
dev_err(&svec_dev->vdev->dev, dev_err(&svec_dev->dev,
"Failed to initialize Devices %d\n", err); "Failed to initialize Devices %d\n", err);
goto err_devs; goto err_devs;
} }
err = svec_fmc_init(svec_fpga); err = svec_fmc_init(svec_fpga);
if (err) { if (err) {
dev_err(&svec_dev->vdev->dev, dev_err(&svec_dev->dev,
"Failed to initialize FMC %d\n", err); "Failed to initialize FMC %d\n", err);
goto err_fmc; goto err_fmc;
} }
err = svec_fpga_app_init(svec_fpga); err = svec_fpga_app_init(svec_fpga);
if (err) { if (err) {
dev_err(&svec_dev->vdev->dev, dev_err(&svec_dev->dev,
"Failed to initialize APP %d\n", err); "Failed to initialize APP %d\n", err);
goto err_app; goto err_app;
} }
......
...@@ -53,10 +53,10 @@ static int svec_fw_load(struct svec_dev *svec_dev, const char *name) ...@@ -53,10 +53,10 @@ static int svec_fw_load(struct svec_dev *svec_dev, const char *name)
{ {
int err; 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); err = svec_fpga_exit(svec_dev);
if (err) { 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"); "Cannot remove FPGA device instances. Try to remove them manually and to reload this device instance\n");
return err; return err;
} }
...@@ -84,7 +84,7 @@ static ssize_t svec_dbg_fw_write(struct file *file, ...@@ -84,7 +84,7 @@ static ssize_t svec_dbg_fw_write(struct file *file,
int err, ret; int err, ret;
if (VBRIDGE_DBG_FW_BUF_LEN < count) { 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", "Firmware name too long max %u\n",
VBRIDGE_DBG_FW_BUF_LEN); VBRIDGE_DBG_FW_BUF_LEN);
...@@ -101,7 +101,7 @@ static ssize_t svec_dbg_fw_write(struct file *file, ...@@ -101,7 +101,7 @@ static ssize_t svec_dbg_fw_write(struct file *file,
err = svec_fw_load(svec_dev, buf_l); err = svec_fw_load(svec_dev, buf_l);
if (err) if (err)
dev_err(&svec_dev->vdev->dev, dev_err(&svec_dev->dev,
"FPGA Configuration failure %d\n", err); "FPGA Configuration failure %d\n", err);
/* /*
...@@ -109,11 +109,11 @@ static ssize_t svec_dbg_fw_write(struct file *file, ...@@ -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 * the SVEC device that we used to re-flash the FPGA disappeard and so
* this driver instance must disapear as well. * this driver instance must disapear as well.
*/ */
dev_warn(&svec_dev->vdev->dev, "VME Slave removed\n"); dev_warn(&svec_dev->dev, "VME Slave removed\n");
dev_warn(&svec_dev->vdev->dev, "Remove this device driver instance\n"); dev_warn(&svec_dev->dev, "Remove this device driver instance\n");
ret = device_schedule_callback(&svec_dev->vdev->dev, remove_callback); ret = device_schedule_callback(svec_dev->dev.parent, remove_callback);
if (ret) { if (ret) {
dev_err(&svec_dev->vdev->dev, dev_err(&svec_dev->dev,
"Can't remove device driver instance %d\n", ret); "Can't remove device driver instance %d\n", ret);
return ret; return ret;
} }
...@@ -181,7 +181,7 @@ static const struct file_operations svec_dbg_meta_ops = { ...@@ -181,7 +181,7 @@ static const struct file_operations svec_dbg_meta_ops = {
static int svec_dbg_init(struct svec_dev *svec_dev) 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); svec_dev->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
if (IS_ERR_OR_NULL(svec_dev->dbg_dir)) { if (IS_ERR_OR_NULL(svec_dev->dbg_dir)) {
...@@ -229,7 +229,8 @@ static void svec_dbg_exit(struct svec_dev *svec_dev) ...@@ -229,7 +229,8 @@ static void svec_dbg_exit(struct svec_dev *svec_dev)
static int svec_fpga_reset(struct fpga_manager *mgr) static int svec_fpga_reset(struct fpga_manager *mgr)
{ {
struct svec_dev *svec = mgr->priv; 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; int i;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
...@@ -252,7 +253,8 @@ static int svec_fpga_reset(struct fpga_manager *mgr) ...@@ -252,7 +253,8 @@ static int svec_fpga_reset(struct fpga_manager *mgr)
static int svec_fpga_loader_is_active(struct fpga_manager *mgr) static int svec_fpga_loader_is_active(struct fpga_manager *mgr)
{ {
struct svec_dev *svec = mgr->priv; 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]; char buf[5];
uint32_t idc; uint32_t idc;
...@@ -282,7 +284,8 @@ static int svec_fpga_write_word(struct fpga_manager *mgr, ...@@ -282,7 +284,8 @@ static int svec_fpga_write_word(struct fpga_manager *mgr,
unsigned int is_last) unsigned int is_last)
{ {
struct svec_dev *svec = mgr->priv; 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_r0; /* Bitstream data input control register */
uint32_t xldr_fifo_r1; /* Bitstream data input register */ uint32_t xldr_fifo_r1; /* Bitstream data input register */
int rv, try = 10000; int rv, try = 10000;
...@@ -315,7 +318,8 @@ static int svec_fpga_write_word(struct fpga_manager *mgr, ...@@ -315,7 +318,8 @@ static int svec_fpga_write_word(struct fpga_manager *mgr,
static int svec_fpga_write_start(struct fpga_manager *mgr) static int svec_fpga_write_start(struct fpga_manager *mgr)
{ {
struct svec_dev *svec = mgr->priv; 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; int err, succ;
/* reset the FPGA */ /* reset the FPGA */
...@@ -355,7 +359,8 @@ static int svec_fpga_write_stop(struct fpga_manager *mgr, ...@@ -355,7 +359,8 @@ static int svec_fpga_write_stop(struct fpga_manager *mgr,
struct fpga_image_info *info) struct fpga_image_info *info)
{ {
struct svec_dev *svec = mgr->priv; 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; u64 timeout;
int rval = 0, err; int rval = 0, err;
...@@ -500,7 +505,7 @@ static const struct fpga_manager_ops svec_fpga_ops = { ...@@ -500,7 +505,7 @@ static const struct fpga_manager_ops svec_fpga_ops = {
static int svec_vme_init(struct svec_dev *svec) 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; int err;
err = vme_disable_device(vdev); err = vme_disable_device(vdev);
...@@ -515,6 +520,35 @@ static int svec_vme_init(struct svec_dev *svec) ...@@ -515,6 +520,35 @@ static int svec_vme_init(struct svec_dev *svec)
return vme_enable_device(vdev); return vme_enable_device(vdev);
} }
static int svec_vme_exit(struct svec_dev *svec)
{
struct vme_dev *vdev = to_vme_dev(svec->dev.parent);
int err;
err = vme_disable_device(vdev);
if (err)
return err;
svec_csr_write(0x0, vdev->map_cr.kernel_va,
SVEC_USER_CSR_INT_VECTOR);
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 * It initialize a new SVEC instance
* @pdev correspondend Linux device instance * @pdev correspondend Linux device instance
...@@ -534,15 +568,27 @@ static int svec_probe(struct device *dev, unsigned int ndev) ...@@ -534,15 +568,27 @@ static int svec_probe(struct device *dev, unsigned int ndev)
goto err; goto err;
} }
dev_set_drvdata(dev, svec);
spin_lock_init(&svec->lock); spin_lock_init(&svec->lock);
mutex_init(&svec->mtx); mutex_init(&svec->mtx);
svec->vdev = vdev; svec->dev.parent = &vdev->dev;
dev_set_drvdata(dev, svec); 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_vme_init(svec);
svec->fpga_status = FPGA_MGR_STATE_UNKNOWN; 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); &svec_fpga_ops, svec);
if (!svec->mgr) { if (!svec->mgr) {
err = -EPERM; err = -EPERM;
...@@ -565,6 +611,9 @@ static int svec_probe(struct device *dev, unsigned int ndev) ...@@ -565,6 +611,9 @@ static int svec_probe(struct device *dev, unsigned int ndev)
err_fpga_reg: err_fpga_reg:
fpga_mgr_free(svec->mgr); fpga_mgr_free(svec->mgr);
err_fpga_new: err_fpga_new:
device_unregister(&svec->dev);
err_dev:
err_name:
dev_set_drvdata(dev, NULL); dev_set_drvdata(dev, NULL);
kfree(svec); kfree(svec);
err: err:
...@@ -585,17 +634,20 @@ static int svec_remove(struct device *dev, unsigned int ndev) ...@@ -585,17 +634,20 @@ static int svec_remove(struct device *dev, unsigned int ndev)
svec_dbg_exit(svec); svec_dbg_exit(svec);
fpga_mgr_unregister(svec->mgr); fpga_mgr_unregister(svec->mgr);
fpga_mgr_free(svec->mgr); fpga_mgr_free(svec->mgr);
dev_set_drvdata(dev, NULL); svec_vme_exit(svec);
if ((svec->flags & SVEC_DEV_FLAGS_REPROGRAMMED) == 0) { if ((svec->flags & SVEC_DEV_FLAGS_REPROGRAMMED) == 0) {
/* /*
* If FPGA is REPROGRAMMED then there is * If FPGA is REPROGRAMMED then there is
* no device to disable * no device to disable
*/ */
vme_disable_device(svec->vdev); vme_disable_device(to_vme_dev(svec->dev.parent));
} }
device_unregister(&svec->dev);
kfree(svec); kfree(svec);
dev_set_drvdata(dev, NULL);
return 0; return 0;
} }
......
...@@ -126,7 +126,7 @@ static inline struct svec_fpga *to_svec_fpga(struct device *_dev) ...@@ -126,7 +126,7 @@ static inline struct svec_fpga *to_svec_fpga(struct device *_dev)
* @mem: ioremapped memory * @mem: ioremapped memory
*/ */
struct svec_dev { struct svec_dev {
struct vme_dev *vdev; struct device dev;
char name[8]; char name[8];
unsigned long flags; unsigned long flags;
struct svec_meta_id meta; struct svec_meta_id meta;
...@@ -150,6 +150,11 @@ struct svec_dev { ...@@ -150,6 +150,11 @@ struct svec_dev {
struct svec_fpga *svec_fpga; 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_init(struct svec_dev *svec_dev, unsigned int function_nr);
extern int svec_fpga_exit(struct svec_dev *svec_dev); extern int svec_fpga_exit(struct svec_dev *svec_dev);
#endif /* __SVEC_H__ */ #endif /* __SVEC_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment