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

fpga: dfl: fme: add interrupt support for global 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 fme global error reporting sub
feature. It follows the common DFL interrupt notification and handling
mechanism. And it implements two ioctls below for user to query
number of irqs supported, and set/unset interrupt triggers.

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

* DFL_FPGA_FME_ERR_SET_IRQ
set/unset given eventfds as fme error reporting 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
d43f20ba fe6a3d65

+47
+18
drivers/fpga/dfl-fme-error.c
··· 15 15 * Mitchel, Henry <henry.mitchel@intel.com> 16 16 */ 17 17 18 + #include <linux/fpga-dfl.h> 18 19 #include <linux/uaccess.h> 19 20 20 21 #include "dfl.h" ··· 349 348 fme_err_mask(&pdev->dev, true); 350 349 } 351 350 351 + static long 352 + fme_global_error_ioctl(struct platform_device *pdev, 353 + struct dfl_feature *feature, 354 + unsigned int cmd, unsigned long arg) 355 + { 356 + switch (cmd) { 357 + case DFL_FPGA_FME_ERR_GET_IRQ_NUM: 358 + return dfl_feature_ioctl_get_num_irqs(pdev, feature, arg); 359 + case DFL_FPGA_FME_ERR_SET_IRQ: 360 + return dfl_feature_ioctl_set_irq(pdev, feature, arg); 361 + default: 362 + dev_dbg(&pdev->dev, "%x cmd not handled", cmd); 363 + return -ENODEV; 364 + } 365 + } 366 + 352 367 const struct dfl_feature_id fme_global_err_id_table[] = { 353 368 {.id = FME_FEATURE_ID_GLOBAL_ERR,}, 354 369 {0,} ··· 373 356 const struct dfl_feature_ops fme_global_err_ops = { 374 357 .init = fme_global_err_init, 375 358 .uinit = fme_global_err_uinit, 359 + .ioctl = fme_global_error_ioctl, 376 360 };
+6
drivers/fpga/dfl-fme-main.c
··· 620 620 { 621 621 struct dfl_feature_platform_data *pdata = filp->private_data; 622 622 struct platform_device *pdev = pdata->dev; 623 + struct dfl_feature *feature; 623 624 624 625 dev_dbg(&pdev->dev, "Device File Release\n"); 625 626 626 627 mutex_lock(&pdata->lock); 627 628 dfl_feature_dev_use_end(pdata); 629 + 630 + if (!dfl_feature_dev_use_count(pdata)) 631 + dfl_fpga_dev_for_each_feature(pdata, feature) 632 + dfl_fpga_set_irq_triggers(feature, 0, 633 + feature->nr_irqs, NULL); 628 634 mutex_unlock(&pdata->lock); 629 635 630 636 return 0;
+23
include/uapi/linux/fpga-dfl.h
··· 230 230 */ 231 231 #define DFL_FPGA_FME_PORT_ASSIGN _IOW(DFL_FPGA_MAGIC, DFL_FME_BASE + 2, int) 232 232 233 + /** 234 + * DFL_FPGA_FME_ERR_GET_IRQ_NUM - _IOR(DFL_FPGA_MAGIC, DFL_FME_BASE + 3, 235 + * __u32 num_irqs) 236 + * 237 + * Get the number of irqs supported by the fpga fme error reporting private 238 + * feature. Currently hardware supports up to 1 irq. 239 + * Return: 0 on success, -errno on failure. 240 + */ 241 + #define DFL_FPGA_FME_ERR_GET_IRQ_NUM _IOR(DFL_FPGA_MAGIC, \ 242 + DFL_FME_BASE + 3, __u32) 243 + 244 + /** 245 + * DFL_FPGA_FME_ERR_SET_IRQ - _IOW(DFL_FPGA_MAGIC, DFL_FME_BASE + 4, 246 + * struct dfl_fpga_irq_set) 247 + * 248 + * Set fpga fme error reporting interrupt trigger if evtfds[n] is valid. 249 + * Unset related interrupt trigger if evtfds[n] is a negative value. 250 + * Return: 0 on success, -errno on failure. 251 + */ 252 + #define DFL_FPGA_FME_ERR_SET_IRQ _IOW(DFL_FPGA_MAGIC, \ 253 + DFL_FME_BASE + 4, \ 254 + struct dfl_fpga_irq_set) 255 + 233 256 #endif /* _UAPI_LINUX_FPGA_DFL_H */