summaryrefslogtreecommitdiffstats
path: root/Documentation/driver-api/fpga/fpga-programming.rst
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2026-09-02 09:55:01 -0400
committerSteven Rostedt <rostedt@goodmis.org>2026-09-02 11:08:21 -0400
commit4617721c502b2ddaa4e324e86da4997edf738fa5 (patch)
tree350aa83b47da0b574a814795392b20b0bed83cbc /Documentation/driver-api/fpga/fpga-programming.rst
downloadlinux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.tar.gz
linux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.zip
ftrace: Synchronize the initialization of ftrace_opsgrafted
There's some internal state that ftrace_ops needs to have set, but since it can be declared outside of the ftrace.c code, it calls ftrace_ops_init() on the ops in every global function. The issue is that if two tasks call it on the same ops at the same time it is possible to have the initialization of one corrupt the initialization of the other call. Create a ops_mutex to use to synchronize every initialization of the ftrace_ops. The mutex is taken within checking the ftrace_ops flag that states it was initializied but the flag is checked again after the mutex has been taken. Checking first outside the mutex allows it to shortcut having to take the mutex. But then the check needs to be done again after the mute is taken in case of races. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260902095501.6b59af20@gandalf.local.home Fixes: f04f24fb7e48d ("ftrace, kprobes: Fix a deadlock on ftrace_regex_lock") Reported-by: sashiko-bot@kernel.org Close: https://lore.kernel.org/all/20260829025528.49A831F000E9@smtp.kernel.org/ Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'Documentation/driver-api/fpga/fpga-programming.rst')
-rw-r--r--Documentation/driver-api/fpga/fpga-programming.rst107
1 files changed, 107 insertions, 0 deletions
diff --git a/Documentation/driver-api/fpga/fpga-programming.rst b/Documentation/driver-api/fpga/fpga-programming.rst
new file mode 100644
index 000000000..fb4da4240
--- /dev/null
+++ b/Documentation/driver-api/fpga/fpga-programming.rst
@@ -0,0 +1,107 @@
+In-kernel API for FPGA Programming
+==================================
+
+Overview
+--------
+
+The in-kernel API for FPGA programming is a combination of APIs from
+FPGA manager, bridge, and regions. The actual function used to
+trigger FPGA programming is fpga_region_program_fpga().
+
+fpga_region_program_fpga() uses functionality supplied by
+the FPGA manager and bridges. It will:
+
+ * lock the region's mutex
+ * lock the mutex of the region's FPGA manager
+ * build a list of FPGA bridges if a method has been specified to do so
+ * disable the bridges
+ * program the FPGA using info passed in :c:expr:`fpga_region->info`.
+ * re-enable the bridges
+ * release the locks
+
+The struct fpga_image_info specifies what FPGA image to program. It is
+allocated/freed by fpga_image_info_alloc() and freed with
+fpga_image_info_free()
+
+How to program an FPGA using a region
+-------------------------------------
+
+When the FPGA region driver probed, it was given a pointer to an FPGA manager
+driver so it knows which manager to use. The region also either has a list of
+bridges to control during programming or it has a pointer to a function that
+will generate that list. Here's some sample code of what to do next::
+
+ #include <linux/fpga/fpga-mgr.h>
+ #include <linux/fpga/fpga-region.h>
+
+ struct fpga_image_info *info;
+ int ret;
+
+ /*
+ * First, alloc the struct with information about the FPGA image to
+ * program.
+ */
+ info = fpga_image_info_alloc(dev);
+ if (!info)
+ return -ENOMEM;
+
+ /* Set flags as needed, such as: */
+ info->flags = FPGA_MGR_PARTIAL_RECONFIG;
+
+ /*
+ * Indicate where the FPGA image is. This is pseudo-code; you're
+ * going to use one of these three.
+ */
+ if (image is in a scatter gather table) {
+
+ info->sgt = [your scatter gather table]
+
+ } else if (image is in a buffer) {
+
+ info->buf = [your image buffer]
+ info->count = [image buffer size]
+
+ } else if (image is in a firmware file) {
+
+ info->firmware_name = devm_kstrdup(dev, firmware_name,
+ GFP_KERNEL);
+
+ }
+
+ /* Add info to region and do the programming */
+ region->info = info;
+ ret = fpga_region_program_fpga(region);
+
+ /* Deallocate the image info if you're done with it */
+ region->info = NULL;
+ fpga_image_info_free(info);
+
+ if (ret)
+ return ret;
+
+ /* Now enumerate whatever hardware has appeared in the FPGA. */
+
+API for programming an FPGA
+---------------------------
+
+* fpga_region_program_fpga() - Program an FPGA
+* fpga_image_info() - Specifies what FPGA image to program
+* fpga_image_info_alloc() - Allocate an FPGA image info struct
+* fpga_image_info_free() - Free an FPGA image info struct
+
+.. kernel-doc:: drivers/fpga/fpga-region.c
+ :functions: fpga_region_program_fpga
+
+FPGA Manager flags
+
+.. kernel-doc:: include/linux/fpga/fpga-mgr.h
+ :doc: FPGA Manager flags
+
+.. kernel-doc:: include/linux/fpga/fpga-mgr.h
+ :functions: fpga_image_info
+
+.. kernel-doc:: drivers/fpga/fpga-mgr.c
+ :functions: fpga_image_info_alloc
+
+.. kernel-doc:: drivers/fpga/fpga-mgr.c
+ :functions: fpga_image_info_free