From patchwork Thu Mar 30 12:08:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wu, Hao" X-Patchwork-Id: 9654077 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2F9DB6034C for ; Thu, 30 Mar 2017 12:19:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1DC042858C for ; Thu, 30 Mar 2017 12:19:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1259028591; Thu, 30 Mar 2017 12:19:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B3532858C for ; Thu, 30 Mar 2017 12:19:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933858AbdC3MSt (ORCPT ); Thu, 30 Mar 2017 08:18:49 -0400 Received: from mga02.intel.com ([134.134.136.20]:27696 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933144AbdC3MPm (ORCPT ); Thu, 30 Mar 2017 08:15:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=intel.com; i=@intel.com; q=dns/txt; s=intel; t=1490876141; x=1522412141; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=yRhHFE9AvaSPPFmCqcUWji+4koHjkorvIxbclMJdlG8=; b=gKXOJlBViL1Nu7BkE8T7u9yObqYMFhXyuefbNJWK7vqkvUfXUtBJgDB2 HUrxhdjY1ZJcaSroRxfN6yikrm8sKw==; Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Mar 2017 05:15:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,246,1486454400"; d="scan'208";a="840018137" Received: from hao-dev.bj.intel.com ([10.238.157.61]) by FMSMGA003.fm.intel.com with ESMTP; 30 Mar 2017 05:15:38 -0700 From: Wu Hao To: atull@kernel.org, moritz.fischer@ettus.com, linux-fpga@vger.kernel.org, linux-kernel@vger.kernel.org Cc: luwei.kang@intel.com, yi.z.zhang@intel.com, hao.wu@intel.com, Xiao Guangrong , Tim Whisonant , Enno Luebbers , Shiva Rao , Christopher Rauer Subject: [PATCH 05/16] fpga: intel: pcie: add chardev support for feature devices Date: Thu, 30 Mar 2017 20:08:05 +0800 Message-Id: <1490875696-15145-6-git-send-email-hao.wu@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1490875696-15145-1-git-send-email-hao.wu@intel.com> References: <1490875696-15145-1-git-send-email-hao.wu@intel.com> Sender: linux-fpga-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fpga@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Xiao Guangrong For feature devices drivers, both the FPGA Management Engine (FME) and Accelerated Function Unit (AFU) driver need to expose user interfaces via the device file, for example, mmap and ioctls. This patch adds chardev support in the pcie driver for feature devices, FME and AFU. It reserves the chardev regions for FME and AFU, and provide interfaces for FME and AFU driver to register their device file operations. Signed-off-by: Tim Whisonant Signed-off-by: Enno Luebbers Signed-off-by: Shiva Rao Signed-off-by: Christopher Rauer Signed-off-by: Zhang Yi Signed-off-by: Xiao Guangrong Signed-off-by: Wu Hao --- drivers/fpga/intel/feature-dev.c | 76 ++++++++++++++++++++++++++++++++++++++++ drivers/fpga/intel/feature-dev.h | 16 +++++++++ drivers/fpga/intel/pcie.c | 18 +++++++++- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/drivers/fpga/intel/feature-dev.c b/drivers/fpga/intel/feature-dev.c index 6952566..ada6548 100644 --- a/drivers/fpga/intel/feature-dev.c +++ b/drivers/fpga/intel/feature-dev.c @@ -59,6 +59,82 @@ int port_feature_num(void) return PORT_FEATURE_ID_MAX; } +struct fpga_chardev_info { + const char *name; + dev_t devt; +}; + +/* indexed by enum fpga_devt_type */ +struct fpga_chardev_info fpga_chrdevs[] = { + {.name = FPGA_FEATURE_DEV_FME}, /* FPGA_DEVT_FME */ + {.name = FPGA_FEATURE_DEV_PORT}, /* FPGA_DEVT_AFU */ +}; + +void fpga_chardev_uinit(void) +{ + int i; + + for (i = 0; i < FPGA_DEVT_MAX; i++) + if (MAJOR(fpga_chrdevs[i].devt)) { + unregister_chrdev_region(fpga_chrdevs[i].devt, + MINORMASK); + fpga_chrdevs[i].devt = MKDEV(0, 0); + } +} + +int fpga_chardev_init(void) +{ + int i, ret; + + for (i = 0; i < FPGA_DEVT_MAX; i++) { + ret = alloc_chrdev_region(&fpga_chrdevs[i].devt, 0, MINORMASK, + fpga_chrdevs[i].name); + if (ret) + goto exit; + } + + return 0; + +exit: + fpga_chardev_uinit(); + return ret; +} + +dev_t fpga_get_devt(enum fpga_devt_type type, int id) +{ + WARN_ON(type >= FPGA_DEVT_MAX); + + return MKDEV(MAJOR(fpga_chrdevs[type].devt), id); +} + +int fpga_register_dev_ops(struct platform_device *pdev, + const struct file_operations *fops, + struct module *owner) +{ + struct feature_platform_data *pdata = dev_get_platdata(&pdev->dev); + + cdev_init(&pdata->cdev, fops); + pdata->cdev.owner = owner; + + /* + * set parent to the feature device so that its refcount is + * decreased after the last refcount of cdev is gone, that + * makes sure the feature device is valid during device + * file's life-cycle. + */ + pdata->cdev.kobj.parent = &pdev->dev.kobj; + return cdev_add(&pdata->cdev, pdev->dev.devt, 1); +} +EXPORT_SYMBOL_GPL(fpga_register_dev_ops); + +void fpga_unregister_dev_ops(struct platform_device *pdev) +{ + struct feature_platform_data *pdata = dev_get_platdata(&pdev->dev); + + cdev_del(&pdata->cdev); +} +EXPORT_SYMBOL_GPL(fpga_unregister_dev_ops); + int fpga_port_id(struct platform_device *pdev) { struct feature_port_header *port_hdr; diff --git a/drivers/fpga/intel/feature-dev.h b/drivers/fpga/intel/feature-dev.h index a1e6e7d..d1723ff 100644 --- a/drivers/fpga/intel/feature-dev.h +++ b/drivers/fpga/intel/feature-dev.h @@ -19,6 +19,7 @@ #define __INTEL_FPGA_FEATURE_H #include +#include #include #include #include @@ -216,6 +217,7 @@ struct feature_platform_data { /* list the feature dev to cci_drvdata->port_dev_list. */ struct list_head node; struct mutex lock; + struct cdev cdev; struct platform_device *dev; unsigned int disable_count; /* count for port disable */ @@ -256,6 +258,20 @@ int feature_platform_data_size(int num); struct feature_platform_data * feature_platform_data_alloc_and_init(struct platform_device *dev, int num); +enum fpga_devt_type { + FPGA_DEVT_FME, + FPGA_DEVT_PORT, + FPGA_DEVT_MAX, +}; + +void fpga_chardev_uinit(void); +int fpga_chardev_init(void); +dev_t fpga_get_devt(enum fpga_devt_type type, int id); +int fpga_register_dev_ops(struct platform_device *pdev, + const struct file_operations *fops, + struct module *owner); +void fpga_unregister_dev_ops(struct platform_device *pdev); + int fpga_port_id(struct platform_device *pdev); static inline int fpga_port_check_id(struct platform_device *pdev, diff --git a/drivers/fpga/intel/pcie.c b/drivers/fpga/intel/pcie.c index 28df63e..e3440ca 100644 --- a/drivers/fpga/intel/pcie.c +++ b/drivers/fpga/intel/pcie.c @@ -276,8 +276,12 @@ build_info_create_dev(struct build_feature_devs_info *binfo, struct platform_device *fdev; struct resource *res; struct feature_platform_data *pdata; + enum fpga_devt_type devt_type = FPGA_DEVT_FME; int ret; + if (type == PORT_ID) + devt_type = FPGA_DEVT_PORT; + /* we will create a new device, commit current device first */ ret = build_info_commit_dev(binfo); if (ret) @@ -296,6 +300,7 @@ build_info_create_dev(struct build_feature_devs_info *binfo, return fdev->id; fdev->dev.parent = &binfo->parent_dev->dev; + fdev->dev.devt = fpga_get_devt(devt_type, fdev->id); /* * we need not care the memory which is associated with the @@ -945,16 +950,27 @@ static int __init ccidrv_init(void) fpga_ids_init(); + ret = fpga_chardev_init(); + if (ret) + goto exit_ids; + ret = pci_register_driver(&cci_pci_driver); if (ret) - fpga_ids_destroy(); + goto exit_chardev; + return 0; + +exit_chardev: + fpga_chardev_uinit(); +exit_ids: + fpga_ids_destroy(); return ret; } static void __exit ccidrv_exit(void) { pci_unregister_driver(&cci_pci_driver); + fpga_chardev_uinit(); fpga_ids_destroy(); }