diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-05-15 17:09:24 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-05-15 17:09:24 +0300 |
commit | f877a18c08fa6674364e469f318a3069c68204d2 (patch) | |
tree | 0e0dbf76b05d4c9119f18fca1d7563ce4ac4bbbb /drivers/fpga | |
parent | 84c1e51d7df85332705ffebc40ef135205492036 (diff) | |
parent | a2b9d4eadb7727772698d06e4cbeb1a1e2538675 (diff) | |
download | linux-f877a18c08fa6674364e469f318a3069c68204d2.tar.xz |
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.
Diffstat (limited to 'drivers/fpga')
-rw-r--r-- | drivers/fpga/dfl-afu-main.c | 35 | ||||
-rw-r--r-- | drivers/fpga/dfl-fme-main.c | 19 | ||||
-rw-r--r-- | drivers/fpga/dfl.c | 15 | ||||
-rw-r--r-- | drivers/fpga/dfl.h | 37 | ||||
-rw-r--r-- | drivers/fpga/ice40-spi.c | 10 | ||||
-rw-r--r-- | drivers/fpga/machxo2-spi.c | 12 | ||||
-rw-r--r-- | drivers/fpga/stratix10-soc.c | 3 |
7 files changed, 95 insertions, 36 deletions
diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c index 65437b6a6842..b0c31789a909 100644 --- a/drivers/fpga/dfl-afu-main.c +++ b/drivers/fpga/dfl-afu-main.c @@ -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; - - dev_dbg(&fdev->dev, "Device File Open\n"); - filp->private_data = fdev; + 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); - 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, diff --git a/drivers/fpga/dfl-fme-main.c b/drivers/fpga/dfl-fme-main.c index 353305629a0e..fc210d4e1863 100644 --- a/drivers/fpga/dfl-fme-main.c +++ b/drivers/fpga/dfl-fme-main.c @@ -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; - - dev_dbg(&fdev->dev, "Device File Open\n"); - filp->private_data = pdata; + 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); - 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; } diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 96a2b8274a33..990994874bf1 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -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); diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h index d312678a9aca..2f5d3052e36e 100644 --- a/drivers/fpga/dfl.h +++ b/drivers/fpga/dfl.h @@ -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 diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c index 56e112e14a10..8d689fea0dab 100644 --- a/drivers/fpga/ice40-spi.c +++ b/drivers/fpga/ice40-spi.c @@ -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; diff --git a/drivers/fpga/machxo2-spi.c b/drivers/fpga/machxo2-spi.c index 4d8a87641587..b316369156fe 100644 --- a/drivers/fpga/machxo2-spi.c +++ b/drivers/fpga/machxo2-spi.c @@ -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) diff --git a/drivers/fpga/stratix10-soc.c b/drivers/fpga/stratix10-soc.c index bae98c8ce362..44b7c569d4dc 100644 --- a/drivers/fpga/stratix10-soc.c +++ b/drivers/fpga/stratix10-soc.c @@ -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"}, {}, }; |