| From dcc67124b4337a29ce04452a177953b3ff14b87a Mon Sep 17 00:00:00 2001 |
| From: Alan Tull <atull@opensource.altera.com> |
| Date: Tue, 1 Nov 2016 14:14:26 -0500 |
| Subject: [PATCH 028/103] fpga-mgr: add fpga image information struct |
| |
| This patch adds a minor change in the FPGA Manager API |
| to hold information that is specific to an FPGA image |
| file. This change is expected to bring little, if any, |
| pain. The socfpga and zynq drivers are fixed up in |
| this patch. |
| |
| An FPGA image file will have particulars that affect how the |
| image is programmed to the FPGA. One example is that |
| current 'flags' currently has one bit which shows whether the |
| FPGA image was built for full reconfiguration or partial |
| reconfiguration. Another example is timeout values for |
| enabling or disabling the bridges in the FPGA. As the |
| complexity of the FPGA design increases, the bridges in the |
| FPGA may take longer times to enable or disable. |
| |
| This patch adds a new 'struct fpga_image_info', moves the |
| current 'u32 flags' to it. Two other image-specific u32's |
| are added for the bridge enable/disable timeouts. The FPGA |
| Manager API functions are changed, replacing the 'u32 flag' |
| parameter with a pointer to struct fpga_image_info. |
| Subsequent patches fix the existing low level FPGA manager |
| drivers. |
| |
| Signed-off-by: Alan Tull <atull@opensource.altera.com> |
| Acked-by: Moritz Fischer <moritz.fischer@ettus.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/fpga/fpga-mgr.c | 17 +++++++++-------- |
| drivers/fpga/socfpga.c | 7 ++++--- |
| drivers/fpga/zynq-fpga.c | 10 ++++++---- |
| include/linux/fpga/fpga-mgr.h | 23 +++++++++++++++++++---- |
| 4 files changed, 38 insertions(+), 19 deletions(-) |
| |
| --- a/drivers/fpga/fpga-mgr.c |
| +++ b/drivers/fpga/fpga-mgr.c |
| @@ -32,7 +32,7 @@ static struct class *fpga_mgr_class; |
| /** |
| * fpga_mgr_buf_load - load fpga from image in buffer |
| * @mgr: fpga manager |
| - * @flags: flags setting fpga confuration modes |
| + * @info: fpga image specific information |
| * @buf: buffer contain fpga image |
| * @count: byte count of buf |
| * |
| @@ -44,8 +44,8 @@ static struct class *fpga_mgr_class; |
| * |
| * Return: 0 on success, negative error code otherwise. |
| */ |
| -int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf, |
| - size_t count) |
| +int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, |
| + const char *buf, size_t count) |
| { |
| struct device *dev = &mgr->dev; |
| int ret; |
| @@ -56,7 +56,7 @@ int fpga_mgr_buf_load(struct fpga_manage |
| * ready to receive an FPGA image. |
| */ |
| mgr->state = FPGA_MGR_STATE_WRITE_INIT; |
| - ret = mgr->mops->write_init(mgr, flags, buf, count); |
| + ret = mgr->mops->write_init(mgr, info, buf, count); |
| if (ret) { |
| dev_err(dev, "Error preparing FPGA for writing\n"); |
| mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; |
| @@ -79,7 +79,7 @@ int fpga_mgr_buf_load(struct fpga_manage |
| * steps to finish and set the FPGA into operating mode. |
| */ |
| mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE; |
| - ret = mgr->mops->write_complete(mgr, flags); |
| + ret = mgr->mops->write_complete(mgr, info); |
| if (ret) { |
| dev_err(dev, "Error after writing image data to FPGA\n"); |
| mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR; |
| @@ -94,7 +94,7 @@ EXPORT_SYMBOL_GPL(fpga_mgr_buf_load); |
| /** |
| * fpga_mgr_firmware_load - request firmware and load to fpga |
| * @mgr: fpga manager |
| - * @flags: flags setting fpga confuration modes |
| + * @info: fpga image specific information |
| * @image_name: name of image file on the firmware search path |
| * |
| * Request an FPGA image using the firmware class, then write out to the FPGA. |
| @@ -105,7 +105,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_buf_load); |
| * |
| * Return: 0 on success, negative error code otherwise. |
| */ |
| -int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags, |
| +int fpga_mgr_firmware_load(struct fpga_manager *mgr, |
| + struct fpga_image_info *info, |
| const char *image_name) |
| { |
| struct device *dev = &mgr->dev; |
| @@ -123,7 +124,7 @@ int fpga_mgr_firmware_load(struct fpga_m |
| return ret; |
| } |
| |
| - ret = fpga_mgr_buf_load(mgr, flags, fw->data, fw->size); |
| + ret = fpga_mgr_buf_load(mgr, info, fw->data, fw->size); |
| |
| release_firmware(fw); |
| |
| --- a/drivers/fpga/socfpga.c |
| +++ b/drivers/fpga/socfpga.c |
| @@ -407,13 +407,14 @@ static int socfpga_fpga_reset(struct fpg |
| /* |
| * Prepare the FPGA to receive the configuration data. |
| */ |
| -static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr, u32 flags, |
| +static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr, |
| + struct fpga_image_info *info, |
| const char *buf, size_t count) |
| { |
| struct socfpga_fpga_priv *priv = mgr->priv; |
| int ret; |
| |
| - if (flags & FPGA_MGR_PARTIAL_RECONFIG) { |
| + if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { |
| dev_err(&mgr->dev, "Partial reconfiguration not supported.\n"); |
| return -EINVAL; |
| } |
| @@ -478,7 +479,7 @@ static int socfpga_fpga_ops_configure_wr |
| } |
| |
| static int socfpga_fpga_ops_configure_complete(struct fpga_manager *mgr, |
| - u32 flags) |
| + struct fpga_image_info *info) |
| { |
| struct socfpga_fpga_priv *priv = mgr->priv; |
| u32 status; |
| --- a/drivers/fpga/zynq-fpga.c |
| +++ b/drivers/fpga/zynq-fpga.c |
| @@ -175,7 +175,8 @@ static irqreturn_t zynq_fpga_isr(int irq |
| return IRQ_HANDLED; |
| } |
| |
| -static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags, |
| +static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, |
| + struct fpga_image_info *info, |
| const char *buf, size_t count) |
| { |
| struct zynq_fpga_priv *priv; |
| @@ -189,7 +190,7 @@ static int zynq_fpga_ops_write_init(stru |
| return err; |
| |
| /* don't globally reset PL if we're doing partial reconfig */ |
| - if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) { |
| + if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { |
| /* assert AXI interface resets */ |
| regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET, |
| FPGA_RST_ALL_MASK); |
| @@ -343,7 +344,8 @@ out_free: |
| return err; |
| } |
| |
| -static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr, u32 flags) |
| +static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr, |
| + struct fpga_image_info *info) |
| { |
| struct zynq_fpga_priv *priv = mgr->priv; |
| int err; |
| @@ -364,7 +366,7 @@ static int zynq_fpga_ops_write_complete( |
| return err; |
| |
| /* for the partial reconfig case we didn't touch the level shifters */ |
| - if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) { |
| + if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { |
| /* enable level shifters from PL to PS */ |
| regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET, |
| LVL_SHFTR_ENABLE_PL_TO_PS); |
| --- a/include/linux/fpga/fpga-mgr.h |
| +++ b/include/linux/fpga/fpga-mgr.h |
| @@ -69,6 +69,18 @@ enum fpga_mgr_states { |
| #define FPGA_MGR_PARTIAL_RECONFIG BIT(0) |
| |
| /** |
| + * struct fpga_image_info - information specific to a FPGA image |
| + * @flags: boolean flags as defined above |
| + * @enable_timeout_us: maximum time to enable traffic through bridge (uSec) |
| + * @disable_timeout_us: maximum time to disable traffic through bridge (uSec) |
| + */ |
| +struct fpga_image_info { |
| + u32 flags; |
| + u32 enable_timeout_us; |
| + u32 disable_timeout_us; |
| +}; |
| + |
| +/** |
| * struct fpga_manager_ops - ops for low level fpga manager drivers |
| * @state: returns an enum value of the FPGA's state |
| * @write_init: prepare the FPGA to receive confuration data |
| @@ -82,10 +94,12 @@ enum fpga_mgr_states { |
| */ |
| struct fpga_manager_ops { |
| enum fpga_mgr_states (*state)(struct fpga_manager *mgr); |
| - int (*write_init)(struct fpga_manager *mgr, u32 flags, |
| + int (*write_init)(struct fpga_manager *mgr, |
| + struct fpga_image_info *info, |
| const char *buf, size_t count); |
| int (*write)(struct fpga_manager *mgr, const char *buf, size_t count); |
| - int (*write_complete)(struct fpga_manager *mgr, u32 flags); |
| + int (*write_complete)(struct fpga_manager *mgr, |
| + struct fpga_image_info *info); |
| void (*fpga_remove)(struct fpga_manager *mgr); |
| }; |
| |
| @@ -109,10 +123,11 @@ struct fpga_manager { |
| |
| #define to_fpga_manager(d) container_of(d, struct fpga_manager, dev) |
| |
| -int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, |
| +int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, |
| const char *buf, size_t count); |
| |
| -int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags, |
| +int fpga_mgr_firmware_load(struct fpga_manager *mgr, |
| + struct fpga_image_info *info, |
| const char *image_name); |
| |
| struct fpga_manager *of_fpga_mgr_get(struct device_node *node); |