Received: by 2002:a25:e7d8:0:0:0:0:0 with SMTP id e207csp2186410ybh; Sun, 15 Mar 2020 21:21:23 -0700 (PDT) X-Google-Smtp-Source: ADFU+vsl9fgGl5iR7rISYuJB9IaydNGBcXjOV935wYrGcDrUWIxNafQ7xvakNnjFSRnz+LmGDl9K X-Received: by 2002:a54:4816:: with SMTP id j22mr16167153oij.179.1584332483441; Sun, 15 Mar 2020 21:21:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584332483; cv=none; d=google.com; s=arc-20160816; b=n5dxz7hZL817vMEz+VSNiH8RazIqqP5SdHpwaCcJi/HK8msSSVlyZjtcz/MU/3EBag O9ScoAvJIJ3EK0uIOsOQ6dnnVFeEgmcSQbh+2hIKWUoEdFsZEvFW1YQOc85sAkP6yUxB mwGPWFyehq++bNVhlmVnS2IYikZ4Kiu8N7V9E6LAEn47C4wseAsZxqAwL0eShb3nmKru vQLuN+jR0s0k7meE7Hf7Dh3OxHcqZ8H5UcSPzXJr+Jptx32u7TcblpYLAppOBbxge7Xt mz9dSqFVfU4eFQ1PxtYf/00bED/tb9ChFdN0kBBVZyVma9sYnr3yuspuR1JNutUeISzc +sPA== 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=mRrUa0JSrEm3R2k2bkByM+RsRwwF30ZBhDVMktYFGDA=; b=BE25F33PxyRjVP7LqpcuHUfuO15XMTqi+q/2eDAeZ5tGowh4JIF+o35hriQ6lFQsAU 8DL1BC0jshWrdbkKzeAMKVIIiH0/FuWJ1Sb84ArB3wynuKxldWxu4zOJqEXUtbG+h0/T IRSttu9MK1uy4ZGlphbJJd/HxFk4o1KOJHPe26jcMyPWcqWoOZfZtA+X0o2bXZE6wP32 vTbBod+DpEd/5Juo7m3Jen/Z6WkNwCU/5FyVrZ+RndJR64rQy12TxBecSL7N6fvuKccT CgnwhsaaNPfmoAgrnkMrOYdxvuNy+YsSqIdLiIqMx6E6vaVk9PpYjBjfeCV0DJ99N6/F GP3g== 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 p17si11287882ota.232.2020.03.15.21.21.11; Sun, 15 Mar 2020 21:21:23 -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 S1729743AbgCPETd (ORCPT + 99 others); Mon, 16 Mar 2020 00:19:33 -0400 Received: from mga12.intel.com ([192.55.52.136]:63079 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729682AbgCPETc (ORCPT ); Mon, 16 Mar 2020 00:19:32 -0400 IronPort-SDR: JBqGKjQMx8aXGoHkJMspc5mNz9NZ+KO+z0knNRg66+qRmWkHfh7sloiR6eOY9F5dDZZUJQEwRz M7HM0eYHu6Yg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2020 21:19:31 -0700 IronPort-SDR: zVBwDtWTIxTWJpwz/E/ujHhQzH7TXCFBQsxvhQsbEUmWYHn/WVG9sTKkRRX8zcE+cKHb4R/9gS 0Ze9X1AbodCw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,559,1574150400"; d="scan'208";a="417007264" Received: from yilunxu-optiplex-7050.sh.intel.com ([10.239.159.141]) by orsmga005.jf.intel.com with ESMTP; 15 Mar 2020 21:19:29 -0700 From: Xu Yilun To: mdf@kernel.org, linux-fpga@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Xu Yilun , Luwei Kang , Wu Hao Subject: [PATCH v2 6/7] fpga: dfl: afu: add user interrupt support Date: Mon, 16 Mar 2020 12:17:01 +0800 Message-Id: <1584332222-26652-7-git-send-email-yilun.xu@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1584332222-26652-1-git-send-email-yilun.xu@intel.com> References: <1584332222-26652-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 AFU (Accelerated Function Unit) is dynamic region of the DFL based FPGA, and always defined by users. Some DFL based FPGA cards allow users to implement their own interrupts in AFU. In order to support this, hardware implements a new UINT (User Interrupt) private feature with related capability register which describes the number of supported user interrupts as well as the local index of the interrupts for software enumeration, and from software side, driver 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_PORT_UINT_GET_IRQ_NUM get the number of irqs, which is used to determine how many interrupts UINT feature supports. * DFL_FPGA_PORT_UINT_SET_IRQ set/unset eventfds as AFU user interrupt triggers. Signed-off-by: Luwei Kang Signed-off-by: Wu Hao Signed-off-by: Xu Yilun ---- v2: use DFL_FPGA_PORT_UINT_GET_IRQ_NUM instead of DFL_FPGA_PORT_UINT_GET_INFO Delete flags field for DFL_FPGA_PORT_UINT_SET_IRQ --- drivers/fpga/dfl-afu-main.c | 74 +++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/fpga-dfl.h | 23 ++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c index fc8b9cf..784817c 100644 --- a/drivers/fpga/dfl-afu-main.c +++ b/drivers/fpga/dfl-afu-main.c @@ -529,6 +529,76 @@ static const struct dfl_feature_ops port_stp_ops = { .init = port_stp_init, }; +static long +port_uint_get_num_irqs(struct platform_device *pdev, + struct dfl_feature *feature, unsigned long arg) +{ + if (copy_to_user((void __user *)arg, &feature->nr_irqs, + sizeof(feature->nr_irqs))) + return -EFAULT; + + return 0; +} + +static long port_uint_set_irq(struct platform_device *pdev, + struct dfl_feature *feature, unsigned long arg) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct dfl_fpga_irq_set hdr; + s32 *fds; + long ret; + + if (!feature->nr_irqs) + return -ENOENT; + + if (copy_from_user(&hdr, (void __user *)arg, sizeof(hdr))) + return -EFAULT; + + if (!hdr.count || (hdr.start + hdr.count > feature->nr_irqs) || + (hdr.start + hdr.count < hdr.start)) + return -EINVAL; + + fds = memdup_user((void __user *)(arg + sizeof(hdr)), + hdr.count * sizeof(s32)); + if (IS_ERR(fds)) + return PTR_ERR(fds); + + mutex_lock(&pdata->lock); + ret = dfl_fpga_set_irq_triggers(feature, hdr.start, hdr.count, fds); + mutex_unlock(&pdata->lock); + + kfree(fds); + return ret; +} + +static long +port_uint_ioctl(struct platform_device *pdev, struct dfl_feature *feature, + unsigned int cmd, unsigned long arg) +{ + long ret = -ENODEV; + + switch (cmd) { + case DFL_FPGA_PORT_UINT_GET_IRQ_NUM: + ret = port_uint_get_num_irqs(pdev, feature, arg); + break; + case DFL_FPGA_PORT_UINT_SET_IRQ: + ret = port_uint_set_irq(pdev, feature, arg); + break; + default: + dev_dbg(&pdev->dev, "%x cmd not handled", cmd); + } + return ret; +} + +static const struct dfl_feature_id port_uint_id_table[] = { + {.id = PORT_FEATURE_ID_UINT,}, + {0,} +}; + +static const struct dfl_feature_ops port_uint_ops = { + .ioctl = port_uint_ioctl, +}; + static struct dfl_feature_driver port_feature_drvs[] = { { .id_table = port_hdr_id_table, @@ -547,6 +617,10 @@ static struct dfl_feature_driver port_feature_drvs[] = { .ops = &port_stp_ops, }, { + .id_table = port_uint_id_table, + .ops = &port_uint_ops, + }, + { .ops = NULL, } }; diff --git a/include/uapi/linux/fpga-dfl.h b/include/uapi/linux/fpga-dfl.h index dc8d370..ca2dc6c 100644 --- a/include/uapi/linux/fpga-dfl.h +++ b/include/uapi/linux/fpga-dfl.h @@ -180,6 +180,29 @@ struct dfl_fpga_irq_set { DFL_PORT_BASE + 6, \ struct dfl_fpga_irq_set) +/** + * DFL_FPGA_PORT_UINT_GET_IRQ_NUM - _IOR(DFL_FPGA_MAGIC, DFL_PORT_BASE + 7, + * __u32 num_irqs) + * + * Get the number of irqs supported by the fpga AFU user interrupt private + * feature. + * Return: 0 on success, -errno on failure. + */ +#define DFL_FPGA_PORT_UINT_GET_IRQ_NUM _IOR(DFL_FPGA_MAGIC, \ + DFL_PORT_BASE + 7, __u32) + +/** + * DFL_FPGA_PORT_UINT_SET_IRQ - _IOW(DFL_FPGA_MAGIC, DFL_PORT_BASE + 8, + * struct dfl_fpga_irq_set) + * + * Set fpga afu user interrupt trigger if evtfds[n] is valid. + * Unset related interrupt trigger if evtfds[n] is a NULL or negative value. + * Return: 0 on success, -errno on failure. + */ +#define DFL_FPGA_PORT_UINT_SET_IRQ _IOW(DFL_FPGA_MAGIC, \ + DFL_PORT_BASE + 8, \ + struct dfl_fpga_irq_set) + /* IOCTLs for FME file descriptor */ /** -- 2.7.4