fpga: mgr: API change to replace fpga load functions with single function

fpga-mgr has three methods for programming FPGAs, depending on
whether the image is in a scatter gather list, a contiguous
buffer, or a firmware file. This makes it difficult to write
upper layers as the caller has to assume whether the FPGA image
is in a sg table, as a single buffer, or a firmware file.
This commit moves these parameters to struct fpga_image_info
and adds a single function for programming fpgas.

New functions:
* fpga_mgr_load - given fpga manager and struct fpga_image_info,
   program the fpga.

* fpga_image_info_alloc - alloc a struct fpga_image_info.

* fpga_image_info_free - free a struct fpga_image_info.

These three functions are unexported:
* fpga_mgr_buf_load_sg
* fpga_mgr_buf_load
* fpga_mgr_firmware_load

Also use devm_kstrdup to copy firmware_name so we aren't making
assumptions about where it comes from when allocing/freeing the
struct fpga_image_info.

API documentation has been updated and a new document for
FPGA region has been added.

Signed-off-by: Alan Tull <atull@kernel.org>
Acked-by: Moritz Fischer <mdf@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt
index 78f197f..6ebc714 100644
--- a/Documentation/fpga/fpga-mgr.txt
+++ b/Documentation/fpga/fpga-mgr.txt
@@ -11,61 +11,53 @@
 The FPGA image data itself is very manufacturer specific, but for our purposes
 it's just binary data.  The FPGA manager core won't parse it.
 
+The FPGA image to be programmed can be in a scatter gather list, a single
+contiguous buffer, or a firmware file.  Because allocating contiguous kernel
+memory for the buffer should be avoided, users are encouraged to use a scatter
+gather list instead if possible.
+
+The particulars for programming the image are presented in a structure (struct
+fpga_image_info).  This struct contains parameters such as pointers to the
+FPGA image as well as image-specific particulars such as whether the image was
+built for full or partial reconfiguration.
 
 API Functions:
 ==============
 
-To program the FPGA from a file or from a buffer:
--------------------------------------------------
+To program the FPGA:
+--------------------
 
-	int fpga_mgr_buf_load(struct fpga_manager *mgr,
-			      struct fpga_image_info *info,
-		              const char *buf, size_t count);
+	int fpga_mgr_load(struct fpga_manager *mgr,
+			  struct fpga_image_info *info);
 
-Load the FPGA from an image which exists as a contiguous buffer in
-memory. Allocating contiguous kernel memory for the buffer should be avoided,
-users are encouraged to use the _sg interface instead of this.
-
-        int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,
-				 struct fpga_image_info *info,
-				 struct sg_table *sgt);
-
-Load the FPGA from an image from non-contiguous in memory. Callers can
-construct a sg_table using alloc_page backed memory.
-
-	int fpga_mgr_firmware_load(struct fpga_manager *mgr,
-				   struct fpga_image_info *info,
-		                   const char *image_name);
-
-Load the FPGA from an image which exists as a file.  The image file must be on
-the firmware search path (see the firmware class documentation).  If successful,
+Load the FPGA from an image which is indicated in the info.  If successful,
 the FPGA ends up in operating mode.  Return 0 on success or a negative error
 code.
 
-A FPGA design contained in a FPGA image file will likely have particulars that
-affect how the image is programmed to the FPGA.  These are contained in struct
-fpga_image_info.  Currently the only such particular is a single flag bit
-indicating whether the image is for full or partial reconfiguration.
+To allocate or free a struct fpga_image_info:
+---------------------------------------------
+
+	struct fpga_image_info *fpga_image_info_alloc(struct device *dev);
+
+	void fpga_image_info_free(struct fpga_image_info *info);
 
 To get/put a reference to a FPGA manager:
 -----------------------------------------
 
 	struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
 	struct fpga_manager *fpga_mgr_get(struct device *dev);
-
-Given a DT node or device, get an exclusive reference to a FPGA manager.
-
 	void fpga_mgr_put(struct fpga_manager *mgr);
 
-Release the reference.
+Given a DT node or device, get an exclusive reference to a FPGA manager.
+fpga_mgr_put releases the reference.
 
 
 To register or unregister the low level FPGA-specific driver:
 -------------------------------------------------------------
 
 	int fpga_mgr_register(struct device *dev, const char *name,
-		              const struct fpga_manager_ops *mops,
-		              void *priv);
+			      const struct fpga_manager_ops *mops,
+			      void *priv);
 
 	void fpga_mgr_unregister(struct device *dev);
 
@@ -78,23 +70,41 @@
 /* Include to get the API */
 #include <linux/fpga/fpga-mgr.h>
 
-/* device node that specifies the FPGA manager to use */
-struct device_node *mgr_node = ...
-
-/* FPGA image is in this buffer.  count is size of the buffer. */
-char *buf = ...
-int count = ...
-
-/* struct with information about the FPGA image to program. */
-struct fpga_image_info info;
-
-/* flags indicates whether to do full or partial reconfiguration */
-info.flags = 0;
-
+struct fpga_manager *mgr;
+struct fpga_image_info *info;
 int ret;
 
-/* Get exclusive control of FPGA manager */
-struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node);
+/* struct with information about the FPGA image to program. */
+info = fpga_image_info_alloc(dev);
+
+/* flags indicates whether to do full or partial reconfiguration */
+info->flags = FPGA_MGR_PARTIAL_RECONFIG;
+
+/*
+ * At this point, indicate where the 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);
+
+}
+
+/*
+ * Get a reference to FPGA manager.  This example uses the  device node of the
+ * manager.  You could use fpga_mgr_get() instead if you have the device instead
+ * of the device node.
+ */
+mgr = of_fpga_mgr_get(mgr_node);
 
 /* Load the buffer to the FPGA */
 ret = fpga_mgr_buf_load(mgr, &info, buf, count);
@@ -102,35 +112,8 @@
 /* Release the FPGA manager */
 fpga_mgr_put(mgr);
 
-
-How to write an image file to a supported FPGA
-==============================================
-/* Include to get the API */
-#include <linux/fpga/fpga-mgr.h>
-
-/* device node that specifies the FPGA manager to use */
-struct device_node *mgr_node = ...
-
-/* FPGA image is in this file which is in the firmware search path */
-const char *path = "fpga-image-9.rbf"
-
-/* struct with information about the FPGA image to program. */
-struct fpga_image_info info;
-
-/* flags indicates whether to do full or partial reconfiguration */
-info.flags = 0;
-
-int ret;
-
-/* Get exclusive control of FPGA manager */
-struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node);
-
-/* Get the firmware image (path) and load it to the FPGA */
-ret = fpga_mgr_firmware_load(mgr, &info, path);
-
-/* Release the FPGA manager */
-fpga_mgr_put(mgr);
-
+/* Deallocate the image info if you're done with it */
+fpga_image_info_free(info);
 
 How to support a new FPGA device
 ================================