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

Merge branch 'release/v1.4.9'

parents 9ec20cf1 50e877c8
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
Change Log 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 [1.4.8] 2020-02-12
================== ==================
......
...@@ -648,22 +648,25 @@ static int svec_fpga_app_init(struct svec_fpga *svec_fpga) ...@@ -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) #define SVEC_FPGA_APP_RES_N (32 - SVEC_FPGA_APP_IRQ_BASE + 1)
struct vme_dev *vdev = to_vme_dev(svec_fpga->dev.parent); struct vme_dev *vdev = to_vme_dev(svec_fpga->dev.parent);
unsigned int res_n = SVEC_FPGA_APP_RES_N; unsigned int res_n = SVEC_FPGA_APP_RES_N;
struct resource res[SVEC_FPGA_APP_RES_N] = { struct resource *res;
[0] = {
.name = "app-mem",
.flags = IORESOURCE_MEM,
},
};
struct platform_device *pdev; struct platform_device *pdev;
struct irq_domain *vic_domain; struct irq_domain *vic_domain;
char app_name[SVEC_FPGA_APP_NAME_MAX]; char app_name[SVEC_FPGA_APP_NAME_MAX];
unsigned long app_offset; 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); app_offset = svec_fpga_csr_app_offset(svec_fpga);
if (!app_offset) { if (!app_offset) {
dev_warn(&svec_fpga->dev, "Application not found\n"); dev_warn(&svec_fpga->dev, "Application not found\n");
return 0; err = 0;
goto err_free;
} }
svec_fpga_metadata_get(&svec_fpga->meta_app, svec_fpga_metadata_get(&svec_fpga->meta_app,
...@@ -695,18 +698,21 @@ static int svec_fpga_app_init(struct svec_fpga *svec_fpga) ...@@ -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, err = svec_fpga_app_id_build(svec_fpga, app_offset,
app_name, SVEC_FPGA_APP_NAME_MAX); app_name, SVEC_FPGA_APP_NAME_MAX);
if (err) if (err)
return err; goto err_free;
svec_fpga_app_restart(svec_fpga); svec_fpga_app_restart(svec_fpga);
pdev = platform_device_register_resndata(&svec_fpga->dev, pdev = platform_device_register_resndata(&svec_fpga->dev,
app_name, PLATFORM_DEVID_AUTO, app_name, PLATFORM_DEVID_AUTO,
res, res_n, res, res_n,
NULL, 0); NULL, 0);
if (IS_ERR(pdev)) err = IS_ERR(pdev);
return PTR_ERR(pdev); if (err)
goto err_free;
svec_fpga->app_pdev = pdev; svec_fpga->app_pdev = pdev;
return 0; err_free:
kfree(res);
return err;
} }
static void svec_fpga_app_exit(struct svec_fpga *svec_fpga) static void svec_fpga_app_exit(struct svec_fpga *svec_fpga)
...@@ -869,6 +875,8 @@ int svec_fpga_exit(struct svec_dev *svec_dev) ...@@ -869,6 +875,8 @@ int svec_fpga_exit(struct svec_dev *svec_dev)
if (!svec_fpga) if (!svec_fpga)
return 0; 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_fpga_app_exit(svec_fpga);
svec_fmc_exit(svec_fpga); svec_fmc_exit(svec_fpga);
svec_fpga_devices_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) ...@@ -64,19 +64,16 @@ static int svec_fw_load(struct svec_dev *svec_dev, const char *name)
mutex_lock(&svec_dev->mtx); mutex_lock(&svec_dev->mtx);
err = compat_svec_fw_load(svec_dev, name); 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); mutex_unlock(&svec_dev->mtx);
return err; return err;
} }
static void remove_callback(struct device *dev)
{
vme_unregister_device(to_vme_dev(dev));
}
#define VBRIDGE_DBG_FW_BUF_LEN 128 #define VBRIDGE_DBG_FW_BUF_LEN 128
static ssize_t svec_dbg_fw_write(struct file *file, static ssize_t svec_dbg_fw_write(struct file *file,
const char __user *buf, const char __user *buf,
...@@ -84,7 +81,7 @@ static ssize_t svec_dbg_fw_write(struct file *file, ...@@ -84,7 +81,7 @@ static ssize_t svec_dbg_fw_write(struct file *file,
{ {
struct svec_dev *svec_dev = file->private_data; struct svec_dev *svec_dev = file->private_data;
char buf_l[VBRIDGE_DBG_FW_BUF_LEN]; char buf_l[VBRIDGE_DBG_FW_BUF_LEN];
int err; 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->vdev->dev,
...@@ -93,11 +90,33 @@ static ssize_t svec_dbg_fw_write(struct file *file, ...@@ -93,11 +90,33 @@ static ssize_t svec_dbg_fw_write(struct file *file,
return -EINVAL; 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) if (err)
return -EFAULT; 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); 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; return err ? err : count;
} }
...@@ -515,6 +534,7 @@ static int svec_probe(struct device *dev, unsigned int ndev) ...@@ -515,6 +534,7 @@ static int svec_probe(struct device *dev, unsigned int ndev)
goto err; goto err;
} }
spin_lock_init(&svec->lock);
mutex_init(&svec->mtx); mutex_init(&svec->mtx);
svec->vdev = vdev; svec->vdev = vdev;
dev_set_drvdata(dev, svec); dev_set_drvdata(dev, svec);
...@@ -567,7 +587,13 @@ static int svec_remove(struct device *dev, unsigned int ndev) ...@@ -567,7 +587,13 @@ static int svec_remove(struct device *dev, unsigned int ndev)
fpga_mgr_free(svec->mgr); fpga_mgr_free(svec->mgr);
dev_set_drvdata(dev, NULL); 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); kfree(svec);
return 0; return 0;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/fmc.h> #include <linux/fmc.h>
#include <linux/spinlock.h>
#include <vmebus.h> #include <vmebus.h>
#include "svec-core-fpga.h" #include "svec-core-fpga.h"
...@@ -61,8 +62,7 @@ enum { ...@@ -61,8 +62,7 @@ enum {
#define SVEC_META_VENDOR_ID PCI_VENDOR_ID_CERN #define SVEC_META_VENDOR_ID PCI_VENDOR_ID_CERN
#define SVEC_META_DEVICE_ID 0x53564543 #define SVEC_META_DEVICE_ID 0x53564543
//#define SVEC_META_BOM_BE 0xFEFF0000 #define SVEC_META_BOM_BE 0xFFFE0000
#define SVEC_META_BOM_BE 0xFFFE0000 /* FIXME */
#define SVEC_META_BOM_END_MASK 0xFFFF0000 #define SVEC_META_BOM_END_MASK 0xFFFF0000
#define SVEC_META_BOM_VER_MASK 0x0000FFFF #define SVEC_META_BOM_VER_MASK 0x0000FFFF
#define SVEC_META_VERSION_MASK 0xFFFF0000 #define SVEC_META_VERSION_MASK 0xFFFF0000
...@@ -106,6 +106,7 @@ static inline struct svec_fpga *to_svec_fpga(struct device *_dev) ...@@ -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 * struct svec_dev - SVEC instance
* It describes a SVEC device instance. * It describes a SVEC device instance.
...@@ -130,6 +131,7 @@ struct svec_dev { ...@@ -130,6 +131,7 @@ struct svec_dev {
unsigned long flags; unsigned long flags;
struct svec_meta_id meta; struct svec_meta_id meta;
struct mutex mtx; struct mutex mtx;
spinlock_t lock;
struct fpga_manager *mgr; struct fpga_manager *mgr;
uint32_t bitstream_last_word; 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