diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-12-01 21:05:53 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-12-01 21:05:53 +0100 |
commit | e073462966b26977b26937c5fc93b4fb24f04fef (patch) | |
tree | 49221ed9ebf8e42ad5d80897e91286250f215e4a | |
parent | 31114fa95bdb815f52f0cb0fad1260bd91007563 (diff) | |
parent | e499807737b75387bcc9d146927dc36a0b7e4cff (diff) |
Merge tag 'fpga-for-greg-20161129' of git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga into char-misc-next
Alan writes:
fpga: Updates for 4.10
These are:
* Add git url to MAINTAINERS
* Allow write_init to specify how much buffer it needs
* Fixes for ISR state in zynq fpga manager driver
* Other small fixes for zynq
* Add Altera SoCFPGA drivers for COMPILE_TEST
-rw-r--r-- | Documentation/fpga/fpga-mgr.txt | 5 | ||||
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/fpga/Kconfig | 5 | ||||
-rw-r--r-- | drivers/fpga/fpga-mgr.c | 6 | ||||
-rw-r--r-- | drivers/fpga/socfpga-a10.c | 1 | ||||
-rw-r--r-- | drivers/fpga/zynq-fpga.c | 46 | ||||
-rw-r--r-- | include/linux/fpga/fpga-mgr.h | 2 |
7 files changed, 38 insertions, 28 deletions
diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt index 087924f2b20c..86ee5078fd03 100644 --- a/Documentation/fpga/fpga-mgr.txt +++ b/Documentation/fpga/fpga-mgr.txt @@ -169,7 +169,10 @@ The programming sequence is: 2. .write (may be called once or multiple times) 3. .write_complete -The .write_init function will prepare the FPGA to receive the image data. +The .write_init function will prepare the FPGA to receive the image data. The +buffer passed into .write_init will be atmost .initial_header_size bytes long, +if the whole bitstream is not immediately available then the core code will +buffer up at least this much before starting. The .write function writes a buffer to the FPGA. The buffer may be contain the whole FPGA image or may be a smaller chunk of an FPGA image. In the latter diff --git a/MAINTAINERS b/MAINTAINERS index 2f89c3be2a39..b0fee8c45135 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4958,6 +4958,7 @@ M: Alan Tull <atull@opensource.altera.com> R: Moritz Fischer <moritz.fischer@ettus.com> L: linux-fpga@vger.kernel.org S: Maintained +T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git F: drivers/fpga/ F: include/linux/fpga/fpga-mgr.h W: http://www.rocketboards.org diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 889e4c398304..ce861a2853a4 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -22,13 +22,14 @@ config FPGA_REGION config FPGA_MGR_SOCFPGA tristate "Altera SOCFPGA FPGA Manager" - depends on ARCH_SOCFPGA + depends on ARCH_SOCFPGA || COMPILE_TEST help FPGA manager driver support for Altera SOCFPGA. config FPGA_MGR_SOCFPGA_A10 tristate "Altera SoCFPGA Arria10" - depends on ARCH_SOCFPGA + depends on ARCH_SOCFPGA || COMPILE_TEST + select REGMAP_MMIO help FPGA manager driver support for Altera Arria10 SoCFPGA. diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 79ce2eea44db..f0a69d3e60a5 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c @@ -53,10 +53,12 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, /* * Call the low level driver's write_init function. This will do the * device-specific things to get the FPGA into the state where it is - * ready to receive an FPGA image. + * ready to receive an FPGA image. The low level driver only gets to + * see the first initial_header_size bytes in the buffer. */ mgr->state = FPGA_MGR_STATE_WRITE_INIT; - ret = mgr->mops->write_init(mgr, info, buf, count); + ret = mgr->mops->write_init(mgr, info, buf, + min(mgr->mops->initial_header_size, count)); if (ret) { dev_err(dev, "Error preparing FPGA for writing\n"); mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c index ccd9fb23bd52..f8770af0f6b5 100644 --- a/drivers/fpga/socfpga-a10.c +++ b/drivers/fpga/socfpga-a10.c @@ -470,6 +470,7 @@ static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr) } static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = { + .initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4, .state = socfpga_a10_fpga_state, .write_init = socfpga_a10_fpga_write_init, .write = socfpga_a10_fpga_write, diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c index 249682e92502..1812bf7614e1 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c @@ -118,7 +118,6 @@ #define FPGA_RST_NONE_MASK 0x0 struct zynq_fpga_priv { - struct device *dev; int irq; struct clk *clk; @@ -218,7 +217,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, INIT_POLL_DELAY, INIT_POLL_TIMEOUT); if (err) { - dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); + dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n"); goto out_err; } @@ -232,7 +231,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, INIT_POLL_DELAY, INIT_POLL_TIMEOUT); if (err) { - dev_err(priv->dev, "Timeout waiting for !PCFG_INIT"); + dev_err(&mgr->dev, "Timeout waiting for !PCFG_INIT\n"); goto out_err; } @@ -246,7 +245,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, INIT_POLL_DELAY, INIT_POLL_TIMEOUT); if (err) { - dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); + dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n"); goto out_err; } } @@ -263,7 +262,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, /* check that we have room in the command queue */ status = zynq_fpga_read(priv, STATUS_OFFSET); if (status & STATUS_DMA_Q_F) { - dev_err(priv->dev, "DMA command queue full"); + dev_err(&mgr->dev, "DMA command queue full\n"); err = -EBUSY; goto out_err; } @@ -296,7 +295,8 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, in_count = count; priv = mgr->priv; - kbuf = dma_alloc_coherent(priv->dev, count, &dma_addr, GFP_KERNEL); + kbuf = + dma_alloc_coherent(mgr->dev.parent, count, &dma_addr, GFP_KERNEL); if (!kbuf) return -ENOMEM; @@ -332,15 +332,14 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, zynq_fpga_write(priv, INT_STS_OFFSET, intr_status); if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) { - dev_err(priv->dev, "Error configuring FPGA"); + dev_err(&mgr->dev, "Error configuring FPGA\n"); err = -EFAULT; } clk_disable(priv->clk); out_free: - dma_free_coherent(priv->dev, in_count, kbuf, dma_addr); - + dma_free_coherent(mgr->dev.parent, count, kbuf, dma_addr); return err; } @@ -418,8 +417,6 @@ static int zynq_fpga_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->io_base = devm_ioremap_resource(dev, res); if (IS_ERR(priv->io_base)) @@ -428,7 +425,7 @@ static int zynq_fpga_probe(struct platform_device *pdev) priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); if (IS_ERR(priv->slcr)) { - dev_err(dev, "unable to get zynq-slcr regmap"); + dev_err(dev, "unable to get zynq-slcr regmap\n"); return PTR_ERR(priv->slcr); } @@ -436,38 +433,41 @@ static int zynq_fpga_probe(struct platform_device *pdev) priv->irq = platform_get_irq(pdev, 0); if (priv->irq < 0) { - dev_err(dev, "No IRQ available"); + dev_err(dev, "No IRQ available\n"); return priv->irq; } - err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, - dev_name(dev), priv); - if (err) { - dev_err(dev, "unable to request IRQ"); - return err; - } - priv->clk = devm_clk_get(dev, "ref_clk"); if (IS_ERR(priv->clk)) { - dev_err(dev, "input clock not found"); + dev_err(dev, "input clock not found\n"); return PTR_ERR(priv->clk); } err = clk_prepare_enable(priv->clk); if (err) { - dev_err(dev, "unable to enable clock"); + dev_err(dev, "unable to enable clock\n"); return err; } /* unlock the device */ zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK); + zynq_fpga_write(priv, INT_MASK_OFFSET, 0xFFFFFFFF); + zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK); + err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev), + priv); + if (err) { + dev_err(dev, "unable to request IRQ\n"); + clk_disable_unprepare(priv->clk); + return err; + } + clk_disable(priv->clk); err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager", &zynq_fpga_ops, priv); if (err) { - dev_err(dev, "unable to register FPGA manager"); + dev_err(dev, "unable to register FPGA manager\n"); clk_unprepare(priv->clk); return err; } diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h index 96a1a3311649..16551d5eac36 100644 --- a/include/linux/fpga/fpga-mgr.h +++ b/include/linux/fpga/fpga-mgr.h @@ -84,6 +84,7 @@ struct fpga_image_info { /** * struct fpga_manager_ops - ops for low level fpga manager drivers + * @initial_header_size: Maximum number of bytes that should be passed into write_init * @state: returns an enum value of the FPGA's state * @write_init: prepare the FPGA to receive confuration data * @write: write count bytes of configuration data to the FPGA @@ -95,6 +96,7 @@ struct fpga_image_info { * called, so leaving them out is fine. */ struct fpga_manager_ops { + size_t initial_header_size; enum fpga_mgr_states (*state)(struct fpga_manager *mgr); int (*write_init)(struct fpga_manager *mgr, struct fpga_image_info *info, |