group driver that manages life cycle of a bunch of leaf driver instances. Signed-off-by: Sonal Santan <sonal.santan@xxxxxxxxxx> Signed-off-by: Max Zhen <max.zhen@xxxxxxxxxx> Signed-off-by: Lizhi Hou <lizhi.hou@xxxxxxxxxx> --- drivers/fpga/xrt/lib/Makefile | 1 + drivers/fpga/xrt/lib/group.c | 94 ++++++++++++++++++++++++++++++++++ drivers/fpga/xrt/lib/lib-drv.c | 18 ++++++- drivers/fpga/xrt/lib/lib-drv.h | 13 +++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 drivers/fpga/xrt/lib/group.c diff --git a/drivers/fpga/xrt/lib/Makefile b/drivers/fpga/xrt/lib/Makefile index fd2af2cbd1da..abf7d5341a69 100644 --- a/drivers/fpga/xrt/lib/Makefile +++ b/drivers/fpga/xrt/lib/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_FPGA_XRT_LIB) += xrt-lib.o xrt-lib-objs := \ lib-drv.o \ xroot.o \ + group.o \ xrt-bus.dtb.o ccflags-y := -I$(FULL_XRT_PATH)/include diff --git a/drivers/fpga/xrt/lib/group.c b/drivers/fpga/xrt/lib/group.c new file mode 100644 index 000000000000..feafc45ddb52 --- /dev/null +++ b/drivers/fpga/xrt/lib/group.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx Alveo FPGA Group Driver + * + * Copyright (C) 2020-2021 Xilinx, Inc. + * + * Authors: + * Cheng Zhen <maxz@xxxxxxxxxx> + */ + +#include <linux/kmod.h> +#include <linux/slab.h> +#include <linux/of.h> +#include <linux/xrt/xdevice.h> +#include "lib-drv.h" +#include "xroot.h" + +#define XRT_GRP "xrt_group" + +struct xgroup_leaf { + struct list_head node; + struct xrt_device *leaf_dev; +}; + +struct xgroup { + struct xrt_device *xdev; + struct list_head leaves; +}; + +static int xrt_grp_probe(struct xrt_device *xdev) +{ + struct xgroup_leaf *leaf; + struct xgroup *xg = NULL; + struct device_node *dn; + + dev_info(&xdev->dev, "probing\n"); + + xg = devm_kzalloc(&xdev->dev, sizeof(*xg), GFP_KERNEL); + if (!xg) + return -ENOMEM; + + xg->xdev = xdev; + INIT_LIST_HEAD(&xg->leaves); + xrt_set_drvdata(xdev, xg); + + for_each_child_of_node(xdev->dev.of_node, dn) { + leaf = kmalloc(sizeof(*leaf), GFP_KERNEL); + if (!leaf) + break; + + leaf->leaf_dev = xrt_device_register(&xdev->dev, dn, NULL, 0, NULL, 0); + if (!leaf->leaf_dev) { + kfree(leaf); + continue; + } + list_add(&leaf->node, &xg->leaves); + } + + return 0; +} + +static void xrt_grp_remove(struct xrt_device *xdev) +{ + struct xgroup *xg = xrt_get_drvdata(xdev); + struct xgroup_leaf *leaf, *tmp; + + list_for_each_entry_safe(leaf, tmp, &xg->leaves, node) { + list_del(&leaf->node); + xrt_device_unregister(leaf->leaf_dev); + kfree(leaf); + } +} + +static int xrt_grp_leaf_call(struct xrt_device *xdev, u32 cmd, void *arg) +{ + return 0; +} + +static const struct of_device_id group_match[] = { + { .compatible = "xlnx,xrt-group" }, + { } +}; + +static struct xrt_driver xrt_group_driver = { + .driver = { + .name = XRT_GRP, + .of_match_table = group_match, + }, + .probe = xrt_grp_probe, + .remove = xrt_grp_remove, + .leaf_call = xrt_grp_leaf_call, +}; + +XRT_LEAF_INIT_FINI_FUNC(group); diff --git a/drivers/fpga/xrt/lib/lib-drv.c b/drivers/fpga/xrt/lib/lib-drv.c index 3ad02a7c2aac..c9c654f692d4 100644 --- a/drivers/fpga/xrt/lib/lib-drv.c +++ b/drivers/fpga/xrt/lib/lib-drv.c @@ -200,9 +200,17 @@ xrt_device_register(struct device *parent, struct device_node *dn, return NULL; } +/* + * Leaf driver's module init/fini callbacks. This is not a open infrastructure for dynamic + * plugging in drivers. All drivers should be statically added. + */ +static void (*leaf_init_fini_cbs[])(bool) = { + group_leaf_init_fini, +}; + static __init int xrt_lib_init(void) { - int ret; + int ret, i; ret = of_overlay_fdt_apply(__dtb_xrt_bus_begin, __dtb_xrt_bus_end - __dtb_xrt_bus_begin, @@ -216,11 +224,19 @@ static __init int xrt_lib_init(void) return ret; } + for (i = 0; i < ARRAY_SIZE(leaf_init_fini_cbs); i++) + leaf_init_fini_cbs[i](true); + return 0; } static __exit void xrt_lib_fini(void) { + int i; + + for (i = 0; i < ARRAY_SIZE(leaf_init_fini_cbs); i++) + leaf_init_fini_cbs[i](false); + bus_unregister(&xrt_bus_type); of_overlay_remove(&xrt_bus_ovcs_id); } diff --git a/drivers/fpga/xrt/lib/lib-drv.h b/drivers/fpga/xrt/lib/lib-drv.h index 4bf8a32c7ec5..02d9b3731351 100644 --- a/drivers/fpga/xrt/lib/lib-drv.h +++ b/drivers/fpga/xrt/lib/lib-drv.h @@ -9,6 +9,19 @@ #ifndef _LIB_DRV_H_ #define _LIB_DRV_H_ +/* Module's init/fini routines for leaf driver in xrt-lib module */ +#define XRT_LEAF_INIT_FINI_FUNC(name) \ +void name##_leaf_init_fini(bool init) \ +{ \ + if (init) \ + xrt_register_driver(&xrt_##name##_driver); \ + else \ + xrt_unregister_driver(&xrt_##name##_driver); \ +} + +/* Module's init/fini routines for leaf driver in xrt-lib module */ +void group_leaf_init_fini(bool init); + extern u8 __dtb_xrt_bus_begin[]; extern u8 __dtb_xrt_bus_end[]; -- 2.27.0