Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fpga: dfl: afu: add interrupt support for port error reporting

Error reporting interrupt is very useful to notify users that some
errors are detected by the hardware. Once users are notified, they
could query hardware logged error states, no need to continuously
poll on these states.

This patch adds interrupt support for port error reporting sub feature.
It follows the common DFL interrupt notification and handling mechanism,
implements two ioctl commands below for user to query number of irqs
supported, and set/unset interrupt triggers.

Ioctls:
* DFL_FPGA_PORT_ERR_GET_IRQ_NUM
get the number of irqs, which is used to determine whether/how many
interrupts error reporting feature supports.

* DFL_FPGA_PORT_ERR_SET_IRQ
set/unset given eventfds as error interrupt triggers.

Signed-off-by: Luwei Kang <luwei.kang@intel.com>
Signed-off-by: Wu Hao <hao.wu@intel.com>
Signed-off-by: Xu Yilun <yilun.xu@intel.com>
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Acked-by: Wu Hao <hao.wu@intel.com>
Signed-off-by: Moritz Fischer <mdf@kernel.org>

authored by

Xu Yilun and committed by
Moritz Fischer
fe6a3d65 322b598b

+44
+17
drivers/fpga/dfl-afu-error.c
··· 14 14 * Mitchel Henry <henry.mitchel@intel.com> 15 15 */ 16 16 17 + #include <linux/fpga-dfl.h> 17 18 #include <linux/uaccess.h> 18 19 19 20 #include "dfl-afu.h" ··· 220 219 afu_port_err_mask(&pdev->dev, true); 221 220 } 222 221 222 + static long 223 + port_err_ioctl(struct platform_device *pdev, struct dfl_feature *feature, 224 + unsigned int cmd, unsigned long arg) 225 + { 226 + switch (cmd) { 227 + case DFL_FPGA_PORT_ERR_GET_IRQ_NUM: 228 + return dfl_feature_ioctl_get_num_irqs(pdev, feature, arg); 229 + case DFL_FPGA_PORT_ERR_SET_IRQ: 230 + return dfl_feature_ioctl_set_irq(pdev, feature, arg); 231 + default: 232 + dev_dbg(&pdev->dev, "%x cmd not handled", cmd); 233 + return -ENODEV; 234 + } 235 + } 236 + 223 237 const struct dfl_feature_id port_err_id_table[] = { 224 238 {.id = PORT_FEATURE_ID_ERROR,}, 225 239 {0,} ··· 243 227 const struct dfl_feature_ops port_err_ops = { 244 228 .init = port_err_init, 245 229 .uinit = port_err_uinit, 230 + .ioctl = port_err_ioctl, 246 231 };
+4
drivers/fpga/dfl-afu-main.c
··· 577 577 { 578 578 struct platform_device *pdev = filp->private_data; 579 579 struct dfl_feature_platform_data *pdata; 580 + struct dfl_feature *feature; 580 581 581 582 dev_dbg(&pdev->dev, "Device File Release\n"); 582 583 ··· 587 586 dfl_feature_dev_use_end(pdata); 588 587 589 588 if (!dfl_feature_dev_use_count(pdata)) { 589 + dfl_fpga_dev_for_each_feature(pdata, feature) 590 + dfl_fpga_set_irq_triggers(feature, 0, 591 + feature->nr_irqs, NULL); 590 592 __port_reset(pdev); 591 593 afu_dma_region_destroy(pdata); 592 594 }
+23
include/uapi/linux/fpga-dfl.h
··· 164 164 __s32 evtfds[]; 165 165 }; 166 166 167 + /** 168 + * DFL_FPGA_PORT_ERR_GET_IRQ_NUM - _IOR(DFL_FPGA_MAGIC, DFL_PORT_BASE + 5, 169 + * __u32 num_irqs) 170 + * 171 + * Get the number of irqs supported by the fpga port error reporting private 172 + * feature. Currently hardware supports up to 1 irq. 173 + * Return: 0 on success, -errno on failure. 174 + */ 175 + #define DFL_FPGA_PORT_ERR_GET_IRQ_NUM _IOR(DFL_FPGA_MAGIC, \ 176 + DFL_PORT_BASE + 5, __u32) 177 + 178 + /** 179 + * DFL_FPGA_PORT_ERR_SET_IRQ - _IOW(DFL_FPGA_MAGIC, DFL_PORT_BASE + 6, 180 + * struct dfl_fpga_irq_set) 181 + * 182 + * Set fpga port error reporting interrupt trigger if evtfds[n] is valid. 183 + * Unset related interrupt trigger if evtfds[n] is a negative value. 184 + * Return: 0 on success, -errno on failure. 185 + */ 186 + #define DFL_FPGA_PORT_ERR_SET_IRQ _IOW(DFL_FPGA_MAGIC, \ 187 + DFL_PORT_BASE + 6, \ 188 + struct dfl_fpga_irq_set) 189 + 167 190 /* IOCTLs for FME file descriptor */ 168 191 169 192 /**