FPGA Manager changes for 5.8
Here's the first set of changes for the 5.8-rc1 merge window. Dominic's change adds support for accessing AFU regions with gdb. Gustavo's change is a cleanup patch regarding variable lenght arrays. Richard's changes update dt-bindings and add support for stratix and agilex. Sergiu's changes update spi transfers with the new delay field. Xu's change addresses an issue with a wrong return value. Shubhrajyoti's change makes the Zynq FPGA driver return -EPROBE_DEFER on check of devm_clk_get failure. Xu's change for DFL enables multiple opens. All of these patches have been reviewed, have appropriate Acked-by's and have been in the last few linux-next releases without issues. Signed-off-by: Moritz Fischer <mdf@kernel.org> -----BEGIN PGP SIGNATURE----- iIUEABYIAC0WIQS/ea/a56fFi9QbQeJ+E8eWOj6VqQUCXrbxaw8cbWRmQGtlcm5l bC5vcmcACgkQfhPHljo+lamnQAD/dQa0AzlcPyIbo6pcufwyeZPgjKEunXiCd0vc nb1caZEBAMV69oNK441+vYy911LuY6x/hdz0Ch4E4NQK0zjUrAcM =LWCH -----END PGP SIGNATURE----- Merge tag 'fpga-for-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga into char-misc-next Moritz writes: FPGA Manager changes for 5.8 Here's the first set of changes for the 5.8-rc1 merge window. Dominic's change adds support for accessing AFU regions with gdb. Gustavo's change is a cleanup patch regarding variable lenght arrays. Richard's changes update dt-bindings and add support for stratix and agilex. Sergiu's changes update spi transfers with the new delay field. Xu's change addresses an issue with a wrong return value. Shubhrajyoti's change makes the Zynq FPGA driver return -EPROBE_DEFER on check of devm_clk_get failure. Xu's change for DFL enables multiple opens. All of these patches have been reviewed, have appropriate Acked-by's and have been in the last few linux-next releases without issues. Signed-off-by: Moritz Fischer <mdf@kernel.org> * tag 'fpga-for-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga: fpga: dfl: afu: support debug access to memory-mapped afu regions fpga: dfl.h: Replace zero-length array with flexible-array member arm64: dts: agilex: correct service layer driver's compatible value dt-bindings, firmware: add compatible value Intel Stratix10 service layer binding fpga: stratix10-soc: add compatible property value for intel agilex arm64: dts: agilex: correct FPGA manager driver's compatible value dt-bindings: fpga: add compatible value to Stratix10 SoC FPGA manager binding fpga: machxo2-spi: Use new structure for SPI transfer delays fpga: ice40-spi: Use new structure for SPI transfer delays fpga: dfl: support multiple opens on feature device node.
This commit is contained in:
commit
f877a18c08
|
@ -23,7 +23,7 @@ Required properties:
|
|||
The svc node has the following mandatory properties, must be located under
|
||||
the firmware node.
|
||||
|
||||
- compatible: "intel,stratix10-svc"
|
||||
- compatible: "intel,stratix10-svc" or "intel,agilex-svc"
|
||||
- method: smc or hvc
|
||||
smc - Secure Monitor Call
|
||||
hvc - Hypervisor Call
|
||||
|
|
|
@ -4,7 +4,8 @@ Required properties:
|
|||
The fpga_mgr node has the following mandatory property, must be located under
|
||||
firmware/svc node.
|
||||
|
||||
- compatible : should contain "intel,stratix10-soc-fpga-mgr"
|
||||
- compatible : should contain "intel,stratix10-soc-fpga-mgr" or
|
||||
"intel,agilex-soc-fpga-mgr"
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -539,12 +539,12 @@
|
|||
|
||||
firmware {
|
||||
svc {
|
||||
compatible = "intel,stratix10-svc";
|
||||
compatible = "intel,agilex-svc";
|
||||
method = "smc";
|
||||
memory-region = <&service_reserved>;
|
||||
|
||||
fpga_mgr: fpga-mgr {
|
||||
compatible = "intel,stratix10-soc-fpga-mgr";
|
||||
compatible = "intel,agilex-soc-fpga-mgr";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -561,14 +561,16 @@ static int afu_open(struct inode *inode, struct file *filp)
|
|||
if (WARN_ON(!pdata))
|
||||
return -ENODEV;
|
||||
|
||||
ret = dfl_feature_dev_use_begin(pdata);
|
||||
if (ret)
|
||||
return ret;
|
||||
mutex_lock(&pdata->lock);
|
||||
ret = dfl_feature_dev_use_begin(pdata, filp->f_flags & O_EXCL);
|
||||
if (!ret) {
|
||||
dev_dbg(&fdev->dev, "Device File Opened %d Times\n",
|
||||
dfl_feature_dev_use_count(pdata));
|
||||
filp->private_data = fdev;
|
||||
}
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
dev_dbg(&fdev->dev, "Device File Open\n");
|
||||
filp->private_data = fdev;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int afu_release(struct inode *inode, struct file *filp)
|
||||
|
@ -581,12 +583,14 @@ static int afu_release(struct inode *inode, struct file *filp)
|
|||
pdata = dev_get_platdata(&pdev->dev);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
__port_reset(pdev);
|
||||
afu_dma_region_destroy(pdata);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
dfl_feature_dev_use_end(pdata);
|
||||
|
||||
if (!dfl_feature_dev_use_count(pdata)) {
|
||||
__port_reset(pdev);
|
||||
afu_dma_region_destroy(pdata);
|
||||
}
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -746,6 +750,12 @@ static long afu_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct afu_vma_ops = {
|
||||
#ifdef CONFIG_HAVE_IOREMAP_PROT
|
||||
.access = generic_access_phys,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int afu_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
{
|
||||
struct platform_device *pdev = filp->private_data;
|
||||
|
@ -775,6 +785,9 @@ static int afu_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
!(region.flags & DFL_PORT_REGION_WRITE))
|
||||
return -EPERM;
|
||||
|
||||
/* Support debug access to the mapping */
|
||||
vma->vm_ops = &afu_vma_ops;
|
||||
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
|
||||
return remap_pfn_range(vma, vma->vm_start,
|
||||
|
|
|
@ -604,14 +604,16 @@ static int fme_open(struct inode *inode, struct file *filp)
|
|||
if (WARN_ON(!pdata))
|
||||
return -ENODEV;
|
||||
|
||||
ret = dfl_feature_dev_use_begin(pdata);
|
||||
if (ret)
|
||||
return ret;
|
||||
mutex_lock(&pdata->lock);
|
||||
ret = dfl_feature_dev_use_begin(pdata, filp->f_flags & O_EXCL);
|
||||
if (!ret) {
|
||||
dev_dbg(&fdev->dev, "Device File Opened %d Times\n",
|
||||
dfl_feature_dev_use_count(pdata));
|
||||
filp->private_data = pdata;
|
||||
}
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
dev_dbg(&fdev->dev, "Device File Open\n");
|
||||
filp->private_data = pdata;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fme_release(struct inode *inode, struct file *filp)
|
||||
|
@ -620,7 +622,10 @@ static int fme_release(struct inode *inode, struct file *filp)
|
|||
struct platform_device *pdev = pdata->dev;
|
||||
|
||||
dev_dbg(&pdev->dev, "Device File Release\n");
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
dfl_feature_dev_use_end(pdata);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1079,6 +1079,7 @@ static int __init dfl_fpga_init(void)
|
|||
*/
|
||||
int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id)
|
||||
{
|
||||
struct dfl_feature_platform_data *pdata;
|
||||
struct platform_device *port_pdev;
|
||||
int ret = -ENODEV;
|
||||
|
||||
|
@ -1093,7 +1094,11 @@ int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id)
|
|||
goto put_dev_exit;
|
||||
}
|
||||
|
||||
ret = dfl_feature_dev_use_begin(dev_get_platdata(&port_pdev->dev));
|
||||
pdata = dev_get_platdata(&port_pdev->dev);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
ret = dfl_feature_dev_use_begin(pdata, true);
|
||||
mutex_unlock(&pdata->lock);
|
||||
if (ret)
|
||||
goto put_dev_exit;
|
||||
|
||||
|
@ -1120,6 +1125,7 @@ EXPORT_SYMBOL_GPL(dfl_fpga_cdev_release_port);
|
|||
*/
|
||||
int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id)
|
||||
{
|
||||
struct dfl_feature_platform_data *pdata;
|
||||
struct platform_device *port_pdev;
|
||||
int ret = -ENODEV;
|
||||
|
||||
|
@ -1138,7 +1144,12 @@ int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id)
|
|||
if (ret)
|
||||
goto put_dev_exit;
|
||||
|
||||
dfl_feature_dev_use_end(dev_get_platdata(&port_pdev->dev));
|
||||
pdata = dev_get_platdata(&port_pdev->dev);
|
||||
|
||||
mutex_lock(&pdata->lock);
|
||||
dfl_feature_dev_use_end(pdata);
|
||||
mutex_unlock(&pdata->lock);
|
||||
|
||||
cdev->released_port_num--;
|
||||
put_dev_exit:
|
||||
put_device(&port_pdev->dev);
|
||||
|
|
|
@ -207,8 +207,6 @@ struct dfl_feature {
|
|||
void *priv;
|
||||
};
|
||||
|
||||
#define DEV_STATUS_IN_USE 0
|
||||
|
||||
#define FEATURE_DEV_ID_UNUSED (-1)
|
||||
|
||||
/**
|
||||
|
@ -221,8 +219,9 @@ struct dfl_feature {
|
|||
* @dfl_cdev: ptr to container device.
|
||||
* @id: id used for this feature device.
|
||||
* @disable_count: count for port disable.
|
||||
* @excl_open: set on feature device exclusive open.
|
||||
* @open_count: count for feature device open.
|
||||
* @num: number for sub features.
|
||||
* @dev_status: dev status (e.g. DEV_STATUS_IN_USE).
|
||||
* @private: ptr to feature dev private data.
|
||||
* @features: sub features of this feature dev.
|
||||
*/
|
||||
|
@ -234,26 +233,46 @@ struct dfl_feature_platform_data {
|
|||
struct dfl_fpga_cdev *dfl_cdev;
|
||||
int id;
|
||||
unsigned int disable_count;
|
||||
unsigned long dev_status;
|
||||
bool excl_open;
|
||||
int open_count;
|
||||
void *private;
|
||||
int num;
|
||||
struct dfl_feature features[0];
|
||||
struct dfl_feature features[];
|
||||
};
|
||||
|
||||
static inline
|
||||
int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata)
|
||||
int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata,
|
||||
bool excl)
|
||||
{
|
||||
/* Test and set IN_USE flags to ensure file is exclusively used */
|
||||
if (test_and_set_bit_lock(DEV_STATUS_IN_USE, &pdata->dev_status))
|
||||
if (pdata->excl_open)
|
||||
return -EBUSY;
|
||||
|
||||
if (excl) {
|
||||
if (pdata->open_count)
|
||||
return -EBUSY;
|
||||
|
||||
pdata->excl_open = true;
|
||||
}
|
||||
pdata->open_count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
void dfl_feature_dev_use_end(struct dfl_feature_platform_data *pdata)
|
||||
{
|
||||
clear_bit_unlock(DEV_STATUS_IN_USE, &pdata->dev_status);
|
||||
pdata->excl_open = false;
|
||||
|
||||
if (WARN_ON(pdata->open_count <= 0))
|
||||
return;
|
||||
|
||||
pdata->open_count--;
|
||||
}
|
||||
|
||||
static inline
|
||||
int dfl_feature_dev_use_count(struct dfl_feature_platform_data *pdata)
|
||||
{
|
||||
return pdata->open_count;
|
||||
}
|
||||
|
||||
static inline
|
||||
|
|
|
@ -46,10 +46,16 @@ static int ice40_fpga_ops_write_init(struct fpga_manager *mgr,
|
|||
struct spi_message message;
|
||||
struct spi_transfer assert_cs_then_reset_delay = {
|
||||
.cs_change = 1,
|
||||
.delay_usecs = ICE40_SPI_RESET_DELAY
|
||||
.delay = {
|
||||
.value = ICE40_SPI_RESET_DELAY,
|
||||
.unit = SPI_DELAY_UNIT_USECS
|
||||
}
|
||||
};
|
||||
struct spi_transfer housekeeping_delay_then_release_cs = {
|
||||
.delay_usecs = ICE40_SPI_HOUSEKEEPING_DELAY
|
||||
.delay = {
|
||||
.value = ICE40_SPI_HOUSEKEEPING_DELAY,
|
||||
.unit = SPI_DELAY_UNIT_USECS
|
||||
}
|
||||
};
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -157,7 +157,8 @@ static int machxo2_cleanup(struct fpga_manager *mgr)
|
|||
spi_message_init(&msg);
|
||||
tx[1].tx_buf = &refresh;
|
||||
tx[1].len = sizeof(refresh);
|
||||
tx[1].delay_usecs = MACHXO2_REFRESH_USEC;
|
||||
tx[1].delay.value = MACHXO2_REFRESH_USEC;
|
||||
tx[1].delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
spi_message_add_tail(&tx[1], &msg);
|
||||
ret = spi_sync(spi, &msg);
|
||||
if (ret)
|
||||
|
@ -208,7 +209,8 @@ static int machxo2_write_init(struct fpga_manager *mgr,
|
|||
spi_message_init(&msg);
|
||||
tx[0].tx_buf = &enable;
|
||||
tx[0].len = sizeof(enable);
|
||||
tx[0].delay_usecs = MACHXO2_LOW_DELAY_USEC;
|
||||
tx[0].delay.value = MACHXO2_LOW_DELAY_USEC;
|
||||
tx[0].delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
spi_message_add_tail(&tx[0], &msg);
|
||||
|
||||
tx[1].tx_buf = &erase;
|
||||
|
@ -269,7 +271,8 @@ static int machxo2_write(struct fpga_manager *mgr, const char *buf,
|
|||
spi_message_init(&msg);
|
||||
tx.tx_buf = payload;
|
||||
tx.len = MACHXO2_BUF_SIZE;
|
||||
tx.delay_usecs = MACHXO2_HIGH_DELAY_USEC;
|
||||
tx.delay.value = MACHXO2_HIGH_DELAY_USEC;
|
||||
tx.delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
spi_message_add_tail(&tx, &msg);
|
||||
ret = spi_sync(spi, &msg);
|
||||
if (ret) {
|
||||
|
@ -317,7 +320,8 @@ static int machxo2_write_complete(struct fpga_manager *mgr,
|
|||
spi_message_init(&msg);
|
||||
tx[1].tx_buf = &refresh;
|
||||
tx[1].len = sizeof(refresh);
|
||||
tx[1].delay_usecs = MACHXO2_REFRESH_USEC;
|
||||
tx[1].delay.value = MACHXO2_REFRESH_USEC;
|
||||
tx[1].delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
spi_message_add_tail(&tx[1], &msg);
|
||||
ret = spi_sync(spi, &msg);
|
||||
if (ret)
|
||||
|
|
|
@ -477,7 +477,8 @@ static int s10_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id s10_of_match[] = {
|
||||
{ .compatible = "intel,stratix10-soc-fpga-mgr", },
|
||||
{.compatible = "intel,stratix10-soc-fpga-mgr"},
|
||||
{.compatible = "intel,agilex-soc-fpga-mgr"},
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue