From 102a0743326a03cd1a1202ceda21e175b7d3575c Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 20 Feb 2024 01:20:52 +0000 Subject: [PATCH] add new system file --- kernel/drivers/fpga/fpga-bridge.c | 84 +++++++++++++++++++++++++++++++---------- 1 files changed, 63 insertions(+), 21 deletions(-) diff --git a/kernel/drivers/fpga/fpga-bridge.c b/kernel/drivers/fpga/fpga-bridge.c index c983dac..851debe 100644 --- a/kernel/drivers/fpga/fpga-bridge.c +++ b/kernel/drivers/fpga/fpga-bridge.c @@ -19,11 +19,6 @@ /* Lock for adding/removing bridges to linked lists*/ static spinlock_t bridge_list_lock; -static int fpga_bridge_of_node_match(struct device *dev, const void *data) -{ - return dev->of_node == data; -} - /** * fpga_bridge_enable - Enable transactions on the bridge * @@ -104,8 +99,7 @@ { struct device *dev; - dev = class_find_device(fpga_bridge_class, NULL, np, - fpga_bridge_of_node_match); + dev = class_find_device_by_of_node(fpga_bridge_class, np); if (!dev) return ERR_PTR(-ENODEV); @@ -121,7 +115,7 @@ /** * fpga_bridge_get - get an exclusive reference to a fpga bridge * @dev: parent device that fpga bridge was registered with - * @info: fpga manager info + * @info: fpga image specific information * * Given a device, get an exclusive reference to a fpga bridge. * @@ -324,6 +318,9 @@ * @br_ops: pointer to structure of fpga bridge ops * @priv: FPGA bridge private data * + * The caller of this function is responsible for freeing the bridge with + * fpga_bridge_free(). Using devm_fpga_bridge_create() instead is recommended. + * * Return: struct fpga_bridge or NULL */ struct fpga_bridge *fpga_bridge_create(struct device *dev, const char *name, @@ -331,7 +328,7 @@ void *priv) { struct fpga_bridge *bridge; - int id, ret = 0; + int id, ret; if (!name || !strlen(name)) { dev_err(dev, "Attempt to register with no name!\n"); @@ -343,10 +340,8 @@ return NULL; id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); - if (id < 0) { - ret = id; + if (id < 0) goto error_kfree; - } mutex_init(&bridge->mutex); INIT_LIST_HEAD(&bridge->node); @@ -378,8 +373,8 @@ EXPORT_SYMBOL_GPL(fpga_bridge_create); /** - * fpga_bridge_free - free a fpga bridge and its id - * @bridge: FPGA bridge struct created by fpga_bridge_create + * fpga_bridge_free - free a fpga bridge created by fpga_bridge_create() + * @bridge: FPGA bridge struct */ void fpga_bridge_free(struct fpga_bridge *bridge) { @@ -388,9 +383,56 @@ } EXPORT_SYMBOL_GPL(fpga_bridge_free); +static void devm_fpga_bridge_release(struct device *dev, void *res) +{ + struct fpga_bridge *bridge = *(struct fpga_bridge **)res; + + fpga_bridge_free(bridge); +} + /** - * fpga_bridge_register - register a fpga bridge - * @bridge: FPGA bridge struct created by fpga_bridge_create + * devm_fpga_bridge_create - create and init a managed struct fpga_bridge + * @dev: FPGA bridge device from pdev + * @name: FPGA bridge name + * @br_ops: pointer to structure of fpga bridge ops + * @priv: FPGA bridge private data + * + * This function is intended for use in a FPGA bridge driver's probe function. + * After the bridge driver creates the struct with devm_fpga_bridge_create(), it + * should register the bridge with fpga_bridge_register(). The bridge driver's + * remove function should call fpga_bridge_unregister(). The bridge struct + * allocated with this function will be freed automatically on driver detach. + * This includes the case of a probe function returning error before calling + * fpga_bridge_register(), the struct will still get cleaned up. + * + * Return: struct fpga_bridge or NULL + */ +struct fpga_bridge +*devm_fpga_bridge_create(struct device *dev, const char *name, + const struct fpga_bridge_ops *br_ops, void *priv) +{ + struct fpga_bridge **ptr, *bridge; + + ptr = devres_alloc(devm_fpga_bridge_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + bridge = fpga_bridge_create(dev, name, br_ops, priv); + if (!bridge) { + devres_free(ptr); + } else { + *ptr = bridge; + devres_add(dev, ptr); + } + + return bridge; +} +EXPORT_SYMBOL_GPL(devm_fpga_bridge_create); + +/** + * fpga_bridge_register - register a FPGA bridge + * + * @bridge: FPGA bridge struct * * Return: 0 for success, error code otherwise. */ @@ -412,8 +454,11 @@ EXPORT_SYMBOL_GPL(fpga_bridge_register); /** - * fpga_bridge_unregister - unregister and free a fpga bridge - * @bridge: FPGA bridge struct created by fpga_bridge_create + * fpga_bridge_unregister - unregister a FPGA bridge + * + * @bridge: FPGA bridge struct + * + * This function is intended for use in a FPGA bridge driver's remove function. */ void fpga_bridge_unregister(struct fpga_bridge *bridge) { @@ -430,9 +475,6 @@ static void fpga_bridge_dev_release(struct device *dev) { - struct fpga_bridge *bridge = to_fpga_bridge(dev); - - fpga_bridge_free(bridge); } static int __init fpga_bridge_dev_init(void) -- Gitblit v1.6.2