From patchwork Wed May 16 23:49:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Tull X-Patchwork-Id: 10405121 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 AA191601F9 for ; Wed, 16 May 2018 23:53:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9629524BFE for ; Wed, 16 May 2018 23:53:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 89840287E0; Wed, 16 May 2018 23:53:01 +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=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, 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 09BD32874F for ; Wed, 16 May 2018 23:53:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751671AbeEPXuV (ORCPT ); Wed, 16 May 2018 19:50:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:57840 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751596AbeEPXuS (ORCPT ); Wed, 16 May 2018 19:50:18 -0400 Received: from localhost.localdomain (user-0ccsrjt.cable.mindspring.com [24.206.110.125]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 7BBD120847; Wed, 16 May 2018 23:50:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1526514618; bh=SlVUBkwt//Xt/jnavbfmSB/Q1MrrauoLLuJ2KUpxM3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cGR/1QKI6rokdj/CQubXUqW0urM8zO56JsXCHdRnpc76DcOkye6R2HLuPD8LWlVzr sWwz3hVrN431B39Q20leVnI81wLkLY12Q2rE8+6r+B31rAp+2P8dZT5KOPs6dGUQgD CaamQ2IfYMpqw55h34WfRU8BE3xXQGtG1SLNxSJs= From: Alan Tull To: Greg Kroah-Hartman , Jonathan Corbet , Moritz Fischer Cc: linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org, Alan Tull Subject: [PATCH 04/14] fpga: region: change api, add fpga_region_create/free Date: Wed, 16 May 2018 18:49:57 -0500 Message-Id: <20180516235007.3951-5-atull@kernel.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180516235007.3951-1-atull@kernel.org> References: <20180516235007.3951-1-atull@kernel.org> 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 Add fpga_region_create/free API functions. Change fpga_region_register to take FPGA region struct as the only parameter. Change fpga_region_unregister to return void. struct fpga_region *fpga_region_create(struct device *dev, struct fpga_manager *mgr, int (*get_bridges)(struct fpga_region *)); void fpga_region_free(struct fpga_region *region); int fpga_region_register(struct fpga_region *region); void fpga_region_unregister(struct fpga_region *region); Remove groups storage from struct fpga_region, it's not needed. Callers can just "region->dev.groups = groups;" after calling fpga_region_create. Update the drivers that call fpga_region_register with the new API. Signed-off-by: Alan Tull Signed-off-by: Moritz Fischer --- Documentation/fpga/fpga-region.txt | 3 +- drivers/fpga/fpga-region.c | 68 ++++++++++++++++++++++++++++++-------- drivers/fpga/of-fpga-region.c | 13 +++----- include/linux/fpga/fpga-region.h | 11 +++--- 4 files changed, 68 insertions(+), 27 deletions(-) diff --git a/Documentation/fpga/fpga-region.txt b/Documentation/fpga/fpga-region.txt index 139a02b..d38fa3b 100644 --- a/Documentation/fpga/fpga-region.txt +++ b/Documentation/fpga/fpga-region.txt @@ -42,8 +42,7 @@ The FPGA region API To register or unregister a region: ----------------------------------- - int fpga_region_register(struct device *dev, - struct fpga_region *region); + int fpga_region_register(struct fpga_region *region); int fpga_region_unregister(struct fpga_region *region); An example of usage can be seen in the probe function of [3] diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index f634a8e..b3ba3e40 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -167,18 +167,36 @@ int fpga_region_program_fpga(struct fpga_region *region) } EXPORT_SYMBOL_GPL(fpga_region_program_fpga); -int fpga_region_register(struct device *dev, struct fpga_region *region) +/** + * fpga_region_create - alloc and init a struct fpga_region + * @dev: device parent + * @mgr: manager that programs this region + * @get_bridges: optional function to get bridges to a list + * + * Return: struct fpga_region or NULL + */ +struct fpga_region +*fpga_region_create(struct device *dev, + struct fpga_manager *mgr, + int (*get_bridges)(struct fpga_region *)) { + struct fpga_region *region; int id, ret = 0; + region = kzalloc(sizeof(*region), GFP_KERNEL); + if (!region) + return NULL; + id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL); if (id < 0) - return id; + goto err_free; + region->mgr = mgr; + region->get_bridges = get_bridges; mutex_init(®ion->mutex); INIT_LIST_HEAD(®ion->bridge_list); + device_initialize(®ion->dev); - region->dev.groups = region->groups; region->dev.class = fpga_region_class; region->dev.parent = dev; region->dev.of_node = dev->of_node; @@ -188,23 +206,47 @@ int fpga_region_register(struct device *dev, struct fpga_region *region) if (ret) goto err_remove; - ret = device_add(®ion->dev); - if (ret) - goto err_remove; - - return 0; + return region; err_remove: ida_simple_remove(&fpga_region_ida, id); - return ret; +err_free: + kfree(region); + + return NULL; +} +EXPORT_SYMBOL_GPL(fpga_region_create); + +/** + * fpga_region_free - free a struct fpga_region + * @region: FPGA region created by fpga_region_create + */ +void fpga_region_free(struct fpga_region *region) +{ + ida_simple_remove(&fpga_region_ida, region->dev.id); + kfree(region); +} +EXPORT_SYMBOL_GPL(fpga_region_free); + +/* + * fpga_region_register - register a FPGA region + * @region: FPGA region created by fpga_region_create + * Return: 0 or -errno + */ +int fpga_region_register(struct fpga_region *region) +{ + return device_add(®ion->dev); + } EXPORT_SYMBOL_GPL(fpga_region_register); -int fpga_region_unregister(struct fpga_region *region) +/* + * fpga_region_unregister - unregister a FPGA region + * @region: FPGA region + */ +void fpga_region_unregister(struct fpga_region *region) { device_unregister(®ion->dev); - - return 0; } EXPORT_SYMBOL_GPL(fpga_region_unregister); @@ -212,7 +254,7 @@ static void fpga_region_dev_release(struct device *dev) { struct fpga_region *region = to_fpga_region(dev); - ida_simple_remove(&fpga_region_ida, region->dev.id); + fpga_region_free(region); } /** diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c index 35e7e8c..9d681a1 100644 --- a/drivers/fpga/of-fpga-region.c +++ b/drivers/fpga/of-fpga-region.c @@ -422,20 +422,15 @@ static int of_fpga_region_probe(struct platform_device *pdev) if (IS_ERR(mgr)) return -EPROBE_DEFER; - region = devm_kzalloc(dev, sizeof(*region), GFP_KERNEL); + region = fpga_region_create(dev, mgr, of_fpga_region_get_bridges); if (!region) { ret = -ENOMEM; goto eprobe_mgr_put; } - region->mgr = mgr; - - /* Specify how to get bridges for this type of region. */ - region->get_bridges = of_fpga_region_get_bridges; - - ret = fpga_region_register(dev, region); + ret = fpga_region_register(region); if (ret) - goto eprobe_mgr_put; + goto eprobe_free; of_platform_populate(np, fpga_region_of_match, NULL, ®ion->dev); dev_set_drvdata(dev, region); @@ -444,6 +439,8 @@ static int of_fpga_region_probe(struct platform_device *pdev) return 0; +eprobe_free: + fpga_region_free(region); eprobe_mgr_put: fpga_mgr_put(mgr); return ret; diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h index b652031..f2e215b 100644 --- a/include/linux/fpga/fpga-region.h +++ b/include/linux/fpga/fpga-region.h @@ -14,7 +14,6 @@ * @info: FPGA image info * @priv: private data * @get_bridges: optional function to get bridges to a list - * @groups: optional attribute groups. */ struct fpga_region { struct device dev; @@ -24,7 +23,6 @@ struct fpga_region { struct fpga_image_info *info; void *priv; int (*get_bridges)(struct fpga_region *region); - const struct attribute_group **groups; }; #define to_fpga_region(d) container_of(d, struct fpga_region, dev) @@ -34,7 +32,12 @@ struct fpga_region *fpga_region_class_find( int (*match)(struct device *, const void *)); int fpga_region_program_fpga(struct fpga_region *region); -int fpga_region_register(struct device *dev, struct fpga_region *region); -int fpga_region_unregister(struct fpga_region *region); + +struct fpga_region +*fpga_region_create(struct device *dev, struct fpga_manager *mgr, + int (*get_bridges)(struct fpga_region *)); +void fpga_region_free(struct fpga_region *region); +int fpga_region_register(struct fpga_region *region); +void fpga_region_unregister(struct fpga_region *region); #endif /* _FPGA_REGION_H */