From 093a89d4c21701e61025386a08a2d1ec5d97c805 Mon Sep 17 00:00:00 2001 From: Alan Tull Date: Mon, 16 Apr 2018 20:43:37 -0700 Subject: fpga: fpga-region: comment on fpga_region_program_fpga locking Add a comment to the header of fpga_region_program_fpga() regarding locking of the bridges. Signed-off-by: Alan Tull Signed-off-by: Moritz Fischer Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/fpga-region.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/fpga/fpga-region.c') diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index edab2a2e03ef..cb0603e07ff8 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -95,6 +95,11 @@ static void fpga_region_put(struct fpga_region *region) * fpga_region_program_fpga - program FPGA * @region: FPGA region * Program an FPGA using fpga image info (region->info). + * If the region has a get_bridges function, the exclusive reference for the + * bridges will be held if programming succeeds. This is intended to prevent + * reprogramming the region until the caller considers it safe to do so. + * The caller will need to call fpga_bridges_put() before attempting to + * reprogram the region. * Return 0 for success or negative error code. */ int fpga_region_program_fpga(struct fpga_region *region) -- cgit v1.2.2 From bbaa9cd3a605e337cefc566e5ac1b110763c8d1c Mon Sep 17 00:00:00 2001 From: Alan Tull Date: Wed, 16 May 2018 18:49:54 -0500 Subject: fpga: region: don't use drvdata in common fpga code Changes to fpga_region_register function to not set drvdata. Setting drvdata is fine for DT based devices that will have one region per platform device. However PCIe based devices may have multiple FPGA regions under one PCIe device. Without these changes, the PCIe solution has to create an extra device for each child region to hold drvdata. Signed-off-by: Alan Tull Reported-by: Jiuyue Ma Signed-off-by: Moritz Fischer Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/fpga-region.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/fpga/fpga-region.c') diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index cb0603e07ff8..f634a8ed5e2c 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -183,7 +183,6 @@ int fpga_region_register(struct device *dev, struct fpga_region *region) region->dev.parent = dev; region->dev.of_node = dev->of_node; region->dev.id = id; - dev_set_drvdata(dev, region); ret = dev_set_name(®ion->dev, "region%d", id); if (ret) -- cgit v1.2.2 From 9f368977b4589e2fe0b9d3a4cbaf11ff6a58ecf5 Mon Sep 17 00:00:00 2001 From: Alan Tull Date: Wed, 16 May 2018 18:49:57 -0500 Subject: fpga: region: change api, add fpga_region_create/free 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 Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/fpga-region.c | 68 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 13 deletions(-) (limited to 'drivers/fpga/fpga-region.c') diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index f634a8ed5e2c..b3ba3e40c44b 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -167,18 +167,36 @@ err_put_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); } /** -- cgit v1.2.2 From 473f01f7e4b9fc53d44c446ad22b39070c65393f Mon Sep 17 00:00:00 2001 From: Alan Tull Date: Wed, 16 May 2018 18:49:58 -0500 Subject: fpga: use SPDX Replace GPLv2 boilerplate with SPDX in FPGA code that came from me or from Altera. Signed-off-by: Alan Tull Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/fpga-region.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers/fpga/fpga-region.c') diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index b3ba3e40c44b..0878f62dd1fc 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -1,22 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * FPGA Region - Device Tree support for FPGA programming under Linux * * Copyright (C) 2013-2016 Altera Corporation * Copyright (C) 2017 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . */ - #include #include #include -- cgit v1.2.2 From 917a4304fe48c12d346f038c7d64da3f51bce53a Mon Sep 17 00:00:00 2001 From: Alan Tull Date: Wed, 16 May 2018 18:50:01 -0500 Subject: fpga: region: kernel-doc fixes Fix formatting and some cleanup for the kernel-doc documentation in fpga-region.c Signed-off-by: Alan Tull Acked-by: Moritz Fischer Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/fpga-region.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/fpga/fpga-region.c') diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index 0878f62dd1fc..112fa3a0f977 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -81,13 +81,16 @@ static void fpga_region_put(struct fpga_region *region) /** * fpga_region_program_fpga - program FPGA + * * @region: FPGA region + * * Program an FPGA using fpga image info (region->info). * If the region has a get_bridges function, the exclusive reference for the * bridges will be held if programming succeeds. This is intended to prevent * reprogramming the region until the caller considers it safe to do so. * The caller will need to call fpga_bridges_put() before attempting to * reprogram the region. + * * Return 0 for success or negative error code. */ int fpga_region_program_fpga(struct fpga_region *region) @@ -216,7 +219,7 @@ void fpga_region_free(struct fpga_region *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 @@ -228,7 +231,7 @@ int fpga_region_register(struct fpga_region *region) } EXPORT_SYMBOL_GPL(fpga_region_register); -/* +/** * fpga_region_unregister - unregister a FPGA region * @region: FPGA region */ -- cgit v1.2.2 From fdff4053d51be4850185aa895813405decd6e956 Mon Sep 17 00:00:00 2001 From: Alan Tull Date: Wed, 16 May 2018 18:50:06 -0500 Subject: fpga: clarify that unregister functions also free The following functions also free the struct. Add that fact to the function documentation. - fpga_mgr_free - fpga_bridge_free - fpga_region_free Signed-off-by: Alan Tull Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/fpga-region.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/fpga/fpga-region.c') diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index 112fa3a0f977..6d214d75c7be 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -232,7 +232,7 @@ int fpga_region_register(struct fpga_region *region) EXPORT_SYMBOL_GPL(fpga_region_register); /** - * fpga_region_unregister - unregister a FPGA region + * fpga_region_unregister - unregister and free a FPGA region * @region: FPGA region */ void fpga_region_unregister(struct fpga_region *region) -- cgit v1.2.2