|  | 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 |