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

Merge branch 'release/v1.4.9'

parents 9ec20cf1 50e877c8
......@@ -2,6 +2,12 @@
Change Log
==========
[1.4.9] 2020-03-10
==================
Fixed
-----
- [sw] reduce allocation on stack
- [sw] automatically remove device after FPGA reprogram (otherwise unusable)
[1.4.8] 2020-02-12
==================
......
......@@ -648,22 +648,25 @@ static int svec_fpga_app_init(struct svec_fpga *svec_fpga)
#define SVEC_FPGA_APP_RES_N (32 - SVEC_FPGA_APP_IRQ_BASE + 1)
struct vme_dev *vdev = to_vme_dev(svec_fpga->dev.parent);
unsigned int res_n = SVEC_FPGA_APP_RES_N;
struct resource res[SVEC_FPGA_APP_RES_N] = {
[0] = {
.name = "app-mem",
.flags = IORESOURCE_MEM,
},
};
struct resource *res;
struct platform_device *pdev;
struct irq_domain *vic_domain;
char app_name[SVEC_FPGA_APP_NAME_MAX];
unsigned long app_offset;
int err, fn = svec_fpga->function_nr;
int err = 0, fn = svec_fpga->function_nr;
res = kcalloc(SVEC_FPGA_APP_RES_N, sizeof(*res), GFP_KERNEL);
if (!res)
return -ENOMEM;
res[0].name = "app-mem";
res[0].flags = IORESOURCE_MEM;
app_offset = svec_fpga_csr_app_offset(svec_fpga);
if (!app_offset) {
dev_warn(&svec_fpga->dev, "Application not found\n");
return 0;
err = 0;
goto err_free;
}
svec_fpga_metadata_get(&svec_fpga->meta_app,
......@@ -695,18 +698,21 @@ static int svec_fpga_app_init(struct svec_fpga *svec_fpga)
err = svec_fpga_app_id_build(svec_fpga, app_offset,
app_name, SVEC_FPGA_APP_NAME_MAX);
if (err)
return err;
goto err_free;
svec_fpga_app_restart(svec_fpga);
pdev = platform_device_register_resndata(&svec_fpga->dev,
app_name, PLATFORM_DEVID_AUTO,
res, res_n,
NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
err = IS_ERR(pdev);
if (err)
goto err_free;
svec_fpga->app_pdev = pdev;
return 0;
err_free:
kfree(res);
return err;
}
static void svec_fpga_app_exit(struct svec_fpga *svec_fpga)
......@@ -869,6 +875,8 @@ int svec_fpga_exit(struct svec_dev *svec_dev)
if (!svec_fpga)
return 0;
/* this function must run before re-flashing */
BUG_ON(svec_dev->flags & SVEC_DEV_FLAGS_REPROGRAMMED);
svec_fpga_app_exit(svec_fpga);
svec_fmc_exit(svec_fpga);
svec_fpga_devices_exit(svec_fpga);
......
......@@ -64,19 +64,16 @@ static int svec_fw_load(struct svec_dev *svec_dev, const char *name)
mutex_lock(&svec_dev->mtx);
err = compat_svec_fw_load(svec_dev, name);
if (err)
goto out;
err = svec_fpga_init(svec_dev, SVEC_FUNC_NR);
if (err)
dev_warn(&svec_dev->vdev->dev,
"FPGA incorrectly programmed %d\n", err);
out:
mutex_unlock(&svec_dev->mtx);
return err;
}
static void remove_callback(struct device *dev)
{
vme_unregister_device(to_vme_dev(dev));
}
#define VBRIDGE_DBG_FW_BUF_LEN 128
static ssize_t svec_dbg_fw_write(struct file *file,
const char __user *buf,
......@@ -84,7 +81,7 @@ static ssize_t svec_dbg_fw_write(struct file *file,
{
struct svec_dev *svec_dev = file->private_data;
char buf_l[VBRIDGE_DBG_FW_BUF_LEN];
int err;
int err, ret;
if (VBRIDGE_DBG_FW_BUF_LEN < count) {
dev_err(&svec_dev->vdev->dev,
......@@ -93,11 +90,33 @@ static ssize_t svec_dbg_fw_write(struct file *file,
return -EINVAL;
}
err = copy_from_user(buf_l, buf, VBRIDGE_DBG_FW_BUF_LEN);
memset(buf_l, 0, VBRIDGE_DBG_FW_BUF_LEN);
err = copy_from_user(buf_l, buf, count);
if (err)
return -EFAULT;
spin_lock(&svec_dev->lock);
svec_dev->flags |= SVEC_DEV_FLAGS_REPROGRAMMED;
spin_unlock(&svec_dev->lock);
err = svec_fw_load(svec_dev, buf_l);
if (err)
dev_err(&svec_dev->vdev->dev,
"FPGA Configuration failure %d\n", err);
/*
* Reprogramming the FPGA means replacing the VME slave. In other words
* the SVEC device that we used to re-flash the FPGA disappeard and so
* this driver instance must disapear as well.
*/
dev_warn(&svec_dev->vdev->dev, "VME Slave removed\n");
dev_warn(&svec_dev->vdev->dev, "Remove this device driver instance\n");
ret = device_schedule_callback(&svec_dev->vdev->dev, remove_callback);
if (ret) {
dev_err(&svec_dev->vdev->dev,
"Can't remove device driver instance %d\n", ret);
return ret;
}
return err ? err : count;
}
......@@ -515,6 +534,7 @@ static int svec_probe(struct device *dev, unsigned int ndev)
goto err;
}
spin_lock_init(&svec->lock);
mutex_init(&svec->mtx);
svec->vdev = vdev;
dev_set_drvdata(dev, svec);
......@@ -567,7 +587,13 @@ static int svec_remove(struct device *dev, unsigned int ndev)
fpga_mgr_free(svec->mgr);
dev_set_drvdata(dev, NULL);
vme_disable_device(svec->vdev);
if ((svec->flags & SVEC_DEV_FLAGS_REPROGRAMMED) == 0) {
/*
* If FPGA is REPROGRAMMED then there is
* no device to disable
*/
vme_disable_device(svec->vdev);
}
kfree(svec);
return 0;
......
......@@ -9,6 +9,7 @@
#include <linux/debugfs.h>
#include <linux/platform_device.h>
#include <linux/fmc.h>
#include <linux/spinlock.h>
#include <vmebus.h>
#include "svec-core-fpga.h"
......@@ -61,8 +62,7 @@ enum {
#define SVEC_META_VENDOR_ID PCI_VENDOR_ID_CERN
#define SVEC_META_DEVICE_ID 0x53564543
//#define SVEC_META_BOM_BE 0xFEFF0000
#define SVEC_META_BOM_BE 0xFFFE0000 /* FIXME */
#define SVEC_META_BOM_BE 0xFFFE0000
#define SVEC_META_BOM_END_MASK 0xFFFF0000
#define SVEC_META_BOM_VER_MASK 0x0000FFFF
#define SVEC_META_VERSION_MASK 0xFFFF0000
......@@ -106,6 +106,7 @@ static inline struct svec_fpga *to_svec_fpga(struct device *_dev)
}
#define SVEC_DEV_FLAGS_REPROGRAMMED BIT(0)
/**
* struct svec_dev - SVEC instance
* It describes a SVEC device instance.
......@@ -130,6 +131,7 @@ struct svec_dev {
unsigned long flags;
struct svec_meta_id meta;
struct mutex mtx;
spinlock_t lock;
struct fpga_manager *mgr;
uint32_t bitstream_last_word;
......
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