diff options
Diffstat (limited to 'drivers/fpga/zynq-fpga.c')
-rw-r--r-- | drivers/fpga/zynq-fpga.c | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c index 1812bf7614e1..f674e32832ec 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c | |||
@@ -89,7 +89,7 @@ | |||
89 | #define IXR_D_P_DONE_MASK BIT(12) | 89 | #define IXR_D_P_DONE_MASK BIT(12) |
90 | /* FPGA programmed */ | 90 | /* FPGA programmed */ |
91 | #define IXR_PCFG_DONE_MASK BIT(2) | 91 | #define IXR_PCFG_DONE_MASK BIT(2) |
92 | #define IXR_ERROR_FLAGS_MASK 0x00F0F860 | 92 | #define IXR_ERROR_FLAGS_MASK 0x00F0C860 |
93 | #define IXR_ALL_MASK 0xF8F7F87F | 93 | #define IXR_ALL_MASK 0xF8F7F87F |
94 | 94 | ||
95 | /* Miscellaneous constant values */ | 95 | /* Miscellaneous constant values */ |
@@ -143,23 +143,10 @@ static inline u32 zynq_fpga_read(const struct zynq_fpga_priv *priv, | |||
143 | readl_poll_timeout(priv->io_base + addr, val, cond, sleep_us, \ | 143 | readl_poll_timeout(priv->io_base + addr, val, cond, sleep_us, \ |
144 | timeout_us) | 144 | timeout_us) |
145 | 145 | ||
146 | static void zynq_fpga_mask_irqs(struct zynq_fpga_priv *priv) | 146 | /* Cause the specified irq mask bits to generate IRQs */ |
147 | static inline void zynq_fpga_set_irq(struct zynq_fpga_priv *priv, u32 enable) | ||
147 | { | 148 | { |
148 | u32 intr_mask; | 149 | zynq_fpga_write(priv, INT_MASK_OFFSET, ~enable); |
149 | |||
150 | intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET); | ||
151 | zynq_fpga_write(priv, INT_MASK_OFFSET, | ||
152 | intr_mask | IXR_DMA_DONE_MASK | IXR_ERROR_FLAGS_MASK); | ||
153 | } | ||
154 | |||
155 | static void zynq_fpga_unmask_irqs(struct zynq_fpga_priv *priv) | ||
156 | { | ||
157 | u32 intr_mask; | ||
158 | |||
159 | intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET); | ||
160 | zynq_fpga_write(priv, INT_MASK_OFFSET, | ||
161 | intr_mask | ||
162 | & ~(IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK)); | ||
163 | } | 150 | } |
164 | 151 | ||
165 | static irqreturn_t zynq_fpga_isr(int irq, void *data) | 152 | static irqreturn_t zynq_fpga_isr(int irq, void *data) |
@@ -167,7 +154,7 @@ static irqreturn_t zynq_fpga_isr(int irq, void *data) | |||
167 | struct zynq_fpga_priv *priv = data; | 154 | struct zynq_fpga_priv *priv = data; |
168 | 155 | ||
169 | /* disable DMA and error IRQs */ | 156 | /* disable DMA and error IRQs */ |
170 | zynq_fpga_mask_irqs(priv); | 157 | zynq_fpga_set_irq(priv, 0); |
171 | 158 | ||
172 | complete(&priv->dma_done); | 159 | complete(&priv->dma_done); |
173 | 160 | ||
@@ -285,6 +272,7 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, | |||
285 | const char *buf, size_t count) | 272 | const char *buf, size_t count) |
286 | { | 273 | { |
287 | struct zynq_fpga_priv *priv; | 274 | struct zynq_fpga_priv *priv; |
275 | const char *why; | ||
288 | int err; | 276 | int err; |
289 | char *kbuf; | 277 | char *kbuf; |
290 | size_t in_count; | 278 | size_t in_count; |
@@ -312,7 +300,7 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, | |||
312 | reinit_completion(&priv->dma_done); | 300 | reinit_completion(&priv->dma_done); |
313 | 301 | ||
314 | /* enable DMA and error IRQs */ | 302 | /* enable DMA and error IRQs */ |
315 | zynq_fpga_unmask_irqs(priv); | 303 | zynq_fpga_set_irq(priv, IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK); |
316 | 304 | ||
317 | /* the +1 in the src addr is used to hold off on DMA_DONE IRQ | 305 | /* the +1 in the src addr is used to hold off on DMA_DONE IRQ |
318 | * until both AXI and PCAP are done ... | 306 | * until both AXI and PCAP are done ... |
@@ -331,11 +319,33 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, | |||
331 | intr_status = zynq_fpga_read(priv, INT_STS_OFFSET); | 319 | intr_status = zynq_fpga_read(priv, INT_STS_OFFSET); |
332 | zynq_fpga_write(priv, INT_STS_OFFSET, intr_status); | 320 | zynq_fpga_write(priv, INT_STS_OFFSET, intr_status); |
333 | 321 | ||
322 | if (intr_status & IXR_ERROR_FLAGS_MASK) { | ||
323 | why = "DMA reported error"; | ||
324 | err = -EIO; | ||
325 | goto out_report; | ||
326 | } | ||
327 | |||
334 | if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) { | 328 | if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) { |
335 | dev_err(&mgr->dev, "Error configuring FPGA\n"); | 329 | why = "DMA did not complete"; |
336 | err = -EFAULT; | 330 | err = -EIO; |
331 | goto out_report; | ||
337 | } | 332 | } |
338 | 333 | ||
334 | err = 0; | ||
335 | goto out_clk; | ||
336 | |||
337 | out_report: | ||
338 | dev_err(&mgr->dev, | ||
339 | "%s: INT_STS:0x%x CTRL:0x%x LOCK:0x%x INT_MASK:0x%x STATUS:0x%x MCTRL:0x%x\n", | ||
340 | why, | ||
341 | intr_status, | ||
342 | zynq_fpga_read(priv, CTRL_OFFSET), | ||
343 | zynq_fpga_read(priv, LOCK_OFFSET), | ||
344 | zynq_fpga_read(priv, INT_MASK_OFFSET), | ||
345 | zynq_fpga_read(priv, STATUS_OFFSET), | ||
346 | zynq_fpga_read(priv, MCTRL_OFFSET)); | ||
347 | |||
348 | out_clk: | ||
339 | clk_disable(priv->clk); | 349 | clk_disable(priv->clk); |
340 | 350 | ||
341 | out_free: | 351 | out_free: |
@@ -452,7 +462,7 @@ static int zynq_fpga_probe(struct platform_device *pdev) | |||
452 | /* unlock the device */ | 462 | /* unlock the device */ |
453 | zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK); | 463 | zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK); |
454 | 464 | ||
455 | zynq_fpga_write(priv, INT_MASK_OFFSET, 0xFFFFFFFF); | 465 | zynq_fpga_set_irq(priv, 0); |
456 | zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK); | 466 | zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK); |
457 | err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev), | 467 | err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev), |
458 | priv); | 468 | priv); |