Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp4599149ybb; Tue, 24 Mar 2020 01:36:11 -0700 (PDT) X-Google-Smtp-Source: ADFU+vu7XYQPkot9MJ8xZq618uViFWQ/PYQWgrQ47sCOeZI5AjVgoyH0k3cYp2TRN9u+qUs+MsCa X-Received: by 2002:a05:6830:1d95:: with SMTP id y21mr4666977oti.180.1585038971133; Tue, 24 Mar 2020 01:36:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1585038971; cv=none; d=google.com; s=arc-20160816; b=lqizy3EZvIoYbgYsYKhWspenZFHQONnfv7ofo0AkVTvQb9ASE7MqOGrGtITThDa1m7 LmLTAEysuBXgWhzSAODRrQBAmjEhwE05pFjEAgoYasO9ZfoCS/oFZdNlO/Jw2YNVE6Li hK/q4BHeRXuhl1ZpDZUBPQujNcEqXoqWU1Ke9dyJxMO0uc0pcktAtHOZ1Ifft0MKAyN9 f7eU+hpUHDhnfTlqwaGsjsCMAk1HX1fCLAIziljzS4vzn3txZUr3sp2zrqcAyEYf5uGY gUZ6M60c3kQeXC5apNVQkvSrai2XgW+juZfk/WsGcB9TCO5jPBgsAzTDnXxxvC8yY08o dVwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:ironport-sdr:ironport-sdr; bh=k75DYMtgdpN+lZ2DLEUfmTxdksm0tBkz5dhWgJXbUR4=; b=ilBnYaLDBwnHC/r+DFZq9jJoaNuDjpmyzwruP/2YPda+DjRNTrRWizCY0HocLiz4XJ emrvzo20oAOBbB3Ubz1sht645XyxgwYQ9Fpv0KneCOsqVDL2ytFAUaKTN7aaosded0DM jFfFvcK5I6MPwU1jKcZT52SY43oRNQ5pa3cucsVcFpMMyV6RGXKtg0umDO2frltpo7fC ANDlFfMYr8Dv+pe20VtFFgZ9nKeueABq8rhFp6rX1xCS8PMM3YKwZ5yvW43KyZggLqfR mGdK8zFRHbdiGtUkjO8T78hZGKhcAYrh7qRbGROhqOTjoYnfazWTWYu7E9XBRpHCx1xb b2WQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v20si2794738ote.176.2020.03.24.01.35.58; Tue, 24 Mar 2020 01:36:11 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727177AbgCXIfb (ORCPT + 99 others); Tue, 24 Mar 2020 04:35:31 -0400 Received: from mga03.intel.com ([134.134.136.65]:53578 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727112AbgCXIfa (ORCPT ); Tue, 24 Mar 2020 04:35:30 -0400 IronPort-SDR: 9wcwVH8+Qgpg9xWxgoguHyGJn72VPVzuSXleMFUb+5AbDVRHW1/hD8890YGvdR1nunbqUi6U6b itWSCsbvIKXw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Mar 2020 01:35:30 -0700 IronPort-SDR: xSspR1e5YNK0eL/2Tmn0BSmm3suTMpwaevfBXioQGyN9oaYNmu2dovT2wxbqy6hV1VOEM/xUoR FpZRJhKKKIhg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,299,1580803200"; d="scan'208";a="446143794" Received: from yilunxu-optiplex-7050.sh.intel.com ([10.239.159.141]) by fmsmga005.fm.intel.com with ESMTP; 24 Mar 2020 01:35:28 -0700 From: Xu Yilun To: mdf@kernel.org, linux-fpga@vger.kernel.org, linux-kernel@vger.kernel.org Cc: trix@redhat.com, bhu@redhat.com, Xu Yilun , Luwei Kang , Wu Hao Subject: [PATCH v3 3/7] fpga: dfl: introduce interrupt trigger setting API Date: Tue, 24 Mar 2020 16:32:39 +0800 Message-Id: <1585038763-22944-4-git-send-email-yilun.xu@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1585038763-22944-1-git-send-email-yilun.xu@intel.com> References: <1585038763-22944-1-git-send-email-yilun.xu@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org FPGA user applications may be interested in interrupts generated by DFL features. For example, users can implement their own FPGA logics with interrupts enabled in AFU (Accelerated Function Unit, dynamic region of DFL based FPGA). So user applications need to be notified to handle these interrupts. In order to allow userspace applications to monitor interrupts, driver requires userspace to provide eventfds as interrupt notification channels. Applications then poll/select on the eventfds to get notified. This patch introduces a generic helper function for sub features to do eventfds binding with given interrupts. Signed-off-by: Luwei Kang Signed-off-by: Wu Hao Signed-off-by: Xu Yilun ---- v2: use unsigned int instead of int for irq array indexes in dfl_fpga_set_irq_triggers() Improves comments for NULL fds param in dfl_fpga_set_irq_triggers() v3: Improve comments of dfl_fpga_set_irq_triggers() refines code for dfl_fpga_set_irq_triggers, delete local variable j --- drivers/fpga/dfl.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/fpga/dfl.h | 11 +++++++ 2 files changed, 108 insertions(+) diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index bc8d966..80805e5 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -535,6 +535,7 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo) unsigned int i; /* save resource information for each feature */ + feature->dev = fdev; feature->id = finfo->fid; feature->resource_index = index; feature->ioaddr = finfo->ioaddr; @@ -1389,6 +1390,102 @@ int dfl_fpga_cdev_config_ports_vf(struct dfl_fpga_cdev *cdev, int num_vfs) } EXPORT_SYMBOL_GPL(dfl_fpga_cdev_config_ports_vf); +static irqreturn_t dfl_irq_handler(int irq, void *arg) +{ + struct eventfd_ctx *trigger = arg; + + eventfd_signal(trigger, 1); + return IRQ_HANDLED; +} + +static int do_set_irq_trigger(struct dfl_feature *feature, unsigned int idx, + int fd) +{ + struct platform_device *pdev = feature->dev; + struct eventfd_ctx *trigger; + int irq, ret; + + if (idx >= feature->nr_irqs) + return -EINVAL; + + irq = feature->irq_ctx[idx].irq; + + if (feature->irq_ctx[idx].trigger) { + free_irq(irq, feature->irq_ctx[idx].trigger); + kfree(feature->irq_ctx[idx].name); + eventfd_ctx_put(feature->irq_ctx[idx].trigger); + feature->irq_ctx[idx].trigger = NULL; + } + + if (fd < 0) + return 0; + + feature->irq_ctx[idx].name = + kasprintf(GFP_KERNEL, "fpga-irq[%u](%s-%llx)", idx, + dev_name(&pdev->dev), + (unsigned long long)feature->id); + if (!feature->irq_ctx[idx].name) + return -ENOMEM; + + trigger = eventfd_ctx_fdget(fd); + if (IS_ERR(trigger)) { + ret = PTR_ERR(trigger); + goto free_name; + } + + ret = request_irq(irq, dfl_irq_handler, 0, + feature->irq_ctx[idx].name, trigger); + if (!ret) { + feature->irq_ctx[idx].trigger = trigger; + return ret; + } + + eventfd_ctx_put(trigger); +free_name: + kfree(feature->irq_ctx[idx].name); + + return ret; +} + +/** + * dfl_fpga_set_irq_triggers - set eventfd triggers for dfl feature interrupts + * + * @feature: dfl sub feature. + * @start: start of irq index in this dfl sub feature. + * @count: number of irqs. + * @fds: eventfds to bind with irqs. unbind related irq if fds[n] is negative. + * unbind "count" specified number of irqs if fds ptr is NULL. + * + * Bind given eventfds with irqs in this dfl sub feature. Unbind related irq if + * fds[n] is negative. Unbind "count" specified number of irqs if fds ptr is + * NULL. + * + * Return: 0 on success, negative error code otherwise. + */ +int dfl_fpga_set_irq_triggers(struct dfl_feature *feature, unsigned int start, + unsigned int count, int32_t *fds) +{ + unsigned int i; + int ret = 0; + + if (start + count < start || start + count > feature->nr_irqs) + return -EINVAL; + + for (i = 0; i < count; i++) { + int fd = fds ? fds[i] : -1; + + ret = do_set_irq_trigger(feature, start + i, fd); + if (ret) { + while (i--) + do_set_irq_trigger(feature, start + i, -1); + break; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(dfl_fpga_set_irq_triggers); + static void __exit dfl_fpga_exit(void) { dfl_chardev_uinit(); diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h index 4bc165f..63eacef 100644 --- a/drivers/fpga/dfl.h +++ b/drivers/fpga/dfl.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include /* maximum supported number of ports */ #define MAX_DFL_FPGA_PORT_NUM 4 @@ -213,14 +215,19 @@ struct dfl_feature_driver { * struct dfl_feature_irq_ctx - dfl private feature interrupt context * * @irq: Linux IRQ number of this interrupt. + * @trigger: eventfd context to signal when interrupt happens. + * @name: irq name needed when requesting irq. */ struct dfl_feature_irq_ctx { int irq; + struct eventfd_ctx *trigger; + char *name; }; /** * struct dfl_feature - sub feature of the feature devices * + * @dev: ptr to pdev of the feature device which has the sub feature. * @id: sub feature id. * @resource_index: each sub feature has one mmio resource for its registers. * this index is used to find its mmio resource from the @@ -231,6 +238,7 @@ struct dfl_feature_irq_ctx { * @ops: ops of this sub feature. */ struct dfl_feature { + struct platform_device *dev; u64 id; int resource_index; void __iomem *ioaddr; @@ -506,4 +514,7 @@ int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id); int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id); void dfl_fpga_cdev_config_ports_pf(struct dfl_fpga_cdev *cdev); int dfl_fpga_cdev_config_ports_vf(struct dfl_fpga_cdev *cdev, int num_vf); + +int dfl_fpga_set_irq_triggers(struct dfl_feature *feature, unsigned int start, + unsigned int count, int32_t *fds); #endif /* __FPGA_DFL_H */ -- 2.7.4